From 9f61db5378ea312ea2aece290bf4accd61d8cd1d Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Thu, 29 Jul 2010 08:35:36 +0000 Subject: [PATCH] Recognizing sense data format 0x72 if given instead of 0x70 --- cdrskin/cdrskin_timestamp.h | 2 +- libburn/mmc.c | 76 ++++++++++--------------------------- libburn/sg-freebsd.c | 11 ++++-- libburn/sg-libcdio.c | 18 ++++----- libburn/sg-solaris.c | 7 ++-- libburn/spc.c | 65 +++++++++++++++++++++---------- libburn/spc.h | 4 ++ 7 files changed, 91 insertions(+), 92 deletions(-) diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index b94ffad..fcf2a98 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2010.07.12.193644" +#define Cdrskin_timestamP "2010.07.29.083453" diff --git a/libburn/mmc.c b/libburn/mmc.c index b42832a..40ae3c1 100644 --- a/libburn/mmc.c +++ b/libburn/mmc.c @@ -813,7 +813,7 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf) { int cancelled; struct command c; - int len; + int len, key, asc, ascq; #ifdef Libburn_log_in_and_out_streaM /* <<< ts A61031 */ @@ -892,33 +892,20 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf) d->pbf_altered = 1; /* ts A61112 : react on eventual error condition */ - if (c.error && c.sense[2]!=0) { + spc_decode_sense(c.sense, 0, &key, &asc, &ascq); + if (c.error && key != 0) { /* >>> make this scsi_notify_error() when liberated */ - if (c.sense[2]!=0) { + char msg[256]; + int key, asc, ascq; -#ifdef NIX - char msg[160]; - sprintf(msg, - "SCSI error on write(%d,%d): key=%X asc=%2.2Xh ascq=%2.2Xh", - start, len, - c.sense[2],c.sense[12],c.sense[13]); -#else /* NIX */ - char msg[256]; - int key, asc, ascq; - - sprintf(msg, "SCSI error on write(%d,%d): ", - start, len); - scsi_error_msg(d, c.sense, 14, msg + strlen(msg), + sprintf(msg, "SCSI error on write(%d,%d): ", start, len); + scsi_error_msg(d, c.sense, 14, msg + strlen(msg), &key, &asc, &ascq); - -#endif /* !NIX */ - - libdax_msgs_submit(libdax_messenger, d->global_index, + libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002011d, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); - } d->cancel = 1; return BE_CANCELLED; } @@ -2334,7 +2321,8 @@ int mmc_set_streaming(struct burn_drive *d, d->issue_command(d, &c); if (c.error) { - if (c.sense[2]!=0 && !d->silent_on_scsi_error) { + spc_decode_sense(c.sense, 0, &key, &asc, &ascq); + if (key != 0 && !d->silent_on_scsi_error) { sprintf(msg, "SCSI error on set_streaming(%d): ", w_speed); scsi_error_msg(d, c.sense, 14, msg + strlen(msg), @@ -2414,7 +2402,7 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len) { struct buffer buf; int len, cp, descr_len = 0, feature_code, prf_number, only_current = 1; - int old_alloc_len, only_current_profile = 0; + int old_alloc_len, only_current_profile = 0, key, asc, ascq; unsigned char *descr, *prf, *up_to, *prf_end; struct command c; int phys_if_std = 0; @@ -2449,6 +2437,7 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len) #ifdef Libisofs_simulate_old_mmc1_drivE c.error = 1; + c.sense[0] = 0x70; /* Fixed format sense data */ c.sense[2] = 0x5; c.sense[12] = 0x20; c.sense[13] = 0x0; @@ -2456,8 +2445,8 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len) if (c.error) { /* ts A90603 : MMC-1 drive do not know 46h GET CONFIGURATION */ - if (c.sense[2] == 0x5 && c.sense[12] == 0x20 && - c.sense[13] == 0x0) { + spc_decode_sense(c.sense, 0, &key, &asc, &ascq); + if (key == 0x5 && asc == 0x20 && ascq == 0x0) { d->current_is_guessed_profile = 1; /* Will yield a non-zero profile only after mmc_read_disc_info_al() was called */ @@ -3608,24 +3597,11 @@ unsuitable_media:; d->issue_command(d, &c); if (c.error && !tolerate_failure) { - if (c.sense[2]!=0) { - -#ifdef NIX - sprintf(msg, - "SCSI error on format_unit(%s): key=%X asc=%2.2Xh ascq=%2.2Xh", - descr, - c.sense[2],c.sense[12],c.sense[13]); - libdax_msgs_submit(libdax_messenger, d->global_index, - 0x00020122, - LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, - msg, 0, 0); -#else /* NIX */ + spc_decode_sense(c.sense, 0, &key, &asc, &ascq); + if (key != 0) { sprintf(msg, "SCSI error on format_unit(%s): ", descr); scsi_error_msg(d, c.sense, 14, msg + strlen(msg), &key, &asc, &ascq); - -#endif /* !NIX */ - } return 0; } else if ((!c.error) && (format_type == 0x13 || format_type == 0x15)) @@ -3695,6 +3671,7 @@ static int mmc_get_write_performance_al(struct burn_drive *d, #ifdef Libisofs_simulate_old_mmc1_drivE c.error = 1; + c.sense[0] = 0x70; /* Fixed format sense data */ c.sense[2] = 0x5; c.sense[12] = 0x20; c.sense[13] = 0x0; @@ -3926,11 +3903,13 @@ int mmc_compose_mode_page_5(struct burn_drive *d, int mmc_read_10(struct burn_drive *d, int start,int amount, struct buffer *buf) { struct command c; + char msg[256]; + int key, asc, ascq; mmc_start_if_needed(d, 0); if (mmc_function_spy(d, "mmc_read_10") <= 0) return -1; -; + if (amount > BUFFER_SIZE / 2048) return -1; @@ -3946,24 +3925,9 @@ int mmc_read_10(struct burn_drive *d, int start,int amount, struct buffer *buf) c.dir = FROM_DRIVE; d->issue_command(d, &c); if (c.error) { - -#ifdef NIX - char msg[160]; - - sprintf(msg, - "SCSI error on read_10(%d,%d): key=%X asc=%2.2Xh ascq=%2.2Xh", - start, amount, - c.sense[2],c.sense[12],c.sense[13]); -#else /* NIX */ - char msg[256]; - int key, asc, ascq; - sprintf(msg, "SCSI error on read_10(%d,%d): ", start, amount); scsi_error_msg(d, c.sense, 14, msg + strlen(msg), &key, &asc, &ascq); - -#endif /* !NIX */ - if(!d->silent_on_scsi_error) libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020144, diff --git a/libburn/sg-freebsd.c b/libburn/sg-freebsd.c index 7385133..f842cd9 100644 --- a/libburn/sg-freebsd.c +++ b/libburn/sg-freebsd.c @@ -760,7 +760,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, no_retry = 0; - int cam_pass_err_recover = 0; + int cam_pass_err_recover = 0, key, asc, ascq; union ccb *ccb; char buf[161]; static FILE *fp = NULL; @@ -867,8 +867,9 @@ int sg_issue_command(struct burn_drive *d, struct command *c) if (sense_len > sizeof(c->sense)) sense_len = sizeof(c->sense); memcpy(c->sense, &ccb->csio.sense_data, sense_len); - if (sense_len >= 14 && cam_pass_err_recover && - (c->sense[2] & 0x0f)) + spc_decode_sense(c->sense, sense_len, + &key, &asc, &ascq); + if (sense_len >= 14 && cam_pass_err_recover && key) ignore_error = 1; } @@ -886,6 +887,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c) fprintf(stderr, "libburn_EXPERIMENTAL: Emulating [2,3A,00] MEDIUM NOT PRESENT\n"); #endif + c->sense[0] = 0x70; /*Fixed format sense data*/ c->sense[2] = 0x02; c->sense[12] = 0x3A; c->sense[13] = 0x00; @@ -901,6 +903,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c) fprintf(stderr, "libburn_EXPERIMENTAL: Emulating [2,04,00] LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE\n"); #endif + c->sense[0] = 0x70; /*Fixed format sense data*/ c->sense[2] = 0x02; c->sense[12] = 0x04; c->sense[13] = 0x00; @@ -914,6 +917,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c) fprintf(stderr, "libburn_EXPERIMENTAL: Emulating [5,24,00] INVALID FIELD IN CDB\n"); #endif + c->sense[0] = 0x70; /*Fixed format sense data*/ c->sense[2] = 0x05; c->sense[12] = 0x24; c->sense[13] = 0x00; @@ -944,6 +948,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c) fprintf(stderr, "libburn_EXPERIMENTAL: CAM_STATUS= %d .Emulating [2,04,00] LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE\n", (ccb->ccb_h.status & CAM_STATUS_MASK)); #endif + c->sense[0] = 0x70; /*Fixed format sense data*/ c->sense[2] = 0x02; c->sense[12] = 0x04; c->sense[13] = 0x00; diff --git a/libburn/sg-libcdio.c b/libburn/sg-libcdio.c index 5bdf5d9..8f2ec63 100644 --- a/libburn/sg-libcdio.c +++ b/libburn/sg-libcdio.c @@ -598,6 +598,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, no_retry = 0; + int key = 0, asc = 0, ascq = 0; time_t start_time; driver_return_code_t i_status; unsigned int dxfer_len; @@ -647,10 +648,13 @@ int sg_issue_command(struct burn_drive *d, struct command *c) i_status = mmc_run_cmd(p_cdio, timeout_ms, &cdb, e_direction, dxfer_len, c->page->data); sense_valid = mmc_last_cmd_sense(p_cdio, &sense_pt); - if (sense_valid >= 18) + if (sense_valid >= 18) { memcpy(c->sense, sense_pt, sense_valid >= sizeof(c->sense) ? sizeof(c->sense) : sense_valid ); + spc_decode_sense(c->sense, 0, &key, &asc, &ascq); + } else + key = asc = ascq = 0; if (sense_pt != NULL) free(sense_pt); @@ -672,22 +676,18 @@ int sg_issue_command(struct burn_drive *d, struct command *c) } */ - if ((!sense_valid) || - ((c->sense[2] & 0x0f) == 0 && c->sense[12] == 0 && - c->sense[13] == 0)) { + if ((!sense_valid) || (key == 0 && asc == 0 && ascq == 0)) { memset(c->sense, 0, sizeof(c->sense)); if (i_status != 0) { /* set dummy sense */ /*LOGICAL UNIT NOT READY, CAUSE NOT REPORTABLE*/ + c->sense[0] = 0x70; /*Fixed format sense data*/ 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 (i_status != 0 || (key || asc || ascq)) { if (no_retry || !c->retry) { c->error = 1; goto ex; diff --git a/libburn/sg-solaris.c b/libburn/sg-solaris.c index 2d83440..faa65f6 100644 --- a/libburn/sg-solaris.c +++ b/libburn/sg-solaris.c @@ -565,7 +565,7 @@ int sg_release(struct burn_drive *d) */ int sg_issue_command(struct burn_drive *d, struct command *c) { - int i, usleep_time, timeout_ms, no_retry = 0, ret; + int i, usleep_time, timeout_ms, no_retry = 0, ret, key, asc, ascq; time_t start_time; struct uscsi_cmd cgc; char msg[80]; @@ -639,11 +639,10 @@ int sg_issue_command(struct burn_drive *d, struct command *c) return -1; } - c->sense[2] &= 15; - /* >>> valid sense: cgc.uscsi_rqlen - cgc.uscsi_rqresid */; - if (c->sense[2] || c->sense[12] || c->sense[13]) { + spc_decode_sense(c->sense, 0, &key, &asc, &ascq); + if (key || asc || ascq) { if (no_retry || !c->retry) { c->error = 1; goto ex; diff --git a/libburn/spc.c b/libburn/spc.c index 93ff05c..f3322b4 100644 --- a/libburn/spc.c +++ b/libburn/spc.c @@ -75,6 +75,30 @@ int scsi_init_command(struct command *c, unsigned char *opcode, int oplen) } +/* ts B00728 */ +int spc_decode_sense(unsigned char *sense, int senselen, + int *key, int *asc, int *ascq) +{ + *key = *asc = *ascq = 0; + if ((sense[0] & 0x7f) == 0x72 || (sense[0] & 0x7f) == 0x73) { + if (senselen <= 0 || senselen > 1) + *key = sense[1] & 0x0f; + if (senselen <= 0 || senselen > 2) + *asc = sense[2]; + if (senselen <= 0 || senselen > 3) + *ascq = sense[3]; + return 1; + } + if (senselen <= 0 || senselen > 2) + *key = sense[2] & 0x0f; + if (senselen <= 0 || senselen > 12) + *asc = sense[12]; + if (senselen <= 0 || senselen > 13) + *ascq = sense[13]; + return 1; +} + + int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq) { struct command c; @@ -83,23 +107,23 @@ int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq) return 0; scsi_init_command(&c, SPC_TEST_UNIT_READY,sizeof(SPC_TEST_UNIT_READY)); -/* - c.oplen = sizeof(SPC_TEST_UNIT_READY); - memcpy(c.opcode, SPC_TEST_UNIT_READY, sizeof(SPC_TEST_UNIT_READY)); - c.page = NULL; -*/ c.retry = 0; c.dir = NO_TRANSFER; d->issue_command(d, &c); if (c.error) { - *key= c.sense[2]; - *asc= c.sense[12]; - *ascq= c.sense[13]; - return (c.sense[2] & 0xF) == 0; + +/* +fprintf(stderr, "sense[0 - 2] = %2.2X %2.2X %2.2X", +c.sense[0], c.sense[1], c.sense[2]); +*/ + + spc_decode_sense(c.sense, 0, key, asc, ascq); + return (key == 0); } return 1; } + int spc_test_unit_ready(struct burn_drive *d) { int key,asc,ascq; @@ -151,6 +175,7 @@ handle_error:; /* ts A90213 */ sprintf(msg, "Asynchronous SCSI error on %s: ", cmd_text); + sense[0] = 0x70; /* Fixed format sense data */ sense[2] = key; sense[12] = asc; sense[13] = ascq; @@ -249,7 +274,7 @@ void spc_inquiry(struct burn_drive *d) memcpy(c.opcode, SPC_INQUIRY, sizeof(SPC_INQUIRY)); c.oplen = sizeof(SPC_INQUIRY); */ - c.dxfer_len= (c.opcode[3] << 8) | c.opcode[4]; + c.dxfer_len = (c.opcode[3] << 8) | c.opcode[4]; c.retry = 1; c.page = &buf; c.page->bytes = 0; @@ -803,9 +828,7 @@ void spc_probe_write_modes(struct burn_drive *d) if (last_try) break; - key = c.sense[2]; - asc = c.sense[12]; - ascq = c.sense[13]; + spc_decode_sense(c.sense, 0, &key, &asc, &ascq); if (key) burn_print(7, "%d not supported\n", try_block_type); else { @@ -958,6 +981,7 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense, int senselen, char msg_data[161], int *key, int *asc, int *ascq) { + int ret; char *msg; static char key_def[16][40] = { "(no specific error)", @@ -981,12 +1005,9 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense, msg= msg_data; *key= *asc= *ascq= -1; - if (senselen<=0 || senselen>2) - *key = sense[2] & 0x0f; - if (senselen<=0 || senselen>12) - *asc = sense[12]; - if (senselen<=0 || senselen>13) - *ascq = sense[13]; + ret = spc_decode_sense(sense, senselen, key, asc, ascq); + if (ret <= 0) + *key= *asc= *ascq= -1; sprintf(msg, "[%X %2.2X %2.2X] ", *key, *asc, *ascq); msg= msg + strlen(msg); @@ -1203,6 +1224,12 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense, sprintf(msg, "Medium not present"); d->status = BURN_DISC_EMPTY; return FAIL; + case 0x3E: + if (*ascq == 1) + sprintf(msg, "Logical unit failure"); + else if (*ascq == 2) + sprintf(msg, "Timeout on logical unit"); + return FAIL; case 0x57: if (*key != 3 || *ascq != 0) break; diff --git a/libburn/spc.h b/libburn/spc.h index 880d692..8db36f4 100644 --- a/libburn/spc.h +++ b/libburn/spc.h @@ -80,5 +80,9 @@ int scsi_log_cmd(struct command *c, void *fp, int flag); int scsi_log_err(struct command *c, void *fp, unsigned char sense[18], int duration, int flag); +/* ts B00728 */ +int spc_decode_sense(unsigned char *sense, int senselen, + int *key, int *asc, int *ascq); + #endif /*__SPC*/