Prepared formatting of DVD-RW

This commit is contained in:
Thomas Schmitt 2007-01-01 17:10:54 +00:00
parent e51b7ffc16
commit f505c56896
11 changed files with 152 additions and 38 deletions

View File

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

View File

@ -35,6 +35,13 @@ struct erase_opts
int fast;
};
/* ts A61230 */
struct format_opts
{
struct burn_drive *drive;
int flag;
};
struct write_opts
{
struct burn_drive *drive;
@ -42,6 +49,7 @@ struct write_opts
struct burn_disc *disc;
};
struct w_list
{
struct burn_drive *drive;
@ -53,6 +61,7 @@ struct w_list
{
struct scan_opts scan;
struct erase_opts erase;
struct format_opts format;
struct write_opts write;
} u;
};
@ -223,6 +232,47 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
add_worker(drive, (WorkerFunc) erase_worker_func, &o);
}
/* ts A61230 */
static void *format_worker_func(struct w_list *w)
{
burn_disc_format_sync(w->u.format.drive, w->u.format.flag);
remove_worker(pthread_self());
return NULL;
}
/* ts A61230 */
void burn_disc_format(struct burn_drive *drive, int flag)
{
struct format_opts o;
char msg[160];
if ((SCAN_GOING()) || find_worker(drive)) {
libdax_msgs_submit(libdax_messenger, drive->global_index,
0x00020102,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"A drive operation is still going on (want to format)",
0, 0);
return;
}
if (drive->current_profile != 0x14) { /* no DVD-RW */
sprintf(msg,"Will not format media type %4.4Xh",
drive->current_profile);
libdax_msgs_submit(libdax_messenger, drive->global_index,
0x00020129,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
drive->cancel = 1;
return;
}
o.drive = drive;
o.flag = flag;
add_worker(drive, (WorkerFunc) format_worker_func, &o);
}
static void *write_disc_worker_func(struct w_list *w)
{
burn_disc_write_sync(w->u.write.opts, w->u.write.disc);

View File

@ -447,8 +447,10 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
/* ts A60825 : allow on parole to blank appendable CDs */
if ( ! (d->status == BURN_DISC_FULL ||
(d->status == BURN_DISC_APPENDABLE &&
! libburn_back_hack_42) ) )
! libburn_back_hack_42) ) ) {
d->cancel = 1;
return;
}
d->cancel = 0;
d->busy = BURN_DRIVE_ERASING;
d->erase(d, fast);
@ -475,6 +477,40 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
burn_drive_inquire_media(d);
}
void burn_disc_format_sync(struct burn_drive *d, int flag)
{
int ret;
d->cancel = 0;
d->busy = BURN_DRIVE_FORMATTING;
ret = d->format_unit(d, 0);
if (ret <= 0)
d->cancel = 1;
/* reset the progress */
d->progress.session = 0;
d->progress.sessions = 1;
d->progress.track = 0;
d->progress.tracks = 1;
d->progress.index = 0;
d->progress.indices = 1;
d->progress.start_sector = 0;
d->progress.sectors = 0x10000;
d->progress.sector = 0;
while (!d->test_unit_ready(d) && d->get_erase_progress(d) == 0)
sleep(1);
while ((d->progress.sector = d->get_erase_progress(d)) > 0 ||
!d->test_unit_ready(d))
sleep(1);
d->progress.sector = 0x10000;
/* ts A61125 : update media state records */
burn_drive_mark_unready(d);
burn_drive_inquire_media(d);
}
enum burn_disc_status burn_disc_get_status(struct burn_drive *d)
{
/* ts A61007 */

View File

@ -91,4 +91,8 @@ int burn_speed_descriptor_destroy(struct burn_speed_descriptor **s, int flag);
/* ts A61226 : free dynamically allocated sub data of struct scsi_mode_data */
int burn_mdata_free_subs(struct scsi_mode_data *m);
/* ts A61230 */
void burn_disc_format_sync(struct burn_drive *d, int flag);
#endif /* __DRIVE */

View File

@ -784,8 +784,8 @@ int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
/* ts A61202 */
/** Tells the MMC Profile identifier of the loaded media. The drive must be
grabbed in order to get a non-zero result.
libburn currently writes only to profiles 0x09 "CD-R", 0x0a "CD-RW" or
0x1a "DVD+RW".
libburn currently writes only to profiles 0x09 "CD-R", 0x0a "CD-RW",
0x13 "DVD-RW restricted overwrite" or 0x1a "DVD+RW".
@param d The drive where the media is inserted.
@param pno Profile Number as of mmc5r03c.pdf, table 89
@param name Profile Name (e.g "CD-RW", unknown profiles have empty name)
@ -841,7 +841,18 @@ void burn_read_opts_free(struct burn_read_opts *opts);
*/
void burn_disc_erase(struct burn_drive *drive, int fast);
/* ts A61109 : this is defunct */
/* ts A70101 */
/** Format media for use with libburn. This currently applies only to DVD-RW
in state "Sequential Recording" (profile 0014h) which get formatted to
state "Restricted Overwrite" (profile 0013h).
@param drive The drive with the disc to format.
@param flag Unused yet. Submit 0.
*/
void burn_disc_format(struct burn_drive *drive, int flag);
/* ts A61109 : this was and is defunct */
/** Read a disc from the drive and write it to an fd pair. The drive must be
grabbed successfully BEFORE calling this function. Always ensure that the
drive reports a status of BURN_DISC_FULL before calling this function.
@ -1136,7 +1147,7 @@ void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi);
/* ts A61222 */
/** Sets a start address for writing to media and write modes which allow to
choose this address at all (DVD+RW only for now). The address is given in
choose this address at all (DVD+-RW only for now). The address is given in
bytes. If it is not -1 then a write run will fail if choice of start
address is not supported or if the block alignment of the address is not
suitable for media and write mode. (Alignment to 32 kB blocks is advised

View File

@ -346,6 +346,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x00020126 (SORRY,HIGH) = Write start address not properly aligned
0x00020127 (NOTE,HIGH) = Write start address is ...
0x00020128 (FATAL,HIGH) = Unsupported inquiry_type with mmc_get_performance
0x00020129 (SORRY,HIGH) = Will not format media type
libdax_audioxtr:
0x00020200 (SORRY,HIGH) = Cannot open audio source file

View File

@ -55,9 +55,15 @@ extern struct libdax_msgs *libdax_messenger;
functions in dvd+rw-tools are a bit intimidating to the reader.
I hope it is possible to leave much of this to the drive.
And if it fails ... well, it's only speed setting. :))
ts A61229 : Burned to several DVD-RW formatted to mode Restricted Overwrite
by dvd+rw-format. Needs Libburn_support_dvd_minusrw_overW.
ts A61230 : Other than growisofs, libburn does not send a mode page 5 for
such DVD-RW (which the MMC-5 standard does deprecate) and it
really seems to work without such a page.
ts A70101 : Formatted DVD-RW media. Success is varying with media, but
dvd+rw-format does not do better with the same media.
Todo:
Determine media capacity.
Determine drive+media speed options.
Determine first free lba for appending data.
Determine start lba of most recent mkisofs session.
*/
@ -173,8 +179,9 @@ int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa)
+ (data[10] << 8) + data[11];
*nwa = (data[12] << 24) + (data[13] << 16)
+ (data[14] << 8) + data[15];
if (d->current_profile == 0x1a) { /* DVD+RW */
*nwa = *nwa = 0;
if (d->current_profile == 0x1a || d->current_profile == 0x13) {
/* DVD+RW or DVD-RW restricted overwrite */
*lba = *nwa = 0;
} else if (!(data[7]&1)) {
/* ts A61106 : MMC-1 Table 142 : NWA_V = NWA Valid Flag */
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
@ -1150,11 +1157,14 @@ int mmc_read_buffer_capacity(struct burn_drive *d)
/* 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)
/*
@param flag unused yet, submit 0
*/
int mmc_format_unit(struct burn_drive *d, int flag)
{
struct buffer buf;
struct command c;
int ret;
int ret, tolerate_failure = 0;
char msg[160],descr[80];
mmc_function_spy("mmc_format_unit");
@ -1183,13 +1193,24 @@ int mmc_format_unit(struct burn_drive *d)
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
msg, 0,0);
}
sprintf(descr, "DVD+RW, BGFS %d",
d->bg_format_status);
sprintf(descr, "DVD+RW, BGFS %d", d->bg_format_status);
} else if (d->current_profile == 0x13) {/*DVD-RW restricted overwrite*/
/* >>> check wether READ FORMAT CAPACITIES does report
0x13 formatting. If not, skip this. It seems to work
without formatting on e.g. freshly formatted media. */
tolerate_failure = 1;
/* 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 */
c.page->data[11] = 16; /* block size * 2k */
sprintf(descr, "DVD-RW, quick grow");
} else if (d->current_profile == 0x14) {/*DVD-RW sequential recording*/
/* 6.5.4.2.10 , DVD-RW Quick (-> Restricted Overwrite) */
/* c.page->data[4-7]==0 : 0 blocks */
c.page->data[8] = 0x15 << 2; /* Format type */
c.page->data[11] = 16; /* block size * 2k */
sprintf(descr, "DVD-RW, quick");
} else {
/* >>> other formattable types to come */
@ -1204,7 +1225,7 @@ int mmc_format_unit(struct burn_drive *d)
}
d->issue_command(d, &c);
if (c.error) {
if (c.error && !tolerate_failure) {
if (c.sense[2]!=0) {
sprintf(msg,
"SCSI error on format_unit(%s): key=%X asc=%2.2Xh ascq=%2.2Xh",

View File

@ -51,6 +51,10 @@ int mmc_read_buffer_capacity(struct burn_drive *d);
*/
int mmc_setup_drive(struct burn_drive *d);
/* 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, int flag);
/* ts A61225 : obtain write speed descriptors via ACh GET PERFORMANCE */
int mmc_get_write_performance(struct burn_drive *d);

View File

@ -421,9 +421,10 @@ void spc_select_write_params(struct burn_drive *d,
c.page->data[22] = 0;
c.page->data[23] = 150; /* audio pause length */
/*XXX need session format! */
#endif /* ! Libburn_mmc_compose_mode_page_5 */
/*XXX need session format! */
c.dir = TO_DRIVE;
d->issue_command(d, &c);
}

View File

@ -224,7 +224,7 @@ struct burn_drive
int (*read_buffer_capacity) (struct burn_drive *d);
/* ts A61220 : format media (e.g. DVD+RW) */
int (*format_unit) (struct burn_drive *d);
int (*format_unit) (struct burn_drive *d, int flag);
};

View File

@ -938,7 +938,7 @@ int burn_disc_setup_dvd_plus_rw(struct burn_write_opts *o,
if (d->bg_format_status==0 || d->bg_format_status==1) {
d->busy = BURN_DRIVE_FORMATTING;
/* start or re-start dvd_plus_rw formatting */
ret = d->format_unit(d);
ret = d->format_unit(d, 0);
if (ret <= 0)
return 0;
d->busy = BURN_DRIVE_WRITING;
@ -972,31 +972,17 @@ int burn_disc_setup_dvd_minus_rw(struct burn_write_opts *o,
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 :
/* ??? 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" */
ret = d->format_unit(d, 0); /* "quick grow" */
if (ret <= 0)
return 0;
d->busy = BURN_DRIVE_WRITING;