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
This commit is contained in:
parent
fea1a98ead
commit
e8144a13e0
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user