diff options
author | ken <ken@FreeBSD.org> | 2003-10-27 06:15:55 +0000 |
---|---|---|
committer | ken <ken@FreeBSD.org> | 2003-10-27 06:15:55 +0000 |
commit | 0e546cc32c7f26787235551242ae501e7cd6d76c (patch) | |
tree | 1146692214bfdaa1a6a8b935bd2dae371c2c5f11 | |
parent | f42a987e4ec559eb51957c68f027c8fa5a7012e6 (diff) | |
download | FreeBSD-src-0e546cc32c7f26787235551242ae501e7cd6d76c.zip FreeBSD-src-0e546cc32c7f26787235551242ae501e7cd6d76c.tar.gz |
In camperiphdone(), make sure we check for fatal errors and bail out
instead of retrying them blindly.
This should fix some of the problems people have been having with cdrom
drives taking a long time to probe. This should also eliminate the need
for the initial TUR in cdsize().
cam_periph.c: Don't keep retrying if the error we get back is a fatal
error. This should help us detect the transition from
"Logical unit not ready, cause not reportable" to "Medium
not present" in the "TUR many" handler. (The TUR many
handler gets triggered for Logical unit not ready, cause
not reportable errors.)
scsi_cd.c: Remove the initial test unit ready in cdsize(). Hopefully
it isn't necessary after the above change.
Submitted by: gibbs (mostly)
Tested by: peter
MFC After: 2 weeks
-rw-r--r-- | sys/cam/cam_periph.c | 19 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_cd.c | 14 |
2 files changed, 17 insertions, 16 deletions
diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c index a860149..0728de5 100644 --- a/sys/cam/cam_periph.c +++ b/sys/cam/cam_periph.c @@ -994,14 +994,26 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb) scsi_cmd = (struct scsi_start_stop_unit *) &done_ccb->csio.cdb_io.cdb_bytes; if (sense != 0) { + struct ccb_getdev cgd; struct scsi_sense_data *sense; int error_code, sense_key, asc, ascq; + scsi_sense_action err_action; sense = &done_ccb->csio.sense_data; scsi_extract_sense(sense, &error_code, &sense_key, &asc, &ascq); /* + * Grab the inquiry data for this device. + */ + xpt_setup_ccb(&cgd.ccb_h, done_ccb->ccb_h.path, + /*priority*/ 1); + cgd.ccb_h.func_code = XPT_GDEV_TYPE; + xpt_action((union ccb *)&cgd); + err_action = scsi_error_action(&done_ccb->csio, + &cgd.inq_data, 0); + + /* * If the error is "invalid field in CDB", * and the load/eject flag is set, turn the * flag off and try again. This is just in @@ -1028,12 +1040,15 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb) xpt_action(done_ccb); - } else if (done_ccb->ccb_h.retry_count > 1) { + } else if ((done_ccb->ccb_h.retry_count > 1) + && ((err_action & SS_MASK) != SS_FAIL)) { + /* * In this case, the error recovery * command failed, but we've got * some retries left on it. Give - * it another try. + * it another try unless this is an + * unretryable error. */ /* set the timeout to .5 sec */ diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c index e51a4b3..3be7b54 100644 --- a/sys/cam/scsi/scsi_cd.c +++ b/sys/cam/scsi/scsi_cd.c @@ -2856,20 +2856,6 @@ cdsize(struct cam_periph *periph, u_int32_t *size) ccb = cdgetccb(periph, /* priority */ 1); - scsi_test_unit_ready(&ccb->csio, 0, cddone, - MSG_SIMPLE_Q_TAG, SSD_FULL_SIZE, 1000); - ccb->ccb_h.ccb_bp = NULL; - - error = cam_periph_runccb(ccb, NULL, - /*cam_flags*/0, - /*sense_flags*/SF_RETRY_UA, - softc->disk.d_devstat); - - if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { - xpt_release_ccb(ccb); - return (ENXIO); - } - rcap_buf = malloc(sizeof(struct scsi_read_capacity_data), M_TEMP, M_WAITOK); |