diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index f12918d..e483e8c 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2010.03.27.172644" +#define Cdrskin_timestamP "2010.03.29.103141" diff --git a/libburn/sg-freebsd.c b/libburn/sg-freebsd.c index 7135589..bc67218 100644 --- a/libburn/sg-freebsd.c +++ b/libburn/sg-freebsd.c @@ -755,7 +755,7 @@ int sg_release(struct burn_drive *d) int sg_issue_command(struct burn_drive *d, struct command *c) { - int done = 0, err, sense_len = 0, ret, ignore_error; + int done = 0, err, sense_len = 0, ret, ignore_error, no_retry = 0; int cam_pass_err_recover = 0; union ccb *ccb; char buf[161]; @@ -874,9 +874,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c) fprintf(stderr, "libburn_EXPERIMENTAL: errno = %d . cam_errbuf = '%s'\n", errno, cam_errbuf); #endif - if (errno == ENXIO) { + if (errno == ENXIO && c->opcode[0] != 0) { /* Operations on empty or ejected tray */ - /* Inquiries while tray is being loaded */ /* MEDIUM NOT PRESENT */ #ifdef Libburn_ahci_verbouS @@ -888,8 +887,10 @@ int sg_issue_command(struct burn_drive *d, struct command *c) c->sense[13] = 0x00; sense_len = 14; ignore_error = 1; - } else if (c->opcode[0] == 0 && errno == EBUSY) { + } else if (c->opcode[0] == 0 && + (errno == EBUSY || errno == ENXIO)) { /* Timeout of TEST UNIT READY loop */ + /* Inquiries while tray is being loaded */ /*LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE*/ #ifdef Libburn_ahci_verbouS @@ -942,14 +943,22 @@ int sg_issue_command(struct burn_drive *d, struct command *c) c->sense[2] = 0x02; c->sense[12] = 0x04; c->sense[13] = 0x00; + no_retry = 1; } - if (!c->retry) { + if (no_retry || ignore_error || !c->retry) { c->error = 1; {ret = 1; goto ex;} } switch (scsi_error(d, c->sense, 0)) { case RETRY: done = 0; + if (burn_sg_log_scsi & 3) { + /* >>> Need own duration time + measurement. Then remove bit1 */ + scsi_log_err(c, fp, c->sense, 0, + (c->error != 0) | 2); + scsi_log_cmd(c,fp,0); + } break; case FAIL: done = 1; diff --git a/libburn/sg-libcdio.c b/libburn/sg-libcdio.c index 138eca9..8c4bf04 100644 --- a/libburn/sg-libcdio.c +++ b/libburn/sg-libcdio.c @@ -553,7 +553,7 @@ int sg_release(struct burn_drive *d) */ int sg_issue_command(struct burn_drive *d, struct command *c) { - int sense_valid = 0, i, usleep_time, timeout_ms; + int sense_valid = 0, i, usleep_time, timeout_ms, no_retry = 0; time_t start_time; driver_return_code_t i_status; unsigned int dxfer_len; @@ -568,15 +568,15 @@ int sg_issue_command(struct burn_drive *d, struct command *c) return 0; } p_cdio = (CdIo_t *) d->p_cdio; - if (burn_sg_log_scsi & 1) { - if (fp == NULL) { - fp= fopen("/tmp/libburn_sg_command_log", "a"); - fprintf(fp, - "\n-----------------------------------------\n"); - } - } - if (burn_sg_log_scsi & 3) - scsi_log_cmd(c,fp,0); + if (burn_sg_log_scsi & 1) { + if (fp == NULL) { + fp= fopen("/tmp/libburn_sg_command_log", "a"); + fprintf(fp, + "\n-----------------------------------------\n"); + } + } + if (burn_sg_log_scsi & 3) + scsi_log_cmd(c,fp,0); memcpy(cdb.field, c->opcode, c->oplen); if (c->dir == TO_DRIVE) { @@ -628,24 +628,35 @@ int sg_issue_command(struct burn_drive *d, struct command *c) } */ - if (!sense_valid) { + if ((!sense_valid) || + ((c->sense[2] & 0x0f) == 0 && c->sense[12] == 0 && + c->sense[13] == 0)) { memset(c->sense, 0, sizeof(c->sense)); if (i_status != 0) { /* set dummy sense */ - /*LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE*/ + /*LOGICAL UNIT NOT READY, + CAUSE NOT REPORTABLE*/ c->sense[2] = 0x02; c->sense[12] = 0x04; + no_retry = 1; } } else c->sense[2] &= 15; if (i_status != 0 || (c->sense[2] || c->sense[12] || c->sense[13])) { - if (!c->retry) { + if (no_retry || !c->retry) { c->error = 1; goto ex; } switch (scsi_error(d, c->sense, 18)) { case RETRY: + if (burn_sg_log_scsi & 3) { + /* >>> Need own duration time + measurement. Then remove bit1 */ + scsi_log_err(c, fp, c->sense, 0, + (c->error != 0) | 2); + scsi_log_cmd(c,fp,0); + } break; case FAIL: c->error = 1; diff --git a/libburn/sg-linux.c b/libburn/sg-linux.c index 2ef61df..214d692 100644 --- a/libburn/sg-linux.c +++ b/libburn/sg-linux.c @@ -1928,6 +1928,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c) switch (scsi_error(d, s.sbp, s.sb_len_wr)) { case RETRY: done = 0; + if (burn_sg_log_scsi & 3) + scsi_log_cmd(c,fp,0); break; case FAIL: done = 1; diff --git a/libburn/spc.c b/libburn/spc.c index c1f1dd9..1418edb 100644 --- a/libburn/spc.c +++ b/libburn/spc.c @@ -113,7 +113,8 @@ int spc_test_unit_ready(struct burn_drive *d) int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text, int flag) { - int i, ret = 1, key = 0, asc = 0, ascq = 0; + int i, ret = 1, key = 0, asc = 0, ascq = 0, clueless_start = 0; + static int clueless_timeout = 5 * 10; char msg[320]; unsigned char sense[14]; enum response resp; @@ -143,6 +144,7 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text, /* media change notice = try again */ goto slumber; +handle_error:; /* ts A90213 */ sprintf(msg, "Asynchronous SCSI error on %s: ", cmd_text); @@ -157,7 +159,23 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text, msg, 0, 0); d->cancel = 1; break; - } + } else if (ascq == 0x00) { /* CAUSE NOT REPORTABLE */ + /* Might be a clueless system adapter */ + if (clueless_start == 0) + clueless_start = i; + if (i - clueless_start > clueless_timeout) { + libdax_msgs_submit(libdax_messenger, + d->global_index, + 0x00000002, + LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, + "Ended clueless NOT READY cycle", + 0, 0); + ret = 1; /* medium not present = ok */ + break; + } + } else if (ascq == 0x02 || ascq == 0x03) + goto handle_error; + slumber:; usleep(100000); } @@ -982,8 +1000,11 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense, sprintf(msg, "Not ready"); return RETRY; case 0x04: - sprintf(msg, + if (*ascq == 1) + sprintf(msg, "Logical unit is in the process of becoming ready"); + else + sprintf(msg, "Logical unit is not ready"); return RETRY; case 0x08: if (*key != 4)