Prepared support for DVD-RW in mode Restricted Overwrite
This commit is contained in:
parent
a6771ca0df
commit
9b42fcf64b
@ -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…
Reference in New Issue
Block a user