diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index bac02a9..3cda464 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2013.10.09.134543" +#define Cdrskin_timestamP "2013.10.10.161931" diff --git a/libburn/drive.c b/libburn/drive.c index 27688a5..8bcaa70 100644 --- a/libburn/drive.c +++ b/libburn/drive.c @@ -844,7 +844,7 @@ void burn_wait_all(void) void burn_disc_erase_sync(struct burn_drive *d, int fast) { - int ret; + int ret, was_error = 0; if (d->drive_role == 5) { /* Random access write-only drive */ ret = truncate(d->devname, (off_t) 0); @@ -898,12 +898,16 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast) ret = d->get_erase_progress(d); if (ret == -2 || ret > 0) break; + if (ret == -3) + was_error = 1; sleep(1); } while (1) { ret = d->get_erase_progress(d); if(ret == -2) break; + if (ret == -3) + was_error = 1; if (ret >= 0) d->progress.sector = ret; sleep(1); @@ -918,6 +922,8 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast) if (d->drive_role == 1) burn_drive_inquire_media(d); d->busy = BURN_DRIVE_IDLE; + if (was_error) + d->cancel = 1; } /* @@ -927,6 +933,7 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast) void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag) { int ret, buf_secs, err, i, stages = 1, pbase, pfill, pseudo_sector; + int was_error = 0; off_t num_bufs; char msg[80]; struct buffer *buf = NULL, *buf_mem = d->buffer; @@ -971,12 +978,16 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag) ret = d->get_erase_progress(d); if (ret == -2 || ret > 0) break; + if (ret == -3) + was_error = 1; sleep(1); } while (1) { pseudo_sector = d->get_erase_progress(d); if(pseudo_sector == -2) break; + if (pseudo_sector == -3) + was_error = 1; if (pseudo_sector >= 0) d->progress.sector = pseudo_sector / stages; sleep(1); @@ -1040,6 +1051,8 @@ ex:; d->progress.sector = 0x10000; d->busy = BURN_DRIVE_IDLE; d->buffer = buf_mem; + if (was_error) + d->cancel = 1; BURN_FREE_MEM(buf); } diff --git a/libburn/spc.c b/libburn/spc.c index 6b2d79b..3418056 100644 --- a/libburn/spc.c +++ b/libburn/spc.c @@ -261,7 +261,34 @@ void spc_request_sense(struct burn_drive *d, struct buffer *buf) d->issue_command(d, c); } -/* @return -2 = drive is ready , -1 = not ready, but no progress reported +static int spc_report_async_error(struct burn_drive *d, + int key, int asc, int ascq, int flag) +{ + char *msg = NULL; + unsigned char sense[14]; + int ret; + + BURN_ALLOC_MEM(msg, char, BURN_DRIVE_ADR_LEN + 160); + + sprintf(msg, "Asynchronous SCSI error : "); + sense[0] = 0x70; /* Fixed format sense data */ + sense[2] = key; + sense[12] = asc; + sense[13] = ascq; + scsi_error_msg(d, sense, 14, msg + strlen(msg), &key, &asc, &ascq); + libdax_msgs_submit(libdax_messenger, d->global_index, + 0x000201a5, + LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, + msg, 0, 0); + ret = 1; +ex:; + BURN_FREE_MEM(msg); + return ret; +} + +/* @return -3 = other error reported + -2 = drive is ready , + -1 = not ready, but no progress reported , >= 0 progress indication between 0 and 65535 */ int spc_get_erase_progress(struct burn_drive *d) @@ -279,6 +306,14 @@ int spc_get_erase_progress(struct burn_drive *d) ret = spc_test_unit_ready_r(d, &key, &asc, &ascq, &progress); if (ret > 0) {ret = -2; goto ex;} + + /* Check key, asc, ascq for errors other than "not yet ready" */ + if (key != 0 && + (key != 0x2 || asc != 0x04 || ascq == 0x02 || ascq ==0x03)) { + spc_report_async_error(d, key, asc, ascq, 0); + ret= -3; goto ex; + } + if (progress >= 0) {ret = progress; goto ex;}