Made SCSI timeout settable at level of SPC, SBC, MMC functions

This commit is contained in:
Thomas Schmitt 2011-11-30 08:11:52 +00:00
parent 974d20ae56
commit 086c62f992
11 changed files with 104 additions and 20 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2011.11.26.153142" #define Cdrskin_timestamP "2011.11.30.081130"

View File

@ -518,7 +518,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x0002014b (SORRY,HIGH) = Drive is already registered resp. scanned 0x0002014b (SORRY,HIGH) = Drive is already registered resp. scanned
0x0002014c (FATAL,HIGH) = Emulated drive caught in SCSI function 0x0002014c (FATAL,HIGH) = Emulated drive caught in SCSI function
0x0002014d (SORRY,HIGH) = Asynchromous SCSI error 0x0002014d (SORRY,HIGH) = Asynchromous SCSI error
0x0002014f (SORRY,HIGH) = Timeout with asynchromous SCSI command 0x0002014f (SORRY,HIGH) = Timeout with asynchronous SCSI command
0x00020150 (DEBUG,LOW) = Reporting asynchronous waiting time 0x00020150 (DEBUG,LOW) = Reporting asynchronous waiting time
0x00020151 (FAILURE,HIGH) = Read attempt on write-only drive 0x00020151 (FAILURE,HIGH) = Read attempt on write-only drive
0x00020152 (FATAL,HIGH) = Cannot start fifo thread 0x00020152 (FATAL,HIGH) = Cannot start fifo thread
@ -576,6 +576,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x00020187 (NOTE,HIGH) = Track not marked as damaged. No action taken. 0x00020187 (NOTE,HIGH) = Track not marked as damaged. No action taken.
0x00020188 (FAILURE,HIGH) = Cannot close damaged track on given media type 0x00020188 (FAILURE,HIGH) = Cannot close damaged track on given media type
0x00020189 (FATAL,HIGH) = Drive is already grabbed by libburn 0x00020189 (FATAL,HIGH) = Drive is already grabbed by libburn
0x0002018a (SORRY,HIGH) = Timeout exceeded. Retry cancled.
libdax_audioxtr: libdax_audioxtr:
0x00020200 (SORRY,HIGH) = Cannot open audio source file 0x00020200 (SORRY,HIGH) = Cannot open audio source file

View File

@ -357,6 +357,7 @@ int mmc_reserve_track(struct burn_drive *d, off_t size)
c->page = NULL; c->page = NULL;
c->dir = NO_TRANSFER; c->dir = NO_TRANSFER;
c->timeout = Libburn_mmc_reserve_timeouT;
d->issue_command(d, c); d->issue_command(d, c);
if (c->error) { if (c->error) {
d->cancel = 1; d->cancel = 1;
@ -588,6 +589,7 @@ void mmc_close(struct burn_drive *d, int session, int track)
c->opcode[5] = track & 0xFF; c->opcode[5] = track & 0xFF;
c->page = NULL; c->page = NULL;
c->dir = NO_TRANSFER; c->dir = NO_TRANSFER;
c->timeout = Libburn_mmc_close_timeouT;
d->issue_command(d, c); d->issue_command(d, c);
/* ts A70918 : Immed : wait for drive to complete command */ /* ts A70918 : Immed : wait for drive to complete command */
@ -855,6 +857,7 @@ void mmc_write_12(struct burn_drive *d, int start, struct buffer *buf)
mmc_int_to_four_char(c->opcode + 6, len); mmc_int_to_four_char(c->opcode + 6, len);
c->page = buf; c->page = buf;
c->dir = TO_DRIVE; c->dir = TO_DRIVE;
c->timeout = Libburn_scsi_write_timeouT;
d->issue_command(d, c); d->issue_command(d, c);
@ -863,6 +866,7 @@ void mmc_write_12(struct burn_drive *d, int start, struct buffer *buf)
d->pbf_altered = 1; d->pbf_altered = 1;
} }
int mmc_write(struct burn_drive *d, int start, struct buffer *buf) int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
{ {
int cancelled; int cancelled;
@ -935,6 +939,7 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
c->retry = 1; c->retry = 1;
c->page = buf; c->page = buf;
c->dir = TO_DRIVE; c->dir = TO_DRIVE;
c->timeout = Libburn_scsi_write_timeouT;
#ifdef Libburn_log_in_and_out_streaM #ifdef Libburn_log_in_and_out_streaM
/* <<< ts A61031 */ /* <<< ts A61031 */
@ -2271,6 +2276,7 @@ void mmc_erase(struct burn_drive *d, int fast)
c->retry = 1; c->retry = 1;
c->page = NULL; c->page = NULL;
c->dir = NO_TRANSFER; c->dir = NO_TRANSFER;
c->timeout = Libburn_mmc_blank_timeouT;
d->issue_command(d, c); d->issue_command(d, c);
} }
@ -2313,6 +2319,7 @@ void mmc_perform_opc(struct burn_drive *d)
c->opcode[1] = 1; c->opcode[1] = 1;
c->page = NULL; c->page = NULL;
c->dir = NO_TRANSFER; c->dir = NO_TRANSFER;
c->timeout = Libburn_mmc_opc_timeouT;
d->issue_command(d, c); d->issue_command(d, c);
} }
@ -2969,6 +2976,7 @@ void mmc_sync_cache(struct burn_drive *d)
c->opcode[1] |= 2; /* ts A70918 : Immed */ c->opcode[1] |= 2; /* ts A70918 : Immed */
c->page = NULL; c->page = NULL;
c->dir = NO_TRANSFER; c->dir = NO_TRANSFER;
c->timeout = Libburn_mmc_sync_timeouT;
libdax_msgs_submit(libdax_messenger, -1, 0x00000002, libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
@ -3113,6 +3121,7 @@ int mmc_format_unit(struct burn_drive *d, off_t size, int flag)
c->page->bytes = 12; c->page->bytes = 12;
c->page->sectors = 0; c->page->sectors = 0;
c->dir = TO_DRIVE; c->dir = TO_DRIVE;
c->timeout = Libburn_mmc_blank_timeouT;
memset(c->page->data, 0, c->page->bytes); memset(c->page->data, 0, c->page->bytes);
descr[0] = 0; descr[0] = 0;

View File

@ -67,6 +67,7 @@ void sbc_load(struct burn_drive *d)
/* c->opcode[1] |= 1; / * ts A70918 : Immed */ /* c->opcode[1] |= 1; / * ts A70918 : Immed */
c->dir = NO_TRANSFER; c->dir = NO_TRANSFER;
c->timeout = Libburn_mmc_load_timeouT;
d->issue_command(d, c); d->issue_command(d, c);
if (c->error) if (c->error)
return; return;

View File

@ -768,10 +768,11 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
mmc_function_spy(NULL, "sg_issue_command"); mmc_function_spy(NULL, "sg_issue_command");
if (d->cam == NULL) {
c->error = 0; c->error = 0;
memset(c->sense, 0, sizeof(c->sense));
if (d->cam == NULL)
return 0; return 0;
}
if (burn_sg_log_scsi & 1) { if (burn_sg_log_scsi & 1) {
if (fp == NULL) { if (fp == NULL) {
fp= fopen("/tmp/libburn_sg_command_log", "a"); fp= fopen("/tmp/libburn_sg_command_log", "a");
@ -783,6 +784,10 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
scsi_log_cmd(c,fp,0); scsi_log_cmd(c,fp,0);
c->error = 0; c->error = 0;
if (c->timeout > 0)
timeout_ms = c->timeout;
else
timeout_ms = 200000;
ccb = cam_getccb(d->cam); ccb = cam_getccb(d->cam);
cam_fill_csio(&ccb->csio, cam_fill_csio(&ccb->csio,
@ -794,7 +799,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
0, /* dxfer_len */ 0, /* dxfer_len */
sizeof (ccb->csio.sense_data), /* sense_len */ sizeof (ccb->csio.sense_data), /* sense_len */
0, /* cdb_len */ 0, /* cdb_len */
30*1000); /* timeout */ timeout_ms); /* timeout */
switch (c->dir) { switch (c->dir) {
case TO_DRIVE: case TO_DRIVE:
ccb->csio.ccb_h.flags |= CAM_DIR_OUT; ccb->csio.ccb_h.flags |= CAM_DIR_OUT;
@ -827,8 +832,6 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
ccb->csio.cdb_len = c->oplen; ccb->csio.cdb_len = c->oplen;
memcpy(&ccb->csio.cdb_io.cdb_bytes, &c->opcode, c->oplen); memcpy(&ccb->csio.cdb_io.cdb_bytes, &c->opcode, c->oplen);
memset(&ccb->csio.sense_data, 0, sizeof (ccb->csio.sense_data));
if (c->page) { if (c->page) {
ccb->csio.data_ptr = c->page->data; ccb->csio.data_ptr = c->page->data;
if (c->dir == FROM_DRIVE) { if (c->dir == FROM_DRIVE) {
@ -854,8 +857,9 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
} }
start_time = time(NULL); start_time = time(NULL);
timeout_ms = 200000;
for (i = 0; !done; i++) { for (i = 0; !done; i++) {
memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data));
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);
@ -963,6 +967,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
sense_len, 0, start_time, sense_len, 0, start_time,
timeout_ms, i, timeout_ms, i,
2 | !!ignore_error); 2 | !!ignore_error);
if (d->cancel)
done = 1;
} else { } else {
done = 1; done = 1;
} }

View File

@ -627,6 +627,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
cdio_mmc_request_sense_t *sense_pt = NULL; cdio_mmc_request_sense_t *sense_pt = NULL;
c->error = 0; c->error = 0;
memset(c->sense, 0, sizeof(c->sense));
if (d->p_cdio == NULL) { if (d->p_cdio == NULL) {
return 0; return 0;
} }
@ -660,11 +662,16 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
/* retry-loop */ /* retry-loop */
start_time = time(NULL); start_time = time(NULL);
if (c->timeout > 0)
timeout_ms = c->timeout;
else
timeout_ms = 200000; timeout_ms = 200000;
for(i = 0; !done; i++) { for(i = 0; !done; i++) {
memset(c->sense, 0, sizeof(c->sense));
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);
sense_valid = mmc_last_cmd_sense(p_cdio, &sense_pt); sense_valid = mmc_last_cmd_sense(p_cdio, &sense_pt);
if (sense_valid >= 18) { if (sense_valid >= 18) {
memcpy(c->sense, (unsigned char *) sense_pt, memcpy(c->sense, (unsigned char *) sense_pt,
@ -711,6 +718,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
sense_len = 0; sense_len = 0;
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len, done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len,
0, start_time, timeout_ms, i, 2); 0, start_time, timeout_ms, i, 2);
if (d->cancel)
done = 1;
} /* end of retry-loop */ } /* end of retry-loop */

View File

@ -1898,6 +1898,9 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
BURN_ALLOC_MEM(msg, char, 161); BURN_ALLOC_MEM(msg, char, 161);
c->error = 0;
memset(c->sense, 0, sizeof(c->sense));
/* <<< ts A60821 /* <<< ts A60821
debug: for tracing calls which might use open drive fds */ debug: for tracing calls which might use open drive fds */
sprintf(msg, "sg_issue_command d->fd= %d d->released= %d\n", sprintf(msg, "sg_issue_command d->fd= %d d->released= %d\n",
@ -1950,8 +1953,10 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
s.cmdp = c->opcode; s.cmdp = c->opcode;
s.mx_sb_len = 32; s.mx_sb_len = 32;
s.sbp = c->sense; s.sbp = c->sense;
memset(c->sense, 0, sizeof(c->sense)); if (c->timeout > 0)
s.timeout = 200000; s.timeout = c->timeout;
else
s.timeout = Libburn_scsi_default_timeouT;
if (c->page && !no_c_page) { if (c->page && !no_c_page) {
s.dxferp = c->page->data; s.dxferp = c->page->data;
if (c->dir == FROM_DRIVE) { if (c->dir == FROM_DRIVE) {
@ -1985,6 +1990,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
start_time = time(NULL); start_time = time(NULL);
for(i = 0; !done; i++) { for(i = 0; !done; i++) {
memset(c->sense, 0, sizeof(c->sense));
err = ioctl(d->fd, SG_IO, &s); err = ioctl(d->fd, SG_IO, &s);
/* ts A61010 */ /* ts A61010 */
@ -2003,6 +2010,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
} }
done = scsi_eval_cmd_outcome(d, c, fp, s.sbp, s.sb_len_wr, done = scsi_eval_cmd_outcome(d, c, fp, s.sbp, s.sb_len_wr,
s.duration, start_time, s.timeout, i, 0); s.duration, start_time, s.timeout, i, 0);
if (d->cancel)
done = 1;
} }
if (s.host_status != Libburn_sg_host_oK || if (s.host_status != Libburn_sg_host_oK ||

View File

@ -586,6 +586,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
static FILE *fp = NULL; static FILE *fp = NULL;
c->error = 0; c->error = 0;
memset(c->sense, 0, sizeof(c->sense));
if (d->fd == -1) if (d->fd == -1)
return 0; return 0;
@ -599,13 +601,17 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
if (burn_sg_log_scsi & 3) if (burn_sg_log_scsi & 3)
scsi_log_cmd(c,fp,0); scsi_log_cmd(c,fp,0);
if (c->timeout > 0)
timeout_ms = c->timeout;
else
timeout_ms = 200000;
memset (&cgc, 0, sizeof (struct uscsi_cmd)); memset (&cgc, 0, sizeof (struct uscsi_cmd));
/* No error messages, no retries, /* No error messages, no retries,
do not execute with other commands, request sense data do not execute with other commands, request sense data
*/ */
cgc.uscsi_flags = USCSI_SILENT | USCSI_DIAGNOSE | USCSI_ISOLATE cgc.uscsi_flags = USCSI_SILENT | USCSI_DIAGNOSE | USCSI_ISOLATE
| USCSI_RQENABLE; | USCSI_RQENABLE;
cgc.uscsi_timeout = 200; cgc.uscsi_timeout = timeout_ms / 1000;
cgc.uscsi_cdb = (caddr_t) c->opcode; cgc.uscsi_cdb = (caddr_t) c->opcode;
cgc.uscsi_bufaddr = (caddr_t) c->page->data; cgc.uscsi_bufaddr = (caddr_t) c->page->data;
if (c->dir == TO_DRIVE) { if (c->dir == TO_DRIVE) {
@ -628,7 +634,6 @@ 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;
for(i = 0; !done; i++) { for(i = 0; !done; i++) {
memset(c->sense, 0, sizeof(c->sense)); memset(c->sense, 0, sizeof(c->sense));
@ -666,6 +671,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
sense_len = 0; sense_len = 0;
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len, 0, done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len, 0,
start_time, timeout_ms, i, 2); start_time, timeout_ms, i, 2);
if (d->cancel)
done = 1;
} /* end of retry-loop */ } /* end of retry-loop */

View File

@ -73,6 +73,7 @@ int scsi_init_command(struct command *c, unsigned char *opcode, int oplen)
c->error = 0; c->error = 0;
c->retry = 0; c->retry = 0;
c->page = NULL; c->page = NULL;
c->timeout = Libburn_scsi_default_timeouT;
return 1; return 1;
} }
@ -1655,13 +1656,14 @@ int scsi_eval_cmd_outcome(struct burn_drive *d, struct command *c, void *fp,
int loop_count, int flag) int loop_count, int flag)
{ {
enum response outcome; enum response outcome;
int done = -1, usleep_time; int done = -1, usleep_time, ret;
char *msg = NULL;
if (burn_sg_log_scsi & 3) if (burn_sg_log_scsi & 3)
scsi_log_err(c, fp, sense, sense_len, duration, scsi_log_err(c, fp, sense, sense_len, duration,
(sense_len > 0) | (flag & 2)); (sense_len > 0) | (flag & 2));
if (sense_len <= 0) if (sense_len <= 0)
return 1; {done = 1; goto ex;}
outcome = scsi_error(d, sense, sense_len); outcome = scsi_error(d, sense, sense_len);
if (outcome == RETRY && c->retry && !(flag & 1)) { if (outcome == RETRY && c->retry && !(flag & 1)) {
@ -1671,22 +1673,36 @@ int scsi_eval_cmd_outcome(struct burn_drive *d, struct command *c, void *fp,
loop_count * Libburn_scsi_retry_incR; loop_count * Libburn_scsi_retry_incR;
if (time(NULL) + usleep_time / 1000000 - start_time > if (time(NULL) + usleep_time / 1000000 - start_time >
timeout_ms / 1000 + 1) { timeout_ms / 1000 + 1) {
BURN_ALLOC_MEM(msg, char, 320);
sprintf(msg,
"Timeout exceed (%d ms). Retry canceled.\n",
timeout_ms);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002018a,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
done = 1; done = 1;
goto ex; goto err_ex;
} }
if (d->cancel)
{done = 1; goto ex;}
usleep(usleep_time); usleep(usleep_time);
if (d->cancel)
{done = 1; goto ex;}
if (burn_sg_log_scsi & 3) if (burn_sg_log_scsi & 3)
scsi_log_cmd(c, fp, 0); scsi_log_cmd(c, fp, 0);
return 0; {done = 0; goto ex;}
} else if (outcome == RETRY) { } else if (outcome == RETRY) {
done = 1; done = 1;
} else if (outcome == GO_ON) { } else if (outcome == GO_ON) {
return 1; {done = 1; goto ex;}
} else if (outcome == FAIL) { } else if (outcome == FAIL) {
done = 1; done = 1;
} }
ex:; err_ex:;
c->error = 1; c->error = 1;
scsi_notify_error(d, c, sense, sense_len, 0); scsi_notify_error(d, c, sense, sense_len, 0);
ex:;
BURN_FREE_MEM(msg);
return done; return done;
} }

View File

@ -118,4 +118,29 @@ int scsi_eval_cmd_outcome(struct burn_drive *d, struct command *c, void *fp_in,
#define Libburn_scsi_retry_incR 100000 #define Libburn_scsi_retry_incR 100000
/* ts B11124 */
/* Millisecond timeout for quickly responding SPC, SBC, and MMC commands */
#define Libburn_scsi_default_timeouT 30000
/* WRITE(10) and WRITE(12) */
#define Libburn_scsi_write_timeouT 200000
/* RESERVE TRACK */
#define Libburn_mmc_reserve_timeouT 200000
/* CLOSE TRACK/SESSION (with Immed bit) */
#define Libburn_mmc_close_timeouT 200000
/* BLANK , FORMAT UNIT (with Immed bit) */
#define Libburn_mmc_blank_timeouT 200000
/* SEND OPC INFORMATION */
#define Libburn_mmc_opc_timeouT 200000
/* MMC_SYNC_CACHE */
#define Libburn_mmc_sync_timeouT 200000
/* START STOP UNIT with Start bit and Load bit set */
#define Libburn_mmc_load_timeouT 300000
#endif /*__SPC*/ #endif /*__SPC*/

View File

@ -64,6 +64,7 @@ struct command
int error; int error;
int retry; int retry;
struct buffer *page; struct buffer *page;
int timeout; /* milliseconds */
}; };
struct burn_scsi_inquiry_data struct burn_scsi_inquiry_data