diff options
author | Alexander Motin <mav@FreeBSD.org> | 2012-06-23 12:32:53 +0000 |
---|---|---|
committer | Alexander Motin <mav@FreeBSD.org> | 2012-06-23 12:32:53 +0000 |
commit | e7493b28418be85e089e8e2657411c889447d74c (patch) | |
tree | bf025f1ed2666c7e0300a1cafd93ae168faa3c9e /sys/cam | |
parent | a665ed986c7aaa530b24c6616a42d2667df8a933 (diff) | |
download | src-e7493b28418be85e089e8e2657411c889447d74c.tar.gz src-e7493b28418be85e089e8e2657411c889447d74c.zip |
Add scsi_extract_sense_ccb() -- wrapper around scsi_extract_sense_len().
It allows to remove number of duplicate checks from several places.
Notes
Notes:
svn path=/head/; revision=237478
Diffstat (limited to 'sys/cam')
-rw-r--r-- | sys/cam/cam_periph.c | 21 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_all.c | 39 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_all.h | 2 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_cd.c | 34 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_da.c | 31 |
5 files changed, 56 insertions, 71 deletions
diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c index 6df914430d7d..d7ab2a12ad4c 100644 --- a/sys/cam/cam_periph.c +++ b/sys/cam/cam_periph.c @@ -1147,22 +1147,15 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb) union ccb *saved_ccb; cam_status status; struct scsi_start_stop_unit *scsi_cmd; + int error_code, sense_key, asc, ascq; scsi_cmd = (struct scsi_start_stop_unit *) &done_ccb->csio.cdb_io.cdb_bytes; status = done_ccb->ccb_h.status; if ((status & CAM_STATUS_MASK) != CAM_REQ_CMP) { - if ((status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR && - (status & CAM_AUTOSNS_VALID)) { - struct scsi_sense_data *sense; - int error_code, sense_key, asc, ascq, sense_len; - - sense = &done_ccb->csio.sense_data; - sense_len = done_ccb->csio.sense_len - - done_ccb->csio.sense_resid; - scsi_extract_sense_len(sense, sense_len, &error_code, - &sense_key, &asc, &ascq, /*show_errors*/ 1); + if (scsi_extract_sense_ccb(done_ccb, + &error_code, &sense_key, &asc, &ascq)) { /* * If the error is "invalid field in CDB", * and the load/eject flag is set, turn the @@ -1421,12 +1414,8 @@ camperiphscsisenseerror(union ccb *ccb, union ccb **orig, cgd.ccb_h.func_code = XPT_GDEV_TYPE; xpt_action((union ccb *)&cgd); - if ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0) - err_action = scsi_error_action(&ccb->csio, - &cgd.inq_data, - sense_flags); - else - err_action = SS_RETRY|SSQ_DECREMENT_COUNT|EIO; + err_action = scsi_error_action(&ccb->csio, &cgd.inq_data, + sense_flags); error = err_action & SS_ERRMASK; /* diff --git a/sys/cam/scsi/scsi_all.c b/sys/cam/scsi/scsi_all.c index 435b58c5dd6c..58053242ff09 100644 --- a/sys/cam/scsi/scsi_all.c +++ b/sys/cam/scsi/scsi_all.c @@ -2834,11 +2834,10 @@ scsi_error_action(struct ccb_scsiio *csio, struct scsi_inquiry_data *inq_data, int error_code, sense_key, asc, ascq; scsi_sense_action action; - scsi_extract_sense_len(&csio->sense_data, csio->sense_len - - csio->sense_resid, &error_code, - &sense_key, &asc, &ascq, /*show_errors*/ 1); - - if ((error_code == SSD_DEFERRED_ERROR) + if (!scsi_extract_sense_ccb((union ccb *)csio, + &error_code, &sense_key, &asc, &ascq)) { + action = SS_RETRY | SSQ_DECREMENT_COUNT | SSQ_PRINT_SENSE | EIO; + } else if ((error_code == SSD_DEFERRED_ERROR) || (error_code == SSD_DESC_DEFERRED_ERROR)) { /* * XXX dufault@FreeBSD.org @@ -4622,6 +4621,36 @@ scsi_extract_sense(struct scsi_sense_data *sense_data, int *error_code, } /* + * Extract basic sense information from SCSI I/O CCB structure. + */ +int +scsi_extract_sense_ccb(union ccb *ccb, + int *error_code, int *sense_key, int *asc, int *ascq) +{ + struct scsi_sense_data *sense_data; + + /* Make sure there are some sense data we can access. */ + if (ccb->ccb_h.func_code != XPT_SCSI_IO || + (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_SCSI_STATUS_ERROR || + (ccb->csio.scsi_status != SCSI_STATUS_CHECK_COND) || + (ccb->ccb_h.status & CAM_AUTOSNS_VALID) == 0 || + (ccb->ccb_h.flags & CAM_SENSE_PHYS)) + return (0); + + if (ccb->ccb_h.flags & CAM_SENSE_PTR) + bcopy(&ccb->csio.sense_data, &sense_data, + sizeof(struct scsi_sense_data *)); + else + sense_data = &ccb->csio.sense_data; + scsi_extract_sense_len(sense_data, + ccb->csio.sense_len - ccb->csio.sense_resid, + error_code, sense_key, asc, ascq, 1); + if (*error_code == -1) + return (0); + return (1); +} + +/* * Extract basic sense information. If show_errors is set, sense values * will be set to -1 if they are not present. */ diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h index 40b10bc03562..7275af45f894 100644 --- a/sys/cam/scsi/scsi_all.h +++ b/sys/cam/scsi/scsi_all.h @@ -2388,6 +2388,8 @@ int scsi_devid_match(uint8_t *rhs, size_t rhs_len, void scsi_extract_sense(struct scsi_sense_data *sense, int *error_code, int *sense_key, int *asc, int *ascq); +int scsi_extract_sense_ccb(union ccb *ccb, int *error_code, int *sense_key, + int *asc, int *ascq); void scsi_extract_sense_len(struct scsi_sense_data *sense, u_int sense_len, int *error_code, int *sense_key, int *asc, int *ascq, int show_errors); diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c index 6908c93e7c87..aafde556551f 100644 --- a/sys/cam/scsi/scsi_cd.c +++ b/sys/cam/scsi/scsi_cd.c @@ -1676,7 +1676,6 @@ cddone(struct cam_periph *periph, union ccb *done_ccb) return; } else if (error != 0) { - struct scsi_sense_data *sense; int asc, ascq; int sense_key, error_code; int have_sense; @@ -1699,20 +1698,12 @@ cddone(struct cam_periph *periph, union ccb *done_ccb) cgd.ccb_h.func_code = XPT_GDEV_TYPE; xpt_action((union ccb *)&cgd); - if (((csio->ccb_h.flags & CAM_SENSE_PHYS) != 0) - || ((csio->ccb_h.flags & CAM_SENSE_PTR) != 0) - || ((status & CAM_AUTOSNS_VALID) == 0)) - have_sense = FALSE; - else + if (scsi_extract_sense_ccb(done_ccb, + &error_code, &sense_key, &asc, &ascq)) have_sense = TRUE; + else + have_sense = FALSE; - if (have_sense) { - sense = &csio->sense_data; - scsi_extract_sense_len(sense, - csio->sense_len - csio->sense_resid, - &error_code, &sense_key, &asc, - &ascq, /*show_errors*/ 1); - } /* * Attach to anything that claims to be a * CDROM or WORM device, as long as it @@ -3138,7 +3129,7 @@ cderror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags) { struct cd_softc *softc; struct cam_periph *periph; - int error; + int error, error_code, sense_key, asc, ascq; periph = xpt_path_periph(ccb->ccb_h.path); softc = (struct cd_softc *)periph->softc; @@ -3152,19 +3143,10 @@ cderror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags) */ if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID) { error = cd6byteworkaround(ccb); - } else if (((ccb->ccb_h.status & CAM_STATUS_MASK) == - CAM_SCSI_STATUS_ERROR) - && (ccb->ccb_h.status & CAM_AUTOSNS_VALID) - && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND) - && ((ccb->ccb_h.flags & CAM_SENSE_PHYS) == 0) - && ((ccb->ccb_h.flags & CAM_SENSE_PTR) == 0)) { - int sense_key, error_code, asc, ascq; - - scsi_extract_sense_len(&ccb->csio.sense_data, - ccb->csio.sense_len - ccb->csio.sense_resid, &error_code, - &sense_key, &asc, &ascq, /*show_errors*/ 1); + } else if (scsi_extract_sense_ccb(ccb, + &error_code, &sense_key, &asc, &ascq)) { if (sense_key == SSD_KEY_ILLEGAL_REQUEST) - error = cd6byteworkaround(ccb); + error = cd6byteworkaround(ccb); } if (error == ERESTART) diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index 34afda86dea5..30cd11b12b42 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -2254,7 +2254,6 @@ dadone(struct cam_periph *periph, union ccb *done_ccb) */ return; } else if (error != 0) { - struct scsi_sense_data *sense; int asc, ascq; int sense_key, error_code; int have_sense; @@ -2277,20 +2276,12 @@ dadone(struct cam_periph *periph, union ccb *done_ccb) cgd.ccb_h.func_code = XPT_GDEV_TYPE; xpt_action((union ccb *)&cgd); - if (((csio->ccb_h.flags & CAM_SENSE_PHYS) != 0) - || ((csio->ccb_h.flags & CAM_SENSE_PTR) != 0) - || ((status & CAM_AUTOSNS_VALID) == 0)) - have_sense = FALSE; - else + if (scsi_extract_sense_ccb(done_ccb, + &error_code, &sense_key, &asc, &ascq)) have_sense = TRUE; + else + have_sense = FALSE; - if (have_sense) { - sense = &csio->sense_data; - scsi_extract_sense_len(sense, - csio->sense_len - csio->sense_resid, - &error_code, &sense_key, &asc, - &ascq, /*show_errors*/ 1); - } /* * If we tried READ CAPACITY(16) and failed, * fallback to READ CAPACITY(10). @@ -2428,7 +2419,7 @@ daerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags) { struct da_softc *softc; struct cam_periph *periph; - int error; + int error, error_code, sense_key, asc, ascq; periph = xpt_path_periph(ccb->ccb_h.path); softc = (struct da_softc *)periph->softc; @@ -2440,16 +2431,8 @@ daerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags) error = 0; if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID) { error = cmd6workaround(ccb); - } else if (((ccb->ccb_h.status & CAM_STATUS_MASK) == - CAM_SCSI_STATUS_ERROR) - && (ccb->ccb_h.status & CAM_AUTOSNS_VALID) - && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND) - && ((ccb->ccb_h.flags & CAM_SENSE_PHYS) == 0) - && ((ccb->ccb_h.flags & CAM_SENSE_PTR) == 0)) { - int sense_key, error_code, asc, ascq; - - scsi_extract_sense(&ccb->csio.sense_data, - &error_code, &sense_key, &asc, &ascq); + } else if (scsi_extract_sense_ccb(ccb, + &error_code, &sense_key, &asc, &ascq)) { if (sense_key == SSD_KEY_ILLEGAL_REQUEST) error = cmd6workaround(ccb); /* |