git: 9abf1f741d54 - stable/12 - ciss(4): Properly handle data underrun.

From: Alexander Motin <mav_at_FreeBSD.org>
Date: Tue, 19 Oct 2021 15:16:01 UTC
The branch stable/12 has been updated by mav:

URL: https://cgit.FreeBSD.org/src/commit/?id=9abf1f741d541a4a1ab684cc417cc6660b0cba1a

commit 9abf1f741d541a4a1ab684cc417cc6660b0cba1a
Author:     Alexander Motin <mav@FreeBSD.org>
AuthorDate: 2021-09-19 17:45:51 +0000
Commit:     Alexander Motin <mav@FreeBSD.org>
CommitDate: 2021-10-19 15:13:31 +0000

    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
    
    (cherry picked from commit e8144a13e075ff13c1f162690c7f14dd3f0a4862)
---
 sys/dev/ciss/ciss.c | 48 ++++++++++++++----------------------------------
 1 file changed, 14 insertions(+), 34 deletions(-)

diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c
index 3cfeb90e9f06..34d3aeb6dae8 100644
--- a/sys/dev/ciss/ciss.c
+++ b/sys/dev/ciss/ciss.c
@@ -2336,13 +2336,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);
@@ -3318,28 +3320,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)
@@ -3348,22 +3339,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;
     }