diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index 6488b6b..fea692f 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2011.11.26.153142" +#define Cdrskin_timestamP "2011.11.30.081130" diff --git a/libburn/libdax_msgs.h b/libburn/libdax_msgs.h index 4866b24..a6a6f88 100644 --- a/libburn/libdax_msgs.h +++ b/libburn/libdax_msgs.h @@ -518,7 +518,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff 0x0002014b (SORRY,HIGH) = Drive is already registered resp. scanned 0x0002014c (FATAL,HIGH) = Emulated drive caught in SCSI function 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 0x00020151 (FAILURE,HIGH) = Read attempt on write-only drive 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. 0x00020188 (FAILURE,HIGH) = Cannot close damaged track on given media type 0x00020189 (FATAL,HIGH) = Drive is already grabbed by libburn + 0x0002018a (SORRY,HIGH) = Timeout exceeded. Retry cancled. libdax_audioxtr: 0x00020200 (SORRY,HIGH) = Cannot open audio source file diff --git a/libburn/mmc.c b/libburn/mmc.c index acbc57c..c8cb73d 100644 --- a/libburn/mmc.c +++ b/libburn/mmc.c @@ -357,6 +357,7 @@ int mmc_reserve_track(struct burn_drive *d, off_t size) c->page = NULL; c->dir = NO_TRANSFER; + c->timeout = Libburn_mmc_reserve_timeouT; d->issue_command(d, c); if (c->error) { d->cancel = 1; @@ -588,6 +589,7 @@ void mmc_close(struct burn_drive *d, int session, int track) c->opcode[5] = track & 0xFF; c->page = NULL; c->dir = NO_TRANSFER; + c->timeout = Libburn_mmc_close_timeouT; d->issue_command(d, c); /* 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); c->page = buf; c->dir = TO_DRIVE; + c->timeout = Libburn_scsi_write_timeouT; 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; } + int mmc_write(struct burn_drive *d, int start, struct buffer *buf) { int cancelled; @@ -935,6 +939,7 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf) c->retry = 1; c->page = buf; c->dir = TO_DRIVE; + c->timeout = Libburn_scsi_write_timeouT; #ifdef Libburn_log_in_and_out_streaM /* <<< ts A61031 */ @@ -2271,6 +2276,7 @@ void mmc_erase(struct burn_drive *d, int fast) c->retry = 1; c->page = NULL; c->dir = NO_TRANSFER; + c->timeout = Libburn_mmc_blank_timeouT; d->issue_command(d, c); } @@ -2313,6 +2319,7 @@ void mmc_perform_opc(struct burn_drive *d) c->opcode[1] = 1; c->page = NULL; c->dir = NO_TRANSFER; + c->timeout = Libburn_mmc_opc_timeouT; 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->page = NULL; c->dir = NO_TRANSFER; + c->timeout = Libburn_mmc_sync_timeouT; libdax_msgs_submit(libdax_messenger, -1, 0x00000002, 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->sectors = 0; c->dir = TO_DRIVE; + c->timeout = Libburn_mmc_blank_timeouT; memset(c->page->data, 0, c->page->bytes); descr[0] = 0; diff --git a/libburn/sbc.c b/libburn/sbc.c index 344d69f..d29f167 100644 --- a/libburn/sbc.c +++ b/libburn/sbc.c @@ -67,6 +67,7 @@ void sbc_load(struct burn_drive *d) /* c->opcode[1] |= 1; / * ts A70918 : Immed */ c->dir = NO_TRANSFER; + c->timeout = Libburn_mmc_load_timeouT; d->issue_command(d, c); if (c->error) return; diff --git a/libburn/sg-freebsd.c b/libburn/sg-freebsd.c index 5818935..387a3df 100644 --- a/libburn/sg-freebsd.c +++ b/libburn/sg-freebsd.c @@ -768,10 +768,11 @@ int sg_issue_command(struct burn_drive *d, struct command *c) 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; - } if (burn_sg_log_scsi & 1) { if (fp == NULL) { 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); c->error = 0; + if (c->timeout > 0) + timeout_ms = c->timeout; + else + timeout_ms = 200000; ccb = cam_getccb(d->cam); cam_fill_csio(&ccb->csio, @@ -794,7 +799,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c) 0, /* dxfer_len */ sizeof (ccb->csio.sense_data), /* sense_len */ 0, /* cdb_len */ - 30*1000); /* timeout */ + timeout_ms); /* timeout */ switch (c->dir) { case TO_DRIVE: 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; 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) { ccb->csio.data_ptr = c->page->data; if (c->dir == FROM_DRIVE) { @@ -854,8 +857,9 @@ int sg_issue_command(struct burn_drive *d, struct command *c) } start_time = time(NULL); - timeout_ms = 200000; for (i = 0; !done; i++) { + + memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data)); memset(c->sense, 0, sizeof(c->sense)); 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, timeout_ms, i, 2 | !!ignore_error); + if (d->cancel) + done = 1; } else { done = 1; } diff --git a/libburn/sg-libcdio.c b/libburn/sg-libcdio.c index aab963e..f2cea51 100644 --- a/libburn/sg-libcdio.c +++ b/libburn/sg-libcdio.c @@ -627,6 +627,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c) cdio_mmc_request_sense_t *sense_pt = NULL; c->error = 0; + memset(c->sense, 0, sizeof(c->sense)); + if (d->p_cdio == NULL) { return 0; } @@ -660,11 +662,16 @@ int sg_issue_command(struct burn_drive *d, struct command *c) /* retry-loop */ start_time = time(NULL); - timeout_ms = 200000; + if (c->timeout > 0) + timeout_ms = c->timeout; + else + timeout_ms = 200000; for(i = 0; !done; i++) { + memset(c->sense, 0, sizeof(c->sense)); 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) { 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; done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len, 0, start_time, timeout_ms, i, 2); + if (d->cancel) + done = 1; } /* end of retry-loop */ diff --git a/libburn/sg-linux.c b/libburn/sg-linux.c index fb6ec73..13510f5 100644 --- a/libburn/sg-linux.c +++ b/libburn/sg-linux.c @@ -1898,6 +1898,9 @@ int sg_issue_command(struct burn_drive *d, struct command *c) BURN_ALLOC_MEM(msg, char, 161); + c->error = 0; + memset(c->sense, 0, sizeof(c->sense)); + /* <<< ts A60821 debug: for tracing calls which might use open drive fds */ 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.mx_sb_len = 32; s.sbp = c->sense; - memset(c->sense, 0, sizeof(c->sense)); - s.timeout = 200000; + if (c->timeout > 0) + s.timeout = c->timeout; + else + s.timeout = Libburn_scsi_default_timeouT; if (c->page && !no_c_page) { s.dxferp = c->page->data; if (c->dir == FROM_DRIVE) { @@ -1985,6 +1990,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c) start_time = time(NULL); for(i = 0; !done; i++) { + + memset(c->sense, 0, sizeof(c->sense)); err = ioctl(d->fd, SG_IO, &s); /* 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, s.duration, start_time, s.timeout, i, 0); + if (d->cancel) + done = 1; } if (s.host_status != Libburn_sg_host_oK || diff --git a/libburn/sg-solaris.c b/libburn/sg-solaris.c index 3c5818b..6286549 100644 --- a/libburn/sg-solaris.c +++ b/libburn/sg-solaris.c @@ -586,6 +586,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c) static FILE *fp = NULL; c->error = 0; + memset(c->sense, 0, sizeof(c->sense)); + if (d->fd == -1) return 0; @@ -599,13 +601,17 @@ int sg_issue_command(struct burn_drive *d, struct command *c) if (burn_sg_log_scsi & 3) 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)); /* No error messages, no retries, do not execute with other commands, request sense data */ cgc.uscsi_flags = USCSI_SILENT | USCSI_DIAGNOSE | USCSI_ISOLATE | USCSI_RQENABLE; - cgc.uscsi_timeout = 200; + cgc.uscsi_timeout = timeout_ms / 1000; cgc.uscsi_cdb = (caddr_t) c->opcode; cgc.uscsi_bufaddr = (caddr_t) c->page->data; if (c->dir == TO_DRIVE) { @@ -628,7 +634,6 @@ int sg_issue_command(struct burn_drive *d, struct command *c) /* retry-loop */ start_time = time(NULL); - timeout_ms = 200000; for(i = 0; !done; i++) { 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; done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len, 0, start_time, timeout_ms, i, 2); + if (d->cancel) + done = 1; } /* end of retry-loop */ diff --git a/libburn/spc.c b/libburn/spc.c index fb74bb4..87499bc 100644 --- a/libburn/spc.c +++ b/libburn/spc.c @@ -73,6 +73,7 @@ int scsi_init_command(struct command *c, unsigned char *opcode, int oplen) c->error = 0; c->retry = 0; c->page = NULL; + c->timeout = Libburn_scsi_default_timeouT; 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) { enum response outcome; - int done = -1, usleep_time; + int done = -1, usleep_time, ret; + char *msg = NULL; if (burn_sg_log_scsi & 3) scsi_log_err(c, fp, sense, sense_len, duration, (sense_len > 0) | (flag & 2)); if (sense_len <= 0) - return 1; + {done = 1; goto ex;} outcome = scsi_error(d, sense, sense_len); 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; if (time(NULL) + usleep_time / 1000000 - start_time > 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; - goto ex; + goto err_ex; } + if (d->cancel) + {done = 1; goto ex;} usleep(usleep_time); + if (d->cancel) + {done = 1; goto ex;} if (burn_sg_log_scsi & 3) scsi_log_cmd(c, fp, 0); - return 0; + {done = 0; goto ex;} } else if (outcome == RETRY) { done = 1; } else if (outcome == GO_ON) { - return 1; + {done = 1; goto ex;} } else if (outcome == FAIL) { done = 1; } -ex:; +err_ex:; c->error = 1; scsi_notify_error(d, c, sense, sense_len, 0); +ex:; + BURN_FREE_MEM(msg); return done; } diff --git a/libburn/spc.h b/libburn/spc.h index 63fbdd1..ca4c95d 100644 --- a/libburn/spc.h +++ b/libburn/spc.h @@ -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 +/* 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*/ diff --git a/libburn/transport.h b/libburn/transport.h index b8aa636..c99d3a4 100644 --- a/libburn/transport.h +++ b/libburn/transport.h @@ -64,6 +64,7 @@ struct command int error; int retry; struct buffer *page; + int timeout; /* milliseconds */ }; struct burn_scsi_inquiry_data