Centralized interpretation of SCSI command outcome
This commit is contained in:
parent
4cc524097b
commit
c1f4063193
@ -1 +1 @@
|
|||||||
#define Cdrskin_timestamP "2010.08.21.095456"
|
#define Cdrskin_timestamP "2010.09.14.124934"
|
||||||
|
@ -759,13 +759,17 @@ int sg_release(struct burn_drive *d)
|
|||||||
|
|
||||||
int sg_issue_command(struct burn_drive *d, struct command *c)
|
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 done = 0, err, sense_len = 0, ret, ignore_error, no_retry = 0, i;
|
||||||
int cam_pass_err_recover = 0, key, asc, ascq;
|
int cam_pass_err_recover = 0, key, asc, ascq, timeout_ms;
|
||||||
union ccb *ccb;
|
union ccb *ccb;
|
||||||
char buf[161];
|
char buf[161];
|
||||||
static FILE *fp = NULL;
|
static FILE *fp = NULL;
|
||||||
|
time_t start_time;
|
||||||
|
|
||||||
snprintf(buf, sizeof (buf), "sg_issue_command d->cam=%p d->released=%d",
|
#define Libburn_use_scsi_eval_cmd_outcomE yes
|
||||||
|
|
||||||
|
snprintf(buf, sizeof (buf),
|
||||||
|
"sg_issue_command d->cam=%p d->released=%d",
|
||||||
(void*)d->cam, d->released);
|
(void*)d->cam, d->released);
|
||||||
mmc_function_spy(NULL, buf);
|
mmc_function_spy(NULL, buf);
|
||||||
|
|
||||||
@ -854,7 +858,9 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
ccb->csio.dxfer_len = 0;
|
ccb->csio.dxfer_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
start_time = time(NULL);
|
||||||
|
timeout_ms = 200000;
|
||||||
|
for (i = 0; !done; i++) {
|
||||||
memset(c->sense, 0, sizeof(c->sense));
|
memset(c->sense, 0, sizeof(c->sense));
|
||||||
err = cam_send_ccb(d->cam, ccb);
|
err = cam_send_ccb(d->cam, ccb);
|
||||||
|
|
||||||
@ -954,6 +960,17 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
c->sense[13] = 0x00;
|
c->sense[13] = 0x00;
|
||||||
no_retry = 1;
|
no_retry = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
|
||||||
|
done = scsi_eval_cmd_outcome(d, c, fp, c->sense,
|
||||||
|
sense_len, 0, start_time,
|
||||||
|
timeout_ms, i,
|
||||||
|
2 | !!ignore_error);
|
||||||
|
|
||||||
|
#else /* Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
if (no_retry || ignore_error || !c->retry) {
|
if (no_retry || ignore_error || !c->retry) {
|
||||||
c->error = 1;
|
c->error = 1;
|
||||||
{ret = 1; goto ex;}
|
{ret = 1; goto ex;}
|
||||||
@ -983,12 +1000,18 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
0, 1 | 2);
|
0, 1 | 2);
|
||||||
{ret = 1; goto ex;}
|
{ret = 1; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* ! Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
} while (!done);
|
} while (!done);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
ex:;
|
ex:;
|
||||||
|
|
||||||
|
#ifndef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
|
||||||
if (c->error)
|
if (c->error)
|
||||||
scsi_notify_error(d, c, c->sense, 18, 0);
|
scsi_notify_error(d, c, c->sense, 18, 0);
|
||||||
|
|
||||||
@ -997,6 +1020,8 @@ ex:;
|
|||||||
scsi_log_err(c, fp, c->sense, sense_len > 0 ? sense_len : 18,
|
scsi_log_err(c, fp, c->sense, sense_len > 0 ? sense_len : 18,
|
||||||
0, (c->error != 0) | 2);
|
0, (c->error != 0) | 2);
|
||||||
|
|
||||||
|
#endif /* ! Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
cam_freeccb(ccb);
|
cam_freeccb(ccb);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -586,6 +586,9 @@ int sg_release(struct burn_drive *d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define Libburn_use_scsi_eval_cmd_outcomE yes
|
||||||
|
|
||||||
|
|
||||||
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
||||||
the command succeeded or shall be retried or finally failed.
|
the command succeeded or shall be retried or finally failed.
|
||||||
Returned SCSI errors shall not lead to a return value indicating failure.
|
Returned SCSI errors shall not lead to a return value indicating failure.
|
||||||
@ -597,8 +600,8 @@ int sg_release(struct burn_drive *d)
|
|||||||
*/
|
*/
|
||||||
int sg_issue_command(struct burn_drive *d, struct command *c)
|
int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
{
|
{
|
||||||
int sense_valid = 0, i, usleep_time, timeout_ms, no_retry = 0;
|
int sense_valid = 0, i, timeout_ms, no_retry = 0;
|
||||||
int key = 0, asc = 0, ascq = 0;
|
int key = 0, asc = 0, ascq = 0, done = 0;
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
driver_return_code_t i_status;
|
driver_return_code_t i_status;
|
||||||
unsigned int dxfer_len;
|
unsigned int dxfer_len;
|
||||||
@ -608,6 +611,10 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
CdIo_t *p_cdio;
|
CdIo_t *p_cdio;
|
||||||
unsigned char *sense_pt = NULL;
|
unsigned char *sense_pt = NULL;
|
||||||
|
|
||||||
|
#ifndef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
int usleep_time;
|
||||||
|
#endif
|
||||||
|
|
||||||
c->error = 0;
|
c->error = 0;
|
||||||
if (d->p_cdio == NULL) {
|
if (d->p_cdio == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -643,7 +650,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
/* retry-loop */
|
/* retry-loop */
|
||||||
start_time = time(NULL);
|
start_time = time(NULL);
|
||||||
timeout_ms = 200000;
|
timeout_ms = 200000;
|
||||||
for(i = 0; ; i++) {
|
for(i = 0; !done; i++) {
|
||||||
|
|
||||||
i_status = mmc_run_cmd(p_cdio, timeout_ms, &cdb, e_direction,
|
i_status = mmc_run_cmd(p_cdio, timeout_ms, &cdb, e_direction,
|
||||||
dxfer_len, c->page->data);
|
dxfer_len, c->page->data);
|
||||||
@ -688,6 +695,14 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i_status != 0 || (key || asc || ascq)) {
|
if (i_status != 0 || (key || asc || ascq)) {
|
||||||
|
|
||||||
|
#ifdef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
|
||||||
|
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, 18,
|
||||||
|
0, start_time, timeout_ms, i, 2);
|
||||||
|
|
||||||
|
#else /* Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
if (no_retry || !c->retry) {
|
if (no_retry || !c->retry) {
|
||||||
c->error = 1;
|
c->error = 1;
|
||||||
goto ex;
|
goto ex;
|
||||||
@ -724,17 +739,24 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
usleep(usleep_time);
|
usleep(usleep_time);
|
||||||
|
#endif /* ! Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
} else
|
} else
|
||||||
break; /* retry-loop */
|
done = 1;
|
||||||
|
|
||||||
} /* end of retry-loop */
|
} /* end of retry-loop */
|
||||||
|
|
||||||
|
#ifndef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
|
||||||
ex:;
|
ex:;
|
||||||
if (c->error)
|
if (c->error)
|
||||||
scsi_notify_error(d, c, c->sense, 18, 0);
|
scsi_notify_error(d, c, c->sense, 18, 0);
|
||||||
|
|
||||||
if (burn_sg_log_scsi & 3)
|
if (burn_sg_log_scsi & 3)
|
||||||
/* >>> Need own duration time measurement. Then remove bit1 */
|
/* >>> Need own duration time measurement. Then remove bit1 */
|
||||||
scsi_log_err(c, fp, c->sense, 18, 0, (c->error != 0) | 2);
|
scsi_log_err(c, fp, c->sense, 18, 0, (c->error != 0) | 2);
|
||||||
|
|
||||||
|
#endif /* ! Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1782,13 +1782,19 @@ int sg_release(struct burn_drive *d)
|
|||||||
*/
|
*/
|
||||||
int sg_issue_command(struct burn_drive *d, struct command *c)
|
int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
{
|
{
|
||||||
int done = 0, no_c_page = 0, usleep_time, i;
|
int done = 0, no_c_page = 0, i;
|
||||||
int err;
|
int err;
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
sg_io_hdr_t s;
|
sg_io_hdr_t s;
|
||||||
/* ts A61030 */
|
/* ts A61030 */
|
||||||
static FILE *fp= NULL;
|
static FILE *fp= NULL;
|
||||||
|
|
||||||
|
#define Libburn_use_scsi_eval_cmd_outcomE yes
|
||||||
|
#ifndef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
int usleep_time;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* <<< ts A60821
|
/* <<< ts A60821
|
||||||
debug: for tracing calls which might use open drive fds */
|
debug: for tracing calls which might use open drive fds */
|
||||||
char buf[161];
|
char buf[161];
|
||||||
@ -1910,6 +1916,14 @@ if(0){
|
|||||||
/* <<< */
|
/* <<< */
|
||||||
#endif /* NIX */
|
#endif /* NIX */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
|
||||||
|
done = scsi_eval_cmd_outcome(d, c, fp, s.sbp, s.sb_len_wr,
|
||||||
|
s.duration, start_time, s.timeout, i, 0);
|
||||||
|
|
||||||
|
#else /* Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
if (s.sb_len_wr) {
|
if (s.sb_len_wr) {
|
||||||
if (!c->retry) {
|
if (!c->retry) {
|
||||||
c->error = 1;
|
c->error = 1;
|
||||||
@ -1951,14 +1965,28 @@ if(0){
|
|||||||
} else {
|
} else {
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* ! Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts A61106 */
|
/* ts A61106 */
|
||||||
|
|
||||||
|
#ifdef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
|
||||||
|
if (s.host_status != Libburn_sg_host_oK ||
|
||||||
|
(s.driver_status != Libburn_sg_driver_oK && !c->error)) {
|
||||||
|
|
||||||
|
#else /* Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
ex:;
|
ex:;
|
||||||
if (c->error) {
|
if (c->error) {
|
||||||
scsi_notify_error(d, c, s.sbp, s.sb_len_wr, 0);
|
scsi_notify_error(d, c, s.sbp, s.sb_len_wr, 0);
|
||||||
} else if (s.host_status != Libburn_sg_host_oK ||
|
} else if (s.host_status != Libburn_sg_host_oK ||
|
||||||
s.driver_status != Libburn_sg_driver_oK) {
|
s.driver_status != Libburn_sg_driver_oK) {
|
||||||
|
|
||||||
|
#endif /* ! Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
char msg[161];
|
char msg[161];
|
||||||
|
|
||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
@ -1973,9 +2001,13 @@ ex:;
|
|||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
msg, 0, 0);
|
msg, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
if (burn_sg_log_scsi & 3)
|
if (burn_sg_log_scsi & 3)
|
||||||
scsi_log_err(c, fp, s.sbp, s.sb_len_wr,
|
scsi_log_err(c, fp, s.sbp, s.sb_len_wr,
|
||||||
s.duration, c->error != 0);
|
s.duration, c->error != 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,12 +565,17 @@ int sg_release(struct burn_drive *d)
|
|||||||
*/
|
*/
|
||||||
int sg_issue_command(struct burn_drive *d, struct command *c)
|
int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
{
|
{
|
||||||
int i, usleep_time, timeout_ms, no_retry = 0, ret, key, asc, ascq;
|
int i, timeout_ms, ret, key, asc, ascq, done = 0;
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
struct uscsi_cmd cgc;
|
struct uscsi_cmd cgc;
|
||||||
char msg[80];
|
char msg[80];
|
||||||
static FILE *fp = NULL;
|
static FILE *fp = NULL;
|
||||||
|
|
||||||
|
#define Libburn_use_scsi_eval_cmd_outcomE yes
|
||||||
|
#ifndef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
int usleep_time, no_retry = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
c->error = 0;
|
c->error = 0;
|
||||||
memset(c->sense, 0, sizeof(c->sense));
|
memset(c->sense, 0, sizeof(c->sense));
|
||||||
if (d->fd == -1)
|
if (d->fd == -1)
|
||||||
@ -616,7 +621,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
/* retry-loop */
|
/* retry-loop */
|
||||||
start_time = time(NULL);
|
start_time = time(NULL);
|
||||||
timeout_ms = 200000;
|
timeout_ms = 200000;
|
||||||
for(i = 0; ; i++) {
|
for(i = 0; !done; i++) {
|
||||||
|
|
||||||
ret = ioctl(d->fd, USCSICMD, &cgc);
|
ret = ioctl(d->fd, USCSICMD, &cgc);
|
||||||
|
|
||||||
@ -639,6 +644,25 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
|
||||||
|
|
||||||
|
/* >>> Should replace "18" by realistic sense length.
|
||||||
|
What's about following older remark ?
|
||||||
|
*/
|
||||||
|
/* >>> valid sense: cgc.uscsi_rqlen - cgc.uscsi_rqresid */;
|
||||||
|
|
||||||
|
spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
|
||||||
|
if (key || asc || ascq) {
|
||||||
|
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, 18, 0,
|
||||||
|
start_time, timeout_ms, i, 2);
|
||||||
|
} else
|
||||||
|
done = 1;
|
||||||
|
|
||||||
|
|
||||||
|
#else /* Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
|
|
||||||
/* >>> valid sense: cgc.uscsi_rqlen - cgc.uscsi_rqresid */;
|
/* >>> valid sense: cgc.uscsi_rqlen - cgc.uscsi_rqresid */;
|
||||||
|
|
||||||
spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
|
spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
|
||||||
@ -681,15 +705,24 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
usleep(usleep_time);
|
usleep(usleep_time);
|
||||||
} else
|
} else
|
||||||
break; /* retry-loop */
|
break; /* retry-loop */
|
||||||
|
|
||||||
|
#endif /* ! Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
} /* end of retry-loop */
|
} /* end of retry-loop */
|
||||||
|
|
||||||
|
#ifndef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
|
||||||
ex:;
|
ex:;
|
||||||
|
|
||||||
if (c->error)
|
if (c->error)
|
||||||
scsi_notify_error(d, c, c->sense, 18, 0);
|
scsi_notify_error(d, c, c->sense, 18, 0);
|
||||||
|
|
||||||
if (burn_sg_log_scsi & 3)
|
if (burn_sg_log_scsi & 3)
|
||||||
/* >>> Need own duration time measurement. Then remove bit1 */
|
/* >>> Need own duration time measurement. Then remove bit1 */
|
||||||
scsi_log_err(c, fp, c->sense, 18, 0, (c->error != 0) | 2);
|
scsi_log_err(c, fp, c->sense, 18, 0, (c->error != 0) | 2);
|
||||||
|
|
||||||
|
#endif /* ! Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1408,28 +1408,10 @@ int scsi_notify_error(struct burn_drive *d, struct command *c,
|
|||||||
sprintf(msg, "SCSI error condition on command %2.2Xh %s: ",
|
sprintf(msg, "SCSI error condition on command %2.2Xh %s: ",
|
||||||
c->opcode[0],
|
c->opcode[0],
|
||||||
scsi_command_name((unsigned int) c->opcode[0], 0));
|
scsi_command_name((unsigned int) c->opcode[0], 0));
|
||||||
|
|
||||||
#ifdef NIX
|
|
||||||
if (key>=0)
|
|
||||||
sprintf(msg+strlen(msg), " key=%Xh", key);
|
|
||||||
if (asc>=0)
|
|
||||||
sprintf(msg+strlen(msg), " asc=%2.2Xh", asc);
|
|
||||||
if (ascq>=0)
|
|
||||||
sprintf(msg+strlen(msg), " ascq=%2.2Xh", ascq);
|
|
||||||
ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f,
|
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f,
|
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
scsi_msg,0,0);
|
|
||||||
#else
|
|
||||||
strcat(msg, scsi_msg);
|
strcat(msg, scsi_msg);
|
||||||
ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f,
|
ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f,
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0);
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0);
|
||||||
|
|
||||||
#endif /* NIX */
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1530,13 +1512,6 @@ int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18],
|
|||||||
|
|
||||||
if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
|
if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
|
||||||
if (flag & 1) {
|
if (flag & 1) {
|
||||||
durtxt[0] = 0;
|
|
||||||
if (!(flag & 2))
|
|
||||||
sprintf(durtxt, " (%6d ms)", duration);
|
|
||||||
spc_decode_sense(sense, 0, &key, &asc, &ascq);
|
|
||||||
fprintf(fp, "+++ key=%X asc=%2.2Xh ascq=%2.2Xh%s\n",
|
|
||||||
(unsigned int) key, (unsigned int) asc,
|
|
||||||
(unsigned int) ascq, durtxt);
|
|
||||||
l = 18;
|
l = 18;
|
||||||
if ((sense[0] & 0x7f) == 0x72 ||
|
if ((sense[0] & 0x7f) == 0x72 ||
|
||||||
(sense[0] & 0x7f) == 0x73)
|
(sense[0] & 0x7f) == 0x73)
|
||||||
@ -1547,6 +1522,13 @@ int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18],
|
|||||||
for (i = 0 ; i < l; i++)
|
for (i = 0 ; i < l; i++)
|
||||||
fprintf(fp, " %2.2X", sense[i]);
|
fprintf(fp, " %2.2X", sense[i]);
|
||||||
fprintf(fp, "\n");
|
fprintf(fp, "\n");
|
||||||
|
durtxt[0] = 0;
|
||||||
|
if (!(flag & 2))
|
||||||
|
sprintf(durtxt, " (%6d ms)", duration);
|
||||||
|
spc_decode_sense(sense, 0, &key, &asc, &ascq);
|
||||||
|
fprintf(fp, "+++ key=%X asc=%2.2Xh ascq=%2.2Xh%s\n",
|
||||||
|
(unsigned int) key, (unsigned int) asc,
|
||||||
|
(unsigned int) ascq, durtxt);
|
||||||
} else {
|
} else {
|
||||||
scsi_show_cmd_reply(c, fp, 0);
|
scsi_show_cmd_reply(c, fp, 0);
|
||||||
if (!(flag & 2))
|
if (!(flag & 2))
|
||||||
@ -1561,3 +1543,51 @@ int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18],
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00808 */
|
||||||
|
/*
|
||||||
|
@param flag bit0 = do not retry
|
||||||
|
bit1 = do not print duration
|
||||||
|
@return 0 = not yet done , 1 = done , -1 = error
|
||||||
|
*/
|
||||||
|
int scsi_eval_cmd_outcome(struct burn_drive *d, struct command *c, void *fp,
|
||||||
|
unsigned char *sense, int sense_len,
|
||||||
|
int duration, time_t start_time, int timeout_ms,
|
||||||
|
int loop_count, int flag)
|
||||||
|
{
|
||||||
|
enum response outcome;
|
||||||
|
int done = -1, usleep_time;
|
||||||
|
|
||||||
|
if (sense_len <= 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (burn_sg_log_scsi & 3)
|
||||||
|
scsi_log_err(c, fp, sense, sense_len, duration,
|
||||||
|
1 | (flag & 2));
|
||||||
|
outcome = scsi_error(d, sense, sense_len);
|
||||||
|
if (outcome == RETRY && c->retry && !(flag & 1)) {
|
||||||
|
/* Calming down retries and breaking up endless cycle
|
||||||
|
*/
|
||||||
|
usleep_time = Libburn_scsi_retry_usleeP +
|
||||||
|
loop_count * Libburn_scsi_retry_incR;
|
||||||
|
if (time(NULL) + usleep_time / 1000000 - start_time >
|
||||||
|
timeout_ms / 1000 + 1) {
|
||||||
|
done = 1;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
usleep(usleep_time);
|
||||||
|
if (burn_sg_log_scsi & 3)
|
||||||
|
scsi_log_cmd(c, fp, 0);
|
||||||
|
return 0;
|
||||||
|
} else if (outcome == RETRY) {
|
||||||
|
done = 1;
|
||||||
|
} else if (outcome == GO_ON) {
|
||||||
|
return 1;
|
||||||
|
} else if (outcome == FAIL) {
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
ex:;
|
||||||
|
c->error = 1;
|
||||||
|
scsi_notify_error(d, c, sense, sense_len, 0);
|
||||||
|
return done;
|
||||||
|
}
|
||||||
|
@ -84,5 +84,23 @@ int scsi_log_err(struct command *c, void *fp, unsigned char sense[18],
|
|||||||
int spc_decode_sense(unsigned char *sense, int senselen,
|
int spc_decode_sense(unsigned char *sense, int senselen,
|
||||||
int *key, int *asc, int *ascq);
|
int *key, int *asc, int *ascq);
|
||||||
|
|
||||||
|
/* ts B00808 */
|
||||||
|
/** Evaluates outcome of a single SCSI command, eventually logs sense data,
|
||||||
|
and issues DEBUG error message in case the command is evaluated as done.
|
||||||
|
@param flag bit1 = do not print duration
|
||||||
|
@return 0 = not yet done , 1 = done , -1 = error
|
||||||
|
*/
|
||||||
|
int scsi_eval_cmd_outcome(struct burn_drive *d, struct command *c, void *fp_in,
|
||||||
|
unsigned char *sense, int sense_len,
|
||||||
|
int duration, time_t start_time, int timeout_ms,
|
||||||
|
int loop_count, int flag);
|
||||||
|
|
||||||
|
/* The waiting time before eventually retrying a failed SCSI command.
|
||||||
|
Before each retry wait Libburn_scsi_retry_incR longer than with
|
||||||
|
the previous one.
|
||||||
|
*/
|
||||||
|
#define Libburn_scsi_retry_usleeP 100000
|
||||||
|
#define Libburn_scsi_retry_incR 100000
|
||||||
|
|
||||||
|
|
||||||
#endif /*__SPC*/
|
#endif /*__SPC*/
|
||||||
|
Loading…
Reference in New Issue
Block a user