aboutsummaryrefslogtreecommitdiff
path: root/sys/cam
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2012-06-23 12:32:53 +0000
committerAlexander Motin <mav@FreeBSD.org>2012-06-23 12:32:53 +0000
commite7493b28418be85e089e8e2657411c889447d74c (patch)
treebf025f1ed2666c7e0300a1cafd93ae168faa3c9e /sys/cam
parenta665ed986c7aaa530b24c6616a42d2667df8a933 (diff)
downloadsrc-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.c21
-rw-r--r--sys/cam/scsi/scsi_all.c39
-rw-r--r--sys/cam/scsi/scsi_all.h2
-rw-r--r--sys/cam/scsi/scsi_cd.c34
-rw-r--r--sys/cam/scsi/scsi_da.c31
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);
/*