From d6fde268240cfe329650626c81040787cfe07ef6 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Tue, 22 Apr 2008 16:13:05 +0000 Subject: [PATCH] Adjustments with DVD-RAM formatting --- cdrskin/cdrskin.1 | 28 +++++++- cdrskin/cdrskin.c | 14 ++-- cdrskin/cdrskin_timestamp.h | 2 +- libburn/drive.c | 16 +++-- libburn/libburn.h | 13 ++-- libburn/mmc.c | 129 ++++++++++++++++++++++++------------ libburn/transport.h | 5 ++ 7 files changed, 149 insertions(+), 58 deletions(-) diff --git a/cdrskin/cdrskin.1 b/cdrskin/cdrskin.1 index 9d3267a..cb4a29b 100644 --- a/cdrskin/cdrskin.1 +++ b/cdrskin/cdrskin.1 @@ -2,7 +2,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH CDRSKIN 1 "April 17, 2008" +.TH CDRSKIN 1 "April 22, 2008" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -383,6 +383,32 @@ This option treats already formatted media even if not option -force is given. For DVD+RW this is the only supported explicit formatting type. It provides complete "de-icing" so no reader slips on unwritten data areas. .TP +format_defectmgt +Format DVD-RAM to reserve a generous amount of spare blocks for defect +management. +.br +The following format_defectmgt_* allow to submit user wishes which +nevertheless have to match one of the available formats. These formats are +offered by the drive after examining the media. +.TP +format_defectmgt_max +Format DVD-RAM to reserve a maximum number of spare blocks. +.TP +format_defectmgt_min +Format DVD-RAM to reserve a minimum number of spare blocks. It might be +necessary to format format_defectmgt_none first in order to get +offered the most minmal spare blocks sizes for format_defectmgt_min. +.TP +format_defectmgt_none +Format DVD-RAM to the largest available payload in the hope to disable +defect management at all. This seems not to have a speed increasing effect, +though. +.TP +format_defectmgt_payload_ +The text after "format_defectmgt_payload_" gives a number of bytes, eventually +with suffixes "s", "k", "m". The largest number of spare blocks will be chosen +which allows at least the given payload size. +.TP deformat_sequential Like blank=all but with the additional ability to blank overwriteable DVD-RW. This will destroy their formatting and make them sequentially recordable. diff --git a/cdrskin/cdrskin.c b/cdrskin/cdrskin.c index d5e7f34..e8d1fa3 100644 --- a/cdrskin/cdrskin.c +++ b/cdrskin/cdrskin.c @@ -6995,19 +6995,21 @@ set_blank:; skin->preskin->demands_cdrskin_caps= 1; } else if(strncmp(cpt,"format_defectmgt",16)==0) { skin->do_blank= 1; - skin->blank_format_type= 4; + skin->blank_format_type= 4|(3<<9); /* default payload size */ skin->blank_format_size= 0; skin->preskin->demands_cdrskin_caps= 1; if(cpt[16]=='_') { cpt+= 17; if(strcmp(cpt,"none")==0) - skin->blank_format_type|= (1<<13); + skin->blank_format_type= 4|(1<<13); else if(strcmp(cpt,"max")==0) - ; + skin->blank_format_type= 4; /* smallest payload size above 0 */ else if(strcmp(cpt,"min")==0) - skin->blank_format_type|= (1<<10); - else if(isdigit(*cpt)) - skin->blank_format_size= Scanf_io_size(cpt,0); + skin->blank_format_type= 4|(2<<9); /*largest payload size with mgt*/ + else if(strncmp(cpt,"payload_",8)==0) { + skin->blank_format_size= Scanf_io_size(cpt+8,0); + skin->blank_format_type= 4; + } } } else if(strcmp(cpt,"deformat_sequential")==0) { skin->do_blank= 1; diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index ca43351..22c2fa3 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2008.04.18.194602" +#define Cdrskin_timestamP "2008.04.22.161139" diff --git a/libburn/drive.c b/libburn/drive.c index d5e7fa0..ae8eec1 100644 --- a/libburn/drive.c +++ b/libburn/drive.c @@ -1260,7 +1260,7 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname) d->current_is_supported_profile = 1; d->block_types[BURN_WRITE_TAO] = BURN_BLOCK_MODE1; d->block_types[BURN_WRITE_SAO] = BURN_BLOCK_SAO; - d->media_capacity_remaining = size; + burn_drive_set_media_capacity_remaining(d, size); /* >>> ? open file for a test ? (>>> beware of "-" = stdin) */; @@ -1872,8 +1872,8 @@ off_t burn_disc_available_space(struct burn_drive *d, return 0; if (d->drive_role != 1) { if (d->media_capacity_remaining <= 0) - d->media_capacity_remaining = - ((off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048); + burn_drive_set_media_capacity_remaining(d, + (off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048); } else { if (o != NULL) d->send_write_parameters(d, o); @@ -2105,7 +2105,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt, o->start_adr = 1; size = d->media_capacity_remaining; burn_os_stdio_capacity(d->devname, &size); - d->media_capacity_remaining = size; + burn_drive_set_media_capacity_remaining(d, size); o->start_range_high = size; o->start_alignment = 2048; /* imposting a drive, not a file */ o->might_do_sao = 4; @@ -2456,3 +2456,11 @@ int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid) } +/* ts A80422 : centralizing this setting for debugging purposes +*/ +int burn_drive_set_media_capacity_remaining(struct burn_drive *d, off_t value) +{ + d->media_capacity_remaining = value; + return 1; +} + diff --git a/libburn/libburn.h b/libburn/libburn.h index 31c383a..abb66fa 100644 --- a/libburn/libburn.h +++ b/libburn/libburn.h @@ -1178,13 +1178,18 @@ void burn_disc_erase(struct burn_drive *drive, int fast); @param drive The drive with the disc to format. @param size The size in bytes to be used with the format command. It should be divisible by 32*1024. The effect of this parameter may - depend on the media profile. + depend on the media profile and on parameter flag. @param flag Bitfield for control purposes: bit0= after formatting, write the given number of zero-bytes to the media and eventually perform preliminary closing. - bit1= insist in size 0 even if there is a better default known - bit2= without bit7: format to maximum available size - with bit7 : take size from indexed format descriptor + bit1+2: size mode + 0 = use parameter size as far as it makes sense + 1 = insist in size 0 even if there is a better default known + (has no effect on DVD-RAM or BD-RE) + 2 = without bit7: format to maximum available size + with bit7 : take size from indexed format descriptor + 3 = without bit7: format to default size + with bit7 : take size from indexed format descriptor bit3= -reserved- bit4= enforce re-format of (partly) formatted media bit5= try to disable eventual defect management diff --git a/libburn/mmc.c b/libburn/mmc.c index 440d8e9..fdce318 100644 --- a/libburn/mmc.c +++ b/libburn/mmc.c @@ -367,7 +367,8 @@ int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa) return 0; } if (num > 0) { - d->media_capacity_remaining = ((off_t) num) * ((off_t) 2048); + burn_drive_set_media_capacity_remaining(d, + ((off_t) num) * ((off_t) 2048)); d->media_lba_limit = *nwa + num; } else d->media_lba_limit = 0; @@ -1049,9 +1050,9 @@ int mmc_fake_toc(struct burn_drive *d) if (session_number > d->disc->sessions) { if (i == d->last_track_no - 1) { /* ts A70212 : Last track field Free Blocks */ - d->media_capacity_remaining = + burn_drive_set_media_capacity_remaining(d, ((off_t) mmc_four_char_to_int(tdata + 16)) * - ((off_t) 2048); + ((off_t) 2048)); d->media_lba_limit = 0; } continue; @@ -2355,6 +2356,12 @@ static int mmc_read_format_capacities_al(struct burn_drive *d, */ d->format_curr_max_size *= (off_t) 2048; + if((d->current_profile == 0x12 || d->current_profile == 0x43) + && d->media_capacity_remaining == 0) { + burn_drive_set_media_capacity_remaining(d, + d->format_curr_max_size); + d->media_lba_limit = d->format_curr_max_size / 2048; + } if (top_wanted == 0x00 || top_wanted == 0x10) sign = -1; /* the caller clearly desires full format */ @@ -2387,11 +2394,6 @@ static int mmc_read_format_capacities_al(struct burn_drive *d, /* Criterion is proximity to quick intermediate state */ if (type == 0x00) { /* full format (with lead out) */ score = 1 * sign; - if(d->current_profile == 0x12 && - d->media_capacity_remaining == 0) { - d->media_capacity_remaining = size; - d->media_lba_limit = num_blocks; - } } else if (type == 0x10) { /* DVD-RW full format */ score = 10 * sign; } else if(type == 0x13) { /* DVD-RW quick grow last session */ @@ -2399,12 +2401,13 @@ static int mmc_read_format_capacities_al(struct burn_drive *d, } else if(type == 0x15) { /* DVD-RW Quick */ score = 50 * sign; if(d->current_profile == 0x13) { - d->media_capacity_remaining = size; + burn_drive_set_media_capacity_remaining(d, + size); d->media_lba_limit = num_blocks; } } else if(type == 0x26) { /* DVD+RW */ score = 1 * sign; - d->media_capacity_remaining = size; + burn_drive_set_media_capacity_remaining(d, size); d->media_lba_limit = num_blocks; } else { continue; @@ -2560,8 +2563,12 @@ int mmc_read_buffer_capacity(struct burn_drive *d) and mmc5r03c.pdf, 6.5 FORMAT UNIT */ /* @param size The size (in bytes) to be sent with the FORMAT comand - @param flag bit1= insist in size 0 even if there is a better default known - bit2= format to maximum available size + @param flag bit1+2: size mode + 0 = use parameter size as far as it makes sense + 1 = insist in size 0 even if there is a better default known + 2 = without bit7: format to maximum available size + with bit7 : take size from indexed format descriptor + 3 = format to default size bit3= expand format up to at least size bit4= enforce re-format of (partly) formatted media bit5= try to disable eventual defect management @@ -2573,13 +2580,14 @@ int mmc_format_unit(struct burn_drive *d, off_t size, int flag) struct buffer buf; struct command c; int ret, tolerate_failure = 0, return_immediately = 0, i, format_type; - int index, format_sub_type = 0; - off_t num_of_blocks = 0, diff, format_size; + int index, format_sub_type = 0, format_00_index, size_mode; + off_t num_of_blocks = 0, diff, format_size, i_size, format_00_max_size; char msg[160],descr[80]; int full_format_type = 0x00; /* Full Format (or 0x10 for DVD-RW ?) */ if (mmc_function_spy(d, "mmc_format_unit") <= 0) return 0; + size_mode = (flag >> 1) & 3; scsi_init_command(&c, MMC_FORMAT_UNIT, sizeof(MMC_FORMAT_UNIT)); /* @@ -2650,6 +2658,8 @@ selected_not_suitable:; /* mmc5r03c.pdf , 6.5.4.2.14, DVD+RW Basic Format */ format_type = 0x26; + /* >>> ??? is this "| 8" a bug ? */ + if ((size <= 0 && !(flag & 2)) || (flag & (4 | 8))) { /* maximum capacity */ memset(c.page->data + 4, 0xff, 4); @@ -2753,33 +2763,65 @@ no_suitable_formatting_type:; } else if (d->current_profile == 0x12) { /* ts A80417 : DVD-RAM */ - index = -1; - format_size = -1; + /* 6.5.4.2.1 Format Type = 00h (Full Format) + 6.5.4.2.2 Format Type = 01h (Spare Area Expansion) + */ + index = format_00_index = -1; + format_size = format_00_max_size = -1; for (i = 0; i < d->num_format_descr; i++) { format_type = d->format_descriptors[i].type; - if (format_type!=0x00 && format_type!=0x01) + i_size = d->format_descriptors[i].size; + if (format_type != 0x00 && format_type != 0x01) continue; - if(flag & (4 | 32)) { /* Max size or no defect mgt */ - /* Search for largest 0x00 or 0x01 - format descriptor */; - if (d->format_descriptors[i].size>format_size){ - format_size = - d->format_descriptors[i].size; - index = i; - } - } else { - /* Search for smallest 0x0 or 0x01 - descriptor >= size */; - if (d->format_descriptors[i].size >= size && - (format_size < 0 || - d->format_descriptors[i].sizeformat_descriptors[i].size; + if (flag & 32) { /* No defect mgt */ + /* Search for largest 0x00 format descriptor */ + if (format_type != 0x00) + continue; + if (i_size < format_size) + continue; + format_size = i_size; + index = i; + continue; + } else if (flag & 4) { /*Max or default size with mgt*/ + /* Search for second largest 0x00 + format descriptor. For max size allow + format type 0x01. + */ + if (format_type == 0x00) { + if (i_size < format_size) + continue; + if (i_size < format_00_max_size) { + format_size = i_size; + index = i; + continue; + } + format_size = format_00_max_size; + index = format_00_index; + format_00_max_size = i_size; + format_00_index = i; + continue; + } + if (size_mode==3) + continue; + if (i_size > format_size) { + format_size = i_size; index = i; } + continue; + } + /* Search for smallest 0x0 or 0x01 + descriptor >= size */; + if (d->format_descriptors[i].size >= size && + (format_size < 0 || i_size < format_size) + ) { + format_size = i_size; + index = i; } } + if(index < 0 && (flag & 4) && !(flag & 32)) { + format_size = format_00_max_size; + index = format_00_index; + } if(index < 0) goto no_suitable_formatting_type; format_type = d->format_descriptors[index].type; @@ -2797,7 +2839,6 @@ no_suitable_formatting_type:; DCRT: Disable Certification and maintain number of blocks c.page->data[1] |= 0x20; */ - /* <<< ts A80418 : experiment: MMC-5 6.5.4.2.1.2 Override maintaining of number of blocks with DCRT c.opcode[1] |= 0x08; @@ -2843,7 +2884,7 @@ unsuitable_media:; libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); - sprintf(msg, "Format list "); + sprintf(msg, "Format list: "); for (i = 0; i < 12; i++) sprintf(msg + strlen(msg), "%2.2X ", c.page->data[i]); strcat(msg, "\n"); @@ -2851,17 +2892,21 @@ unsuitable_media:; LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); - - /* <<< - if(d->current_profile == 0x12 || d->current_profile == 0x43) { +/* + # define Libburn_do_not_format_dvd_raM 1 +*/ + if(d->current_profile == 0x43 +#ifdef Libburn_do_not_format_dvd_raM + || d->current_profile == 0x12 +#endif + ) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, - LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_ZERO, - "Formatting of DVD-RAM or BD-RE not implemented yet", + LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_ZERO, + "Formatting of BD-RE not implemented yet - This is a dummy", 0, 0); return 1; } - */ d->issue_command(d, &c); if (c.error && !tolerate_failure) { diff --git a/libburn/transport.h b/libburn/transport.h index 5904c5f..22c2000 100644 --- a/libburn/transport.h +++ b/libburn/transport.h @@ -353,4 +353,9 @@ struct burn_drive /* end of generic 'drive' data structures */ +/* ts A80422 : centralizing this setting for debugging purposes +*/ +int burn_drive_set_media_capacity_remaining(struct burn_drive *d, off_t value); + + #endif /* __TRANSPORT */