summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorken <ken@FreeBSD.org>2003-10-27 06:15:55 +0000
committerken <ken@FreeBSD.org>2003-10-27 06:15:55 +0000
commit0e546cc32c7f26787235551242ae501e7cd6d76c (patch)
tree1146692214bfdaa1a6a8b935bd2dae371c2c5f11
parentf42a987e4ec559eb51957c68f027c8fa5a7012e6 (diff)
downloadFreeBSD-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.c19
-rw-r--r--sys/cam/scsi/scsi_cd.c14
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);
OpenPOWER on IntegriCloud