Commit 7dfaae6a authored by Mike Christie's avatar Mike Christie Committed by Martin K. Petersen
Browse files

scsi: core: Convert scsi_decide_disposition() to use SCSIML_STAT

Don't use:

 - DID_TARGET_FAILURE

 - DID_NEXUS_FAILURE

 - DID_ALLOC_FAILURE

 - DID_MEDIUM_ERROR

Instead use the SCSI midlayer internal values.

Link: https://lore.kernel.org/r/20220812010027.8251-10-michael.christie@oracle.com


Reviewed-by: default avatarBart Van Assche <bvanassche@acm.org>
Signed-off-by: default avatarMike Christie <michael.christie@oracle.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 36ebf1e2
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -649,7 +649,7 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd)
	case DATA_PROTECT:
		if (sshdr.asc == 0x27 && sshdr.ascq == 0x07) {
			/* Thin provisioning hard threshold reached */
			set_host_byte(scmd, DID_ALLOC_FAILURE);
			set_scsi_ml_byte(scmd, SCSIML_STAT_NOSPC);
			return SUCCESS;
		}
		fallthrough;
@@ -657,14 +657,14 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd)
	case VOLUME_OVERFLOW:
	case MISCOMPARE:
	case BLANK_CHECK:
		set_host_byte(scmd, DID_TARGET_FAILURE);
		set_scsi_ml_byte(scmd, SCSIML_STAT_TGT_FAILURE);
		return SUCCESS;

	case MEDIUM_ERROR:
		if (sshdr.asc == 0x11 || /* UNRECOVERED READ ERR */
		    sshdr.asc == 0x13 || /* AMNF DATA FIELD */
		    sshdr.asc == 0x14) { /* RECORD NOT FOUND */
			set_host_byte(scmd, DID_MEDIUM_ERROR);
			set_scsi_ml_byte(scmd, SCSIML_STAT_MED_ERROR);
			return SUCCESS;
		}
		return NEEDS_RETRY;
@@ -673,7 +673,7 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd)
		if (scmd->device->retry_hwerror)
			return ADD_TO_MLQUEUE;
		else
			set_host_byte(scmd, DID_TARGET_FAILURE);
			set_scsi_ml_byte(scmd, SCSIML_STAT_TGT_FAILURE);
		fallthrough;

	case ILLEGAL_REQUEST:
@@ -683,7 +683,7 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd)
		    sshdr.asc == 0x24 || /* Invalid field in cdb */
		    sshdr.asc == 0x26 || /* Parameter value invalid */
		    sshdr.asc == 0x27) { /* Write protected */
			set_host_byte(scmd, DID_TARGET_FAILURE);
			set_scsi_ml_byte(scmd, SCSIML_STAT_TGT_FAILURE);
		}
		return SUCCESS;

@@ -1988,7 +1988,7 @@ enum scsi_disposition scsi_decide_disposition(struct scsi_cmnd *scmd)
	case SAM_STAT_RESERVATION_CONFLICT:
		sdev_printk(KERN_INFO, scmd->device,
			    "reservation conflict\n");
		set_host_byte(scmd, DID_NEXUS_FAILURE);
		set_scsi_ml_byte(scmd, SCSIML_STAT_RESV_CONFLICT);
		return SUCCESS; /* causes immediate i/o error */
	}
	return FAILED;
+5 −19
Original line number Diff line number Diff line
@@ -583,13 +583,11 @@ static inline u8 get_scsi_ml_byte(int result)

/**
 * scsi_result_to_blk_status - translate a SCSI result code into blk_status_t
 * @cmd:	SCSI command
 * @result:	scsi error code
 *
 * Translate a SCSI result code into a blk_status_t value. May reset the host
 * byte of @cmd->result.
 * Translate a SCSI result code into a blk_status_t value.
 */
static blk_status_t scsi_result_to_blk_status(struct scsi_cmnd *cmd, int result)
static blk_status_t scsi_result_to_blk_status(int result)
{
	/*
	 * Check the scsi-ml byte first in case we converted a host or status
@@ -616,18 +614,6 @@ static blk_status_t scsi_result_to_blk_status(struct scsi_cmnd *cmd, int result)
	case DID_TRANSPORT_FAILFAST:
	case DID_TRANSPORT_MARGINAL:
		return BLK_STS_TRANSPORT;
	case DID_TARGET_FAILURE:
		set_host_byte(cmd, DID_OK);
		return BLK_STS_TARGET;
	case DID_NEXUS_FAILURE:
		set_host_byte(cmd, DID_OK);
		return BLK_STS_NEXUS;
	case DID_ALLOC_FAILURE:
		set_host_byte(cmd, DID_OK);
		return BLK_STS_NOSPC;
	case DID_MEDIUM_ERROR:
		set_host_byte(cmd, DID_OK);
		return BLK_STS_MEDIUM;
	default:
		return BLK_STS_IOERR;
	}
@@ -715,7 +701,7 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result)
	if (sense_valid)
		sense_current = !scsi_sense_is_deferred(&sshdr);

	blk_stat = scsi_result_to_blk_status(cmd, result);
	blk_stat = scsi_result_to_blk_status(result);

	if (host_byte(result) == DID_RESET) {
		/* Third party bus reset or reset for error recovery
@@ -893,14 +879,14 @@ static int scsi_io_completion_nz_result(struct scsi_cmnd *cmd, int result,
					     SCSI_SENSE_BUFFERSIZE);
		}
		if (sense_current)
			*blk_statp = scsi_result_to_blk_status(cmd, result);
			*blk_statp = scsi_result_to_blk_status(result);
	} else if (blk_rq_bytes(req) == 0 && sense_current) {
		/*
		 * Flush commands do not transfers any data, and thus cannot use
		 * good_bytes != blk_rq_bytes(req) as the signal for an error.
		 * This sets *blk_statp explicitly for the problem case.
		 */
		*blk_statp = scsi_result_to_blk_status(cmd, result);
		*blk_statp = scsi_result_to_blk_status(result);
	}
	/*
	 * Recovered errors need reporting, but they're always treated as