All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 00/22] Allow scsi_execute users to control retries
@ 2022-09-22 10:06 Mike Christie
  2022-09-22 10:06 ` [PATCH RFC 01/22] scsi: Add helper to prep sense during error handling Mike Christie
                   ` (21 more replies)
  0 siblings, 22 replies; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:06 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley

The following patches made over a combo of linus's tree nd Martin's
6.1-queue tree (the are both missing patches) allow scsi_execute* users
to control exactly which errors are retried.

The patches allow scsi_execute users to pass in an array of failures
which they want retried and also specify how many times they want them
retried. If we hit an error that the user did not specify then we drop
down the the default behavior. This allows us to remove all the retry code
from the callers except for a couple cases where the caller:

1. wants to sleep between retries or had strict timings (sd_spinup_disk
or ufs).
2. needed to set some internal state between retries (scsi_test_unit_ready)
3. retried based on the error code and it's internal state (alua rtpg).

These patches have only been lightly tested. I'm more looking for an
ACK on the idea because this is different than what I mentioned on the
list a couple weeks ago.

TODO:
1. There is still the scsi_cmnd->allowed/retries. I think I could just
add a default scsi_failure struct on the scsi_cmnd and make the code
more common.



^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH RFC 01/22] scsi: Add helper to prep sense during error handling
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
@ 2022-09-22 10:06 ` Mike Christie
  2022-09-22 16:57   ` Bart Van Assche
  2022-09-22 10:06 ` [PATCH RFC 02/22] scsi: Allow passthrough to override what errors to retry Mike Christie
                   ` (20 subsequent siblings)
  21 siblings, 1 reply; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:06 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

This breaks out the sense prep so it can be used in helper that will be
added in this patchset for passthrough commands.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/scsi_error.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index b5fa2aad05f9..5fed56b6b7c5 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -519,6 +519,22 @@ static inline void set_scsi_ml_byte(struct scsi_cmnd *cmd, u8 status)
 	cmd->result = (cmd->result & 0xffff00ff) | (status << 8);
 }
 
+static enum scsi_disposition scsi_prep_sense(struct scsi_cmnd *scmd,
+					     struct scsi_sense_hdr *sshdr)
+{
+	struct scsi_device *sdev = scmd->device;
+
+	if (!scsi_command_normalize_sense(scmd, sshdr))
+		return FAILED;  /* no valid sense data */
+
+	scsi_report_sense(sdev, sshdr);
+
+	if (scsi_sense_is_deferred(sshdr))
+		return NEEDS_RETRY;
+
+	return SUCCESS;
+}
+
 /**
  * scsi_check_sense - Examine scsi cmd sense
  * @scmd:	Cmd to have sense checked.
@@ -534,14 +550,11 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd)
 {
 	struct scsi_device *sdev = scmd->device;
 	struct scsi_sense_hdr sshdr;
+	enum scsi_disposition ret;
 
-	if (! scsi_command_normalize_sense(scmd, &sshdr))
-		return FAILED;	/* no valid sense data */
-
-	scsi_report_sense(sdev, &sshdr);
-
-	if (scsi_sense_is_deferred(&sshdr))
-		return NEEDS_RETRY;
+	ret = scsi_prep_sense(scmd, &sshdr);
+	if (ret != SUCCESS)
+		return ret;
 
 	if (sdev->handler && sdev->handler->check_sense) {
 		enum scsi_disposition rc;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 02/22] scsi: Allow passthrough to override what errors to retry
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
  2022-09-22 10:06 ` [PATCH RFC 01/22] scsi: Add helper to prep sense during error handling Mike Christie
@ 2022-09-22 10:06 ` Mike Christie
  2022-09-22 16:59   ` Bart Van Assche
  2022-09-22 10:06 ` [PATCH RFC 03/22] scsi: Take an array of failures for passthrough Mike Christie
                   ` (19 subsequent siblings)
  21 siblings, 1 reply; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:06 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

This adds the core code to allow users to specify what errors they want
scsi-ml to retry. We can then convert users to drop their sense parsing
and retry handling.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/scsi_error.c | 63 +++++++++++++++++++++++++++++++++++++++
 drivers/scsi/scsi_lib.c   |  1 +
 include/scsi/scsi_cmnd.h  | 24 ++++++++++++++-
 3 files changed, 87 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 5fed56b6b7c5..059c5f40d236 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1830,6 +1830,63 @@ bool scsi_noretry_cmd(struct scsi_cmnd *scmd)
 	return false;
 }
 
+static enum scsi_disposition scsi_check_passthrough(struct scsi_cmnd *scmd)
+{
+	struct scsi_failure *failure;
+	struct scsi_sense_hdr sshdr;
+	enum scsi_disposition ret;
+	int i = 0;
+
+	if (!scmd->failures)
+		return SCSI_RETURN_NOT_HANDLED;
+
+	while ((failure = &scmd->failures[i++])) {
+		if (!failure->result)
+			break;
+
+		if (host_byte(scmd->result) & host_byte(failure->result)) {
+			goto maybe_retry;
+		} else if (get_status_byte(scmd) &
+			   __get_status_byte(failure->result)) {
+
+			if (failure->result == SCMD_FAILURE_ANY)
+				goto maybe_retry;
+
+			if (get_status_byte(scmd) != SAM_STAT_CHECK_CONDITION)
+				goto maybe_retry;
+
+			ret = scsi_prep_sense(scmd, &sshdr);
+			if (ret == NEEDS_RETRY)
+				goto maybe_retry;
+			else if (ret != SUCCESS)
+				return ret;
+
+			if (failure->sense != sshdr.sense_key)
+				continue;
+
+			if (failure->asc == SCMD_FAILURE_ASC_ANY)
+				goto maybe_retry;
+
+			if (failure->asc != sshdr.asc)
+				continue;
+
+			if (failure->ascq == SCMD_FAILURE_ASCQ_ANY)
+				goto maybe_retry;
+
+			if (failure->ascq != sshdr.ascq)
+				continue;
+		}
+	}
+
+	return SCSI_RETURN_NOT_HANDLED;
+
+maybe_retry:
+	if (++failure->retries <= failure->allowed)
+		return NEEDS_RETRY;
+
+	return SUCCESS;
+}
+
 /**
  * scsi_decide_disposition - Disposition a cmd on return from LLD.
  * @scmd:	SCSI cmd to examine.
@@ -1858,6 +1915,12 @@ enum scsi_disposition scsi_decide_disposition(struct scsi_cmnd *scmd)
 		return SUCCESS;
 	}
 
+	if (blk_rq_is_passthrough(scsi_cmd_to_rq(scmd))) {
+		rtn = scsi_check_passthrough(scmd);
+		if (rtn != SCSI_RETURN_NOT_HANDLED)
+			return rtn;
+	}
+
 	/*
 	 * first check the host byte, to see if there is anything in there
 	 * that would indicate what we need to do.
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 497efc0da259..56aefe38d69b 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1608,6 +1608,7 @@ static blk_status_t scsi_prepare_cmd(struct request *req)
 
 	/* Usually overridden by the ULP */
 	cmd->allowed = 0;
+	cmd->failures = NULL;
 	memset(cmd->cmnd, 0, sizeof(cmd->cmnd));
 	return scsi_cmd_to_driver(cmd)->init_command(cmd);
 }
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index bac55decf900..ee3986401f52 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -65,6 +65,21 @@ enum scsi_cmnd_submitter {
 	SUBMITTED_BY_SCSI_RESET_IOCTL = 2,
 } __packed;
 
+#define SCMD_FAILURE_NONE	0
+#define SCMD_FAILURE_ANY	0xffffffff
+#define SCMD_FAILURE_ASC_ANY	0xff
+#define SCMD_FAILURE_ASCQ_ANY	0xff
+
+struct scsi_failure {
+	u8 sense;
+	u8 asc;
+	u8 ascq;
+	int result;
+
+	s8 allowed;
+	u8 retries;
+};
+
 struct scsi_cmnd {
 	struct scsi_device *device;
 	struct list_head eh_entry; /* entry for the host eh_abort_list/eh_cmd_q */
@@ -85,6 +100,8 @@ struct scsi_cmnd {
 
 	int retries;
 	int allowed;
+	/* optional array of failures that passthrough users want retried */
+	struct scsi_failure *failures;
 
 	unsigned char prot_op;
 	unsigned char prot_type;
@@ -330,9 +347,14 @@ static inline void set_status_byte(struct scsi_cmnd *cmd, char status)
 	cmd->result = (cmd->result & 0xffffff00) | status;
 }
 
+static inline u8 __get_status_byte(int result)
+{
+	return result & 0xff;
+}
+
 static inline u8 get_status_byte(struct scsi_cmnd *cmd)
 {
-	return cmd->result & 0xff;
+	return __get_status_byte(cmd->result);
 }
 
 static inline void set_host_byte(struct scsi_cmnd *cmd, char status)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 03/22] scsi: Take an array of failures for passthrough
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
  2022-09-22 10:06 ` [PATCH RFC 01/22] scsi: Add helper to prep sense during error handling Mike Christie
  2022-09-22 10:06 ` [PATCH RFC 02/22] scsi: Allow passthrough to override what errors to retry Mike Christie
@ 2022-09-22 10:06 ` Mike Christie
  2022-09-22 17:02   ` Bart Van Assche
  2022-09-22 10:06 ` [PATCH RFC 04/22] scsi: Have scsi-ml retry scsi_probe_lun errors Mike Christie
                   ` (18 subsequent siblings)
  21 siblings, 1 reply; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:06 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

This allows scsi_execute/scsi_execute_req users to pass in an array of
scsi_failure structs they want retried. In most cases they can then drop
their sesne parsing and error handling.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/ata/libata-scsi.c                   |  6 ++++--
 drivers/hwmon/drivetemp.c                   |  2 +-
 drivers/scsi/ch.c                           |  2 +-
 drivers/scsi/cxlflash/superpipe.c           |  2 +-
 drivers/scsi/cxlflash/vlun.c                |  2 +-
 drivers/scsi/device_handler/scsi_dh_alua.c  |  4 ++--
 drivers/scsi/device_handler/scsi_dh_emc.c   |  2 +-
 drivers/scsi/device_handler/scsi_dh_hp_sw.c |  6 ++++--
 drivers/scsi/device_handler/scsi_dh_rdac.c  |  4 ++--
 drivers/scsi/scsi.c                         |  4 ++--
 drivers/scsi/scsi_ioctl.c                   |  2 +-
 drivers/scsi/scsi_lib.c                     | 11 ++++++----
 drivers/scsi/scsi_scan.c                    |  7 ++++---
 drivers/scsi/scsi_transport_spi.c           |  2 +-
 drivers/scsi/sd.c                           | 23 +++++++++++++--------
 drivers/scsi/sd_zbc.c                       |  2 +-
 drivers/scsi/ses.c                          |  4 ++--
 drivers/scsi/sr.c                           |  5 +++--
 drivers/scsi/sr_ioctl.c                     |  2 +-
 drivers/scsi/virtio_scsi.c                  |  3 ++-
 drivers/target/target_core_pscsi.c          |  8 +++----
 drivers/ufs/core/ufshcd.c                   |  2 +-
 include/scsi/scsi_device.h                  | 15 ++++++++------
 23 files changed, 69 insertions(+), 51 deletions(-)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 29e2f55c6faa..cb8f8e1c8065 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -414,7 +414,8 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
 	/* Good values for timeout and retries?  Values below
 	   from scsi_ioctl_send_command() for default case... */
 	cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize,
-				  sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL);
+				  sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL,
+				  NULL);
 
 	if (cmd_result < 0) {
 		rc = cmd_result;
@@ -498,7 +499,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
 	/* Good values for timeout and retries?  Values below
 	   from scsi_ioctl_send_command() for default case... */
 	cmd_result = scsi_execute(scsidev, scsi_cmd, DMA_NONE, NULL, 0,
-				sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL);
+				  sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL,
+				  NULL);
 
 	if (cmd_result < 0) {
 		rc = cmd_result;
diff --git a/drivers/hwmon/drivetemp.c b/drivers/hwmon/drivetemp.c
index 5bac2b0fc7bb..cb4549194771 100644
--- a/drivers/hwmon/drivetemp.c
+++ b/drivers/hwmon/drivetemp.c
@@ -194,7 +194,7 @@ static int drivetemp_scsi_command(struct drivetemp_data *st,
 
 	return scsi_execute_req(st->sdev, scsi_cmd, data_dir,
 				st->smartdata, ATA_SECT_SIZE, NULL, HZ, 5,
-				NULL);
+				NULL, NULL);
 }
 
 static int drivetemp_ata_command(struct drivetemp_data *st, u8 feature,
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index 7ab29eaec6f3..cdef392be5fc 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -197,7 +197,7 @@ ch_do_scsi(scsi_changer *ch, unsigned char *cmd, int cmd_len,
 	errno = 0;
 	result = scsi_execute_req(ch->device, cmd, direction, buffer,
 				  buflength, &sshdr, timeout * HZ,
-				  MAX_RETRIES, NULL);
+				  MAX_RETRIES, NULL, NULL);
 	if (result < 0)
 		return result;
 	if (scsi_sense_valid(&sshdr)) {
diff --git a/drivers/scsi/cxlflash/superpipe.c b/drivers/scsi/cxlflash/superpipe.c
index df0ebabbf387..cc1a63986bff 100644
--- a/drivers/scsi/cxlflash/superpipe.c
+++ b/drivers/scsi/cxlflash/superpipe.c
@@ -359,7 +359,7 @@ static int read_cap16(struct scsi_device *sdev, struct llun_info *lli)
 	up_read(&cfg->ioctl_rwsem);
 	result = scsi_execute(sdev, scsi_cmd, DMA_FROM_DEVICE, cmd_buf,
 			      CMD_BUFSIZE, NULL, &sshdr, to, CMD_RETRIES,
-			      0, 0, NULL);
+			      0, 0, NULL, NULL);
 	down_read(&cfg->ioctl_rwsem);
 	rc = check_state(cfg);
 	if (rc) {
diff --git a/drivers/scsi/cxlflash/vlun.c b/drivers/scsi/cxlflash/vlun.c
index 5c74dc7c2288..dc934800edda 100644
--- a/drivers/scsi/cxlflash/vlun.c
+++ b/drivers/scsi/cxlflash/vlun.c
@@ -452,7 +452,7 @@ static int write_same16(struct scsi_device *sdev,
 		up_read(&cfg->ioctl_rwsem);
 		result = scsi_execute(sdev, scsi_cmd, DMA_TO_DEVICE, cmd_buf,
 				      CMD_BUFSIZE, NULL, NULL, to,
-				      CMD_RETRIES, 0, 0, NULL);
+				      CMD_RETRIES, 0, 0, NULL, NULL);
 		down_read(&cfg->ioctl_rwsem);
 		rc = check_state(cfg);
 		if (rc) {
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index 610a51538f03..335daaf90bb2 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -141,7 +141,7 @@ static int submit_rtpg(struct scsi_device *sdev, unsigned char *buff,
 
 	return scsi_execute(sdev, cdb, DMA_FROM_DEVICE, buff, bufflen, NULL,
 			sshdr, ALUA_FAILOVER_TIMEOUT * HZ,
-			ALUA_FAILOVER_RETRIES, req_flags, 0, NULL);
+			ALUA_FAILOVER_RETRIES, req_flags, 0, NULL, NULL);
 }
 
 /*
@@ -173,7 +173,7 @@ static int submit_stpg(struct scsi_device *sdev, int group_id,
 
 	return scsi_execute(sdev, cdb, DMA_TO_DEVICE, stpg_data, stpg_len, NULL,
 			sshdr, ALUA_FAILOVER_TIMEOUT * HZ,
-			ALUA_FAILOVER_RETRIES, req_flags, 0, NULL);
+			ALUA_FAILOVER_RETRIES, req_flags, 0, NULL, NULL);
 }
 
 static struct alua_port_group *alua_find_get_pg(char *id_str, size_t id_size,
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c
index 2e21ab447873..162d822241ba 100644
--- a/drivers/scsi/device_handler/scsi_dh_emc.c
+++ b/drivers/scsi/device_handler/scsi_dh_emc.c
@@ -265,7 +265,7 @@ static int send_trespass_cmd(struct scsi_device *sdev,
 
 	err = scsi_execute(sdev, cdb, DMA_TO_DEVICE, csdev->buffer, len, NULL,
 			&sshdr, CLARIION_TIMEOUT * HZ, CLARIION_RETRIES,
-			req_flags, 0, NULL);
+			req_flags, 0, NULL, NULL);
 	if (err) {
 		if (scsi_sense_valid(&sshdr))
 			res = trespass_endio(sdev, &sshdr);
diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
index 0d2cfa60aa06..64345f9125ca 100644
--- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c
+++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
@@ -88,7 +88,8 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h)
 
 retry:
 	res = scsi_execute(sdev, cmd, DMA_NONE, NULL, 0, NULL, &sshdr,
-			HP_SW_TIMEOUT, HP_SW_RETRIES, req_flags, 0, NULL);
+			   HP_SW_TIMEOUT, HP_SW_RETRIES, req_flags, 0, NULL,
+			   NULL);
 	if (res) {
 		if (scsi_sense_valid(&sshdr))
 			ret = tur_done(sdev, h, &sshdr);
@@ -126,7 +127,8 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h)
 
 retry:
 	res = scsi_execute(sdev, cmd, DMA_NONE, NULL, 0, NULL, &sshdr,
-			HP_SW_TIMEOUT, HP_SW_RETRIES, req_flags, 0, NULL);
+			   HP_SW_TIMEOUT, HP_SW_RETRIES, req_flags, 0, NULL,
+			   NULL);
 	if (res) {
 		if (!scsi_sense_valid(&sshdr)) {
 			sdev_printk(KERN_WARNING, sdev,
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index bf8754741f85..fce6886b8319 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -556,8 +556,8 @@ static void send_mode_select(struct work_struct *work)
 		(retry_cnt == RDAC_RETRY_COUNT) ? "queueing" : "retrying");
 
 	if (scsi_execute(sdev, cdb, DMA_TO_DEVICE, &h->ctlr->mode_select,
-			data_size, NULL, &sshdr, RDAC_TIMEOUT * HZ,
-			RDAC_RETRIES, req_flags, 0, NULL)) {
+			 data_size, NULL, &sshdr, RDAC_TIMEOUT * HZ,
+			 RDAC_RETRIES, req_flags, 0, NULL, NULL)) {
 		err = mode_select_handle_sense(sdev, &sshdr);
 		if (err == SCSI_DH_RETRY && retry_cnt--)
 			goto retry;
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index c59eac7a32f2..d6c9e18d8044 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -310,7 +310,7 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer,
 	 * all the existing users tried this hard.
 	 */
 	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer,
-				  len, NULL, 30 * HZ, 3, NULL);
+				  len, NULL, 30 * HZ, 3, NULL, NULL);
 	if (result)
 		return -EIO;
 
@@ -532,7 +532,7 @@ int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer,
 	memset(buffer, 0, len);
 
 	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer,
-				  request_len, &sshdr, 30 * HZ, 3, NULL);
+				  request_len, &sshdr, 30 * HZ, 3, NULL, NULL);
 
 	if (result < 0)
 		return result;
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
index 729e309e6034..cd7d25edfc77 100644
--- a/drivers/scsi/scsi_ioctl.c
+++ b/drivers/scsi/scsi_ioctl.c
@@ -74,7 +74,7 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
 				      "Trying ioctl with scsi command %d\n", *cmd));
 
 	result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0,
-				  &sshdr, timeout, retries, NULL);
+				  &sshdr, timeout, retries, NULL, NULL);
 
 	SCSI_LOG_IOCTL(2, sdev_printk(KERN_INFO, sdev,
 				      "Ioctl returned  0x%x\n", result));
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 56aefe38d69b..7e4cc0b28f61 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -200,6 +200,7 @@ void scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
  * @flags:	flags for ->cmd_flags
  * @rq_flags:	flags for ->rq_flags
  * @resid:	optional residual length
+ * @failures:	optional array of scsi_failure structs
  *
  * Returns the scsi_cmnd result field if a command was executed, or a negative
  * Linux error code if we didn't get that far.
@@ -208,7 +209,8 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
 		 int data_direction, void *buffer, unsigned bufflen,
 		 unsigned char *sense, struct scsi_sense_hdr *sshdr,
 		 int timeout, int retries, blk_opf_t flags,
-		 req_flags_t rq_flags, int *resid)
+		 req_flags_t rq_flags, int *resid,
+		 struct scsi_failure *failures)
 {
 	struct request *req;
 	struct scsi_cmnd *scmd;
@@ -231,6 +233,7 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
 	scmd->cmd_len = COMMAND_SIZE(cmd[0]);
 	memcpy(scmd->cmnd, cmd, scmd->cmd_len);
 	scmd->allowed = retries;
+	scmd->failures = failures;
 	req->timeout = timeout;
 	req->cmd_flags |= flags;
 	req->rq_flags |= rq_flags | RQF_QUIET;
@@ -2138,7 +2141,7 @@ int scsi_mode_select(struct scsi_device *sdev, int pf, int sp,
 	}
 
 	ret = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, real_buffer, len,
-			       sshdr, timeout, retries, NULL);
+			       sshdr, timeout, retries, NULL, NULL);
 	kfree(real_buffer);
 	return ret;
 }
@@ -2203,7 +2206,7 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
 	memset(buffer, 0, len);
 
 	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len,
-				  sshdr, timeout, retries, NULL);
+				  sshdr, timeout, retries, NULL, NULL);
 	if (result < 0)
 		return result;
 
@@ -2288,7 +2291,7 @@ scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries,
 	/* try to eat the UNIT_ATTENTION if there are enough retries */
 	do {
 		result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0, sshdr,
-					  timeout, 1, NULL);
+					  timeout, 1, NULL, NULL);
 		if (sdev->removable && scsi_sense_valid(sshdr) &&
 		    sshdr->sense_key == UNIT_ATTENTION)
 			sdev->changed = 1;
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 5d27f5196de6..ddaa9e7b3e34 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -211,7 +211,7 @@ static void scsi_unlock_floptical(struct scsi_device *sdev,
 	scsi_cmd[4] = 0x2a;     /* size */
 	scsi_cmd[5] = 0;
 	scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE, result, 0x2a, NULL,
-			 SCSI_TIMEOUT, 3, NULL);
+			 SCSI_TIMEOUT, 3, NULL, NULL);
 }
 
 static int scsi_realloc_sdev_budget_map(struct scsi_device *sdev,
@@ -677,7 +677,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
 		result = scsi_execute_req(sdev,  scsi_cmd, DMA_FROM_DEVICE,
 					  inq_result, try_inquiry_len, &sshdr,
 					  HZ / 2 + HZ * scsi_inq_timeout, 3,
-					  &resid);
+					  &resid, NULL);
 
 		SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev,
 				"scsi scan: INQUIRY %s with code 0x%x\n",
@@ -1479,7 +1479,8 @@ static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflag
 
 		result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
 					  lun_data, length, &sshdr,
-					  SCSI_REPORT_LUNS_TIMEOUT, 3, NULL);
+					  SCSI_REPORT_LUNS_TIMEOUT, 3, NULL,
+					  NULL);
 
 		SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
 				"scsi scan: REPORT LUNS"
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index bd72c38d7bfc..4f4c2b155da0 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -126,7 +126,7 @@ static int spi_execute(struct scsi_device *sdev, const void *cmd,
 				      REQ_FAILFAST_DEV |
 				      REQ_FAILFAST_TRANSPORT |
 				      REQ_FAILFAST_DRIVER,
-				      RQF_PM, NULL);
+				      RQF_PM, NULL, NULL);
 		if (result < 0 || !scsi_sense_valid(sshdr) ||
 		    sshdr->sense_key != UNIT_ATTENTION)
 			break;
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index eb76ba055021..c215da95fb8f 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -673,7 +673,7 @@ static int sd_sec_submit(void *data, u16 spsp, u8 secp, void *buffer,
 
 	ret = scsi_execute(sdev, cdb, send ? DMA_TO_DEVICE : DMA_FROM_DEVICE,
 		buffer, len, NULL, NULL, SD_TIMEOUT, sdkp->max_retries, 0,
-		RQF_PM, NULL);
+		RQF_PM, NULL, NULL);
 	return ret <= 0 ? ret : -EIO;
 }
 #endif /* CONFIG_BLK_SED_OPAL */
@@ -1595,7 +1595,8 @@ static int sd_sync_cache(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr)
 		 * flush everything.
 		 */
 		res = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, sshdr,
-				timeout, sdkp->max_retries, 0, RQF_PM, NULL);
+				   timeout, sdkp->max_retries, 0, RQF_PM, NULL,
+				   NULL);
 		if (res == 0)
 			break;
 	}
@@ -1721,7 +1722,7 @@ static int sd_pr_command(struct block_device *bdev, u8 sa,
 	data[20] = flags;
 
 	result = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, &data, sizeof(data),
-			&sshdr, SD_TIMEOUT, sdkp->max_retries, NULL);
+			&sshdr, SD_TIMEOUT, sdkp->max_retries, NULL, NULL);
 
 	if (scsi_status_is_check_condition(result) &&
 	    scsi_sense_valid(&sshdr)) {
@@ -2065,7 +2066,8 @@ sd_spinup_disk(struct scsi_disk *sdkp)
 			the_result = scsi_execute_req(sdkp->device, cmd,
 						      DMA_NONE, NULL, 0,
 						      &sshdr, SD_TIMEOUT,
-						      sdkp->max_retries, NULL);
+						      sdkp->max_retries, NULL,
+						      NULL);
 
 			/*
 			 * If the drive has indicated to us that it
@@ -2125,7 +2127,7 @@ sd_spinup_disk(struct scsi_disk *sdkp)
 				scsi_execute_req(sdkp->device, cmd, DMA_NONE,
 						 NULL, 0, &sshdr,
 						 SD_TIMEOUT, sdkp->max_retries,
-						 NULL);
+						 NULL, NULL);
 				spintime_expire = jiffies + 100 * HZ;
 				spintime = 1;
 			}
@@ -2274,7 +2276,8 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
 
 		the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE,
 					buffer, RC16_LEN, &sshdr,
-					SD_TIMEOUT, sdkp->max_retries, NULL);
+					SD_TIMEOUT, sdkp->max_retries, NULL,
+					NULL);
 
 		if (media_not_present(sdkp, &sshdr))
 			return -ENODEV;
@@ -2359,7 +2362,8 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
 
 		the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE,
 					buffer, 8, &sshdr,
-					SD_TIMEOUT, sdkp->max_retries, NULL);
+					SD_TIMEOUT, sdkp->max_retries, NULL,
+					NULL);
 
 		if (media_not_present(sdkp, &sshdr))
 			return -ENODEV;
@@ -3609,7 +3613,8 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
 		return -ENODEV;
 
 	res = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, &sshdr,
-			SD_TIMEOUT, sdkp->max_retries, 0, RQF_PM, NULL);
+			   SD_TIMEOUT, sdkp->max_retries, 0, RQF_PM, NULL,
+			   NULL);
 	if (res) {
 		sd_print_result(sdkp, "Start/Stop Unit failed", res);
 		if (res > 0 && scsi_sense_valid(&sshdr)) {
@@ -3752,7 +3757,7 @@ static int sd_resume_runtime(struct device *dev)
 
 		if (scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL,
 				 NULL, sdp->request_queue->rq_timeout, 1, 0,
-				 RQF_PM, NULL))
+				 RQF_PM, NULL, NULL))
 			sd_printk(KERN_NOTICE, sdkp,
 				  "Failed to clear sense data\n");
 	}
diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c
index bd15624c6322..1c9db71335a7 100644
--- a/drivers/scsi/sd_zbc.c
+++ b/drivers/scsi/sd_zbc.c
@@ -159,7 +159,7 @@ static int sd_zbc_do_report_zones(struct scsi_disk *sdkp, unsigned char *buf,
 
 	result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE,
 				  buf, buflen, &sshdr,
-				  timeout, SD_MAX_RETRIES, NULL);
+				  timeout, SD_MAX_RETRIES, NULL, NULL);
 	if (result) {
 		sd_printk(KERN_ERR, sdkp,
 			  "REPORT ZONES start lba %llu failed\n", lba);
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index 0a1734f34587..8f5a6370f334 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -92,7 +92,7 @@ static int ses_recv_diag(struct scsi_device *sdev, int page_code,
 
 	do {
 		ret = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,
-				       &sshdr, SES_TIMEOUT, 1, NULL);
+				       &sshdr, SES_TIMEOUT, 1, NULL, NULL);
 	} while (ret > 0 && --retries && scsi_sense_valid(&sshdr) &&
 		 (sshdr.sense_key == NOT_READY ||
 		  (sshdr.sense_key == UNIT_ATTENTION && sshdr.asc == 0x29)));
@@ -133,7 +133,7 @@ static int ses_send_diag(struct scsi_device *sdev, int page_code,
 
 	do {
 		result = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, buf, bufflen,
-					  &sshdr, SES_TIMEOUT, 1, NULL);
+					  &sshdr, SES_TIMEOUT, 1, NULL, NULL);
 	} while (result > 0 && --retries && scsi_sense_valid(&sshdr) &&
 		 (sshdr.sense_key == NOT_READY ||
 		  (sshdr.sense_key == UNIT_ATTENTION && sshdr.asc == 0x29)));
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index a278b739d0c5..8b28a8a28b45 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -173,7 +173,7 @@ static unsigned int sr_get_events(struct scsi_device *sdev)
 	int result;
 
 	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, sizeof(buf),
-				  &sshdr, SR_TIMEOUT, MAX_RETRIES, NULL);
+				  &sshdr, SR_TIMEOUT, MAX_RETRIES, NULL, NULL);
 	if (scsi_sense_valid(&sshdr) && sshdr.sense_key == UNIT_ATTENTION)
 		return DISK_EVENT_MEDIA_CHANGE;
 
@@ -732,7 +732,8 @@ static void get_sectorsize(struct scsi_cd *cd)
 		/* Do the command and wait.. */
 		the_result = scsi_execute_req(cd->device, cmd, DMA_FROM_DEVICE,
 					      buffer, sizeof(buffer), NULL,
-					      SR_TIMEOUT, MAX_RETRIES, NULL);
+					      SR_TIMEOUT, MAX_RETRIES, NULL,
+					      NULL);
 
 		retries--;
 
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c
index fbdb5124d7f7..40146ef3afa5 100644
--- a/drivers/scsi/sr_ioctl.c
+++ b/drivers/scsi/sr_ioctl.c
@@ -204,7 +204,7 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
 
 	result = scsi_execute(SDev, cgc->cmd, cgc->data_direction,
 			      cgc->buffer, cgc->buflen, NULL, sshdr,
-			      cgc->timeout, IOCTL_RETRIES, 0, 0, NULL);
+			      cgc->timeout, IOCTL_RETRIES, 0, 0, NULL, NULL);
 
 	/* Minimal error checking.  Ignore cases we know about, and report the rest. */
 	if (result < 0) {
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
index 00cf6743db8c..052b30b00b50 100644
--- a/drivers/scsi/virtio_scsi.c
+++ b/drivers/scsi/virtio_scsi.c
@@ -349,7 +349,8 @@ static void virtscsi_rescan_hotunplug(struct virtio_scsi *vscsi)
 
 		result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
 					  inq_result, inquiry_len, NULL,
-					  SD_TIMEOUT, SD_MAX_RETRIES, NULL);
+					  SD_TIMEOUT, SD_MAX_RETRIES, NULL,
+					  NULL);
 
 		if (result == 0 && inq_result[0] >> 5) {
 			/* PQ indicates the LUN is not attached */
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index e6a967ddc08c..554f9ccef001 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -145,7 +145,7 @@ static void pscsi_tape_read_blocksize(struct se_device *dev,
 	cdb[4] = 0x0c; /* 12 bytes */
 
 	ret = scsi_execute_req(sdev, cdb, DMA_FROM_DEVICE, buf, 12, NULL,
-			HZ, 1, NULL);
+			HZ, 1, NULL, NULL);
 	if (ret)
 		goto out_free;
 
@@ -196,7 +196,7 @@ pscsi_get_inquiry_vpd_serial(struct scsi_device *sdev, struct t10_wwn *wwn)
 	put_unaligned_be16(INQUIRY_VPD_SERIAL_LEN, &cdb[3]);
 
 	ret = scsi_execute_req(sdev, cdb, DMA_FROM_DEVICE, buf,
-			      INQUIRY_VPD_SERIAL_LEN, NULL, HZ, 1, NULL);
+			      INQUIRY_VPD_SERIAL_LEN, NULL, HZ, 1, NULL, NULL);
 	if (ret)
 		goto out_free;
 
@@ -231,8 +231,8 @@ pscsi_get_inquiry_vpd_device_ident(struct scsi_device *sdev,
 	put_unaligned_be16(INQUIRY_VPD_DEVICE_IDENTIFIER_LEN, &cdb[3]);
 
 	ret = scsi_execute_req(sdev, cdb, DMA_FROM_DEVICE, buf,
-			      INQUIRY_VPD_DEVICE_IDENTIFIER_LEN,
-			      NULL, HZ, 1, NULL);
+			      INQUIRY_VPD_DEVICE_IDENTIFIER_LEN, NULL, HZ, 1,
+			      NULL, NULL);
 	if (ret)
 		goto out;
 
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index a202d7d5240d..601648352aff 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -8782,7 +8782,7 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba,
 		if (remaining <= 0)
 			break;
 		ret = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, &sshdr,
-				   remaining / HZ, 0, 0, RQF_PM, NULL);
+				   remaining / HZ, 0, 0, RQF_PM, NULL, NULL);
 		if (!scsi_status_is_check_condition(ret) ||
 				!scsi_sense_valid(&sshdr) ||
 				sshdr.sense_key != UNIT_ATTENTION)
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 2493bd65351a..85c5baac1b17 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -14,6 +14,7 @@ struct bsg_device;
 struct device;
 struct request_queue;
 struct scsi_cmnd;
+struct scsi_failure;
 struct scsi_lun;
 struct scsi_sense_hdr;
 
@@ -458,24 +459,26 @@ extern int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
 			int data_direction, void *buffer, unsigned bufflen,
 			unsigned char *sense, struct scsi_sense_hdr *sshdr,
 			int timeout, int retries, blk_opf_t flags,
-			req_flags_t rq_flags, int *resid);
+			req_flags_t rq_flags, int *resid,
+			struct scsi_failure *failures);
 /* Make sure any sense buffer is the correct size. */
 #define scsi_execute(sdev, cmd, data_direction, buffer, bufflen, sense,	\
-		     sshdr, timeout, retries, flags, rq_flags, resid)	\
+		     sshdr, timeout, retries, flags, rq_flags, resid,	\
+		     failures)						\
 ({									\
 	BUILD_BUG_ON((sense) != NULL &&					\
 		     sizeof(sense) != SCSI_SENSE_BUFFERSIZE);		\
 	__scsi_execute(sdev, cmd, data_direction, buffer, bufflen,	\
 		       sense, sshdr, timeout, retries, flags, rq_flags,	\
-		       resid);						\
+		       resid, failures);				\
 })
 static inline int scsi_execute_req(struct scsi_device *sdev,
 	const unsigned char *cmd, int data_direction, void *buffer,
 	unsigned bufflen, struct scsi_sense_hdr *sshdr, int timeout,
-	int retries, int *resid)
+	int retries, int *resid, struct scsi_failure *failures)
 {
-	return scsi_execute(sdev, cmd, data_direction, buffer,
-		bufflen, NULL, sshdr, timeout, retries,  0, 0, resid);
+	return scsi_execute(sdev, cmd, data_direction, buffer, bufflen, NULL,
+			    sshdr, timeout, retries,  0, 0, resid, failures);
 }
 extern void sdev_disable_disk_events(struct scsi_device *sdev);
 extern void sdev_enable_disk_events(struct scsi_device *sdev);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 04/22] scsi: Have scsi-ml retry scsi_probe_lun errors
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
                   ` (2 preceding siblings ...)
  2022-09-22 10:06 ` [PATCH RFC 03/22] scsi: Take an array of failures for passthrough Mike Christie
@ 2022-09-22 10:06 ` Mike Christie
  2022-09-22 17:03   ` Bart Van Assche
  2022-09-22 10:06 ` [PATCH RFC 05/22] scsi: retry INQUIRY after timeout Mike Christie
                   ` (17 subsequent siblings)
  21 siblings, 1 reply; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:06 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

This has scsi_probe_lun ask scsi-ml to retry UAs instead of driving them
itself.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/scsi_scan.c | 41 +++++++++++++++++++++++-----------------
 1 file changed, 24 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index ddaa9e7b3e34..08eaa7ddfb97 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -649,6 +649,28 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
 	int response_len = 0;
 	int pass, count, result;
 	struct scsi_sense_hdr sshdr;
+	/*
+	 * not-ready to ready transition [asc/ascq=0x28/0x0] or power-on,
+	 * reset [asc/ascq=0x29/0x0], continue. INQUIRY should not yield
+	 * UNIT_ATTENTION but many buggy devices do so anyway.
+	 */
+	struct scsi_failure failures[] = {
+		{
+			.sense = UNIT_ATTENTION,
+			.asc = 0x28,
+			.ascq = 0,
+			.allowed = 3,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{
+			.sense = UNIT_ATTENTION,
+			.asc = 0x29,
+			.ascq = 0,
+			.allowed = 3,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{},
+	};
 
 	*bflags = 0;
 
@@ -677,28 +699,13 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
 		result = scsi_execute_req(sdev,  scsi_cmd, DMA_FROM_DEVICE,
 					  inq_result, try_inquiry_len, &sshdr,
 					  HZ / 2 + HZ * scsi_inq_timeout, 3,
-					  &resid, NULL);
+					  &resid, failures);
 
 		SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev,
 				"scsi scan: INQUIRY %s with code 0x%x\n",
 				result ? "failed" : "successful", result));
 
-		if (result > 0) {
-			/*
-			 * not-ready to ready transition [asc/ascq=0x28/0x0]
-			 * or power-on, reset [asc/ascq=0x29/0x0], continue.
-			 * INQUIRY should not yield UNIT_ATTENTION
-			 * but many buggy devices do so anyway. 
-			 */
-			if (scsi_status_is_check_condition(result) &&
-			    scsi_sense_valid(&sshdr)) {
-				if ((sshdr.sense_key == UNIT_ATTENTION) &&
-				    ((sshdr.asc == 0x28) ||
-				     (sshdr.asc == 0x29)) &&
-				    (sshdr.ascq == 0))
-					continue;
-			}
-		} else if (result == 0) {
+		if (result == 0) {
 			/*
 			 * if nothing was transferred, we try
 			 * again. It's a workaround for some USB
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 05/22] scsi: retry INQUIRY after timeout
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
                   ` (3 preceding siblings ...)
  2022-09-22 10:06 ` [PATCH RFC 04/22] scsi: Have scsi-ml retry scsi_probe_lun errors Mike Christie
@ 2022-09-22 10:06 ` Mike Christie
  2022-09-22 10:06 ` [PATCH RFC 06/22] scsi: Have scsi-ml retry read_capacity_16 errors Mike Christie
                   ` (16 subsequent siblings)
  21 siblings, 0 replies; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:06 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

Description from: Martin Wilck <mwilck@suse.com>:

The SCSI mid layer doesn't retry commands after DID_TIME_OUT (see
scsi_noretry_cmd()). Packet loss in the fabric can cause spurious timeouts
during SCSI device probing, causing device probing to fail. This has been
observed in FCoE uplink failover tests, for example.

This patch fixes the issue by retrying the INQUIRY up to 3 times (in
practice, we never observed more than a single retry),

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/scsi_scan.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 08eaa7ddfb97..744fb8b469db 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -669,6 +669,10 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
 			.allowed = 3,
 			.result = SAM_STAT_CHECK_CONDITION,
 		},
+		{
+			.allowed = 3,
+			.result = DID_TIME_OUT << 16,
+		},
 		{},
 	};
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 06/22] scsi: Have scsi-ml retry read_capacity_16 errors
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
                   ` (4 preceding siblings ...)
  2022-09-22 10:06 ` [PATCH RFC 05/22] scsi: retry INQUIRY after timeout Mike Christie
@ 2022-09-22 10:06 ` Mike Christie
  2022-09-22 10:06 ` [PATCH RFC 07/22] scsi: Have scsi-ml retry sd_spinup_disk errors Mike Christie
                   ` (15 subsequent siblings)
  21 siblings, 0 replies; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:06 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

This has read_capacity_16 have scsi-ml retry errors instead of driving
them itself.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/sd.c | 70 ++++++++++++++++++++++++-----------------------
 1 file changed, 36 insertions(+), 34 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index c215da95fb8f..46383b680893 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2259,50 +2259,52 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
 	struct scsi_sense_hdr sshdr;
 	int sense_valid = 0;
 	int the_result;
-	int retries = 3, reset_retries = READ_CAPACITY_RETRIES_ON_RESET;
 	unsigned int alignment;
 	unsigned long long lba;
 	unsigned sector_size;
+	struct scsi_failure failures[] = {
+		{
+			.sense = UNIT_ATTENTION,
+			.asc = 0x29,
+			.ascq = 0,
+			/* Device reset might occur several times */
+			.allowed = READ_CAPACITY_RETRIES_ON_RESET,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{
+			.result = SCMD_FAILURE_ANY,
+			.allowed = 3,
+		},
+		{},
+	};
 
 	if (sdp->no_read_capacity_16)
 		return -EINVAL;
 
-	do {
-		memset(cmd, 0, 16);
-		cmd[0] = SERVICE_ACTION_IN_16;
-		cmd[1] = SAI_READ_CAPACITY_16;
-		cmd[13] = RC16_LEN;
-		memset(buffer, 0, RC16_LEN);
-
-		the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE,
-					buffer, RC16_LEN, &sshdr,
-					SD_TIMEOUT, sdkp->max_retries, NULL,
-					NULL);
+	memset(cmd, 0, 16);
+	cmd[0] = SERVICE_ACTION_IN_16;
+	cmd[1] = SAI_READ_CAPACITY_16;
+	cmd[13] = RC16_LEN;
+	memset(buffer, 0, RC16_LEN);
 
-		if (media_not_present(sdkp, &sshdr))
-			return -ENODEV;
+	the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE, buffer,
+				      RC16_LEN, &sshdr, SD_TIMEOUT,
+				      sdkp->max_retries, NULL, failures);
 
-		if (the_result > 0) {
-			sense_valid = scsi_sense_valid(&sshdr);
-			if (sense_valid &&
-			    sshdr.sense_key == ILLEGAL_REQUEST &&
-			    (sshdr.asc == 0x20 || sshdr.asc == 0x24) &&
-			    sshdr.ascq == 0x00)
-				/* Invalid Command Operation Code or
-				 * Invalid Field in CDB, just retry
-				 * silently with RC10 */
-				return -EINVAL;
-			if (sense_valid &&
-			    sshdr.sense_key == UNIT_ATTENTION &&
-			    sshdr.asc == 0x29 && sshdr.ascq == 0x00)
-				/* Device reset might occur several times,
-				 * give it one more chance */
-				if (--reset_retries > 0)
-					continue;
-		}
-		retries--;
+	if (media_not_present(sdkp, &sshdr))
+		return -ENODEV;
 
-	} while (the_result && retries);
+	if (the_result > 0) {
+		sense_valid = scsi_sense_valid(&sshdr);
+		if (sense_valid && sshdr.sense_key == ILLEGAL_REQUEST &&
+		    (sshdr.asc == 0x20 || sshdr.asc == 0x24) &&
+		    sshdr.ascq == 0x00)
+			/*
+			 * Invalid Command Operation Code or Invalid Field in
+			 * CDB, just retry silently with RC10
+			 */
+			return -EINVAL;
+	}
 
 	if (the_result) {
 		sd_print_result(sdkp, "Read Capacity(16) failed", the_result);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 07/22] scsi: Have scsi-ml retry sd_spinup_disk errors
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
                   ` (5 preceding siblings ...)
  2022-09-22 10:06 ` [PATCH RFC 06/22] scsi: Have scsi-ml retry read_capacity_16 errors Mike Christie
@ 2022-09-22 10:06 ` Mike Christie
  2022-09-22 10:06 ` [PATCH RFC 08/22] scsi: cxlflash: Have scsi-ml retry read_cap16 errors Mike Christie
                   ` (14 subsequent siblings)
  21 siblings, 0 replies; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:06 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

This simplifies sd_spinup_disk so scsi-ml retries UAs. It doesn't convert
the errors we will do a msleep for since scsi-ml does not yet handle that.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/sd.c | 58 +++++++++++++++++++++++------------------------
 1 file changed, 29 insertions(+), 29 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 46383b680893..b76e0b1900a0 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2045,48 +2045,48 @@ sd_spinup_disk(struct scsi_disk *sdkp)
 {
 	unsigned char cmd[10];
 	unsigned long spintime_expire = 0;
-	int retries, spintime;
+	int spintime;
 	unsigned int the_result;
 	struct scsi_sense_hdr sshdr;
 	int sense_valid = 0;
+	struct scsi_failure failures[] = {
+		{
+			.sense = UNIT_ATTENTION,
+			.asc = SCMD_FAILURE_ASC_ANY,
+			.ascq = SCMD_FAILURE_ASCQ_ANY,
+			.allowed = 3,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{},
+	};
 
 	spintime = 0;
 
 	/* Spin up drives, as required.  Only do this at boot time */
 	/* Spinup needs to be done for module loads too. */
 	do {
-		retries = 0;
-
-		do {
-			bool media_was_present = sdkp->media_present;
+		bool media_was_present = sdkp->media_present;
 
-			cmd[0] = TEST_UNIT_READY;
-			memset((void *) &cmd[1], 0, 9);
+		cmd[0] = TEST_UNIT_READY;
+		memset((void *) &cmd[1], 0, 9);
 
-			the_result = scsi_execute_req(sdkp->device, cmd,
-						      DMA_NONE, NULL, 0,
-						      &sshdr, SD_TIMEOUT,
-						      sdkp->max_retries, NULL,
-						      NULL);
+		the_result = scsi_execute_req(sdkp->device, cmd, DMA_NONE, NULL,
+					      0, &sshdr, SD_TIMEOUT,
+					      sdkp->max_retries, NULL,
+					      failures);
 
-			/*
-			 * If the drive has indicated to us that it
-			 * doesn't have any media in it, don't bother
-			 * with any more polling.
-			 */
-			if (media_not_present(sdkp, &sshdr)) {
-				if (media_was_present)
-					sd_printk(KERN_NOTICE, sdkp, "Media removed, stopped polling\n");
-				return;
-			}
+		/*
+		 * If the drive has indicated to us that it doesn't have any
+		 * media in it, don't bother  with any more polling.
+		 */
+		if (media_not_present(sdkp, &sshdr)) {
+			if (media_was_present)
+				sd_printk(KERN_NOTICE, sdkp, "Media removed, stopped polling\n");
+			return;
+		}
 
-			if (the_result)
-				sense_valid = scsi_sense_valid(&sshdr);
-			retries++;
-		} while (retries < 3 &&
-			 (!scsi_status_is_good(the_result) ||
-			  (scsi_status_is_check_condition(the_result) &&
-			  sense_valid && sshdr.sense_key == UNIT_ATTENTION)));
+		if (the_result)
+			sense_valid = scsi_sense_valid(&sshdr);
 
 		if (!scsi_status_is_check_condition(the_result)) {
 			/* no sense, TUR either succeeded or failed
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 08/22] scsi: cxlflash: Have scsi-ml retry read_cap16 errors
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
                   ` (6 preceding siblings ...)
  2022-09-22 10:06 ` [PATCH RFC 07/22] scsi: Have scsi-ml retry sd_spinup_disk errors Mike Christie
@ 2022-09-22 10:06 ` Mike Christie
  2022-09-22 10:06 ` [PATCH RFC 09/22] scsi: hp_sw: Have scsi-ml retry hp_sw_start_stop errors Mike Christie
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:06 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

This has read_cap16 have scsi-ml retry errors instead of driving them
itself.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/cxlflash/superpipe.c | 45 ++++++++++++++++++-------------
 1 file changed, 26 insertions(+), 19 deletions(-)

diff --git a/drivers/scsi/cxlflash/superpipe.c b/drivers/scsi/cxlflash/superpipe.c
index cc1a63986bff..ddb9a8f29141 100644
--- a/drivers/scsi/cxlflash/superpipe.c
+++ b/drivers/scsi/cxlflash/superpipe.c
@@ -337,10 +337,32 @@ static int read_cap16(struct scsi_device *sdev, struct llun_info *lli)
 	u8 *scsi_cmd = NULL;
 	int rc = 0;
 	int result = 0;
-	int retry_cnt = 0;
 	u32 to = CMD_TIMEOUT * HZ;
+	struct scsi_failure failures[] = {
+		{
+			.sense = UNIT_ATTENTION,
+			.asc = 0x29,
+			.ascq = SCMD_FAILURE_ASCQ_ANY,
+			.allowed = 1,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{
+			.sense = UNIT_ATTENTION,
+			.asc = 0x2A,
+			.ascq = SCMD_FAILURE_ASCQ_ANY,
+			.allowed = 1,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{
+			.sense = UNIT_ATTENTION,
+			.asc = 0x3F,
+			.ascq = SCMD_FAILURE_ASCQ_ANY,
+			.allowed = 1,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{},
+	};
 
-retry:
 	cmd_buf = kzalloc(CMD_BUFSIZE, GFP_KERNEL);
 	scsi_cmd = kzalloc(MAX_COMMAND_SIZE, GFP_KERNEL);
 	if (unlikely(!cmd_buf || !scsi_cmd)) {
@@ -352,14 +374,13 @@ static int read_cap16(struct scsi_device *sdev, struct llun_info *lli)
 	scsi_cmd[1] = SAI_READ_CAPACITY_16;	/* service action */
 	put_unaligned_be32(CMD_BUFSIZE, &scsi_cmd[10]);
 
-	dev_dbg(dev, "%s: %ssending cmd(%02x)\n", __func__,
-		retry_cnt ? "re" : "", scsi_cmd[0]);
+	dev_dbg(dev, "%s: sending cmd(%02x)\n", __func__, scsi_cmd[0]);
 
 	/* Drop the ioctl read semahpore across lengthy call */
 	up_read(&cfg->ioctl_rwsem);
 	result = scsi_execute(sdev, scsi_cmd, DMA_FROM_DEVICE, cmd_buf,
 			      CMD_BUFSIZE, NULL, &sshdr, to, CMD_RETRIES,
-			      0, 0, NULL, NULL);
+			      0, 0, NULL, failures);
 	down_read(&cfg->ioctl_rwsem);
 	rc = check_state(cfg);
 	if (rc) {
@@ -377,20 +398,6 @@ static int read_cap16(struct scsi_device *sdev, struct llun_info *lli)
 			case NOT_READY:
 				result &= ~SAM_STAT_CHECK_CONDITION;
 				break;
-			case UNIT_ATTENTION:
-				switch (sshdr.asc) {
-				case 0x29: /* Power on Reset or Device Reset */
-					fallthrough;
-				case 0x2A: /* Device capacity changed */
-				case 0x3F: /* Report LUNs changed */
-					/* Retry the command once more */
-					if (retry_cnt++ < 1) {
-						kfree(cmd_buf);
-						kfree(scsi_cmd);
-						goto retry;
-					}
-				}
-				break;
 			default:
 				break;
 			}
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 09/22] scsi: hp_sw: Have scsi-ml retry hp_sw_start_stop errors
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
                   ` (7 preceding siblings ...)
  2022-09-22 10:06 ` [PATCH RFC 08/22] scsi: cxlflash: Have scsi-ml retry read_cap16 errors Mike Christie
@ 2022-09-22 10:06 ` Mike Christie
  2022-09-22 10:06 ` [PATCH RFC 10/22] scsi: Allow passthrough to request infinite retries Mike Christie
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:06 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

This has hp_sw_start_stop have scsi-ml retry errors instead of driving
them itself.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/device_handler/scsi_dh_hp_sw.c | 26 +++++++++++++--------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
index 64345f9125ca..07f3129abe4e 100644
--- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c
+++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
@@ -121,14 +121,27 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h)
 	struct scsi_sense_hdr sshdr;
 	struct scsi_device *sdev = h->sdev;
 	int res, rc = SCSI_DH_OK;
-	int retry_cnt = HP_SW_RETRIES;
 	blk_opf_t req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
 		REQ_FAILFAST_DRIVER;
+	struct scsi_failure failures[] = {
+		{
+			/*
+			 * LUN not ready - manual intervention required
+			 *
+			 * Switch-over in progress, retry.
+			 */
+			.sense = NOT_READY,
+			.asc = 0x04,
+			.ascq = 0x03,
+			.allowed = HP_SW_RETRIES,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{},
+	};
 
-retry:
 	res = scsi_execute(sdev, cmd, DMA_NONE, NULL, 0, NULL, &sshdr,
 			   HP_SW_TIMEOUT, HP_SW_RETRIES, req_flags, 0, NULL,
-			   NULL);
+			   failures);
 	if (res) {
 		if (!scsi_sense_valid(&sshdr)) {
 			sdev_printk(KERN_WARNING, sdev,
@@ -139,13 +152,6 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h)
 		switch (sshdr.sense_key) {
 		case NOT_READY:
 			if (sshdr.asc == 0x04 && sshdr.ascq == 3) {
-				/*
-				 * LUN not ready - manual intervention required
-				 *
-				 * Switch-over in progress, retry.
-				 */
-				if (--retry_cnt)
-					goto retry;
 				rc = SCSI_DH_RETRY;
 				break;
 			}
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 10/22] scsi: Allow passthrough to request infinite retries
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
                   ` (8 preceding siblings ...)
  2022-09-22 10:06 ` [PATCH RFC 09/22] scsi: hp_sw: Have scsi-ml retry hp_sw_start_stop errors Mike Christie
@ 2022-09-22 10:06 ` Mike Christie
  2022-09-22 10:06 ` [PATCH RFC 11/22] scsi: hp_sw: Have scsi-ml retry hp_sw_tur errors Mike Christie
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:06 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

hp_sw and rdac request unimited retries for their failover commands. This
allows them to request this by using a special value.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/scsi_error.c | 3 ++-
 include/scsi/scsi_cmnd.h  | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 059c5f40d236..ea79bad4b865 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1881,7 +1881,8 @@ static enum scsi_disposition scsi_check_passthrough(struct scsi_cmnd *scmd)
 	return SCSI_RETURN_NOT_HANDLED;
 
 maybe_retry:
-	if (++failure->retries <= failure->allowed)
+	if (failure->allowed == SCMD_FAILURE_NO_LIMIT ||
+	    ++failure->retries <= failure->allowed)
 		return NEEDS_RETRY;
 
 	return SUCCESS;
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index ee3986401f52..cb1191ff698c 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -69,6 +69,7 @@ enum scsi_cmnd_submitter {
 #define SCMD_FAILURE_ANY	0xffffffff
 #define SCMD_FAILURE_ASC_ANY	0xff
 #define SCMD_FAILURE_ASCQ_ANY	0xff
+#define SCMD_FAILURE_NO_LIMIT	255
 
 struct scsi_failure {
 	u8 sense;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 11/22] scsi: hp_sw: Have scsi-ml retry hp_sw_tur errors
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
                   ` (9 preceding siblings ...)
  2022-09-22 10:06 ` [PATCH RFC 10/22] scsi: Allow passthrough to request infinite retries Mike Christie
@ 2022-09-22 10:06 ` Mike Christie
  2022-09-22 10:06 ` [PATCH RFC 12/22] scsi: rdac: Have scsi-ml retry send_mode_select errors Mike Christie
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:06 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

This has hp_sw_tur have scsi-ml retry errors instead of driving them
itself.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/device_handler/scsi_dh_hp_sw.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
index 07f3129abe4e..e4f9d1dc6efb 100644
--- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c
+++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
@@ -46,9 +46,6 @@ static int tur_done(struct scsi_device *sdev, struct hp_sw_dh_data *h,
 	int ret = SCSI_DH_IO;
 
 	switch (sshdr->sense_key) {
-	case UNIT_ATTENTION:
-		ret = SCSI_DH_IMM_RETRY;
-		break;
 	case NOT_READY:
 		if (sshdr->asc == 0x04 && sshdr->ascq == 2) {
 			/*
@@ -85,11 +82,20 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h)
 	int ret = SCSI_DH_OK, res;
 	blk_opf_t req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
 		REQ_FAILFAST_DRIVER;
+	struct scsi_failure failures[] = {
+		{
+			.sense = UNIT_ATTENTION,
+			.asc = SCMD_FAILURE_ASC_ANY,
+			.ascq = SCMD_FAILURE_ASCQ_ANY,
+			.allowed = SCMD_FAILURE_NO_LIMIT,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{},
+	};
 
-retry:
 	res = scsi_execute(sdev, cmd, DMA_NONE, NULL, 0, NULL, &sshdr,
 			   HP_SW_TIMEOUT, HP_SW_RETRIES, req_flags, 0, NULL,
-			   NULL);
+			   failures);
 	if (res) {
 		if (scsi_sense_valid(&sshdr))
 			ret = tur_done(sdev, h, &sshdr);
@@ -103,8 +109,6 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h)
 		h->path_state = HP_SW_PATH_ACTIVE;
 		ret = SCSI_DH_OK;
 	}
-	if (ret == SCSI_DH_IMM_RETRY)
-		goto retry;
 
 	return ret;
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 12/22] scsi: rdac: Have scsi-ml retry send_mode_select errors
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
                   ` (10 preceding siblings ...)
  2022-09-22 10:06 ` [PATCH RFC 11/22] scsi: hp_sw: Have scsi-ml retry hp_sw_tur errors Mike Christie
@ 2022-09-22 10:06 ` Mike Christie
  2022-09-22 10:06 ` [PATCH RFC 13/22] scsi: spi: Have scsi-ml retry spi_execute errors Mike Christie
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:06 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

This has rdac have scsi-ml retry errors instead of driving them itself.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/device_handler/scsi_dh_rdac.c | 87 ++++++++++++----------
 1 file changed, 49 insertions(+), 38 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index fce6886b8319..cedbc13af6ba 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -485,43 +485,17 @@ static int set_mode_select(struct scsi_device *sdev, struct rdac_dh_data *h)
 static int mode_select_handle_sense(struct scsi_device *sdev,
 				    struct scsi_sense_hdr *sense_hdr)
 {
-	int err = SCSI_DH_IO;
 	struct rdac_dh_data *h = sdev->handler_data;
 
 	if (!scsi_sense_valid(sense_hdr))
-		goto done;
-
-	switch (sense_hdr->sense_key) {
-	case NO_SENSE:
-	case ABORTED_COMMAND:
-	case UNIT_ATTENTION:
-		err = SCSI_DH_RETRY;
-		break;
-	case NOT_READY:
-		if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x01)
-			/* LUN Not Ready and is in the Process of Becoming
-			 * Ready
-			 */
-			err = SCSI_DH_RETRY;
-		break;
-	case ILLEGAL_REQUEST:
-		if (sense_hdr->asc == 0x91 && sense_hdr->ascq == 0x36)
-			/*
-			 * Command Lock contention
-			 */
-			err = SCSI_DH_IMM_RETRY;
-		break;
-	default:
-		break;
-	}
+		return SCSI_DH_IO;
 
 	RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, "
 		"MODE_SELECT returned with sense %02x/%02x/%02x",
 		(char *) h->ctlr->array_name, h->ctlr->index,
 		sense_hdr->sense_key, sense_hdr->asc, sense_hdr->ascq);
 
-done:
-	return err;
+	return SCSI_DH_IO;
 }
 
 static void send_mode_select(struct work_struct *work)
@@ -530,7 +504,7 @@ static void send_mode_select(struct work_struct *work)
 		container_of(work, struct rdac_controller, ms_work);
 	struct scsi_device *sdev = ctlr->ms_sdev;
 	struct rdac_dh_data *h = sdev->handler_data;
-	int err = SCSI_DH_OK, retry_cnt = RDAC_RETRY_COUNT;
+	int err = SCSI_DH_OK;
 	struct rdac_queue_data *tmp, *qdata;
 	LIST_HEAD(list);
 	unsigned char cdb[MAX_COMMAND_SIZE];
@@ -538,6 +512,49 @@ static void send_mode_select(struct work_struct *work)
 	unsigned int data_size;
 	blk_opf_t req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
 		REQ_FAILFAST_DRIVER;
+	struct scsi_failure failures[] = {
+		{
+			/* Command Lock contention */
+			.sense = ILLEGAL_REQUEST,
+			.asc = 0x91,
+			.ascq = 0x36,
+			.allowed = SCMD_FAILURE_NO_LIMIT,
+			.result = SAM_STAT_CHECK_CONDITION,
+			},
+		{
+			.sense = NO_SENSE,
+			.asc = SCMD_FAILURE_ASC_ANY,
+			.ascq = SCMD_FAILURE_ASCQ_ANY,
+			.allowed = RDAC_RETRY_COUNT,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{
+			.sense = ABORTED_COMMAND,
+			.asc = SCMD_FAILURE_ASC_ANY,
+			.ascq = SCMD_FAILURE_ASCQ_ANY,
+			.allowed = RDAC_RETRY_COUNT,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{
+			.sense = UNIT_ATTENTION,
+			.asc = SCMD_FAILURE_ASC_ANY,
+			.ascq = SCMD_FAILURE_ASCQ_ANY,
+			.allowed = RDAC_RETRY_COUNT,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{
+			/*
+			 * LUN Not Ready and is in the Process of Becoming
+			 * Ready
+			 */
+			.sense = NOT_READY,
+			.asc = 0x04,
+			.ascq = 0x01,
+			.allowed = RDAC_RETRY_COUNT,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{},
+	};
 
 	spin_lock(&ctlr->ms_lock);
 	list_splice_init(&ctlr->ms_head, &list);
@@ -545,24 +562,18 @@ static void send_mode_select(struct work_struct *work)
 	ctlr->ms_sdev = NULL;
 	spin_unlock(&ctlr->ms_lock);
 
- retry:
 	memset(cdb, 0, sizeof(cdb));
 
 	data_size = rdac_failover_get(ctlr, &list, cdb);
 
 	RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, "
-		"%s MODE_SELECT command",
-		(char *) h->ctlr->array_name, h->ctlr->index,
-		(retry_cnt == RDAC_RETRY_COUNT) ? "queueing" : "retrying");
+		"MODE_SELECT command",
+		(char *) h->ctlr->array_name, h->ctlr->index);
 
 	if (scsi_execute(sdev, cdb, DMA_TO_DEVICE, &h->ctlr->mode_select,
 			 data_size, NULL, &sshdr, RDAC_TIMEOUT * HZ,
-			 RDAC_RETRIES, req_flags, 0, NULL, NULL)) {
+			 RDAC_RETRIES, req_flags, 0, NULL, failures)) {
 		err = mode_select_handle_sense(sdev, &sshdr);
-		if (err == SCSI_DH_RETRY && retry_cnt--)
-			goto retry;
-		if (err == SCSI_DH_IMM_RETRY)
-			goto retry;
 	}
 	if (err == SCSI_DH_OK) {
 		h->state = RDAC_STATE_ACTIVE;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 13/22] scsi: spi: Have scsi-ml retry spi_execute errors
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
                   ` (11 preceding siblings ...)
  2022-09-22 10:06 ` [PATCH RFC 12/22] scsi: rdac: Have scsi-ml retry send_mode_select errors Mike Christie
@ 2022-09-22 10:06 ` Mike Christie
  2022-09-22 10:06 ` [PATCH RFC 14/22] scsi: sd: Have scsi-ml retry sd_sync_cache errors Mike Christie
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:06 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

This has spi_execute have scsi-ml retry errors instead of driving them.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/scsi_transport_spi.c | 37 +++++++++++++++++--------------
 1 file changed, 20 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index 4f4c2b155da0..4df56ee4eaac 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -109,29 +109,32 @@ static int spi_execute(struct scsi_device *sdev, const void *cmd,
 		       void *buffer, unsigned bufflen,
 		       struct scsi_sense_hdr *sshdr)
 {
-	int i, result;
 	unsigned char sense[SCSI_SENSE_BUFFERSIZE];
 	struct scsi_sense_hdr sshdr_tmp;
+	struct scsi_failure failures[] = {
+		{
+			.sense = UNIT_ATTENTION,
+			.asc = SCMD_FAILURE_ASC_ANY,
+			.ascq = SCMD_FAILURE_ASCQ_ANY,
+			.allowed = DV_RETRIES,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{},
+	};
 
 	if (!sshdr)
 		sshdr = &sshdr_tmp;
 
-	for(i = 0; i < DV_RETRIES; i++) {
-		/*
-		 * The purpose of the RQF_PM flag below is to bypass the
-		 * SDEV_QUIESCE state.
-		 */
-		result = scsi_execute(sdev, cmd, dir, buffer, bufflen, sense,
-				      sshdr, DV_TIMEOUT, /* retries */ 1,
-				      REQ_FAILFAST_DEV |
-				      REQ_FAILFAST_TRANSPORT |
-				      REQ_FAILFAST_DRIVER,
-				      RQF_PM, NULL, NULL);
-		if (result < 0 || !scsi_sense_valid(sshdr) ||
-		    sshdr->sense_key != UNIT_ATTENTION)
-			break;
-	}
-	return result;
+	/*
+	 * The purpose of the RQF_PM flag below is to bypass the
+	 * SDEV_QUIESCE state.
+	 */
+	return scsi_execute(sdev, cmd, dir, buffer, bufflen, sense,
+			    sshdr, DV_TIMEOUT, /* retries */ 1,
+			    REQ_FAILFAST_DEV |
+			    REQ_FAILFAST_TRANSPORT |
+			    REQ_FAILFAST_DRIVER,
+			    RQF_PM, NULL, failures);
 }
 
 static struct {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 14/22] scsi: sd: Have scsi-ml retry sd_sync_cache errors
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
                   ` (12 preceding siblings ...)
  2022-09-22 10:06 ` [PATCH RFC 13/22] scsi: spi: Have scsi-ml retry spi_execute errors Mike Christie
@ 2022-09-22 10:06 ` Mike Christie
  2022-09-22 10:06 ` [PATCH RFC 15/22] scsi: ch: Have scsi-ml retry ch_do_scsi errors Mike Christie
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:06 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

This has sd_sync_cache have scsi-ml retry errors instead of driving them
itself.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/sd.c | 31 +++++++++++++++----------------
 1 file changed, 15 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index b76e0b1900a0..264c63b10e06 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1573,11 +1573,19 @@ static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing)
 
 static int sd_sync_cache(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr)
 {
-	int retries, res;
 	struct scsi_device *sdp = sdkp->device;
 	const int timeout = sdp->request_queue->rq_timeout
 		* SD_FLUSH_TIMEOUT_MULTIPLIER;
 	struct scsi_sense_hdr my_sshdr;
+	struct scsi_failure failures[] = {
+		{
+			.allowed = 3,
+			.result = SCMD_FAILURE_ANY,
+		},
+		{},
+	};
+	unsigned char cmd[10] = { SYNCHRONIZE_CACHE };
+	int res;
 
 	if (!scsi_device_online(sdp))
 		return -ENODEV;
@@ -1586,21 +1594,12 @@ static int sd_sync_cache(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr)
 	if (!sshdr)
 		sshdr = &my_sshdr;
 
-	for (retries = 3; retries > 0; --retries) {
-		unsigned char cmd[10] = { 0 };
-
-		cmd[0] = SYNCHRONIZE_CACHE;
-		/*
-		 * Leave the rest of the command zero to indicate
-		 * flush everything.
-		 */
-		res = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, sshdr,
-				   timeout, sdkp->max_retries, 0, RQF_PM, NULL,
-				   NULL);
-		if (res == 0)
-			break;
-	}
-
+	/*
+	 * Leave the rest of the command zero to indicate flush everything.
+	 */
+	res = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, sshdr,
+			   timeout, sdkp->max_retries, 0, RQF_PM, NULL,
+			   failures);
 	if (res) {
 		sd_print_result(sdkp, "Synchronize Cache(10) failed", res);
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 15/22] scsi: ch: Have scsi-ml retry ch_do_scsi errors
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
                   ` (13 preceding siblings ...)
  2022-09-22 10:06 ` [PATCH RFC 14/22] scsi: sd: Have scsi-ml retry sd_sync_cache errors Mike Christie
@ 2022-09-22 10:06 ` Mike Christie
  2022-09-22 10:06 ` [PATCH RFC 16/22] scsi: Have scsi-ml retry scsi_mode_sense errors Mike Christie
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:06 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

This has ch_do_scsi have scsi-ml retry errors instead of driving them
itself.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/ch.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index cdef392be5fc..683389acd870 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -113,7 +113,6 @@ typedef struct {
 	struct scsi_device  **dt;        /* ptrs to data transfer elements */
 	u_int               firsts[CH_TYPES];
 	u_int               counts[CH_TYPES];
-	u_int               unit_attention;
 	u_int		    voltags;
 	struct mutex	    lock;
 } scsi_changer;
@@ -187,31 +186,32 @@ ch_do_scsi(scsi_changer *ch, unsigned char *cmd, int cmd_len,
 	   void *buffer, unsigned buflength,
 	   enum dma_data_direction direction)
 {
-	int errno, retries = 0, timeout, result;
+	int errno, timeout, result;
 	struct scsi_sense_hdr sshdr;
+	struct scsi_failure failures[] = {
+		{
+			.sense = UNIT_ATTENTION,
+			.asc = SCMD_FAILURE_ASC_ANY,
+			.ascq = SCMD_FAILURE_ASCQ_ANY,
+			.allowed = 3,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{},
+	};
 
 	timeout = (cmd[0] == INITIALIZE_ELEMENT_STATUS)
 		? timeout_init : timeout_move;
 
- retry:
 	errno = 0;
 	result = scsi_execute_req(ch->device, cmd, direction, buffer,
 				  buflength, &sshdr, timeout * HZ,
-				  MAX_RETRIES, NULL, NULL);
+				  MAX_RETRIES, NULL, failures);
 	if (result < 0)
 		return result;
 	if (scsi_sense_valid(&sshdr)) {
 		if (debug)
 			scsi_print_sense_hdr(ch->device, ch->name, &sshdr);
 		errno = ch_find_errno(&sshdr);
-
-		switch(sshdr.sense_key) {
-		case UNIT_ATTENTION:
-			ch->unit_attention = 1;
-			if (retries++ < 3)
-				goto retry;
-			break;
-		}
 	}
 	return errno;
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 16/22] scsi: Have scsi-ml retry scsi_mode_sense errors
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
                   ` (14 preceding siblings ...)
  2022-09-22 10:06 ` [PATCH RFC 15/22] scsi: ch: Have scsi-ml retry ch_do_scsi errors Mike Christie
@ 2022-09-22 10:06 ` Mike Christie
  2022-09-22 10:06 ` [PATCH RFC 17/22] scsi: Have scsi-ml retry scsi_report_lun_scan errors Mike Christie
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:06 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

This has scsi_mode_sense have scsi-ml retry errors instead of driving them
itself.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/scsi_lib.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 7e4cc0b28f61..c708503d574e 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -2170,8 +2170,18 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
 	unsigned char cmd[12];
 	int use_10_for_ms;
 	int header_length;
-	int result, retry_count = retries;
+	int result;
 	struct scsi_sense_hdr my_sshdr;
+	struct scsi_failure failures[] = {
+		{
+			.sense = UNIT_ATTENTION,
+			.asc = SCMD_FAILURE_ASC_ANY,
+			.ascq = SCMD_FAILURE_ASCQ_ANY,
+			.allowed = retries,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{},
+	};
 
 	memset(data, 0, sizeof(*data));
 	memset(&cmd[0], 0, 12);
@@ -2206,7 +2216,7 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
 	memset(buffer, 0, len);
 
 	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len,
-				  sshdr, timeout, retries, NULL, NULL);
+				  sshdr, timeout, retries, NULL, failures);
 	if (result < 0)
 		return result;
 
@@ -2233,12 +2243,6 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
 					goto retry;
 				}
 			}
-			if (scsi_status_is_check_condition(result) &&
-			    sshdr->sense_key == UNIT_ATTENTION &&
-			    retry_count) {
-				retry_count--;
-				goto retry;
-			}
 		}
 		return -EIO;
 	}
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 17/22] scsi: Have scsi-ml retry scsi_report_lun_scan errors
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
                   ` (15 preceding siblings ...)
  2022-09-22 10:06 ` [PATCH RFC 16/22] scsi: Have scsi-ml retry scsi_mode_sense errors Mike Christie
@ 2022-09-22 10:06 ` Mike Christie
  2022-09-22 10:07 ` [PATCH RFC 18/22] scsi: sd: Have sd_pr_command retry UAs Mike Christie
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:06 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

This has scsi_report_lun_scan have scsi-ml retry errors instead of driving
them itself.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/scsi_scan.c | 42 ++++++++++++++++++----------------------
 1 file changed, 19 insertions(+), 23 deletions(-)

diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 744fb8b469db..836e03ca73e8 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1408,13 +1408,22 @@ static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflag
 	unsigned int length;
 	u64 lun;
 	unsigned int num_luns;
-	unsigned int retries;
 	int result;
 	struct scsi_lun *lunp, *lun_data;
 	struct scsi_sense_hdr sshdr;
 	struct scsi_device *sdev;
 	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
 	int ret = 0;
+	struct scsi_failure failures[] = {
+		{
+			.sense = UNIT_ATTENTION,
+			.asc = SCMD_FAILURE_ASC_ANY,
+			.ascq = SCMD_FAILURE_ASCQ_ANY,
+			.allowed = 3,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{},
+	};
 
 	/*
 	 * Only support SCSI-3 and up devices if BLIST_NOREPORTLUN is not set.
@@ -1483,29 +1492,16 @@ static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflag
 	 * should come through as a check condition, and will not generate
 	 * a retry.
 	 */
-	for (retries = 0; retries < 3; retries++) {
-		SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
-				"scsi scan: Sending REPORT LUNS to (try %d)\n",
-				retries));
-
-		result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
-					  lun_data, length, &sshdr,
-					  SCSI_REPORT_LUNS_TIMEOUT, 3, NULL,
-					  NULL);
-
-		SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
-				"scsi scan: REPORT LUNS"
-				" %s (try %d) result 0x%x\n",
-				result ?  "failed" : "successful",
-				retries, result));
-		if (result == 0)
-			break;
-		else if (scsi_sense_valid(&sshdr)) {
-			if (sshdr.sense_key != UNIT_ATTENTION)
-				break;
-		}
-	}
+	SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
+			  "scsi scan: Sending REPORT LUNS\n"));
+
+	result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE, lun_data,
+				  length, &sshdr, SCSI_REPORT_LUNS_TIMEOUT, 3,
+				  NULL, failures);
 
+	SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
+			  "scsi scan: REPORT LUNS %s result 0x%x\n",
+			  result ?  "failed" : "successful", result));
 	if (result) {
 		/*
 		 * The device probably does not support a REPORT LUN command
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 18/22] scsi: sd: Have sd_pr_command retry UAs
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
                   ` (16 preceding siblings ...)
  2022-09-22 10:06 ` [PATCH RFC 17/22] scsi: Have scsi-ml retry scsi_report_lun_scan errors Mike Christie
@ 2022-09-22 10:07 ` Mike Christie
  2022-09-22 10:07 ` [PATCH RFC 19/22] scsi: sd: Have scsi-ml retry read_capacity_10 errors Mike Christie
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:07 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

It's common to get a UA when doing PR commands. It could be due to a
target restarting, transport level relogin or other PR commands like a
release causing it. The upper layers don't get the sense and in some cases
have no idea if it's a SCSI device, so this has the sd layer retry.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/sd.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 264c63b10e06..d655549dee94 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1710,6 +1710,16 @@ static int sd_pr_command(struct block_device *bdev, u8 sa,
 	int result;
 	u8 cmd[16] = { 0, };
 	u8 data[24] = { 0, };
+	struct scsi_failure failures[] = {
+		{
+			.sense = UNIT_ATTENTION,
+			.asc = SCMD_FAILURE_ASC_ANY,
+			.ascq = SCMD_FAILURE_ASCQ_ANY,
+			.allowed = 5,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{},
+	};
 
 	cmd[0] = PERSISTENT_RESERVE_OUT;
 	cmd[1] = sa;
@@ -1721,7 +1731,7 @@ static int sd_pr_command(struct block_device *bdev, u8 sa,
 	data[20] = flags;
 
 	result = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, &data, sizeof(data),
-			&sshdr, SD_TIMEOUT, sdkp->max_retries, NULL, NULL);
+			&sshdr, SD_TIMEOUT, sdkp->max_retries, NULL, failures);
 
 	if (scsi_status_is_check_condition(result) &&
 	    scsi_sense_valid(&sshdr)) {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 19/22] scsi: sd: Have scsi-ml retry read_capacity_10 errors
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
                   ` (17 preceding siblings ...)
  2022-09-22 10:07 ` [PATCH RFC 18/22] scsi: sd: Have sd_pr_command retry UAs Mike Christie
@ 2022-09-22 10:07 ` Mike Christie
  2022-09-22 10:07 ` [PATCH RFC 20/22] scsi: ses: Have scsi-ml retry ses_recv_diag errors Mike Christie
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:07 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

This has read_capacity_10 have scsi-ml retry errors instead of driving
them itself.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/sd.c | 48 +++++++++++++++++++++++------------------------
 1 file changed, 23 insertions(+), 25 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index d655549dee94..f6f7e16d2a71 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2362,36 +2362,34 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
 	struct scsi_sense_hdr sshdr;
 	int sense_valid = 0;
 	int the_result;
-	int retries = 3, reset_retries = READ_CAPACITY_RETRIES_ON_RESET;
 	sector_t lba;
 	unsigned sector_size;
+	struct scsi_failure failures[] = {
+		{
+			.sense = UNIT_ATTENTION,
+			.asc = 0x29,
+			.ascq = 0,
+			/* Device reset might occur several times */
+			.allowed = READ_CAPACITY_RETRIES_ON_RESET,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{
+			.result = SCMD_FAILURE_ANY,
+			.allowed = 3,
+		},
+		{},
+	};
 
-	do {
-		cmd[0] = READ_CAPACITY;
-		memset(&cmd[1], 0, 9);
-		memset(buffer, 0, 8);
-
-		the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE,
-					buffer, 8, &sshdr,
-					SD_TIMEOUT, sdkp->max_retries, NULL,
-					NULL);
-
-		if (media_not_present(sdkp, &sshdr))
-			return -ENODEV;
+	cmd[0] = READ_CAPACITY;
+	memset(&cmd[1], 0, 9);
+	memset(buffer, 0, 8);
 
-		if (the_result > 0) {
-			sense_valid = scsi_sense_valid(&sshdr);
-			if (sense_valid &&
-			    sshdr.sense_key == UNIT_ATTENTION &&
-			    sshdr.asc == 0x29 && sshdr.ascq == 0x00)
-				/* Device reset might occur several times,
-				 * give it one more chance */
-				if (--reset_retries > 0)
-					continue;
-		}
-		retries--;
+	the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE, buffer, 8,
+				      &sshdr, SD_TIMEOUT, sdkp->max_retries,
+				      NULL, failures);
 
-	} while (the_result && retries);
+	if (media_not_present(sdkp, &sshdr))
+		return -ENODEV;
 
 	if (the_result) {
 		sd_print_result(sdkp, "Read Capacity(10) failed", the_result);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 20/22] scsi: ses: Have scsi-ml retry ses_recv_diag errors
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
                   ` (18 preceding siblings ...)
  2022-09-22 10:07 ` [PATCH RFC 19/22] scsi: sd: Have scsi-ml retry read_capacity_10 errors Mike Christie
@ 2022-09-22 10:07 ` Mike Christie
  2022-09-22 10:07 ` [PATCH RFC 21/22] scsi: ses: Have scsi-ml retry ses_send_diag errors Mike Christie
  2022-09-22 10:07 ` [PATCH RFC 22/22] scsi: sr: Have scsi-ml retry get_sectorsize errors Mike Christie
  21 siblings, 0 replies; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:07 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

This has ses_recv_diag have scsi-ml retry errors instead of driving them
itself.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/ses.c | 27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index 8f5a6370f334..d5de65dc034b 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -87,16 +87,27 @@ static int ses_recv_diag(struct scsi_device *sdev, int page_code,
 		0
 	};
 	unsigned char recv_page_code;
-	unsigned int retries = SES_RETRIES;
 	struct scsi_sense_hdr sshdr;
+	struct scsi_failure failures[] = {
+		{
+			.sense = UNIT_ATTENTION,
+			.asc = 0x29,
+			.ascq = SCMD_FAILURE_ASCQ_ANY,
+			.allowed = SES_RETRIES,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{
+			.sense = NOT_READY,
+			.asc = SCMD_FAILURE_ASC_ANY,
+			.ascq = SCMD_FAILURE_ASCQ_ANY,
+			.allowed = SES_RETRIES,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{},
+	};
 
-	do {
-		ret = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,
-				       &sshdr, SES_TIMEOUT, 1, NULL, NULL);
-	} while (ret > 0 && --retries && scsi_sense_valid(&sshdr) &&
-		 (sshdr.sense_key == NOT_READY ||
-		  (sshdr.sense_key == UNIT_ATTENTION && sshdr.asc == 0x29)));
-
+	ret = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,
+			       &sshdr, SES_TIMEOUT, 1, NULL, failures);
 	if (unlikely(ret))
 		return ret;
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 21/22] scsi: ses: Have scsi-ml retry ses_send_diag errors
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
                   ` (19 preceding siblings ...)
  2022-09-22 10:07 ` [PATCH RFC 20/22] scsi: ses: Have scsi-ml retry ses_recv_diag errors Mike Christie
@ 2022-09-22 10:07 ` Mike Christie
  2022-09-22 10:07 ` [PATCH RFC 22/22] scsi: sr: Have scsi-ml retry get_sectorsize errors Mike Christie
  21 siblings, 0 replies; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:07 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

This has ses_send_diag have scsi-ml retry errors instead of driving them
itself.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/ses.c | 27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index d5de65dc034b..6bcc31104486 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -140,15 +140,26 @@ static int ses_send_diag(struct scsi_device *sdev, int page_code,
 		0
 	};
 	struct scsi_sense_hdr sshdr;
-	unsigned int retries = SES_RETRIES;
-
-	do {
-		result = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, buf, bufflen,
-					  &sshdr, SES_TIMEOUT, 1, NULL, NULL);
-	} while (result > 0 && --retries && scsi_sense_valid(&sshdr) &&
-		 (sshdr.sense_key == NOT_READY ||
-		  (sshdr.sense_key == UNIT_ATTENTION && sshdr.asc == 0x29)));
+	struct scsi_failure failures[] = {
+		{
+			.sense = UNIT_ATTENTION,
+			.asc = 0x29,
+			.ascq = SCMD_FAILURE_ASCQ_ANY,
+			.allowed = SES_RETRIES,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{
+			.sense = NOT_READY,
+			.asc = SCMD_FAILURE_ASC_ANY,
+			.ascq = SCMD_FAILURE_ASCQ_ANY,
+			.allowed = SES_RETRIES,
+			.result = SAM_STAT_CHECK_CONDITION,
+		},
+		{},
+	};
 
+	result = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, buf, bufflen,
+				  &sshdr, SES_TIMEOUT, 1, NULL, failures);
 	if (result)
 		sdev_printk(KERN_ERR, sdev, "SEND DIAGNOSTIC result: %8x\n",
 			    result);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH RFC 22/22] scsi: sr: Have scsi-ml retry get_sectorsize errors
  2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
                   ` (20 preceding siblings ...)
  2022-09-22 10:07 ` [PATCH RFC 21/22] scsi: ses: Have scsi-ml retry ses_send_diag errors Mike Christie
@ 2022-09-22 10:07 ` Mike Christie
  21 siblings, 0 replies; 31+ messages in thread
From: Mike Christie @ 2022-09-22 10:07 UTC (permalink / raw)
  To: mwilck, hch, martin.petersen, linux-scsi, james.bottomley; +Cc: Mike Christie

This has get_sectorsize have scsi-ml retry errors instead of driving them
itself.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/sr.c | 31 +++++++++++++++----------------
 1 file changed, 15 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 8b28a8a28b45..cf1f498671f0 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -720,26 +720,25 @@ static void get_sectorsize(struct scsi_cd *cd)
 {
 	unsigned char cmd[10];
 	unsigned char buffer[8];
-	int the_result, retries = 3;
+	int the_result;
 	int sector_size;
 	struct request_queue *queue;
+	struct scsi_failure failures[] = {
+		{
+			.result = SCMD_FAILURE_ANY,
+			.allowed = 3,
+		},
+		{},
+	};
 
-	do {
-		cmd[0] = READ_CAPACITY;
-		memset((void *) &cmd[1], 0, 9);
-		memset(buffer, 0, sizeof(buffer));
-
-		/* Do the command and wait.. */
-		the_result = scsi_execute_req(cd->device, cmd, DMA_FROM_DEVICE,
-					      buffer, sizeof(buffer), NULL,
-					      SR_TIMEOUT, MAX_RETRIES, NULL,
-					      NULL);
-
-		retries--;
-
-	} while (the_result && retries);
-
+	cmd[0] = READ_CAPACITY;
+	memset((void *) &cmd[1], 0, 9);
+	memset(buffer, 0, sizeof(buffer));
 
+	/* Do the command and wait.. */
+	the_result = scsi_execute_req(cd->device, cmd, DMA_FROM_DEVICE,
+				      buffer, sizeof(buffer), NULL,
+				      SR_TIMEOUT, MAX_RETRIES, NULL, failures);
 	if (the_result) {
 		cd->capacity = 0x1fffff;
 		sector_size = 2048;	/* A guess, just in case */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH RFC 01/22] scsi: Add helper to prep sense during error handling
  2022-09-22 10:06 ` [PATCH RFC 01/22] scsi: Add helper to prep sense during error handling Mike Christie
@ 2022-09-22 16:57   ` Bart Van Assche
  2022-09-22 17:36     ` michael.christie
  0 siblings, 1 reply; 31+ messages in thread
From: Bart Van Assche @ 2022-09-22 16:57 UTC (permalink / raw)
  To: Mike Christie, mwilck, hch, martin.petersen, linux-scsi, james.bottomley

On 9/22/22 03:06, Mike Christie wrote:
> +static enum scsi_disposition scsi_prep_sense(struct scsi_cmnd *scmd,
> +					     struct scsi_sense_hdr *sshdr)

How about choosing another name for this function? All other functions 
with "prep" in their name are called before a command is submitted while 
this function is called from the completion path.

Thanks,

Bart.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH RFC 02/22] scsi: Allow passthrough to override what errors to retry
  2022-09-22 10:06 ` [PATCH RFC 02/22] scsi: Allow passthrough to override what errors to retry Mike Christie
@ 2022-09-22 16:59   ` Bart Van Assche
  2022-09-22 17:28     ` michael.christie
  0 siblings, 1 reply; 31+ messages in thread
From: Bart Van Assche @ 2022-09-22 16:59 UTC (permalink / raw)
  To: Mike Christie, mwilck, hch, martin.petersen, linux-scsi, james.bottomley

On 9/22/22 03:06, Mike Christie wrote:
> +	while ((failure = &scmd->failures[i++])) {

Has this patch been verified with checkpatch? I don't think that the 
Linux kernel coding style allows assignments inside conditions.

Thanks,

Bart.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH RFC 03/22] scsi: Take an array of failures for passthrough
  2022-09-22 10:06 ` [PATCH RFC 03/22] scsi: Take an array of failures for passthrough Mike Christie
@ 2022-09-22 17:02   ` Bart Van Assche
  0 siblings, 0 replies; 31+ messages in thread
From: Bart Van Assche @ 2022-09-22 17:02 UTC (permalink / raw)
  To: Mike Christie, mwilck, hch, martin.petersen, linux-scsi, james.bottomley

On 9/22/22 03:06, Mike Christie wrote:
> @@ -458,24 +459,26 @@ extern int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
>   			int data_direction, void *buffer, unsigned bufflen,
>   			unsigned char *sense, struct scsi_sense_hdr *sshdr,
>   			int timeout, int retries, blk_opf_t flags,
> -			req_flags_t rq_flags, int *resid);
> +			req_flags_t rq_flags, int *resid,
> +			struct scsi_failure *failures);
>   /* Make sure any sense buffer is the correct size. */
>   #define scsi_execute(sdev, cmd, data_direction, buffer, bufflen, sense,	\
> -		     sshdr, timeout, retries, flags, rq_flags, resid)	\
> +		     sshdr, timeout, retries, flags, rq_flags, resid,	\
> +		     failures)						\
>   ({									\
>   	BUILD_BUG_ON((sense) != NULL &&					\
>   		     sizeof(sense) != SCSI_SENSE_BUFFERSIZE);		\
>   	__scsi_execute(sdev, cmd, data_direction, buffer, bufflen,	\
>   		       sense, sshdr, timeout, retries, flags, rq_flags,	\
> -		       resid);						\
> +		       resid, failures);				\
>   })
>   static inline int scsi_execute_req(struct scsi_device *sdev,
>   	const unsigned char *cmd, int data_direction, void *buffer,
>   	unsigned bufflen, struct scsi_sense_hdr *sshdr, int timeout,
> -	int retries, int *resid)
> +	int retries, int *resid, struct scsi_failure *failures)
>   {
> -	return scsi_execute(sdev, cmd, data_direction, buffer,
> -		bufflen, NULL, sshdr, timeout, retries,  0, 0, resid);
> +	return scsi_execute(sdev, cmd, data_direction, buffer, bufflen, NULL,
> +			    sshdr, timeout, retries,  0, 0, resid, failures);
>   }

Both scsi_execute() and scsi_execute_req() have way too many arguments. 
Please do not add any new arguments but instead convert the existing and 
new arguments into a struct. That will allow callers to be written e.g. 
as follows:

	scsi_execute((struct scsi_execute_args){.sdev = ..., .cmd = ...,
			...});

Thanks,

Bart.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH RFC 04/22] scsi: Have scsi-ml retry scsi_probe_lun errors
  2022-09-22 10:06 ` [PATCH RFC 04/22] scsi: Have scsi-ml retry scsi_probe_lun errors Mike Christie
@ 2022-09-22 17:03   ` Bart Van Assche
  2022-09-22 17:30     ` michael.christie
  0 siblings, 1 reply; 31+ messages in thread
From: Bart Van Assche @ 2022-09-22 17:03 UTC (permalink / raw)
  To: Mike Christie, mwilck, hch, martin.petersen, linux-scsi, james.bottomley

On 9/22/22 03:06, Mike Christie wrote:
> +	struct scsi_failure failures[] = {
> +		{
> +			.sense = UNIT_ATTENTION,
> +			.asc = 0x28,
> +			.ascq = 0,
> +			.allowed = 3,
> +			.result = SAM_STAT_CHECK_CONDITION,
> +		},
> +		{
> +			.sense = UNIT_ATTENTION,
> +			.asc = 0x29,
> +			.ascq = 0,
> +			.allowed = 3,
> +			.result = SAM_STAT_CHECK_CONDITION,
> +		},
> +		{},
> +	};

Can the 'failures' array be declared 'static const'?

Thanks,

Bart.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH RFC 02/22] scsi: Allow passthrough to override what errors to retry
  2022-09-22 16:59   ` Bart Van Assche
@ 2022-09-22 17:28     ` michael.christie
  0 siblings, 0 replies; 31+ messages in thread
From: michael.christie @ 2022-09-22 17:28 UTC (permalink / raw)
  To: Bart Van Assche, mwilck, hch, martin.petersen, linux-scsi,
	james.bottomley

On 9/22/22 11:59 AM, Bart Van Assche wrote:
> On 9/22/22 03:06, Mike Christie wrote:
>> +    while ((failure = &scmd->failures[i++])) {
> 
> Has this patch been verified with checkpatch? I don't think that the Linux kernel coding style allows assignments inside conditions.
> 

Yes. With --strict that part was fine.

--strict just didn't like me adding a new line further down the function, but
I thought it looked weird without the new line.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH RFC 04/22] scsi: Have scsi-ml retry scsi_probe_lun errors
  2022-09-22 17:03   ` Bart Van Assche
@ 2022-09-22 17:30     ` michael.christie
  0 siblings, 0 replies; 31+ messages in thread
From: michael.christie @ 2022-09-22 17:30 UTC (permalink / raw)
  To: Bart Van Assche, mwilck, hch, martin.petersen, linux-scsi,
	james.bottomley

On 9/22/22 12:03 PM, Bart Van Assche wrote:
> On 9/22/22 03:06, Mike Christie wrote:
>> +    struct scsi_failure failures[] = {
>> +        {
>> +            .sense = UNIT_ATTENTION,
>> +            .asc = 0x28,
>> +            .ascq = 0,
>> +            .allowed = 3,
>> +            .result = SAM_STAT_CHECK_CONDITION,
>> +        },
>> +        {
>> +            .sense = UNIT_ATTENTION,
>> +            .asc = 0x29,
>> +            .ascq = 0,
>> +            .allowed = 3,
>> +            .result = SAM_STAT_CHECK_CONDITION,
>> +        },
>> +        {},
>> +    };
> 
> Can the 'failures' array be declared 'static const'?

No, the struct scsi_failures in there get updated when we track how many times
we've hit the error.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH RFC 01/22] scsi: Add helper to prep sense during error handling
  2022-09-22 16:57   ` Bart Van Assche
@ 2022-09-22 17:36     ` michael.christie
  2022-09-22 18:19       ` Bart Van Assche
  0 siblings, 1 reply; 31+ messages in thread
From: michael.christie @ 2022-09-22 17:36 UTC (permalink / raw)
  To: Bart Van Assche, mwilck, hch, martin.petersen, linux-scsi,
	james.bottomley

On 9/22/22 11:57 AM, Bart Van Assche wrote:
> On 9/22/22 03:06, Mike Christie wrote:
>> +static enum scsi_disposition scsi_prep_sense(struct scsi_cmnd *scmd,
>> +                         struct scsi_sense_hdr *sshdr)
> 
> How about choosing another name for this function? All other functions with "prep" in their name are called before a command is submitted while this function is called from the completion path.

I'll think of something. scsi_init_sense_processing or scsi_start_sense_processing?

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH RFC 01/22] scsi: Add helper to prep sense during error handling
  2022-09-22 17:36     ` michael.christie
@ 2022-09-22 18:19       ` Bart Van Assche
  0 siblings, 0 replies; 31+ messages in thread
From: Bart Van Assche @ 2022-09-22 18:19 UTC (permalink / raw)
  To: michael.christie, mwilck, hch, martin.petersen, linux-scsi,
	james.bottomley

On 9/22/22 10:36, michael.christie@oracle.com wrote:
> On 9/22/22 11:57 AM, Bart Van Assche wrote:
>> On 9/22/22 03:06, Mike Christie wrote:
>>> +static enum scsi_disposition scsi_prep_sense(struct scsi_cmnd *scmd,
>>> +                         struct scsi_sense_hdr *sshdr)
>>
>> How about choosing another name for this function? All other functions with "prep" in their name are called before a command is submitted while this function is called from the completion path.
> 
> I'll think of something. scsi_init_sense_processing or scsi_start_sense_processing?

Thanks - I like the second name a bit better than the first :-)

Bart.

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2022-09-22 18:19 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-22 10:06 [PATCH RFC 00/22] Allow scsi_execute users to control retries Mike Christie
2022-09-22 10:06 ` [PATCH RFC 01/22] scsi: Add helper to prep sense during error handling Mike Christie
2022-09-22 16:57   ` Bart Van Assche
2022-09-22 17:36     ` michael.christie
2022-09-22 18:19       ` Bart Van Assche
2022-09-22 10:06 ` [PATCH RFC 02/22] scsi: Allow passthrough to override what errors to retry Mike Christie
2022-09-22 16:59   ` Bart Van Assche
2022-09-22 17:28     ` michael.christie
2022-09-22 10:06 ` [PATCH RFC 03/22] scsi: Take an array of failures for passthrough Mike Christie
2022-09-22 17:02   ` Bart Van Assche
2022-09-22 10:06 ` [PATCH RFC 04/22] scsi: Have scsi-ml retry scsi_probe_lun errors Mike Christie
2022-09-22 17:03   ` Bart Van Assche
2022-09-22 17:30     ` michael.christie
2022-09-22 10:06 ` [PATCH RFC 05/22] scsi: retry INQUIRY after timeout Mike Christie
2022-09-22 10:06 ` [PATCH RFC 06/22] scsi: Have scsi-ml retry read_capacity_16 errors Mike Christie
2022-09-22 10:06 ` [PATCH RFC 07/22] scsi: Have scsi-ml retry sd_spinup_disk errors Mike Christie
2022-09-22 10:06 ` [PATCH RFC 08/22] scsi: cxlflash: Have scsi-ml retry read_cap16 errors Mike Christie
2022-09-22 10:06 ` [PATCH RFC 09/22] scsi: hp_sw: Have scsi-ml retry hp_sw_start_stop errors Mike Christie
2022-09-22 10:06 ` [PATCH RFC 10/22] scsi: Allow passthrough to request infinite retries Mike Christie
2022-09-22 10:06 ` [PATCH RFC 11/22] scsi: hp_sw: Have scsi-ml retry hp_sw_tur errors Mike Christie
2022-09-22 10:06 ` [PATCH RFC 12/22] scsi: rdac: Have scsi-ml retry send_mode_select errors Mike Christie
2022-09-22 10:06 ` [PATCH RFC 13/22] scsi: spi: Have scsi-ml retry spi_execute errors Mike Christie
2022-09-22 10:06 ` [PATCH RFC 14/22] scsi: sd: Have scsi-ml retry sd_sync_cache errors Mike Christie
2022-09-22 10:06 ` [PATCH RFC 15/22] scsi: ch: Have scsi-ml retry ch_do_scsi errors Mike Christie
2022-09-22 10:06 ` [PATCH RFC 16/22] scsi: Have scsi-ml retry scsi_mode_sense errors Mike Christie
2022-09-22 10:06 ` [PATCH RFC 17/22] scsi: Have scsi-ml retry scsi_report_lun_scan errors Mike Christie
2022-09-22 10:07 ` [PATCH RFC 18/22] scsi: sd: Have sd_pr_command retry UAs Mike Christie
2022-09-22 10:07 ` [PATCH RFC 19/22] scsi: sd: Have scsi-ml retry read_capacity_10 errors Mike Christie
2022-09-22 10:07 ` [PATCH RFC 20/22] scsi: ses: Have scsi-ml retry ses_recv_diag errors Mike Christie
2022-09-22 10:07 ` [PATCH RFC 21/22] scsi: ses: Have scsi-ml retry ses_send_diag errors Mike Christie
2022-09-22 10:07 ` [PATCH RFC 22/22] scsi: sr: Have scsi-ml retry get_sectorsize errors Mike Christie

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.