1 /* $NetBSD: mmcformat.c,v 1.2 2008/05/18 13:08:58 tron Exp $ */
4 * Copyright (c) 2006, 2008 Reinoud Zandijk
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 #include <sys/types.h>
47 extern int scsilib_verbose
;
49 /* #define DEBUG(a) {a;} */
58 gettimeofday(&tp
, NULL
);
59 return (uint64_t) 1000000 * tp
.tv_sec
+ tp
.tv_usec
;
64 print_eta(uint32_t progress
, uint64_t now
, uint64_t start_time
)
66 int hours
, minutes
, seconds
;
67 uint64_t tbusy
, ttot_est
, eta
;
70 printf(" ETA --:--:--");
73 tbusy
= now
- start_time
;
74 ttot_est
= (tbusy
* 0x10000) / progress
;
75 eta
= (ttot_est
- tbusy
) / 1000000;
77 hours
= (int) (eta
/3600);
78 minutes
= (int) (eta
/60) % 60;
79 seconds
= (int) eta
% 60;
80 printf(" ETA %02d:%02d:%02d", hours
, minutes
, seconds
);
85 uscsi_waitop(struct uscsi_dev
*mydev
)
88 struct uscsi_sense sense
;
95 bzero(cmd
, SCSI_CMD_LEN
);
96 bzero(buffer
, sizeof(buffer
));
99 * not be to unpatient... give the drive some time to start or it
103 start_time
= getmtime();
107 while (progress
< 0x10000) {
108 /* we need a command that is NOT going to stop the formatting */
109 bzero(cmd
, SCSI_CMD_LEN
);
110 cmd
[0] = 0; /* test unit ready */
111 uscsi_command(SCSI_READCMD
, mydev
,
112 cmd
, 6, buffer
, 0, 10000, &sense
);
115 * asc may be `not-ready' or `no-sense'. ascq for format in
120 if (((asc
== 0) && (ascq
== 4)) || (asc
== 4)) {
121 /* drive not ready : operation/format in progress */
122 if (sense
.skey_valid
) {
123 progress
= sense
.sense_key
;
129 /* check if drive is ready again, ifso break out loop */
130 if ((asc
== 0) && (ascq
== 0)) {
134 printf("%3d %% ", (100 * progress
/ 0x10000));
135 printf("%c", "|/-\\" [cnt
++ %4]); /* twirl */
138 print_eta(progress
, getmtime(), start_time
);
142 printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
152 print_mmc_profile(int profile
)
154 static char scrap
[100];
157 case 0x00 : return "Unknown[0] profile";
158 case 0x01 : return "Non removeable disc";
159 case 0x02 : return "Removable disc";
160 case 0x03 : return "Magneto Optical with sector erase";
161 case 0x04 : return "Magneto Optical write once";
162 case 0x05 : return "Advance Storage Magneto Optical";
163 case 0x08 : return "CD-ROM";
164 case 0x09 : return "CD-R recordable";
165 case 0x0a : return "CD-RW rewritable";
166 case 0x10 : return "DVD-ROM";
167 case 0x11 : return "DVD-R sequential";
168 case 0x12 : return "DVD-RAM rewritable";
169 case 0x13 : return "DVD-RW restricted overwrite";
170 case 0x14 : return "DVD-RW sequential";
171 case 0x1a : return "DVD+RW rewritable";
172 case 0x1b : return "DVD+R recordable";
173 case 0x20 : return "DDCD readonly";
174 case 0x21 : return "DDCD-R recordable";
175 case 0x22 : return "DDCD-RW rewritable";
176 case 0x2b : return "DVD+R double layer";
177 case 0x40 : return "BD-ROM";
178 case 0x41 : return "BD-R Sequential Recording (SRM)";
179 case 0x42 : return "BD-R Random Recording (RRM)";
180 case 0x43 : return "BD-RE rewritable";
182 sprintf(scrap
, "Reserved profile 0x%02x", profile
);
188 uscsi_get_mmc_profile(struct uscsi_dev
*mydev
, int *mmc_profile
)
196 bzero(cmd
, SCSI_CMD_LEN
);
197 cmd
[ 0] = 0x46; /* Get configuration */
198 cmd
[ 8] = 32; /* just a small buffer size */
199 cmd
[ 9] = 0; /* control */
200 error
= uscsi_command(SCSI_READCMD
, mydev
, cmd
, 10, buf
, 32, 30000, NULL
);
202 *mmc_profile
= buf
[7] | (buf
[6] << 8);
210 uscsi_set_packet_parameters(struct uscsi_dev
*mydev
, int blockingnr
)
214 uint8_t res
[10000], *pos
;
217 /* Set up CD/DVD recording parameters */
218 DEBUG(printf("Setting device's recording parameters\n"));
225 bzero(cmd
, SCSI_CMD_LEN
);
226 pos
[ 0] = 0x05; /* page code 5 : cd writing */
227 pos
[ 1] = 0x32; /* length in bytes */
228 pos
[ 2] = 0; /* write type 0 : packet/incremental */
230 /* next session OK, data packet, rec. incr. fixed packets */
231 pos
[ 3] = (3<<6) | 32 | 5;
232 pos
[ 4] = 10; /* ISO mode 2; XA form 1 */
233 pos
[ 8] = 0x20; /* CD-ROM XA disc or DDCD disc */
234 pos
[10] = (blockingnr
>> 24) & 0xff; /* MSB packet size */
235 pos
[11] = (blockingnr
>> 16) & 0xff;
236 pos
[12] = (blockingnr
>> 8) & 0xff;
237 pos
[13] = (blockingnr
) & 0xff; /* LSB packet size */
239 bzero(cmd
, SCSI_CMD_LEN
);
240 cmd
[0] = 0x55; /* MODE SELECT (10) */
241 cmd
[1] = 16; /* PF format */
242 cmd
[7] = val_len
>> 8; /* length of blob */
243 cmd
[8] = val_len
& 0xff;
244 cmd
[9] = 0; /* control */
246 error
= uscsi_command(SCSI_WRITECMD
, mydev
,
247 cmd
, 10, res
, val_len
, 30000, NULL
);
249 perror("While WRTITING parameter page 5");
259 get_format_capabilities(struct uscsi_dev
*mydev
, uint8_t *buf
, uint32_t *len
)
264 size_t buf_len
= 512;
267 assert(*len
>= buf_len
);
270 trans_len
= 12; /* only fixed header first */
271 bzero(cmd
, SCSI_CMD_LEN
);
272 cmd
[0] = 0x23; /* Read format capabilities */
273 cmd
[7] = trans_len
>> 8; /* MSB allocation length */
274 cmd
[8] = trans_len
& 0xff; /* LSB allocation length */
275 cmd
[9] = 0; /* control */
276 error
= uscsi_command(SCSI_READCMD
, mydev
,
277 cmd
, 10, buf
, trans_len
, 30000, NULL
);
279 fprintf(stderr
, "While reading format capabilities : %s\n",
284 list_length
= buf
[ 3];
286 if (list_length
% 8) {
287 printf( "\t\tWarning: violating SCSI spec,"
288 "capacity list length ought to be multiple of 8\n");
289 printf("\t\tInterpreting as including header of 4 bytes\n");
290 assert(list_length
% 8 == 4);
294 /* read in full capacity list */
295 trans_len
= 12 + list_length
; /* complete structure */
296 bzero(cmd
, SCSI_CMD_LEN
);
297 cmd
[0] = 0x23; /* Read format capabilities */
298 cmd
[7] = trans_len
>> 8; /* MSB allocation length */
299 cmd
[8] = trans_len
& 0xff; /* LSB allocation length */
300 cmd
[9] = 0; /* control */
301 error
= uscsi_command(SCSI_READCMD
, mydev
,
302 cmd
, 10, buf
, trans_len
, 30000, NULL
);
304 fprintf(stderr
, "While reading format capabilities : %s\n",
315 print_format(int format_tp
, uint32_t num_blks
, uint32_t param
,
316 int dscr_type
, int verbose
, int *supported
)
318 char const *format_str
, *nblks_str
, *param_str
, *user_spec
;
320 format_str
= nblks_str
= param_str
= "reserved";
326 format_str
= "full format capacity";
327 nblks_str
= "sectors";
328 param_str
= "block length in bytes";
329 user_spec
= "'-F [-b blockingnr]'";
332 format_str
= "spare area expansion";
333 nblks_str
= "extension in blocks";
334 param_str
= "block length in bytes";
337 /* 0x02 - 0x03 reserved */
339 format_str
= "variable length zone'd format";
340 nblks_str
= "zone length";
341 param_str
= "zone number";
345 format_str
= "fixed length zone'd format";
346 nblks_str
= "zone lenght";
347 param_str
= "last zone number";
350 /* 0x06 - 0x0f reserved */
352 format_str
= "CD-RW/DVD-RW full packet format";
353 nblks_str
= "adressable blocks";
354 param_str
= "fixed packet size/ECC blocksize in sectors";
355 user_spec
= "'-F -p [-b blockingnr]'";
358 format_str
= "CD-RW/DVD-RW grow session";
359 nblks_str
= "adressable blocks";
360 param_str
= "fixed packet size/ECC blocksize in sectors";
364 format_str
= "CD-RW/DVD-RW add session";
365 nblks_str
= "adressable blocks";
366 param_str
= "maximum fixed packet size/ECC blocksize "
371 format_str
= "DVD-RW max growth of last complete session";
372 nblks_str
= "adressable blocks";
373 param_str
= "ECC blocksize in sectors";
377 format_str
= "DVD-RW quick grow last session";
378 nblks_str
= "adressable blocks";
379 param_str
= "ECC blocksize in sectors";
383 format_str
= "DVD-RW quick full format";
384 nblks_str
= "adressable blocks";
385 param_str
= "ECC blocksize in sectors";
388 /* 0x16 - 0x23 reserved */
390 format_str
= "background MRW format";
391 nblks_str
= "Defect Management Area blocks";
392 param_str
= "not used";
393 user_spec
= "'[-R] [-s] [-w] -F -M [-b blockingnr]'";
397 format_str
= "background DVD+RW full format";
398 nblks_str
= "sectors";
399 param_str
= "not used";
400 user_spec
= "'[-R] [-w] -F'";
402 /* 0x27 - 0x2f reserved */
404 format_str
= "BD-RE full format with spare area";
405 nblks_str
= "blocks";
406 param_str
= "total spare area size in clusters";
407 user_spec
= "'[-s] -F'";
410 format_str
= "BD-RE full format without spare area";
411 nblks_str
= "blocks";
412 param_str
= "block length in bytes";
415 /* 0x32 - 0x3f reserved */
421 printf("\n\tFormat type 0x%02x : %s\n", format_tp
, format_str
);
425 printf( "\t\tUnformatted media,"
426 "maximum formatted capacity\n");
429 printf( "\t\tFormatted media,"
430 "current formatted capacity\n");
433 printf( "\t\tNo media present or incomplete session, "
434 "maximum formatted capacity\n");
437 printf("\t\tUnspecified descriptor type\n");
441 printf("\t\tNumber of blocks : %12d\t(%s)\n",
442 num_blks
, nblks_str
);
443 printf("\t\tParameter : %12d\t(%s)\n",
446 if (format_tp
== 0x24) {
447 printf( "\t\tExpert select : "
448 "'-X 0x%02x:0xffffff:0' or "
449 "'-X 0x%02x:0xffff0000:0'\n",
450 format_tp
, format_tp
);
452 printf( "\t\tExpert select : "
453 "'-X 0x%02x:%d:%d'\n",
454 format_tp
, num_blks
, param
);
457 printf("\t\tmmc_format arg : %s\n", user_spec
);
459 printf("\t\t** not supported **\n");
466 process_format_caps(uint8_t *buf
, int list_length
, int verbose
,
467 uint8_t *allow
, uint32_t *blks
, uint32_t *params
)
469 uint32_t num_blks
, param
;
471 int dscr_type
, format_tp
;
476 bzero(params
, 255*4);
479 list_length
-= 4; /* strip header */
482 printf("\tCurrent/max capacity followed by additional capacity,"
483 "reported length of %d bytes (8/entry)\n", list_length
);
485 while (list_length
> 0) {
486 num_blks
= fcd
[ 3] | (fcd
[ 2] << 8) |
487 (fcd
[ 1] << 16) | (fcd
[ 0] << 24);
488 dscr_type
= fcd
[ 4] & 3;
489 format_tp
= fcd
[ 4] >> 2;
490 param
= fcd
[ 7] | (fcd
[ 6] << 8) | (fcd
[ 5] << 16);
492 print_format(format_tp
, num_blks
, param
, dscr_type
, verbose
,
495 allow
[format_tp
] = 1; /* TODO = supported? */
496 blks
[format_tp
] = num_blks
;
497 params
[format_tp
] = param
;
506 /* format a CD-RW disc */
507 /* old style format 7 */
509 uscsi_format_cdrw_mode7(struct uscsi_dev
*mydev
, uint32_t blocks
)
512 struct uscsi_sense sense
;
520 blocks
-= blocks
% 32;
523 bzero(cmd
, SCSI_CMD_LEN
);
524 bzero(buffer
, sizeof(buffer
));
526 cmd
[0] = 0x04; /* format unit */
527 cmd
[1] = 0x17; /* parameter list format 7 follows */
528 cmd
[5] = 0; /* control */
530 /* format list header */
531 buffer
[ 0] = 0; /* reserved */
532 buffer
[ 1] = 0x80 | 0x02; /* Valid info, immediate return */
533 buffer
[ 2] = 0; /* MSB format descriptor length */
534 buffer
[ 3] = 8; /* LSB ... */
537 * for CD-RW the initialisation pattern bit is reserved, but there IS
541 buffer
[ 4] = 0; /* no header */
542 buffer
[ 5] = 0; /* default pattern */
543 buffer
[ 6] = 0; /* pattern length MSB */
544 buffer
[ 7] = 0; /* pattern length LSB */
546 /* 8 bytes of format descriptor */
547 /* (s)ession bit 1<<7, (g)row bit 1<<6 */
549 /* 00 format disc with number of user data blocks */
550 /* 10 create new session with number of data blocks */
551 /* x1 grow session to be number of data blocks */
553 buffer
[ 8] = 0x00; /* session and grow bits (7 and 6) */
554 buffer
[ 9] = 0; /* reserved */
555 buffer
[10] = 0; /* reserved */
556 buffer
[11] = 0; /* reserved */
557 buffer
[12] = (blocks
>> 24) & 0xff; /* blocks MSB */
558 buffer
[13] = (blocks
>> 16) & 0xff;
559 buffer
[14] = (blocks
>> 8) & 0xff;
560 buffer
[15] = (blocks
) & 0xff; /* blocks LSB */
562 /* this will take a while .... */
563 error
= uscsi_command(SCSI_WRITECMD
, mydev
,
564 cmd
, 6, buffer
, sizeof(buffer
), UINT_MAX
, &sense
);
574 uscsi_format_disc(struct uscsi_dev
*mydev
, int immed
, int format_type
,
575 uint32_t blocks
, uint32_t param
, int certification
, int cmplist
)
578 struct uscsi_sense sense
;
579 uint8_t buffer
[16], fmt_flags
;
582 fmt_flags
= 0x80; /* valid info flag */
585 if (certification
== 0)
592 if (mmc_profile
!= 0x43) {
593 /* certification specifier only valid for BD-RE */
598 bzero(cmd
, SCSI_CMD_LEN
);
599 bzero(buffer
, sizeof(buffer
));
601 cmd
[0] = 0x04; /* format unit */
602 cmd
[1] = 0x11 | cmplist
; /* parameter list format 1 follows */
603 cmd
[5] = 0; /* control */
605 /* format list header */
606 buffer
[ 0] = 0; /* reserved */
607 buffer
[ 1] = 0x80 | fmt_flags
; /* Valid info, flags follow */
608 buffer
[ 2] = 0; /* MSB format descriptor length */
609 buffer
[ 3] = 8; /* LSB ... */
611 /* 8 bytes of format descriptor */
612 buffer
[ 4] = (blocks
>> 24) & 0xff; /* blocks MSB */
613 buffer
[ 5] = (blocks
>> 16) & 0xff;
614 buffer
[ 6] = (blocks
>> 8) & 0xff;
615 buffer
[ 7] = (blocks
) & 0xff; /* blocks LSB */
616 buffer
[ 8] = (format_type
<< 2) | certification
;
617 buffer
[ 9] = (param
>> 16) & 0xff; /* parameter MSB */
618 buffer
[10] = (param
>> 8) & 0xff; /* packet size */
619 buffer
[11] = (param
) & 0xff; /* parameter LSB */
621 /* this will take a while .... */
622 error
= uscsi_command(SCSI_WRITECMD
, mydev
,
623 cmd
, 6, buffer
, 12, UINT_MAX
, &sense
);
635 uscsi_blank_disc(struct uscsi_dev
*mydev
)
640 /* XXX check if the device can blank! */
644 bzero(cmd
, SCSI_CMD_LEN
);
645 cmd
[ 0] = 0xA1; /* blank */
646 cmd
[ 1] = 16; /* Immediate, blank complete */
647 cmd
[11] = 0; /* control */
649 /* this will take a while .... */
650 error
= uscsi_command(SCSI_WRITECMD
, mydev
,
651 cmd
, 12, NULL
, 0, UINT_MAX
, NULL
);
663 fprintf(stderr
, "\n");
664 fprintf(stderr
, "Usage: %s [options] devicename\n", program
);
666 "-B blank cd-rw disc before formatting\n"
667 "-F format cd-rw disc\n"
668 "-O CD-RW formatting 'old-style' for old CD-RW drives\n"
669 "-M select MRW format\n"
670 "-R restart MRW & DVD+RW format\n"
671 "-G grow last CD-RW/DVD-RW session\n"
672 "-S grow spare space DVD-RAM/BD-RE\n"
673 "-s format DVD+MRW/BD-RE with extra spare space\n"
674 "-w wait until completion of background format\n"
675 "-p explicitly set packet format\n"
676 "-c num media certification for DVD-RAM/BD-RE : "
677 "0 no, 1 full, 2 quick\n"
678 "-r recompile defect list for DVD-RAM (cmplist)\n"
679 "-h -H -I help/inquiry formats\n"
680 "-X format expert format selector form 'fmt:blks:param' with -c\n"
681 "-b blockingnr in sectors (for CD-RW)\n"
682 "-D verbose SCSI command errors\n"
694 main(int argc
, char *argv
[])
696 struct uscsi_addr saddr
;
697 uint32_t blks
[256], params
[256];
698 uint32_t format_type
, format_blks
, format_param
, blockingnr
;
701 uint32_t caps_len
= sizeof(caps
);
703 int blank
, format
, mrw
, background
;
704 int inquiry
, spare
, oldtimer
;
706 int restart_format
, grow_session
, grow_spare
, packet_wr
;
707 int mmc_profile
, flag
, error
, display_usage
;
708 int certification
, cmplist
;
709 int wait_until_finished
;
710 progname
= strdup(argv
[0]);
712 return usage(progname
);
721 wait_until_finished
= 0;
732 uscsilib_verbose
= 0;
733 while ((flag
= getopt(argc
, argv
, "BFMRGSwpsc:rhHIX:Ob:D")) != -1) {
754 wait_until_finished
= 1;
763 certification
= atoi(optarg
);
775 /* TODO parse expert mode string */
776 printf("-X not implemented yet\n");
781 /* oldtimer CD-RW format */
786 blockingnr
= atoi(optarg
);
789 uscsilib_verbose
= 1;
792 return usage(progname
);
798 if ((!blank
&& !format
&& !grow_session
&& !grow_spare
) &&
799 (!expert
&& !inquiry
)) {
800 fprintf(stderr
, "%s : at least one of -B, -F, -G, -S, -X or -I "
801 "needs to be specified\n\n", progname
);
802 return usage(progname
);
805 if (format
+ grow_session
+ grow_spare
+ expert
> 1) {
806 fprintf(stderr
, "%s : at most one of -F, -G, -S or -X "
807 "needs to be specified\n\n", progname
);
808 return usage(progname
);
811 if (argc
!= 1) return usage(progname
);
813 /* Open the device */
814 dev
.dev_name
= strdup(*argv
);
815 printf("Opening device %s\n", dev
.dev_name
);
816 error
= uscsi_open(&dev
);
818 fprintf(stderr
, "Device failed to open : %s\n",
823 error
= uscsi_check_for_scsi(&dev
);
825 fprintf(stderr
, "sorry, not a SCSI/ATAPI device : %s\n",
830 error
= uscsi_identify(&dev
, &saddr
);
832 fprintf(stderr
, "SCSI/ATAPI identify returned : %s\n",
837 printf("\nDevice identifies itself as : ");
839 if (saddr
.type
== USCSI_TYPE_SCSI
) {
840 printf("SCSI busnum = %d, target = %d, lun = %d\n",
841 saddr
.addr
.scsi
.scbus
, saddr
.addr
.scsi
.target
,
842 saddr
.addr
.scsi
.lun
);
844 printf("ATAPI busnum = %d, drive = %d\n",
845 saddr
.addr
.atapi
.atbus
, saddr
.addr
.atapi
.drive
);
850 /* get MMC profile */
851 error
= uscsi_get_mmc_profile(&dev
, &mmc_profile
);
854 "Can't get the disc's MMC profile because of :"
855 " %s\n", strerror(error
));
856 fprintf(stderr
, "aborting\n");
861 /* blank disc section */
863 printf("\nBlanking disc.... "); fflush(stdout
);
864 error
= uscsi_blank_disc(&dev
);
867 printf("fail\n"); fflush(stdout
);
869 "Blanking failed because of : %s\n",
875 printf("success!\n\n");
879 /* re-get MMC profile */
880 error
= uscsi_get_mmc_profile(&dev
, &mmc_profile
);
883 "Can't get the disc's MMC profile because of : %s\n",
885 fprintf(stderr
, "aborting\n");
890 error
= get_format_capabilities(&dev
, caps
, &caps_len
);
894 process_format_caps(caps
, caps_len
, inquiry
, allow
, blks
, params
);
897 /* expert format section */
901 if (!format
&& !grow_spare
&& !grow_session
) {
909 /* normal format section */
911 /* get current mmc profile of disc */
913 if (oldtimer
&& mmc_profile
!= 0x0a) {
914 printf("Oldtimer flag only defined for CD-RW; "
918 switch (mmc_profile
) {
919 case 0x12 : /* DVD-RAM */
922 case 0x0a : /* CD-RW */
923 format_type
= mrw
? 0x24 : 0x10;
926 case 0x13 : /* DVD-RW restricted overwrite */
927 case 0x14 : /* DVD-RW sequential */
930 * Some drives suddenly stop supporting this format
931 * type when packet_wr = 1
935 case 0x1a : /* DVD+RW */
936 format_type
= mrw
? 0x24 : 0x26;
938 case 0x43 : /* BD-RE */
939 format_type
= spare
? 0x30 : 0x31;
942 fprintf(stderr
, "Can't format discs of type %s\n",
943 print_mmc_profile(mmc_profile
));
950 switch (mmc_profile
) {
951 case 0x12 : /* DVD-RAM */
952 case 0x43 : /* BD-RE */
957 "Can't grow spare area for discs of type %s\n",
958 print_mmc_profile(mmc_profile
));
965 switch (mmc_profile
) {
966 case 0x0a : /* CD-RW */
969 case 0x13 : /* DVD-RW restricted overwrite */
970 case 0x14 : /* DVD-RW sequential ? */
976 "Can't grow session for discs of type %s\n",
977 print_mmc_profile(mmc_profile
));
982 /* check if format type is allowed */
983 format_blks
= blks
[format_type
];
984 format_param
= params
[format_type
];
985 if (!allow
[format_type
]) {
987 process_format_caps(caps
, caps_len
, 1, allow
,
993 "Drive indicates it can't format with deduced format "
994 "type 0x%02x\n", format_type
);
999 if (restart_format
&& !((mmc_profile
== 0x1a) || (format_type
== 0x24)))
1002 "Format restarting only for MRW formats or DVD+RW "
1008 if (restart_format
&& !wait_until_finished
) {
1009 printf( "Warning : format restarting without waiting for it be "
1010 "finished is prolly not handy\n");
1013 /* explicitly select packet write just in case */
1015 printf("Explicitly setting packet type and blocking number\n");
1016 error
= uscsi_set_packet_parameters(&dev
, blockingnr
);
1019 "Can't set packet writing and blocking number: "
1020 "%s\n", strerror(error
));
1026 /* determine if formatting is done in the background */
1028 if (format_type
== 0x24) background
= 1;
1029 if (format_type
== 0x26) background
= 1;
1031 /* special case format type 0x24 : MRW */
1032 if (format_type
== 0x24) {
1033 format_blks
= spare
? 0xffff0000 : 0xffffffff;
1034 format_param
= restart_format
;
1036 /* special case format type 0x26 : DVD+RW */
1037 if (format_type
== 0x26) {
1038 format_param
= restart_format
;
1041 /* verbose to the user */
1043 printf("Actual format selected: "
1044 "format_type 0x%02x, blks %d, param %d, "
1045 "certification %d, cmplist %d\n",
1046 format_type
, format_blks
, format_param
,
1047 certification
, cmplist
);
1049 printf("\nFormatting.... "); fflush(stdout
);
1051 /* formatting time! */
1053 error
= uscsi_format_cdrw_mode7(&dev
, format_blks
);
1056 error
= uscsi_format_disc(&dev
, !background
, format_type
,
1057 format_blks
, format_param
, certification
,
1063 printf("fail\n"); fflush(stdout
);
1064 fprintf(stderr
, "Formatting failed because of : %s\n",
1068 printf("background formatting in progress\n");
1069 if (wait_until_finished
) {
1070 printf("Waiting for completion ... ");
1073 /* explicitly do NOT close disc ... (for now) */
1076 printf("success!\n\n");