Add scsi_extract_sense_ccb() -- wrapper around scsi_extract_sense_len().

It allows to remove number of duplicate checks from several places.
This commit is contained in:
Alexander Motin 2012-06-23 12:32:53 +00:00
parent a665ed986c
commit e7493b2841
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=237478
5 changed files with 56 additions and 71 deletions

View File

@ -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;
/*

View File

@ -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
@ -4621,6 +4620,36 @@ scsi_extract_sense(struct scsi_sense_data *sense_data, int *error_code,
sense_key, asc, ascq, /*show_errors*/ 0);
}
/*
* 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.

View File

@ -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);

View File

@ -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)

View File

@ -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);
/*