Skip to content

Commit bd7f0ef

Browse files
Merge patch series "scsi: sshdr and retry fixes"
Mike Christie <[email protected]> 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/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
2 parents 1caddfc + f7d7129 commit bd7f0ef

File tree

7 files changed

+82
-75
lines changed

7 files changed

+82
-75
lines changed

drivers/scsi/device_handler/scsi_dh_hp_sw.c

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h)
8282
{
8383
unsigned char cmd[6] = { TEST_UNIT_READY };
8484
struct scsi_sense_hdr sshdr;
85-
int ret = SCSI_DH_OK, res;
85+
int ret, res;
8686
blk_opf_t opf = REQ_OP_DRV_IN | REQ_FAILFAST_DEV |
8787
REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER;
8888
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)
9292
retry:
9393
res = scsi_execute_cmd(sdev, cmd, opf, NULL, 0, HP_SW_TIMEOUT,
9494
HP_SW_RETRIES, &exec_args);
95-
if (res) {
96-
if (scsi_sense_valid(&sshdr))
97-
ret = tur_done(sdev, h, &sshdr);
98-
else {
99-
sdev_printk(KERN_WARNING, sdev,
100-
"%s: sending tur failed with %x\n",
101-
HP_SW_NAME, res);
102-
ret = SCSI_DH_IO;
103-
}
104-
} else {
95+
if (res > 0 && scsi_sense_valid(&sshdr)) {
96+
ret = tur_done(sdev, h, &sshdr);
97+
} else if (res == 0) {
10598
h->path_state = HP_SW_PATH_ACTIVE;
10699
ret = SCSI_DH_OK;
100+
} else {
101+
sdev_printk(KERN_WARNING, sdev,
102+
"%s: sending tur failed with %x\n",
103+
HP_SW_NAME, res);
104+
ret = SCSI_DH_IO;
107105
}
106+
108107
if (ret == SCSI_DH_IMM_RETRY)
109108
goto retry;
110109

@@ -122,7 +121,7 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h)
122121
unsigned char cmd[6] = { START_STOP, 0, 0, 0, 1, 0 };
123122
struct scsi_sense_hdr sshdr;
124123
struct scsi_device *sdev = h->sdev;
125-
int res, rc = SCSI_DH_OK;
124+
int res, rc;
126125
int retry_cnt = HP_SW_RETRIES;
127126
blk_opf_t opf = REQ_OP_DRV_IN | REQ_FAILFAST_DEV |
128127
REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER;
@@ -133,35 +132,37 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h)
133132
retry:
134133
res = scsi_execute_cmd(sdev, cmd, opf, NULL, 0, HP_SW_TIMEOUT,
135134
HP_SW_RETRIES, &exec_args);
136-
if (res) {
137-
if (!scsi_sense_valid(&sshdr)) {
138-
sdev_printk(KERN_WARNING, sdev,
139-
"%s: sending start_stop_unit failed, "
140-
"no sense available\n", HP_SW_NAME);
141-
return SCSI_DH_IO;
142-
}
143-
switch (sshdr.sense_key) {
144-
case NOT_READY:
145-
if (sshdr.asc == 0x04 && sshdr.ascq == 3) {
146-
/*
147-
* LUN not ready - manual intervention required
148-
*
149-
* Switch-over in progress, retry.
150-
*/
151-
if (--retry_cnt)
152-
goto retry;
153-
rc = SCSI_DH_RETRY;
154-
break;
155-
}
156-
fallthrough;
157-
default:
158-
sdev_printk(KERN_WARNING, sdev,
159-
"%s: sending start_stop_unit failed, "
160-
"sense %x/%x/%x\n", HP_SW_NAME,
161-
sshdr.sense_key, sshdr.asc, sshdr.ascq);
162-
rc = SCSI_DH_IO;
135+
if (!res) {
136+
return SCSI_DH_OK;
137+
} else if (res < 0 || !scsi_sense_valid(&sshdr)) {
138+
sdev_printk(KERN_WARNING, sdev,
139+
"%s: sending start_stop_unit failed, "
140+
"no sense available\n", HP_SW_NAME);
141+
return SCSI_DH_IO;
142+
}
143+
144+
switch (sshdr.sense_key) {
145+
case NOT_READY:
146+
if (sshdr.asc == 0x04 && sshdr.ascq == 3) {
147+
/*
148+
* LUN not ready - manual intervention required
149+
*
150+
* Switch-over in progress, retry.
151+
*/
152+
if (--retry_cnt)
153+
goto retry;
154+
rc = SCSI_DH_RETRY;
155+
break;
163156
}
157+
fallthrough;
158+
default:
159+
sdev_printk(KERN_WARNING, sdev,
160+
"%s: sending start_stop_unit failed, "
161+
"sense %x/%x/%x\n", HP_SW_NAME,
162+
sshdr.sense_key, sshdr.asc, sshdr.ascq);
163+
rc = SCSI_DH_IO;
164164
}
165+
165166
return rc;
166167
}
167168

drivers/scsi/device_handler/scsi_dh_rdac.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ static void send_mode_select(struct work_struct *work)
530530
container_of(work, struct rdac_controller, ms_work);
531531
struct scsi_device *sdev = ctlr->ms_sdev;
532532
struct rdac_dh_data *h = sdev->handler_data;
533-
int err = SCSI_DH_OK, retry_cnt = RDAC_RETRY_COUNT;
533+
int rc, err, retry_cnt = RDAC_RETRY_COUNT;
534534
struct rdac_queue_data *tmp, *qdata;
535535
LIST_HEAD(list);
536536
unsigned char cdb[MAX_COMMAND_SIZE];
@@ -558,20 +558,23 @@ static void send_mode_select(struct work_struct *work)
558558
(char *) h->ctlr->array_name, h->ctlr->index,
559559
(retry_cnt == RDAC_RETRY_COUNT) ? "queueing" : "retrying");
560560

561-
if (scsi_execute_cmd(sdev, cdb, opf, &h->ctlr->mode_select, data_size,
562-
RDAC_TIMEOUT * HZ, RDAC_RETRIES, &exec_args)) {
561+
rc = scsi_execute_cmd(sdev, cdb, opf, &h->ctlr->mode_select, data_size,
562+
RDAC_TIMEOUT * HZ, RDAC_RETRIES, &exec_args);
563+
if (!rc) {
564+
h->state = RDAC_STATE_ACTIVE;
565+
RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, "
566+
"MODE_SELECT completed",
567+
(char *) h->ctlr->array_name, h->ctlr->index);
568+
err = SCSI_DH_OK;
569+
} else if (rc < 0) {
570+
err = SCSI_DH_IO;
571+
} else {
563572
err = mode_select_handle_sense(sdev, &sshdr);
564573
if (err == SCSI_DH_RETRY && retry_cnt--)
565574
goto retry;
566575
if (err == SCSI_DH_IMM_RETRY)
567576
goto retry;
568577
}
569-
if (err == SCSI_DH_OK) {
570-
h->state = RDAC_STATE_ACTIVE;
571-
RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, "
572-
"MODE_SELECT completed",
573-
(char *) h->ctlr->array_name, h->ctlr->index);
574-
}
575578

576579
list_for_each_entry_safe(qdata, tmp, &list, entry) {
577580
list_del(&qdata->entry);

drivers/scsi/scsi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ int scsi_cdl_enable(struct scsi_device *sdev, bool enable)
692692
ret = scsi_mode_select(sdev, 1, 0, buf_data, len, 5 * HZ, 3,
693693
&data, &sshdr);
694694
if (ret) {
695-
if (scsi_sense_valid(&sshdr))
695+
if (ret > 0 && scsi_sense_valid(&sshdr))
696696
scsi_print_sense_hdr(sdev,
697697
dev_name(&sdev->sdev_gendev), &sshdr);
698698
return ret;

drivers/scsi/scsi_lib.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2299,10 +2299,10 @@ scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries,
22992299
do {
23002300
result = scsi_execute_cmd(sdev, cmd, REQ_OP_DRV_IN, NULL, 0,
23012301
timeout, 1, &exec_args);
2302-
if (sdev->removable && scsi_sense_valid(sshdr) &&
2302+
if (sdev->removable && result > 0 && scsi_sense_valid(sshdr) &&
23032303
sshdr->sense_key == UNIT_ATTENTION)
23042304
sdev->changed = 1;
2305-
} while (scsi_sense_valid(sshdr) &&
2305+
} while (result > 0 && scsi_sense_valid(sshdr) &&
23062306
sshdr->sense_key == UNIT_ATTENTION && --retries);
23072307

23082308
return result;

drivers/scsi/scsi_transport_spi.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -676,10 +676,10 @@ spi_dv_device_echo_buffer(struct scsi_device *sdev, u8 *buffer,
676676
for (r = 0; r < retries; r++) {
677677
result = spi_execute(sdev, spi_write_buffer, REQ_OP_DRV_OUT,
678678
buffer, len, &sshdr);
679-
if(result || !scsi_device_online(sdev)) {
679+
if (result || !scsi_device_online(sdev)) {
680680

681681
scsi_device_set_state(sdev, SDEV_QUIESCE);
682-
if (scsi_sense_valid(&sshdr)
682+
if (result > 0 && scsi_sense_valid(&sshdr)
683683
&& sshdr.sense_key == ILLEGAL_REQUEST
684684
/* INVALID FIELD IN CDB */
685685
&& sshdr.asc == 0x24 && sshdr.ascq == 0x00)

drivers/scsi/sd.c

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ cache_type_store(struct device *dev, struct device_attribute *attr,
143143
struct scsi_mode_data data;
144144
struct scsi_sense_hdr sshdr;
145145
static const char temp[] = "temporary ";
146-
int len;
146+
int len, ret;
147147

148148
if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
149149
/* no cache control on RBC devices; theoretically they
@@ -190,9 +190,10 @@ cache_type_store(struct device *dev, struct device_attribute *attr,
190190
*/
191191
data.device_specific = 0;
192192

193-
if (scsi_mode_select(sdp, 1, sp, buffer_data, len, SD_TIMEOUT,
194-
sdkp->max_retries, &data, &sshdr)) {
195-
if (scsi_sense_valid(&sshdr))
193+
ret = scsi_mode_select(sdp, 1, sp, buffer_data, len, SD_TIMEOUT,
194+
sdkp->max_retries, &data, &sshdr);
195+
if (ret) {
196+
if (ret > 0 && scsi_sense_valid(&sshdr))
196197
sd_print_sense_hdr(sdkp, &sshdr);
197198
return -EINVAL;
198199
}
@@ -2180,19 +2181,21 @@ sd_spinup_disk(struct scsi_disk *sdkp)
21802181
sdkp->max_retries,
21812182
&exec_args);
21822183

2183-
/*
2184-
* If the drive has indicated to us that it
2185-
* doesn't have any media in it, don't bother
2186-
* with any more polling.
2187-
*/
2188-
if (media_not_present(sdkp, &sshdr)) {
2189-
if (media_was_present)
2190-
sd_printk(KERN_NOTICE, sdkp, "Media removed, stopped polling\n");
2191-
return;
2192-
}
2184+
if (the_result > 0) {
2185+
/*
2186+
* If the drive has indicated to us that it
2187+
* doesn't have any media in it, don't bother
2188+
* with any more polling.
2189+
*/
2190+
if (media_not_present(sdkp, &sshdr)) {
2191+
if (media_was_present)
2192+
sd_printk(KERN_NOTICE, sdkp,
2193+
"Media removed, stopped polling\n");
2194+
return;
2195+
}
21932196

2194-
if (the_result)
21952197
sense_valid = scsi_sense_valid(&sshdr);
2198+
}
21962199
retries++;
21972200
} while (retries < 3 &&
21982201
(!scsi_status_is_good(the_result) ||
@@ -2388,11 +2391,10 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
23882391
the_result = scsi_execute_cmd(sdp, cmd, REQ_OP_DRV_IN,
23892392
buffer, RC16_LEN, SD_TIMEOUT,
23902393
sdkp->max_retries, &exec_args);
2391-
2392-
if (media_not_present(sdkp, &sshdr))
2393-
return -ENODEV;
2394-
23952394
if (the_result > 0) {
2395+
if (media_not_present(sdkp, &sshdr))
2396+
return -ENODEV;
2397+
23962398
sense_valid = scsi_sense_valid(&sshdr);
23972399
if (sense_valid &&
23982400
sshdr.sense_key == ILLEGAL_REQUEST &&
@@ -2889,7 +2891,7 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
28892891
}
28902892

28912893
bad_sense:
2892-
if (scsi_sense_valid(&sshdr) &&
2894+
if (res == -EIO && scsi_sense_valid(&sshdr) &&
28932895
sshdr.sense_key == ILLEGAL_REQUEST &&
28942896
sshdr.asc == 0x24 && sshdr.ascq == 0x0)
28952897
/* Invalid field in CDB */
@@ -2937,7 +2939,7 @@ static void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer)
29372939
sd_first_printk(KERN_WARNING, sdkp,
29382940
"getting Control mode page failed, assume no ATO\n");
29392941

2940-
if (scsi_sense_valid(&sshdr))
2942+
if (res == -EIO && scsi_sense_valid(&sshdr))
29412943
sd_print_sense_hdr(sdkp, &sshdr);
29422944

29432945
return;

drivers/scsi/sr.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,8 @@ static unsigned int sr_get_events(struct scsi_device *sdev)
177177

178178
result = scsi_execute_cmd(sdev, cmd, REQ_OP_DRV_IN, buf, sizeof(buf),
179179
SR_TIMEOUT, MAX_RETRIES, &exec_args);
180-
if (scsi_sense_valid(&sshdr) && sshdr.sense_key == UNIT_ATTENTION)
180+
if (result > 0 && scsi_sense_valid(&sshdr) &&
181+
sshdr.sense_key == UNIT_ATTENTION)
181182
return DISK_EVENT_MEDIA_CHANGE;
182183

183184
if (result || be16_to_cpu(eh->data_len) < sizeof(*med))

0 commit comments

Comments
 (0)