New API calls burn_drive_was_feat21_failure(), burn_write_opts_set_fail21h_sev()

This commit is contained in:
Thomas Schmitt 2013-10-28 10:51:05 +00:00
parent 72637a0ce8
commit 4426be4951
9 changed files with 160 additions and 13 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2013.10.10.161931" #define Cdrskin_timestamP "2013.10.28.104957"

View File

@ -570,6 +570,7 @@ struct burn_drive *burn_drive_register(struct burn_drive *d)
d->toc_entry = NULL; d->toc_entry = NULL;
d->disc = NULL; d->disc = NULL;
d->erasable = 0; d->erasable = 0;
d->write_opts = NULL;
#ifdef Libburn_ticket_62_re_register_is_possiblE #ifdef Libburn_ticket_62_re_register_is_possiblE
/* ts A60904 : ticket 62, contribution by elmom */ /* ts A60904 : ticket 62, contribution by elmom */
@ -675,6 +676,10 @@ int burn_drive_mark_unready(struct burn_drive *d, int flag)
free(d->toc_entry); free(d->toc_entry);
d->toc_entry = NULL; d->toc_entry = NULL;
d->toc_entries = 0; d->toc_entries = 0;
if (d->write_opts != NULL) {
burn_write_opts_free(d->write_opts);
d->write_opts = NULL;
}
if (d->disc != NULL) { if (d->disc != NULL) {
burn_disc_free(d->disc); burn_disc_free(d->disc);
d->disc = NULL; d->disc = NULL;
@ -3402,3 +3407,13 @@ int burn_disc_get_leadin_text(struct burn_drive *d,
return ret; return ret;
} }
/* ts B31023 API */
/* Inquire for DVD-RW failure of TAO
*/
int burn_drive_was_feat21_failure(struct burn_drive *d)
{
return !!d->was_feat21h_failure;
}

View File

@ -1814,6 +1814,18 @@ void burn_drive_cancel(struct burn_drive *drive);
int burn_drive_wrote_well(struct burn_drive *d); int burn_drive_wrote_well(struct burn_drive *d);
/* ts B31023 */
/** Inquire whether a write error occured which is suspected to have happened
due to a false report about DVD-RW capability to be written in write type
BURN_WRITE_TAO.
@param d The drive to inquire.
@return 1= it seems that BURN_WRITE_TAO on DVD-RW caused error,
0= it does not seem so
@since 1.3.4
*/
int burn_drive_was_feat21_failure(struct burn_drive *d);
/** Convert a minute-second-frame (MSF) value to sector count /** Convert a minute-second-frame (MSF) value to sector count
@param m Minute component @param m Minute component
@param s Second component @param s Second component
@ -3055,6 +3067,29 @@ void burn_write_opts_set_has_mediacatalog(struct burn_write_opts *opts,
*/ */
void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi); void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi);
/* ts B31024 */
/** Set the severity to be used with write error messages which are potentially
caused by not using write type BURN_WRITE_SAO on fast blanked DVD-RW.
Normally the call burn_write_opts_auto_write_type() can prevent such
errors by looking for MMC feature 21h "Incremental Streaming Writable"
which anounnces the capability for BURN_WRITE_TAO and multi session.
Regrettable many drives announce feature 21h even if they only can do
BURN_WRITE_SAO. This mistake becomes obvious by an early write error.
If you plan to call burn_drive_was_feat21_failure() and to repeat the
burn attempt with BURN_WRITE_SAO, then set the severity of the error
message low enough, so that the application does not see reason to abort.
@param opts The option object to be manipulated
@param severity Severity as with burn_msgs_set_severities().
"ALL" or empty text means the default severity that
is attributed to other kinds of write errors.
*/
void burn_write_opts_set_fail21h_sev(struct burn_write_opts *opts,
char *severity);
/* ts B11204 */ /* ts B11204 */
/** Submit an array of CD-TEXT packs which shall be written to the Lead-in /** Submit an array of CD-TEXT packs which shall be written to the Lead-in
of a SAO write run on CD. of a SAO write run on CD.

View File

@ -73,6 +73,7 @@ burn_drive_set_buffer_waiting;
burn_drive_set_speed; burn_drive_set_speed;
burn_drive_set_stream_recording; burn_drive_set_stream_recording;
burn_drive_snooze; burn_drive_snooze;
burn_drive_was_feat21_failure;
burn_drive_wrote_well; burn_drive_wrote_well;
burn_fd_source_new; burn_fd_source_new;
burn_fifo_fill; burn_fifo_fill;
@ -175,6 +176,7 @@ burn_write_opts_free;
burn_write_opts_get_drive; burn_write_opts_get_drive;
burn_write_opts_new; burn_write_opts_new;
burn_write_opts_set_dvd_obs; burn_write_opts_set_dvd_obs;
burn_write_opts_set_fail21h_sev;
burn_write_opts_set_fillup; burn_write_opts_set_fillup;
burn_write_opts_set_force; burn_write_opts_set_force;
burn_write_opts_set_format; burn_write_opts_set_format;

View File

@ -1007,9 +1007,8 @@ fprintf(stderr, "libburn_DEBUG: buffer sectors= %d bytes= %d\n",
/* ts A61112 : react on eventual error condition */ /* ts A61112 : react on eventual error condition */
spc_decode_sense(c->sense, 0, &key, &asc, &ascq); spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
if (c->error && key != 0) { if (c->error && key != 0) {
/* >>> make this scsi_notify_error() when liberated */
int key, asc, ascq; int key, asc, ascq;
int err_sev = LIBDAX_MSGS_SEV_FATAL;
msg = calloc(1, 256); msg = calloc(1, 256);
if (msg != NULL) { if (msg != NULL) {
@ -1017,13 +1016,33 @@ fprintf(stderr, "libburn_DEBUG: buffer sectors= %d bytes= %d\n",
start, len); start, len);
scsi_error_msg(d, c->sense, 14, msg + strlen(msg), scsi_error_msg(d, c->sense, 14, msg + strlen(msg),
&key, &asc, &ascq); &key, &asc, &ascq);
}
/* ts B31023 */
/* Memorize if on DVD-RW write mode is TAO/Incremental and
error [5 64 00] occurs within the first drive buffer fill.
*/
if (d->current_profile == 0x14 && d->write_opts != NULL &&
(d->progress.buffer_capacity == 0 ||
start < (int) d->progress.buffer_capacity / 2048) &&
key == 5 && asc == 0x64 && ascq == 0) {
if (d->write_opts->write_type == BURN_WRITE_TAO) {
d->was_feat21h_failure = 1 + (start == 0);
if (d->write_opts->feat21h_fail_sev != 0)
err_sev =
d->write_opts->feat21h_fail_sev;
}
}
if (msg != NULL) {
libdax_msgs_submit(libdax_messenger, d->global_index, libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002011d, 0x0002011d,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, err_sev, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0); msg, 0, 0);
free(msg); free(msg);
} }
d->cancel = 1; d->cancel = 1;
return BE_CANCELLED; return BE_CANCELLED;
} }

View File

@ -78,6 +78,24 @@ void burn_write_opts_free(struct burn_write_opts *opts)
free(opts); free(opts);
} }
int burn_write_opts_clone(struct burn_write_opts *from,
struct burn_write_opts **to, int flag)
{
if (*to != NULL)
burn_write_opts_free(*to);
if (from == NULL)
return 1;
*to = calloc(1, sizeof(struct burn_write_opts));
if (*to == NULL) {
libdax_msgs_submit(libdax_messenger, -1, 0x00000003,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Out of virtual memory", 0, 0);
return -1;
}
memcpy(*to, from, sizeof(struct burn_write_opts));
return 1;
}
struct burn_read_opts *burn_read_opts_new(struct burn_drive *drive) struct burn_read_opts *burn_read_opts_new(struct burn_drive *drive)
{ {
struct burn_read_opts *opts; struct burn_read_opts *opts;
@ -204,6 +222,21 @@ void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi)
} }
/* ts B31024 */
/* API */
void burn_write_opts_set_fail21h_sev(struct burn_write_opts *opts,
char *severity)
{
int ret, sevno;
ret = libdax_msgs__text_to_sev(severity, &sevno, 0);
if (ret <= 0)
opts->feat21h_fail_sev = 0;
else
opts->feat21h_fail_sev = sevno;
}
/* ts B11204 */ /* ts B11204 */
/* @param flag bit0=do not verify checksums /* @param flag bit0=do not verify checksums
bit1= repair mismatching checksums bit1= repair mismatching checksums

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net> Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later. Provided under GPL version 2 or later.
*/ */
@ -81,9 +81,19 @@ struct burn_write_opts
unsigned char mediacatalog[13]; unsigned char mediacatalog[13];
/** Session format */ /** Session format */
int format; int format;
/* internal use only */ /* internal use only */
unsigned char control; unsigned char control;
/* Whether to keep medium appendable */
unsigned char multi; unsigned char multi;
/* ts B31024 */
/* The severity to be attributed to error messages about failed
write attempt with blank DVD-RW, possibly due to falsely reported
feature 21h Incremental Streaming Writable
*/
int feat21h_fail_sev;
}; };
/* Default value for burn_write_opts.stdio_flush_size /* Default value for burn_write_opts.stdio_flush_size
@ -139,4 +149,9 @@ struct burn_read_opts
}; };
int burn_write_opts_clone(struct burn_write_opts *from,
struct burn_write_opts **to, int flag);
#endif /* BURN__OPTIONS_H */ #endif /* BURN__OPTIONS_H */

View File

@ -188,6 +188,15 @@ struct burn_drive
/* 1 = incremental recording available, 0 = not available */ /* 1 = incremental recording available, 0 = not available */
int current_has_feat21h; int current_has_feat21h;
/* Some drives announce feature 21h on fast-blanked DVD-RW
although they cannot write them in Incremental mode.
0= does not look like the recent write run failed due to
Incremental on fast blanked DVD-RW
1= it seems to have happened
2= it seems to have happened with write address 0
*/
int was_feat21h_failure;
/* Link Size item number 0 from feature 0021h descriptor */ /* Link Size item number 0 from feature 0021h descriptor */
int current_feat21h_link_size; int current_feat21h_link_size;
@ -356,6 +365,13 @@ struct burn_drive
volatile int cancel; volatile int cancel;
volatile enum burn_drive_status busy; volatile enum burn_drive_status busy;
/* During write runs, this points to a copy of the applied
struct burn_write_opts. Only read this underneath
burn_disc_write_sync() which removes the copy when done.
Especially do not read it from outside the write thread.
*/
struct burn_write_opts *write_opts;
/* ts A70929 */ /* ts A70929 */
pid_t thread_pid; pid_t thread_pid;
int thread_pid_valid; int thread_pid_valid;

View File

@ -1318,7 +1318,7 @@ int burn_disc_init_write_status(struct burn_write_opts *o,
{ {
struct burn_drive *d = o->drive; struct burn_drive *d = o->drive;
struct burn_track *t = NULL; struct burn_track *t = NULL;
int sx, tx; int sx, tx, ret;
d->cancel = 0; d->cancel = 0;
@ -1363,6 +1363,11 @@ int burn_disc_init_write_status(struct burn_write_opts *o,
if (o->fill_up_media && t != NULL) if (o->fill_up_media && t != NULL)
burn_track_set_fillup(t, 1); burn_track_set_fillup(t, 1);
d->was_feat21h_failure = 0;
ret = burn_write_opts_clone(o, &(d->write_opts), 0);
if (ret <= 0)
return ret;
d->busy = BURN_DRIVE_WRITING; d->busy = BURN_DRIVE_WRITING;
return 1; return 1;
@ -2124,6 +2129,8 @@ int burn_dvd_write_session(struct burn_write_opts *o,
if (d->current_profile == 0x11 || d->current_profile == 0x14 || if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
d->current_profile == 0x15) { d->current_profile == 0x15) {
/* DVD-R , DVD-RW Sequential, DVD-R/DL Sequential */ /* DVD-R , DVD-RW Sequential, DVD-R/DL Sequential */
/* If feature 21h failed on write 0: do not close session */
if (d->was_feat21h_failure != 2) {
multi_mem = o->multi; multi_mem = o->multi;
if (!is_last_session) if (!is_last_session)
o->multi = 1; o->multi = 1;
@ -2131,6 +2138,7 @@ int burn_dvd_write_session(struct burn_write_opts *o,
o->multi = multi_mem; o->multi = multi_mem;
if (ret <= 0) if (ret <= 0)
return 0; return 0;
}
} else if (d->current_profile == 0x12 || d->current_profile == 0x43) { } else if (d->current_profile == 0x12 || d->current_profile == 0x43) {
/* DVD-RAM , BD-RE */ /* DVD-RAM , BD-RE */
/* ??? any finalization needed ? */; /* ??? any finalization needed ? */;
@ -3129,6 +3137,10 @@ ex:;
burn_os_free_buffer((char *) d->buffer, burn_os_free_buffer((char *) d->buffer,
sizeof(struct buffer), 0); sizeof(struct buffer), 0);
d->buffer = buffer_mem; d->buffer = buffer_mem;
if (d->write_opts != NULL) {
burn_write_opts_free(d->write_opts);
d->write_opts = NULL;
}
return; return;
} }