2
** sg_format : format a SCSI disk
3
** potentially with a different number of blocks and block size
5
** formerly called blk512-linux.c (v0.4)
7
** Copyright (C) 2003 Grant Grundler grundler at parisc-linux dot org
8
** Copyright (C) 2003 James Bottomley jejb at parisc-linux dot org
9
** Copyright (C) 2005-2006 Douglas Gilbert dgilbert at interlog dot com
11
** This program is free software; you can redistribute it and/or modify
12
** it under the terms of the GNU General Public License as published by
13
** the Free Software Foundation; either version 2, or (at your option)
16
** http://www.t10.org/scsi-3.htm
17
** http://www.tldp.org/HOWTO/SCSI-Generic-HOWTO
20
** List of some (older) disk manufacturers' block counts.
21
** These are not needed in newer disks which will automatically use
22
** the manufacturers' recommended block count if a count of -1 is given.
23
** Inquiry Block Count (@512 byte blocks)
25
** IBM_DCHS04F 8888543
26
** IBM_DGHS09Y 17916240
27
** ST336704FC 71132960
28
** ST318304FC 35145034 (Factory spec is 35885167 sectors)
30
** ST336753FC 71132960 (Factory spec is 71687372 sectors)
43
#define RW_ERROR_RECOVERY_PAGE 1 /* every disk should have one */
44
#define FORMAT_DEV_PAGE 3 /* Format Device Mode Page [now obsolete] */
45
#define CONTROL_MODE_PAGE 0xa /* alternative page all devices have?? */
47
#define SHORT_TIMEOUT 20 /* 20 seconds unless immed=0 ... */
48
#define FORMAT_TIMEOUT (4 * 3600) /* 4 hours ! */
50
#define POLL_DURATION_SECS 30
53
#define MAX_BUFF_SZ 252
54
static unsigned char dbuff[MAX_BUFF_SZ];
56
static char * version_str = "1.09 20060623";
58
static struct option long_options[] = {
61
{"format", 0, 0, 'F'},
65
{"resize", 0, 0, 'r'},
66
{"rto_req", 0, 0, 'R'},
69
{"verbose", 0, 0, 'v'},
70
{"version", 0, 0, 'V'},
75
/* Return 0 on success, else see sg_ll_format_unit() */
77
scsi_format(int fd, int pinfo, int rto_req, int immed, int early, int verbose)
80
const char FORMAT_HEADER_SIZE = 4;
81
unsigned char fmt_hdr[FORMAT_HEADER_SIZE];
83
/* fmt_hdr is a short format header, only used when 'immed' is set */
84
fmt_hdr[0] = 0; /* reserved */
85
fmt_hdr[1] = 0x2; /* use device defaults, IMMED return */
86
fmt_hdr[2] = 0; /* defect list length MSB */
87
fmt_hdr[3] = 0; /* defect list length LSB */
89
res = sg_ll_format_unit(fd, pinfo, rto_req, 0 /* longlist */,
90
(!! immed) /* fmtdata */, 0 /* cmplist */,
92
(immed ? SHORT_TIMEOUT : FORMAT_TIMEOUT),
93
fmt_hdr, (immed ? sizeof(fmt_hdr) : 0),
99
case SG_LIB_CAT_NOT_READY:
100
fprintf(stderr, "Format command, device not ready\n");
102
case SG_LIB_CAT_INVALID_OP:
103
fprintf(stderr, "Format command not supported\n");
105
case SG_LIB_CAT_ILLEGAL_REQ:
106
fprintf(stderr, "Format command, illegal parameter\n");
108
case SG_LIB_CAT_UNIT_ATTENTION:
109
fprintf(stderr, "Format command, unit attention\n");
112
fprintf(stderr, "Format command failed\n");
121
printf("\nFormat has started\n");
124
printf("Format continuing, request sense or test "
125
"unit ready can be used to monitor progress\n");
132
sleep(POLL_DURATION_SECS);
134
res = sg_ll_test_unit_ready_progress(fd, 0, &progress, 0,
137
printf("Format in progress, %d%% done\n",
138
(progress * 100) / 65536);
142
printf("FORMAT Complete\n");
146
#define RCAP_REPLY_LEN 32
149
print_read_cap(int fd, int do_16, int verbose)
152
unsigned char resp_buff[RCAP_REPLY_LEN];
153
unsigned int last_blk_addr, block_size;
154
unsigned long long llast_blk_addr;
157
res = sg_ll_readcap_16(fd, 0 /* pmi */, 0 /* llba */,
158
resp_buff, 32, 0, verbose);
160
for (k = 0, llast_blk_addr = 0; k < 8; ++k) {
161
llast_blk_addr <<= 8;
162
llast_blk_addr |= resp_buff[k];
164
block_size = ((resp_buff[8] << 24) |
165
(resp_buff[9] << 16) |
166
(resp_buff[10] << 8) |
168
printf("Read Capacity (16) results:\n");
169
printf(" Protection: prot_en=%d, rto_en=%d\n",
170
!!(resp_buff[12] & 0x1),
171
!!(resp_buff[12] & 0x2));
172
printf(" Number of blocks=%llu\n",
174
printf(" Block size=%u bytes\n", block_size);
175
return (int)block_size;
178
res = sg_ll_readcap_10(fd, 0 /* pmi */, 0 /* lba */,
179
resp_buff, 8, 0, verbose);
181
last_blk_addr = ((resp_buff[0] << 24) |
182
(resp_buff[1] << 16) |
183
(resp_buff[2] << 8) |
185
block_size = ((resp_buff[4] << 24) |
186
(resp_buff[5] << 16) |
187
(resp_buff[6] << 8) |
189
printf("Read Capacity (10) results:\n");
190
printf(" Number of blocks=%u\n",
192
printf(" Block size=%u bytes\n", block_size);
193
return (int)block_size;
196
if (SG_LIB_CAT_NOT_READY == res)
197
fprintf(stderr, "READ CAPACITY (%d): device not ready\n",
199
else if (SG_LIB_CAT_INVALID_OP == res)
200
fprintf(stderr, "READ CAPACITY (%d) not supported\n",
202
else if (SG_LIB_CAT_ILLEGAL_REQ == res)
203
fprintf(stderr, "bad field in READ CAPACITY (%d) "
204
"cdb\n", (do_16 ? 16 : 10));
206
fprintf(stderr, "READ CAPACITY (%d) failed "
207
"[res=%d]\n", (do_16 ? 16 : 10), res);
213
printf("usage: sg_format [--count=<block count>] [--early] [--format]"
215
" [--long] [--pinfo] [--resize] [--rto_req] "
217
" [--size=<block size>] [--verbose]"
218
" [--version] [--wait]\n"
221
" --count=<block count> | -c <block count>\n"
222
" best left alone during format (defaults "
223
"to max allowable)\n"
224
" --early | -e exit once format started (user can "
225
"monitor progress)\n"
226
" --format | -F format unit (default report current count"
228
" --help | -h prints out this usage message\n"
229
" --long | -l allow for 64 bit lbas (default: assume "
231
" --pinfo | -p set the FMTPINFO bit to format with "
233
printf( " information (defaults to no protection "
235
" --resize | -r resize (rather than format) to '--count' "
237
" --rto_req | -R set the RTO_REQ bit in format (only valid "
239
" --six | -6 use 6 byte MODE SENSE/SELECT\n"
240
" --size=<block size> | -s <block size>\n"
241
" only needed to change block size"
243
" current device's block size)\n"
244
" --verbose | -v verbosity (show commands + parameters "
246
" use multiple time for more verbosity\n"
247
" --version | -V print version details and exit\n"
248
" --wait | -w format command waits till complete (def: "
250
"\tExample: sg_format --format /dev/sdc\n\n"
251
"This utility formats or resizes SCSI disks.\n");
252
printf("WARNING: This utility will destroy all the data on the "
253
"target device when\n\t '--format' is given. Check that you "
254
"have the correct device.\n");
258
int main(int argc, char **argv)
260
const int mode_page = RW_ERROR_RECOVERY_PAGE;
261
int fd, res, calc_len, bd_len, dev_specific_param;
262
int offset, j, bd_blk_len, prob, len;
263
unsigned long long ull;
264
long long blk_count = 0; /* -c value */
265
int blk_size = 0; /* -s value */
266
int format = 0; /* -F */
267
int resize = 0; /* -r */
268
int verbose = 0; /* -v */
269
int fwait = 0; /* -w */
276
char device_name[256];
278
struct sg_simple_inquiry_resp inq_out;
281
device_name[0] = '\0';
283
int option_index = 0;
286
c = getopt_long(argc, argv, "c:eFhlprRs:vVw6",
287
long_options, &option_index);
293
if (0 == strcmp("-1", optarg))
296
blk_count = sg_get_llnum(optarg);
297
if (-1 == blk_count) {
298
fprintf(stderr, "bad argument to "
300
return SG_LIB_SYNTAX_ERROR;
327
blk_size = sg_get_num(optarg);
329
fprintf(stderr, "bad argument to '--size', "
331
return SG_LIB_SYNTAX_ERROR;
338
fprintf(stderr, "sg_format version: %s\n",
349
return SG_LIB_SYNTAX_ERROR;
353
if ('\0' == device_name[0]) {
354
strncpy(device_name, argv[optind],
355
sizeof(device_name) - 1);
356
device_name[sizeof(device_name) - 1] = '\0';
361
for (; optind < argc; ++optind)
362
fprintf(stderr, "Unexpected extra argument: %s\n",
365
return SG_LIB_SYNTAX_ERROR;
367
if ('\0' == device_name[0]) {
368
fprintf(stderr, "no device name given\n");
370
return SG_LIB_SYNTAX_ERROR;
374
fprintf(stderr, "both '--format' and '--resize'"
377
return SG_LIB_SYNTAX_ERROR;
378
} else if (0 == blk_count) {
379
fprintf(stderr, "'--resize' needs a '--count' (other"
382
return SG_LIB_SYNTAX_ERROR;
383
} else if (0 != blk_size) {
384
fprintf(stderr, "'--resize' not compatible with "
387
return SG_LIB_SYNTAX_ERROR;
391
/* FIXME: add more sanity checks:
392
** o block size/count might already be set...don't repeat
393
** o verify SCSI device is a disk (get inquiry data first)
396
if ((fd = sg_cmds_open_device(device_name, 0 /* rw */, verbose)) < 0) {
397
fprintf(stderr, "error opening device file: %s: %s\n",
398
device_name, safe_strerror(-fd));
399
return SG_LIB_FILE_ERROR;
402
if (sg_simple_inquiry(fd, &inq_out, 1, verbose)) {
403
fprintf(stderr, "%s doesn't respond to a SCSI INQUIRY\n",
405
ret = SG_LIB_CAT_OTHER;
408
printf(" %.8s %.16s %.4s peripheral_type: %s [0x%x]\n",
409
inq_out.vendor, inq_out.product, inq_out.revision,
410
sg_get_pdt_str(inq_out.peripheral_type, sizeof(pdt_name),
412
inq_out.peripheral_type);
414
printf(" PROTECT=%d\n", !!(inq_out.byte_5 & 1));
415
if (inq_out.byte_5 & 1)
416
printf(" << supports 'protection information'>>\n");
418
if ((0 != inq_out.peripheral_type) &&
419
(0xe != inq_out.peripheral_type)) {
420
fprintf(stderr, "This format is only defined for disks "
421
"(using SBC-2 or RBC)\n");
422
ret = SG_LIB_CAT_MALFORMED;
426
memset(dbuff, 0, MAX_BUFF_SZ);
428
res = sg_ll_mode_sense6(fd, 0 /* DBD */, 0 /* current */,
429
mode_page, 0 /* subpage */, dbuff,
430
MAX_BUFF_SZ, 1, verbose);
432
res = sg_ll_mode_sense10(fd, long_lba, 0 /* DBD */,
433
0 /* current */, mode_page,
434
0 /* subpage */, dbuff,
435
MAX_BUFF_SZ, 1, verbose);
438
if (SG_LIB_CAT_NOT_READY == res)
439
fprintf(stderr, "MODE SENSE (%d) command, device "
440
"not ready\n", (mode6 ? 6 : 10));
441
else if (SG_LIB_CAT_UNIT_ATTENTION == res)
442
fprintf(stderr, "MODE SENSE (%d) command, unit "
443
"attention\n", (mode6 ? 6 : 10));
444
else if (SG_LIB_CAT_INVALID_OP == res) {
445
fprintf(stderr, "MODE SENSE (%d) command is not "
446
"supported\n", (mode6 ? 6 : 10));
447
fprintf(stderr, " try again %s the '--six' "
448
"option\n", (mode6 ? "without" : "with"));
450
} else if (SG_LIB_CAT_ILLEGAL_REQ == res) {
451
if (long_lba && (! mode6))
452
fprintf(stderr, "bad field in MODE SENSE "
453
"(%d) [longlba flag not supported?]"
454
"\n", (mode6 ? 6 : 10));
456
fprintf(stderr, "bad field in MODE SENSE "
457
"(%d) [mode_page %d not supported?]"
458
"\n", (mode6 ? 6 : 10), mode_page);
460
fprintf(stderr, "MODE SENSE (%d) command failed\n",
463
fprintf(stderr, " try '-v' for more "
468
calc_len = dbuff[0] + 1;
469
dev_specific_param = dbuff[2];
473
/* prepare for mode select */
478
calc_len = (dbuff[0] << 8) + dbuff[1] + 2;
479
dev_specific_param = dbuff[3];
480
bd_len = (dbuff[6] << 8) + dbuff[7];
481
long_lba = (dbuff[4] & 1);
483
/* prepare for mode select */
489
if ((offset + bd_len) < calc_len)
490
dbuff[offset + bd_len] &= 0x7f; /* clear PS bit in mpage */
493
printf("Mode sense (block descriptor) data, prior to changes:\n");
494
if (dev_specific_param & 0x40)
495
printf(" <<< Write Protect (WP) bit set >>>\n");
498
for (j = 0; j < (long_lba ? 8 : 4); ++j) {
501
ull |= dbuff[offset + j];
504
bd_blk_len = (dbuff[offset + 12] << 24) +
505
(dbuff[offset + 13] << 16) +
506
(dbuff[offset + 14] << 8) +
509
bd_blk_len = (dbuff[offset + 5] << 16) +
510
(dbuff[offset + 6] << 8) +
513
printf(" <<< longlba flag set (64 bit lba) >>>\n");
516
} else if (bd_len != 8)
518
printf(" Number of blocks=%llu [0x%llx]\n", ull, ull);
519
printf(" Block size=%d [0x%x]\n", bd_blk_len, bd_blk_len);
521
printf(" No block descriptors present\n");
525
(format && ((blk_count != 0) ||
526
((blk_size > 0) && (blk_size != bd_blk_len))))) {
527
/* want to run MODE SELECT */
529
/* Working Draft SCSI Primary Commands - 3 (SPC-3) pg 255
531
** If the SCSI device doesn't support changing its capacity by changing
532
** the NUMBER OF BLOCKS field using the MODE SELECT command, the value
533
** in the NUMBER OF BLOCKS field is ignored. If the device supports changing
534
** its capacity by changing the NUMBER OF BLOCKS field, then the
535
** NUMBER OF BLOCKS field is interpreted as follows:
536
** a) If the number of blocks is set to zero, the device shall retain
537
** its current capacity if the block size has not changed. If the
538
** number of blocks is set to zero and the block size has changed,
539
** the device shall be set to its maximum capacity when the new
540
** block size takes effect;
542
** b) If the number of blocks is greater than zero and less than or
543
** equal to its maximum capacity, the device shall be set to that
544
** number of blocks. If the block size has not changed, the device
545
** shall not become format corrupted. This capacity setting shall be
546
** retained through power cycles, hard resets, logical unit resets,
547
** and I_T nexus losses;
549
** c) If the number of blocks field is set to a value greater than the
550
** maximum capacity of the device and less than FFFF FFFFh, then the
551
** command is terminated with a CHECK CONDITION status. The sense key
552
** is set to ILLEGAL REQUEST. The device shall retain its previous
553
** block descriptor settings; or
555
** d) If the number of blocks is set to FFFF FFFFh, the device shall be
556
** set to its maximum capacity. If the block size has not changed,
557
** the device shall not become format corrupted. This capacity setting
558
** shall be retained through power cycles, hard resets, logical unit
559
** resets, and I_T nexus losses.
563
fprintf(stderr, "Need to perform MODE SELECT (to "
564
"change number or blocks or block length)\n");
565
fprintf(stderr, "but (single) block descriptor not "
566
"found in earlier MODE SENSE\n");
567
ret = SG_LIB_CAT_MALFORMED;
570
if (blk_count != 0) {
571
len = (long_lba ? 8 : 4);
572
for (j = 0; j < len; ++j)
574
(blk_count >> ((len - j - 1) * 8)) & 0xff;
575
} else if ((blk_size > 0) && (blk_size != bd_blk_len)) {
576
len = (long_lba ? 8 : 4);
577
for (j = 0; j < len; ++j)
578
dbuff[offset + j] = 0;
580
if ((blk_size > 0) && (blk_size != bd_blk_len)) {
582
dbuff[offset + 12] = (blk_size >> 24) & 0xff;
583
dbuff[offset + 13] = (blk_size >> 16) & 0xff;
584
dbuff[offset + 14] = (blk_size >> 8) & 0xff;
585
dbuff[offset + 15] = blk_size & 0xff;
587
dbuff[offset + 5] = (blk_size >> 16) & 0xff;
588
dbuff[offset + 6] = (blk_size >> 8) & 0xff;
589
dbuff[offset + 7] = blk_size & 0xff;
593
res = sg_ll_mode_select6(fd, 1 /* PF */, 1 /* SP */,
594
dbuff, calc_len, 1, verbose);
596
res = sg_ll_mode_select10(fd, 1 /* PF */, 1 /* SP */,
597
dbuff, calc_len, 1, verbose);
600
if (SG_LIB_CAT_NOT_READY == res)
601
fprintf(stderr, "MODE SELECT command, "
602
"device not ready\n");
603
else if (SG_LIB_CAT_UNIT_ATTENTION == res)
604
fprintf(stderr, "MODE SELECT command, "
606
else if (SG_LIB_CAT_INVALID_OP == res)
607
fprintf(stderr, "MODE SELECT (%d) command is "
608
"not supported\n", (mode6 ? 6 : 10));
609
else if (SG_LIB_CAT_ILLEGAL_REQ == res)
610
fprintf(stderr, "bad field in MODE SELECT "
611
"(%d)\n", (mode6 ? 6 : 10));
613
fprintf(stderr, "MODE SELECT (%d) command "
614
"failed\n", (mode6 ? 6 : 10));
616
fprintf(stderr, " try '-v' for "
617
"more information\n");
622
printf("Resize operation seems to have been successful\n");
626
res = print_read_cap(fd, do_rcap16, verbose);
629
if ((res > 0) && (bd_blk_len > 0) &&
630
(res != (int)bd_blk_len)) {
631
printf(" Warning: mode sense and read capacity "
632
"report different block sizes [%d,%d]\n",
634
printf(" Probably needs format\n");
636
printf("No changes made. To format use '--format'. To "
637
"resize use '--resize'\n");
643
printf("\nA FORMAT will commence in 10 seconds\n");
644
printf(" ALL data on %s will be DESTROYED\n", device_name);
645
printf(" Press control-C to abort\n");
647
printf("A FORMAT will commence in 5 seconds\n");
648
printf(" ALL data on %s will be DESTROYED\n", device_name);
649
printf(" Press control-C to abort\n");
651
res = scsi_format(fd, pinfo, rto_req, ! fwait, early,
655
fprintf(stderr, "FORMAT failed\n");
657
fprintf(stderr, " try '-v' for more "
661
fprintf(stderr, "FORMAT ignored, testing\n");
665
res = sg_cmds_close_device(fd);
667
fprintf(stderr, "close error: %s\n", safe_strerror(-res));
669
return SG_LIB_FILE_ERROR;
671
return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;