aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/scsi_error.c26
-rw-r--r--drivers/scsi/sd.c26
-rw-r--r--include/scsi/scsi_driver.h2
3 files changed, 30 insertions, 24 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index e8bee9f0ad0f..67c001457cb8 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -941,12 +941,6 @@ retry:
941 941
942 scsi_eh_restore_cmnd(scmd, &ses); 942 scsi_eh_restore_cmnd(scmd, &ses);
943 943
944 if (scmd->request->cmd_type != REQ_TYPE_BLOCK_PC) {
945 struct scsi_driver *sdrv = scsi_cmd_to_driver(scmd);
946 if (sdrv->eh_action)
947 rtn = sdrv->eh_action(scmd, cmnd, cmnd_size, rtn);
948 }
949
950 return rtn; 944 return rtn;
951} 945}
952 946
@@ -964,6 +958,16 @@ static int scsi_request_sense(struct scsi_cmnd *scmd)
964 return scsi_send_eh_cmnd(scmd, NULL, 0, scmd->device->eh_timeout, ~0); 958 return scsi_send_eh_cmnd(scmd, NULL, 0, scmd->device->eh_timeout, ~0);
965} 959}
966 960
961static int scsi_eh_action(struct scsi_cmnd *scmd, int rtn)
962{
963 if (scmd->request->cmd_type != REQ_TYPE_BLOCK_PC) {
964 struct scsi_driver *sdrv = scsi_cmd_to_driver(scmd);
965 if (sdrv->eh_action)
966 rtn = sdrv->eh_action(scmd, rtn);
967 }
968 return rtn;
969}
970
967/** 971/**
968 * scsi_eh_finish_cmd - Handle a cmd that eh is finished with. 972 * scsi_eh_finish_cmd - Handle a cmd that eh is finished with.
969 * @scmd: Original SCSI cmd that eh has finished. 973 * @scmd: Original SCSI cmd that eh has finished.
@@ -1142,7 +1146,9 @@ static int scsi_eh_test_devices(struct list_head *cmd_list,
1142 1146
1143 list_for_each_entry_safe(scmd, next, cmd_list, eh_entry) 1147 list_for_each_entry_safe(scmd, next, cmd_list, eh_entry)
1144 if (scmd->device == sdev) { 1148 if (scmd->device == sdev) {
1145 if (finish_cmds) 1149 if (finish_cmds &&
1150 (try_stu ||
1151 scsi_eh_action(scmd, SUCCESS) == SUCCESS))
1146 scsi_eh_finish_cmd(scmd, done_q); 1152 scsi_eh_finish_cmd(scmd, done_q);
1147 else 1153 else
1148 list_move_tail(&scmd->eh_entry, work_q); 1154 list_move_tail(&scmd->eh_entry, work_q);
@@ -1283,7 +1289,8 @@ static int scsi_eh_stu(struct Scsi_Host *shost,
1283 !scsi_eh_tur(stu_scmd)) { 1289 !scsi_eh_tur(stu_scmd)) {
1284 list_for_each_entry_safe(scmd, next, 1290 list_for_each_entry_safe(scmd, next,
1285 work_q, eh_entry) { 1291 work_q, eh_entry) {
1286 if (scmd->device == sdev) 1292 if (scmd->device == sdev &&
1293 scsi_eh_action(scmd, SUCCESS) == SUCCESS)
1287 scsi_eh_finish_cmd(scmd, done_q); 1294 scsi_eh_finish_cmd(scmd, done_q);
1288 } 1295 }
1289 } 1296 }
@@ -1350,7 +1357,8 @@ static int scsi_eh_bus_device_reset(struct Scsi_Host *shost,
1350 !scsi_eh_tur(bdr_scmd)) { 1357 !scsi_eh_tur(bdr_scmd)) {
1351 list_for_each_entry_safe(scmd, next, 1358 list_for_each_entry_safe(scmd, next,
1352 work_q, eh_entry) { 1359 work_q, eh_entry) {
1353 if (scmd->device == sdev) 1360 if (scmd->device == sdev &&
1361 scsi_eh_action(scmd, rtn) != FAILED)
1354 scsi_eh_finish_cmd(scmd, 1362 scsi_eh_finish_cmd(scmd,
1355 done_q); 1363 done_q);
1356 } 1364 }
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 69725f7c32c1..35a785609364 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -110,7 +110,7 @@ static int sd_suspend_runtime(struct device *);
110static int sd_resume(struct device *); 110static int sd_resume(struct device *);
111static void sd_rescan(struct device *); 111static void sd_rescan(struct device *);
112static int sd_done(struct scsi_cmnd *); 112static int sd_done(struct scsi_cmnd *);
113static int sd_eh_action(struct scsi_cmnd *, unsigned char *, int, int); 113static int sd_eh_action(struct scsi_cmnd *, int);
114static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer); 114static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer);
115static void scsi_disk_release(struct device *cdev); 115static void scsi_disk_release(struct device *cdev);
116static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); 116static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *);
@@ -1551,23 +1551,23 @@ static const struct block_device_operations sd_fops = {
1551/** 1551/**
1552 * sd_eh_action - error handling callback 1552 * sd_eh_action - error handling callback
1553 * @scmd: sd-issued command that has failed 1553 * @scmd: sd-issued command that has failed
1554 * @eh_cmnd: The command that was sent during error handling
1555 * @eh_cmnd_len: Length of eh_cmnd in bytes
1556 * @eh_disp: The recovery disposition suggested by the midlayer 1554 * @eh_disp: The recovery disposition suggested by the midlayer
1557 * 1555 *
1558 * This function is called by the SCSI midlayer upon completion of 1556 * This function is called by the SCSI midlayer upon completion of an
1559 * an error handling command (TEST UNIT READY, START STOP UNIT, 1557 * error test command (currently TEST UNIT READY). The result of sending
1560 * etc.) The command sent to the device by the error handler is 1558 * the eh command is passed in eh_disp. We're looking for devices that
1561 * stored in eh_cmnd. The result of sending the eh command is 1559 * fail medium access commands but are OK with non access commands like
1562 * passed in eh_disp. 1560 * test unit ready (so wrongly see the device as having a successful
1561 * recovery)
1563 **/ 1562 **/
1564static int sd_eh_action(struct scsi_cmnd *scmd, unsigned char *eh_cmnd, 1563static int sd_eh_action(struct scsi_cmnd *scmd, int eh_disp)
1565 int eh_cmnd_len, int eh_disp)
1566{ 1564{
1567 struct scsi_disk *sdkp = scsi_disk(scmd->request->rq_disk); 1565 struct scsi_disk *sdkp = scsi_disk(scmd->request->rq_disk);
1568 1566
1569 if (!scsi_device_online(scmd->device) || 1567 if (!scsi_device_online(scmd->device) ||
1570 !scsi_medium_access_command(scmd)) 1568 !scsi_medium_access_command(scmd) ||
1569 host_byte(scmd->result) != DID_TIME_OUT ||
1570 eh_disp != SUCCESS)
1571 return eh_disp; 1571 return eh_disp;
1572 1572
1573 /* 1573 /*
@@ -1577,9 +1577,7 @@ static int sd_eh_action(struct scsi_cmnd *scmd, unsigned char *eh_cmnd,
1577 * process of recovering or has it suffered an internal failure 1577 * process of recovering or has it suffered an internal failure
1578 * that prevents access to the storage medium. 1578 * that prevents access to the storage medium.
1579 */ 1579 */
1580 if (host_byte(scmd->result) == DID_TIME_OUT && eh_disp == SUCCESS && 1580 sdkp->medium_access_timed_out++;
1581 eh_cmnd_len && eh_cmnd[0] == TEST_UNIT_READY)
1582 sdkp->medium_access_timed_out++;
1583 1581
1584 /* 1582 /*
1585 * If the device keeps failing read/write commands but TEST UNIT 1583 * If the device keeps failing read/write commands but TEST UNIT
diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h
index d443aa06a722..20fdfc2526ad 100644
--- a/include/scsi/scsi_driver.h
+++ b/include/scsi/scsi_driver.h
@@ -16,7 +16,7 @@ struct scsi_driver {
16 16
17 void (*rescan)(struct device *); 17 void (*rescan)(struct device *);
18 int (*done)(struct scsi_cmnd *); 18 int (*done)(struct scsi_cmnd *);
19 int (*eh_action)(struct scsi_cmnd *, unsigned char *, int, int); 19 int (*eh_action)(struct scsi_cmnd *, int);
20}; 20};
21#define to_scsi_driver(drv) \ 21#define to_scsi_driver(drv) \
22 container_of((drv), struct scsi_driver, gendrv) 22 container_of((drv), struct scsi_driver, gendrv)