Prepared support for DVD-RW in mode Restricted Overwrite

ZeroThreeEight
Thomas Schmitt 16 years ago
parent 6e9c399930
commit c05d6550cb
  1. 9
      cdrskin/cdrskin.c
  2. 2
      cdrskin/cdrskin_timestamp.h
  3. 2
      libburn/libdax_msgs.h
  4. 83
      libburn/mmc.c
  5. 11
      libburn/mmc.h
  6. 26
      libburn/spc.c
  7. 120
      libburn/write.c

@ -3781,6 +3781,9 @@ int Cdrskin_atip(struct CdrskiN *skin, int flag)
}
if(strstr(profile_name,"DVD")==profile_name) {
printf("book type: %s (emulated booktype)\n", profile_name);
if(profile_number==0x13)
printf(
"cdrskin: for sdvdbackup: \"(growisofs mode Restricted Overwrite)\"\n");
} else {
printf("ATIP info from disk:\n");
if(burn_disc_erasable(drive)) {
@ -4293,13 +4296,14 @@ int Cdrskin_activate_write_mode(struct CdrskiN *skin, enum burn_disc_status s,
int flag)
{
int ok, was_still_default= 0, block_type_demand,track_type,sector_size, i;
int profile_number= -1;
struct burn_drive_info *drive_info = NULL;
char profile_name[80];
profile_name[0]= 0;
#ifdef Cdrskin_libburn_has_get_profilE
if(skin->grabbed_drive)
burn_disc_get_profile(skin->grabbed_drive,&i,profile_name);
burn_disc_get_profile(skin->grabbed_drive,&profile_number,profile_name);
#endif
if(strcmp(skin->preskin->write_mode_name,"DEFAULT")==0) {
@ -4308,7 +4312,8 @@ int Cdrskin_activate_write_mode(struct CdrskiN *skin, enum burn_disc_status s,
if(s == BURN_DISC_APPENDABLE) {
strcpy(skin->preskin->write_mode_name,"TAO");
was_still_default= 2; /*<<< prevents trying of SAO if drive dislikes TAO*/
} else if(strstr(profile_name,"DVD+RW")==profile_name) {
} else if(strstr(profile_name,"DVD+RW")==profile_name ||
profile_number == 0x13) { /* DVD-RW Restricted Overwrite */
strcpy(skin->preskin->write_mode_name,"TAO");
} else {
strcpy(skin->preskin->write_mode_name,"SAO");

@ -1 +1 @@
#define Cdrskin_timestamP "2006.12.29.143734"
#define Cdrskin_timestamP "2006.12.30.001343"

@ -336,7 +336,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x0002011c (FATAL,HIGH) = Attempt to read track info from busy drive
0x0002011d (FATAL,HIGH) = SCSI error on write
0x0002011e (SORRY,HIGH) = Unsuitable media detected
0x0002011f (SORRY,HIGH) = Burning of DVD+RW is restricted to a single track
0x0002011f (SORRY,HIGH) = Burning is restricted to a single track
0x00020120 (NOTE,HIGH) = FORMAT UNIT ignored
0x00020121 (FATAL,HIGH) = Write preparation setup failed
0x00020122 (FATAL,HIGH) = SCSI error on format_unit

@ -37,6 +37,11 @@ extern struct libdax_msgs *libdax_messenger;
/* ts A61219 : Based on knowlege from dvd+rw-tools-7.0 and mmc5r03c.pdf */
#define Libburn_support_dvd_plus_rW 1
/* ts A61229 */
/*
*/
#define Libburn_support_dvd_minusrw_overW 1
/* Progress report (with Libburn_support_dvd_plus_rW defined):
ts A61219 : It seems to work with a used (i.e. thoroughly formatted) DVD+RW.
Error messages of class DEBUG appear because of inability to
@ -152,7 +157,8 @@ int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa)
memcpy(c.opcode, MMC_TRACK_INFO, sizeof(MMC_TRACK_INFO));
c.opcode[1] = 1;
if(trackno<=0) {
if (d->current_profile == 0x1a) /* DVD+RW */
if (d->current_profile == 0x1a || d->current_profile == 0x13)
/* DVD+RW or DVD-RW restricted overwrite*/
c.opcode[5] = 1;
else /* mmc5r03c.pdf: valid only for CD, DVD+R, DVD+R DL */
c.opcode[5] = 0xFF;
@ -593,9 +599,10 @@ void mmc_read_disc_info(struct burn_drive *d)
*/
d->bg_format_status = data[7] & 3;
/* <<< ts A61219 : preliminarily declare all DVD+RW blank,
/* ts A61219 : preliminarily declare all DVD+RW blank,
(which is not the same as bg_format_status==0 "blank") */
if (d->current_profile == 0x1a)
/* ts A61229 : same for DVD-RW Restricted overwrite */
if (d->current_profile == 0x1a || d->current_profile == 0x13)
d->status = BURN_DISC_BLANK;
}
@ -1079,6 +1086,10 @@ void mmc_get_configuration(struct burn_drive *d)
if (cp == 0x1a)
d->current_is_supported_profile = 1;
#endif
#ifdef Libburn_support_dvd_minusrw_overW
if (cp == 0x13)
d->current_is_supported_profile = 1;
#endif
}
@ -1137,7 +1148,8 @@ int mmc_read_buffer_capacity(struct burn_drive *d)
}
/* ts A61219 : learned much from dvd+rw-tools-7.0: plus_rw_format() */
/* ts A61219 : learned much from dvd+rw-tools-7.0: plus_rw_format()
and mmc5r03c.pdf, 6.5 FORMAT UNIT */
int mmc_format_unit(struct burn_drive *d)
{
struct buffer buf;
@ -1156,10 +1168,10 @@ int mmc_format_unit(struct burn_drive *d)
memset(c.page->data, 0, c.page->bytes);
descr[0] = 0;
c.page->data[1] = 0x02; /* Immed */
c.page->data[3] = 8; /* Format descriptor length */
if (d->current_profile == 0x1a) { /* DVD+RW */
c.page->data[1] = 0x02; /* Immed */
c.page->data[3] = 8; /* Format descriptor length */
/* mmc5r03c.pdf , 6.5.4.2.14 */
/* mmc5r03c.pdf , 6.5.4.2.14, DVD+RW Basic Format */
c.page->data[8] = 0x26 << 2; /* Format type */
memset(c.page->data + 4, 0xff, 4); /* maximum blocksize */
if (d->bg_format_status == 1) /* is partly formatted */
@ -1173,6 +1185,11 @@ int mmc_format_unit(struct burn_drive *d)
}
sprintf(descr, "DVD+RW, BGFS %d",
d->bg_format_status);
} else if (d->current_profile == 0x13) {/*DVD-RW restricted overwrite*/
/* 6.5.4.2.8 , DVD-RW Quick Grow Last Border */
c.page->data[8] = 0x13 << 2; /* Format type */
c.page->data[11] = 16; /* Restart bit */
sprintf(descr, "DVD-RW, quick grow");
} else {
/* >>> other formattable types to come */
@ -1359,3 +1376,55 @@ int mmc_setup_drive(struct burn_drive *d)
return 1;
}
/* ts A61229 : outsourced from spc_select_write_params() */
/* Note: Page data is not zeroed here to allow preset defaults. Thus
memset(pd, 0, 2 + d->mdata->write_page_length);
is the eventual duty of the caller.
*/
int mmc_compose_mode_page_5(struct burn_drive *d,
const struct burn_write_opts *o,
unsigned char *pd)
{
pd[0] = 5;
pd[1] = d->mdata->write_page_length;
/* ts A61229 */
if (d->current_profile == 0x13) { /* DVD-RW restricted overwrite */
/* learned from transport.hxx : page05_setup()
and mmc3r10g.pdf table 347 */
/* BUFE (burnproof), no LS_V (i.e. default Link Size, i hope),
no simulate, write type 0 = packet */
pd[2] = (1 << 6);
/* no multi, fixed packet, track mode 5 */
pd[3] = (1 << 5) | 5;
/* Data Block Type */
pd[4] = 8;
/* Link size dummy */
pd[5] = 0;
} else {
/* Traditional setup for CD */
pd[2] = ((!!o->underrun_proof) << 6)
| ((!!o->simulate) << 4)
| (o->write_type & 0x0f);
/* ts A61106 : MMC-1 table 110 : multi==0 or multi==3 */
pd[3] = ((3 * !!o->multi) << 6) | (o->control & 0x0f);
pd[4] = spc_block_type(o->block_type);
/* ts A61104 */
if(!(o->control&4)) /* audio (MMC-1 table 61) */
if(o->write_type == BURN_WRITE_TAO)
pd[4] = 0; /* Data Block Type: Raw Data */
pd[14] = 0; /* audio pause length MSB */
pd[15] = 150; /* audio pause length LSB */
/*XXX need session format! */
/* ts A61229 : but session format (pd[8]) = 0 seems ok */
}
return 1;
}

@ -54,4 +54,15 @@ int mmc_setup_drive(struct burn_drive *d);
/* ts A61225 : obtain write speed descriptors via ACh GET PERFORMANCE */
int mmc_get_write_performance(struct burn_drive *d);
/* ts A61229 : outsourced from spc_select_write_params() */
/* Note: Page data is not zeroed here to allow preset defaults. Thus
memset(pd, 0, 2 + d->mdata->write_page_length);
is the eventual duty of the caller.
*/
int mmc_compose_mode_page_5(struct burn_drive *d,
const struct burn_write_opts *o,
unsigned char *pd);
#endif /*__MMC*/

@ -345,6 +345,11 @@ void spc_sense_write_params(struct burn_drive *d)
mmc_read_disc_info(d);
}
/* ts A61229 */
#define Libburn_mmc_compose_mode_page_5 1
/* remark ts A61104 :
Although command MODE SELECT is SPC, the content of the
Write Parameters Mode Page (05h) is MMC (Table 108 in MMC-1).
@ -355,7 +360,9 @@ void spc_select_write_params(struct burn_drive *d,
{
struct buffer buf;
struct command c;
#ifndef Libburn_mmc_compose_mode_page_5
int bufe, sim;
#endif
/* ts A61007 : All current callers are safe. */
/* a ssert(o->drive == d); */
@ -380,11 +387,21 @@ void spc_select_write_params(struct burn_drive *d,
memset(c.page->data, 0, 8 + 2 + d->mdata->write_page_length);
c.page->bytes = 8 + 2 + d->mdata->write_page_length;
c.page->data[8] = 5;
c.page->data[9] = d->mdata->write_page_length;
burn_print(12, "using write page length %d (valid %d)\n",
d->mdata->write_page_length, d->mdata->write_page_valid);
#ifdef Libburn_mmc_compose_mode_page_5
/* ts A61229 */
if (mmc_compose_mode_page_5(d, o, c.page->data + 8) <= 0)
return;
#else
c.page->data[8] = 5;
c.page->data[9] = d->mdata->write_page_length;
bufe = o->underrun_proof;
sim = o->simulate;
c.page->data[10] = (bufe << 6)
@ -403,6 +420,9 @@ void spc_select_write_params(struct burn_drive *d,
c.page->data[22] = 0;
c.page->data[23] = 150; /* audio pause length */
#endif /* ! Libburn_mmc_compose_mode_page_5 */
/*XXX need session format! */
c.dir = TO_DRIVE;
d->issue_command(d, &c);
@ -500,6 +520,8 @@ void spc_probe_write_modes(struct burn_drive *d)
}
}
/* ( ts A61229 : shouldn't this go to mmc.c too ?) */
/** @return -1 = error */
int spc_block_type(enum burn_block_types b)
{

@ -887,6 +887,20 @@ int burn_disc_close_session_dvd_plus_rw(struct burn_write_opts *o,
}
/* ts A61228 */
int burn_disc_close_session_dvd_minus_rw(struct burn_write_opts *o,
struct burn_session *s)
{
struct burn_drive *d = o->drive;
d->busy = BURN_DRIVE_CLOSING_SESSION;
if (d->current_profile == 0x13)
d->close_track_session(d, 1, 0); /* CLOSE SESSION */
d->busy = BURN_DRIVE_WRITING;
return 1;
}
/* ts A61218 */
int burn_dvd_write_session(struct burn_write_opts *o,
struct burn_session *s)
@ -903,6 +917,11 @@ int burn_dvd_write_session(struct burn_write_opts *o,
ret = burn_disc_close_session_dvd_plus_rw(o, s);
if (ret <= 0)
return 0;
} else if (d->current_profile == 0x13) {
/* DVD-RW restricted overwrite */
ret = burn_disc_close_session_dvd_minus_rw(o, s);
if (ret <= 0)
return 0;
}
return 1;
}
@ -943,6 +962,74 @@ int burn_disc_setup_dvd_plus_rw(struct burn_write_opts *o,
}
/* ts A61228 : learned much from dvd+rw-tools-7.0/growisofs_mmc.cpp */
int burn_disc_setup_dvd_minus_rw(struct burn_write_opts *o,
struct burn_disc *disc)
{
struct burn_drive *d = o->drive;
char msg[160];
int ret;
if (d->current_profile == 0x13) { /* DVD-RW restricted overwrite */
#ifdef NIX
/* >>> compose mode page 5 -> spc_select_write_params() */
/* learned from transport.hxx : page05_setup()
and mmc3r10g.pdf table 347 */
o->underrun_proof = 1;
o->write_type = 0; /* packet */
o->multi = 0;
o->control = (1<<5) | 5; /* Fixed packet, Track mode 5 */
>>> make controllable in spc_select_write_params() :
>>> c.page->data[10] &= ~(1<<5); /* LS_V = 0 */
>>> c.page->data[12] = 8; /* Data Block Type */
>>> .page->data[13] = 0; /* Link size */
#endif /* NIX */
/* ??? urm ... mmc5r03c.pdf 7.5.2 :
"For DVD-RW media ... If a medium is in Restricted overwrite
mode, this mode page shall not be used."
But growisofs composes a page 5 and sends it.
*/
d->send_write_parameters(d, o);
d->busy = BURN_DRIVE_FORMATTING;
ret = d->format_unit(d); /* "quick grow" */
if (ret <= 0)
return 0;
d->busy = BURN_DRIVE_WRITING;
} else {
sprintf(msg, "Unsuitable media detected. Profile %4.4Xh %s",
d->current_profile, d->current_profile_text);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002011e,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0,0);
return 0;
}
d->nwa = 0;
if (o->start_byte >= 0) {
d->nwa = o->start_byte / 32768;
sprintf(msg, "Write start address is %d * 32768", d->nwa);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020127,
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
msg, 0,0);
}
/* >>> perform OPC if needed */;
/* >>> */;
return 1;
}
/* ts A61218 */
int burn_dvd_write_sync(struct burn_write_opts *o,
struct burn_disc *disc)
@ -966,12 +1053,12 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
goto early_failure;
}
if (strcmp(d->current_profile_text,"DVD+RW")==0) {
if (d->current_profile == 0x1a || d->current_profile == 0x13) {
/* DVD+RW or DVD-RW Restricted Overwrite */
if (disc->sessions!=1 || disc->session[0]->tracks>1
|| o->multi ) {
sprintf(msg,
"Burning of DVD+RW is restricted to a single track and session"
"Burning is restricted to a single track and no multi-session"
);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002011f,
@ -979,6 +1066,8 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
msg, 0,0);
goto early_failure;
}
}
if (d->current_profile == 0x1a) { /* DVD+RW */
if (o->start_byte >= 0 && (o->start_byte % 2048)) {
sprintf(msg,
"Write start address not properly aligned to 2048");
@ -988,7 +1077,6 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
msg, 0,0);
goto early_failure;
}
ret = burn_disc_setup_dvd_plus_rw(o, disc);
if (ret <= 0) {
sprintf(msg,
@ -1001,6 +1089,30 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
}
o->obs_pad = 0; /* no filling-up of track's last 32k buffer */
} else if (d->current_profile == 0x13) { /* DVD-RW Rest. Overwrite */
if (o->start_byte >= 0 && (o->start_byte % 32768)) {
sprintf(msg,
"Write start address not properly aligned to 32K");
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020125,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0,0);
goto early_failure;
}
ret = burn_disc_setup_dvd_minus_rw(o, disc);
if (ret <= 0) {
sprintf(msg,
"Write preparation setup failed for DVD-RW");
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020121,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
msg, 0,0);
goto early_failure;
}
/* ??? is this necessary ? */
o->obs_pad = 1; /* fill-up track's last 32k buffer */
} else {
sprintf(msg, "Unsuitable media detected. Profile %4.4Xh %s",
d->current_profile, d->current_profile_text);

Loading…
Cancel
Save