aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2021-09-19 17:45:51 +0000
committerAlexander Motin <mav@FreeBSD.org>2021-09-19 18:08:22 +0000
commite8144a13e075ff13c1f162690c7f14dd3f0a4862 (patch)
tree0699bc9ed0dc06f9fbd90be6c57b2e2bb8bd29f9
parentfea1a98ead918b39280b586773a923e76194400b (diff)
downloadsrc-e8144a13e075ff13c1f162690c7f14dd3f0a4862.tar.gz
src-e8144a13e075ff13c1f162690c7f14dd3f0a4862.zip
ciss(4): Properly handle data underrun.
For SCSI data underrun is a part of normal life. It should not be reported as error. This fixes MODE SENSE used by modern CAM. MFC after: 1 month
-rw-r--r--sys/dev/ciss/ciss.c48
1 files changed, 14 insertions, 34 deletions
diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c
index 74baf164b860..36d1225fbe4a 100644
--- a/sys/dev/ciss/ciss.c
+++ b/sys/dev/ciss/ciss.c
@@ -2331,13 +2331,15 @@ _ciss_report_request(struct ciss_request *cr, int *command_status, int *scsi_sta
if (command_status != NULL)
*command_status = ce->command_status;
if (scsi_status != NULL) {
- if (ce->command_status == CISS_CMD_STATUS_TARGET_STATUS) {
+ if (ce->command_status == CISS_CMD_STATUS_DATA_UNDERRUN) {
+ *scsi_status = SCSI_STATUS_OK;
+ } else if (ce->command_status == CISS_CMD_STATUS_TARGET_STATUS) {
*scsi_status = ce->scsi_status;
} else {
*scsi_status = -1;
}
}
- if (bootverbose)
+ if (bootverbose && ce->command_status != CISS_CMD_STATUS_DATA_UNDERRUN)
ciss_printf(cr->cr_sc, "command status 0x%x (%s) scsi status 0x%x\n",
ce->command_status, ciss_name_command_status(ce->command_status),
ce->scsi_status);
@@ -3311,28 +3313,17 @@ ciss_cam_complete(struct ciss_request *cr)
* Extract status values from request.
*/
ciss_report_request(cr, &command_status, &scsi_status);
- csio->scsi_status = scsi_status;
-
- /*
- * Handle specific SCSI status values.
- */
- switch(scsi_status) {
- /* no status due to adapter error */
- case -1:
- debug(0, "adapter error");
- csio->ccb_h.status |= CAM_REQ_CMP_ERR;
- break;
-
- /* no status due to command completed OK */
- case SCSI_STATUS_OK: /* CISS_SCSI_STATUS_GOOD */
+ switch(command_status) {
+ case CISS_CMD_STATUS_DATA_UNDERRUN:
+ csio->resid = ce->residual_count;
+ /* FALLTHROUGH */
+ case CISS_CMD_STATUS_SUCCESS:
+ csio->scsi_status = scsi_status;
debug(2, "SCSI_STATUS_OK");
csio->ccb_h.status |= CAM_REQ_CMP;
break;
-
- /* check condition, sense data included */
- case SCSI_STATUS_CHECK_COND: /* CISS_SCSI_STATUS_CHECK_CONDITION */
- debug(0, "SCSI_STATUS_CHECK_COND sense size %d resid %d\n",
- ce->sense_length, ce->residual_count);
+ case CISS_CMD_STATUS_TARGET_STATUS:
+ csio->scsi_status = scsi_status;
bzero(&csio->sense_data, SSD_FULL_SIZE);
bcopy(&ce->sense_info[0], &csio->sense_data, ce->sense_length);
if (csio->sense_len > ce->sense_length)
@@ -3341,22 +3332,11 @@ ciss_cam_complete(struct ciss_request *cr)
csio->sense_resid = 0;
csio->resid = ce->residual_count;
csio->ccb_h.status |= CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID;
-#ifdef CISS_DEBUG
- {
- struct scsi_sense_data *sns = (struct scsi_sense_data *)&ce->sense_info[0];
- debug(0, "sense key %x", scsi_get_sense_key(sns, csio->sense_len -
- csio->sense_resid, /*show_errors*/ 1));
- }
-#endif
break;
-
- case SCSI_STATUS_BUSY: /* CISS_SCSI_STATUS_BUSY */
- debug(0, "SCSI_STATUS_BUSY");
- csio->ccb_h.status |= CAM_SCSI_BUSY;
+ case CISS_CMD_STATUS_DATA_OVERRUN:
+ csio->ccb_h.status |= CAM_DATA_RUN_ERR;
break;
-
default:
- debug(0, "unknown status 0x%x", csio->scsi_status);
csio->ccb_h.status |= CAM_REQ_CMP_ERR;
break;
}