Commit bd7f0ef2 authored by Martin K. Petersen's avatar Martin K. Petersen
Browse files

Merge patch series "scsi: sshdr and retry fixes"

Mike Christie <michael.christie@oracle.com> says:

The following patches were made over Linus tree (Martin's 6.7 branch
was missing some changes to sd.c). They only contain the sshdr and
rdac retry fixes from the "Allow scsi_execute users to control
retries" patchset.

The patches in this set are reviewed and tested but the changes to how
we do retries will take a little longer and require more testing, so I
broke up the series to make them easier to review.

Link: https://lore.kernel.org/r/20231004210013.5601-1-michael.christie@oracle.com


Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parents 1caddfc5 f7d7129c
Loading
Loading
Loading
Loading
+40 −39
Original line number Diff line number Diff line
@@ -82,7 +82,7 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h)
{
	unsigned char cmd[6] = { TEST_UNIT_READY };
	struct scsi_sense_hdr sshdr;
	int ret = SCSI_DH_OK, res;
	int ret, res;
	blk_opf_t opf = REQ_OP_DRV_IN | REQ_FAILFAST_DEV |
				REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER;
	const struct scsi_exec_args exec_args = {
@@ -92,19 +92,18 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h)
retry:
	res = scsi_execute_cmd(sdev, cmd, opf, NULL, 0, HP_SW_TIMEOUT,
			       HP_SW_RETRIES, &exec_args);
	if (res) {
		if (scsi_sense_valid(&sshdr))
	if (res > 0 && scsi_sense_valid(&sshdr)) {
		ret = tur_done(sdev, h, &sshdr);
		else {
	} else if (res == 0) {
		h->path_state = HP_SW_PATH_ACTIVE;
		ret = SCSI_DH_OK;
	} else {
		sdev_printk(KERN_WARNING, sdev,
			    "%s: sending tur failed with %x\n",
			    HP_SW_NAME, res);
		ret = SCSI_DH_IO;
	}
	} else {
		h->path_state = HP_SW_PATH_ACTIVE;
		ret = SCSI_DH_OK;
	}

	if (ret == SCSI_DH_IMM_RETRY)
		goto retry;

@@ -122,7 +121,7 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h)
	unsigned char cmd[6] = { START_STOP, 0, 0, 0, 1, 0 };
	struct scsi_sense_hdr sshdr;
	struct scsi_device *sdev = h->sdev;
	int res, rc = SCSI_DH_OK;
	int res, rc;
	int retry_cnt = HP_SW_RETRIES;
	blk_opf_t opf = REQ_OP_DRV_IN | REQ_FAILFAST_DEV |
				REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER;
@@ -133,13 +132,15 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h)
retry:
	res = scsi_execute_cmd(sdev, cmd, opf, NULL, 0, HP_SW_TIMEOUT,
			       HP_SW_RETRIES, &exec_args);
	if (res) {
		if (!scsi_sense_valid(&sshdr)) {
	if (!res) {
		return SCSI_DH_OK;
	} else if (res < 0 || !scsi_sense_valid(&sshdr)) {
		sdev_printk(KERN_WARNING, sdev,
			    "%s: sending start_stop_unit failed, "
			    "no sense available\n", HP_SW_NAME);
		return SCSI_DH_IO;
	}

	switch (sshdr.sense_key) {
	case NOT_READY:
		if (sshdr.asc == 0x04 && sshdr.ascq == 3) {
@@ -161,7 +162,7 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h)
			    sshdr.sense_key, sshdr.asc, sshdr.ascq);
		rc = SCSI_DH_IO;
	}
	}

	return rc;
}

+12 −9
Original line number Diff line number Diff line
@@ -530,7 +530,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 rc, err, retry_cnt = RDAC_RETRY_COUNT;
	struct rdac_queue_data *tmp, *qdata;
	LIST_HEAD(list);
	unsigned char cdb[MAX_COMMAND_SIZE];
@@ -558,20 +558,23 @@ static void send_mode_select(struct work_struct *work)
		(char *) h->ctlr->array_name, h->ctlr->index,
		(retry_cnt == RDAC_RETRY_COUNT) ? "queueing" : "retrying");

	if (scsi_execute_cmd(sdev, cdb, opf, &h->ctlr->mode_select, data_size,
			     RDAC_TIMEOUT * HZ, RDAC_RETRIES, &exec_args)) {
	rc = scsi_execute_cmd(sdev, cdb, opf, &h->ctlr->mode_select, data_size,
			      RDAC_TIMEOUT * HZ, RDAC_RETRIES, &exec_args);
	if (!rc) {
		h->state = RDAC_STATE_ACTIVE;
		RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, "
				"MODE_SELECT completed",
				(char *) h->ctlr->array_name, h->ctlr->index);
		err = SCSI_DH_OK;
	} else if (rc < 0) {
		err = SCSI_DH_IO;
	} else {
		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;
		RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, "
				"MODE_SELECT completed",
				(char *) h->ctlr->array_name, h->ctlr->index);
	}

	list_for_each_entry_safe(qdata, tmp, &list, entry) {
		list_del(&qdata->entry);
+1 −1
Original line number Diff line number Diff line
@@ -692,7 +692,7 @@ int scsi_cdl_enable(struct scsi_device *sdev, bool enable)
		ret = scsi_mode_select(sdev, 1, 0, buf_data, len, 5 * HZ, 3,
				       &data, &sshdr);
		if (ret) {
			if (scsi_sense_valid(&sshdr))
			if (ret > 0 && scsi_sense_valid(&sshdr))
				scsi_print_sense_hdr(sdev,
					dev_name(&sdev->sdev_gendev), &sshdr);
			return ret;
+2 −2
Original line number Diff line number Diff line
@@ -2299,10 +2299,10 @@ scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries,
	do {
		result = scsi_execute_cmd(sdev, cmd, REQ_OP_DRV_IN, NULL, 0,
					  timeout, 1, &exec_args);
		if (sdev->removable && scsi_sense_valid(sshdr) &&
		if (sdev->removable && result > 0 && scsi_sense_valid(sshdr) &&
		    sshdr->sense_key == UNIT_ATTENTION)
			sdev->changed = 1;
	} while (scsi_sense_valid(sshdr) &&
	} while (result > 0 && scsi_sense_valid(sshdr) &&
		 sshdr->sense_key == UNIT_ATTENTION && --retries);

	return result;
+2 −2
Original line number Diff line number Diff line
@@ -679,7 +679,7 @@ spi_dv_device_echo_buffer(struct scsi_device *sdev, u8 *buffer,
		if (result || !scsi_device_online(sdev)) {

			scsi_device_set_state(sdev, SDEV_QUIESCE);
			if (scsi_sense_valid(&sshdr)
			if (result > 0 && scsi_sense_valid(&sshdr)
			    && sshdr.sense_key == ILLEGAL_REQUEST
			    /* INVALID FIELD IN CDB */
			    && sshdr.asc == 0x24 && sshdr.ascq == 0x00)
Loading