aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_lib.c
diff options
context:
space:
mode:
authorMike Christie <michael.christie@oracle.com>2022-08-11 20:00:25 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2022-09-06 22:05:59 -0400
commit36ebf1e2aa148bdcf03c413bddfc605c54b57669 (patch)
treef82ce46fd05634ab5d811af207fd46ba83dd34c4 /drivers/scsi/scsi_lib.c
parentscsi: cxlflash: Drop DID_ALLOC_FAILURE use (diff)
downloadlinux-dev-36ebf1e2aa148bdcf03c413bddfc605c54b57669.tar.xz
linux-dev-36ebf1e2aa148bdcf03c413bddfc605c54b57669.zip
scsi: core: Add error codes for internal SCSI midlayer use
If a driver returns: - DID_TARGET_FAILURE - DID_NEXUS_FAILURE - DID_ALLOC_FAILURE - DID_MEDIUM_ERROR we hit a couple bugs: 1. The SCSI error handler runs because scsi_decide_disposition() has no case statements for them and we return FAILED. 2. For SG IO the userspace app gets a success status instead of failed, because scsi_result_to_blk_status() clears those errors. This patch adds a new internal error code byte for use by the SCSI midlayer. This will be used instead of the above error codes, so we don't have to play that clearing the host code game in scsi_result_to_blk_status() and drivers cannot accidentally use them. A subsequent commit will then remove the internal users of the above codes and convert us to use the new ones. Link: https://lore.kernel.org/r/20220812010027.8251-9-michael.christie@oracle.com Reviewed-by: Bart Van Assche <bvanassche@acm.org> Signed-off-by: Mike Christie <michael.christie@oracle.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r--drivers/scsi/scsi_lib.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 4dbd29ab1dcc..92b8c050697e 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -576,6 +576,11 @@ static bool scsi_end_request(struct request *req, blk_status_t error,
return false;
}
+static inline u8 get_scsi_ml_byte(int result)
+{
+ return (result >> 8) & 0xff;
+}
+
/**
* scsi_result_to_blk_status - translate a SCSI result code into blk_status_t
* @cmd: SCSI command
@@ -586,6 +591,23 @@ static bool scsi_end_request(struct request *req, blk_status_t error,
*/
static blk_status_t scsi_result_to_blk_status(struct scsi_cmnd *cmd, int result)
{
+ /*
+ * Check the scsi-ml byte first in case we converted a host or status
+ * byte.
+ */
+ switch (get_scsi_ml_byte(result)) {
+ case SCSIML_STAT_OK:
+ break;
+ case SCSIML_STAT_RESV_CONFLICT:
+ return BLK_STS_NEXUS;
+ case SCSIML_STAT_NOSPC:
+ return BLK_STS_NOSPC;
+ case SCSIML_STAT_MED_ERROR:
+ return BLK_STS_MEDIUM;
+ case SCSIML_STAT_TGT_FAILURE:
+ return BLK_STS_TARGET;
+ }
+
switch (host_byte(result)) {
case DID_OK:
if (scsi_status_is_good(result))