From e8f76e190ffc1cf2a956e4976c11ba062c2b1b75 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Tue, 19 Aug 2008 18:45:31 -0500 Subject: [PATCH] --- yaml --- r: 115449 b: refs/heads/master c: 4a27446f3e39b06c28d1c8e31d33a5340826ed5c h: refs/heads/master i: 115447: d7b6057bdcdfcde16269c2eda3d1f9f3bea6472b v: v3 --- [refs] | 2 +- trunk/drivers/scsi/scsi_error.c | 38 +++++++++++++++++++++++++++++++-- trunk/drivers/scsi/scsi_lib.c | 2 +- trunk/drivers/scsi/scsi_priv.h | 1 + 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index cf82cfba4b1e..c520f1db3684 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6000a368cd8e6da1caf101411bdb494cd6fb8b09 +refs/heads/master: 4a27446f3e39b06c28d1c8e31d33a5340826ed5c diff --git a/trunk/drivers/scsi/scsi_error.c b/trunk/drivers/scsi/scsi_error.c index 5bf8be21a165..ad019ece2139 100644 --- a/trunk/drivers/scsi/scsi_error.c +++ b/trunk/drivers/scsi/scsi_error.c @@ -1218,6 +1218,40 @@ static void scsi_eh_offline_sdevs(struct list_head *work_q, return; } +/** + * scsi_noretry_cmd - determinte if command should be failed fast + * @scmd: SCSI cmd to examine. + */ +int scsi_noretry_cmd(struct scsi_cmnd *scmd) +{ + switch (host_byte(scmd->result)) { + case DID_OK: + break; + case DID_BUS_BUSY: + return blk_failfast_transport(scmd->request); + case DID_PARITY: + return blk_failfast_dev(scmd->request); + case DID_ERROR: + if (msg_byte(scmd->result) == COMMAND_COMPLETE && + status_byte(scmd->result) == RESERVATION_CONFLICT) + return 0; + /* fall through */ + case DID_SOFT_ERROR: + return blk_failfast_driver(scmd->request); + } + + switch (status_byte(scmd->result)) { + case CHECK_CONDITION: + /* + * assume caller has checked sense and determinted + * the check condition was retryable. + */ + return blk_failfast_dev(scmd->request); + } + + return 0; +} + /** * scsi_decide_disposition - Disposition a cmd on return from LLD. * @scmd: SCSI cmd to examine. @@ -1396,7 +1430,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd) * even if the request is marked fast fail, we still requeue * for queue congestion conditions (QUEUE_FULL or BUSY) */ if ((++scmd->retries) <= scmd->allowed - && !blk_noretry_request(scmd->request)) { + && !scsi_noretry_cmd(scmd)) { return NEEDS_RETRY; } else { /* @@ -1521,7 +1555,7 @@ void scsi_eh_flush_done_q(struct list_head *done_q) list_for_each_entry_safe(scmd, next, done_q, eh_entry) { list_del_init(&scmd->eh_entry); if (scsi_device_online(scmd->device) && - !blk_noretry_request(scmd->request) && + !scsi_noretry_cmd(scmd) && (++scmd->retries <= scmd->allowed)) { SCSI_LOG_ERROR_RECOVERY(3, printk("%s: flush" " retry cmd: %p\n", diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index 91c74c55aa5e..e5a9526d2037 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -706,7 +706,7 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int error, leftover = req->data_len; /* kill remainder if no retrys */ - if (error && blk_noretry_request(req)) + if (error && scsi_noretry_cmd(cmd)) blk_end_request(req, error, leftover); else { if (requeue) { diff --git a/trunk/drivers/scsi/scsi_priv.h b/trunk/drivers/scsi/scsi_priv.h index 6cddd5dd323c..e1850904ff73 100644 --- a/trunk/drivers/scsi/scsi_priv.h +++ b/trunk/drivers/scsi/scsi_priv.h @@ -59,6 +59,7 @@ void scsi_eh_ready_devs(struct Scsi_Host *shost, struct list_head *done_q); int scsi_eh_get_sense(struct list_head *work_q, struct list_head *done_q); +int scsi_noretry_cmd(struct scsi_cmnd *scmd); /* scsi_lib.c */ extern int scsi_maybe_unblock_host(struct scsi_device *sdev);