diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/scsi_error.c | 38 | ||||
-rw-r--r-- | drivers/scsi/scsi_lib.c | 2 | ||||
-rw-r--r-- | drivers/scsi/scsi_priv.h | 1 |
3 files changed, 38 insertions, 3 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 5bf8be21a165..ad019ece2139 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -1219,6 +1219,40 @@ static void scsi_eh_offline_sdevs(struct list_head *work_q, | |||
1219 | } | 1219 | } |
1220 | 1220 | ||
1221 | /** | 1221 | /** |
1222 | * scsi_noretry_cmd - determinte if command should be failed fast | ||
1223 | * @scmd: SCSI cmd to examine. | ||
1224 | */ | ||
1225 | int scsi_noretry_cmd(struct scsi_cmnd *scmd) | ||
1226 | { | ||
1227 | switch (host_byte(scmd->result)) { | ||
1228 | case DID_OK: | ||
1229 | break; | ||
1230 | case DID_BUS_BUSY: | ||
1231 | return blk_failfast_transport(scmd->request); | ||
1232 | case DID_PARITY: | ||
1233 | return blk_failfast_dev(scmd->request); | ||
1234 | case DID_ERROR: | ||
1235 | if (msg_byte(scmd->result) == COMMAND_COMPLETE && | ||
1236 | status_byte(scmd->result) == RESERVATION_CONFLICT) | ||
1237 | return 0; | ||
1238 | /* fall through */ | ||
1239 | case DID_SOFT_ERROR: | ||
1240 | return blk_failfast_driver(scmd->request); | ||
1241 | } | ||
1242 | |||
1243 | switch (status_byte(scmd->result)) { | ||
1244 | case CHECK_CONDITION: | ||
1245 | /* | ||
1246 | * assume caller has checked sense and determinted | ||
1247 | * the check condition was retryable. | ||
1248 | */ | ||
1249 | return blk_failfast_dev(scmd->request); | ||
1250 | } | ||
1251 | |||
1252 | return 0; | ||
1253 | } | ||
1254 | |||
1255 | /** | ||
1222 | * scsi_decide_disposition - Disposition a cmd on return from LLD. | 1256 | * scsi_decide_disposition - Disposition a cmd on return from LLD. |
1223 | * @scmd: SCSI cmd to examine. | 1257 | * @scmd: SCSI cmd to examine. |
1224 | * | 1258 | * |
@@ -1396,7 +1430,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd) | |||
1396 | * even if the request is marked fast fail, we still requeue | 1430 | * even if the request is marked fast fail, we still requeue |
1397 | * for queue congestion conditions (QUEUE_FULL or BUSY) */ | 1431 | * for queue congestion conditions (QUEUE_FULL or BUSY) */ |
1398 | if ((++scmd->retries) <= scmd->allowed | 1432 | if ((++scmd->retries) <= scmd->allowed |
1399 | && !blk_noretry_request(scmd->request)) { | 1433 | && !scsi_noretry_cmd(scmd)) { |
1400 | return NEEDS_RETRY; | 1434 | return NEEDS_RETRY; |
1401 | } else { | 1435 | } else { |
1402 | /* | 1436 | /* |
@@ -1521,7 +1555,7 @@ void scsi_eh_flush_done_q(struct list_head *done_q) | |||
1521 | list_for_each_entry_safe(scmd, next, done_q, eh_entry) { | 1555 | list_for_each_entry_safe(scmd, next, done_q, eh_entry) { |
1522 | list_del_init(&scmd->eh_entry); | 1556 | list_del_init(&scmd->eh_entry); |
1523 | if (scsi_device_online(scmd->device) && | 1557 | if (scsi_device_online(scmd->device) && |
1524 | !blk_noretry_request(scmd->request) && | 1558 | !scsi_noretry_cmd(scmd) && |
1525 | (++scmd->retries <= scmd->allowed)) { | 1559 | (++scmd->retries <= scmd->allowed)) { |
1526 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: flush" | 1560 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: flush" |
1527 | " retry cmd: %p\n", | 1561 | " retry cmd: %p\n", |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 91c74c55aa5e..e5a9526d2037 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -706,7 +706,7 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int error, | |||
706 | leftover = req->data_len; | 706 | leftover = req->data_len; |
707 | 707 | ||
708 | /* kill remainder if no retrys */ | 708 | /* kill remainder if no retrys */ |
709 | if (error && blk_noretry_request(req)) | 709 | if (error && scsi_noretry_cmd(cmd)) |
710 | blk_end_request(req, error, leftover); | 710 | blk_end_request(req, error, leftover); |
711 | else { | 711 | else { |
712 | if (requeue) { | 712 | if (requeue) { |
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 6cddd5dd323c..e1850904ff73 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h | |||
@@ -59,6 +59,7 @@ void scsi_eh_ready_devs(struct Scsi_Host *shost, | |||
59 | struct list_head *done_q); | 59 | struct list_head *done_q); |
60 | int scsi_eh_get_sense(struct list_head *work_q, | 60 | int scsi_eh_get_sense(struct list_head *work_q, |
61 | struct list_head *done_q); | 61 | struct list_head *done_q); |
62 | int scsi_noretry_cmd(struct scsi_cmnd *scmd); | ||
62 | 63 | ||
63 | /* scsi_lib.c */ | 64 | /* scsi_lib.c */ |
64 | extern int scsi_maybe_unblock_host(struct scsi_device *sdev); | 65 | extern int scsi_maybe_unblock_host(struct scsi_device *sdev); |