summaryrefslogtreecommitdiffstats
path: root/include/scsi
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2013-11-11 13:44:54 +0100
committerJames Bottomley <JBottomley@Parallels.com>2013-12-19 07:39:02 -0800
commite494f6a728394ab0df194342549ee20e6f0752df (patch)
tree2cbae9eea944540b2777e40f1787a90b78123334 /include/scsi
parent2451079bc2ae1334058be8babd44be03ecfa7041 (diff)
downloadlinux-e494f6a728394ab0df194342549ee20e6f0752df.tar.gz
linux-e494f6a728394ab0df194342549ee20e6f0752df.tar.bz2
linux-e494f6a728394ab0df194342549ee20e6f0752df.zip
[SCSI] improved eh timeout handler
When a command runs into a timeout we need to send an 'ABORT TASK' TMF. This is typically done by the 'eh_abort_handler' LLDD callback. Conceptually, however, this function is a normal SCSI command, so there is no need to enter the error handler. This patch implements a new scsi_abort_command() function which invokes an asynchronous function scsi_eh_abort_handler() to abort the commands via the usual 'eh_abort_handler'. If abort succeeds the command is either retried or terminated, depending on the number of allowed retries. However, 'eh_eflags' records the abort, so if the retry would fail again the command is pushed onto the error handler without trying to abort it (again); it'll be cleared up from SCSI EH. [hare: smatch detected stray switch fixed] Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'include/scsi')
-rw-r--r--include/scsi/scsi_cmnd.h1
-rw-r--r--include/scsi/scsi_host.h10
2 files changed, 11 insertions, 0 deletions
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index de5f5d8f1f8a..91558a1f97f4 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -55,6 +55,7 @@ struct scsi_cmnd {
struct scsi_device *device;
struct list_head list; /* scsi_cmnd participates in queue lists */
struct list_head eh_entry; /* entry for the host eh_cmd_q */
+ struct delayed_work abort_work;
int eh_eflags; /* Used by error handlr */
/*
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index fe3b58e836c8..53075e5039e6 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -479,6 +479,11 @@ struct scsi_host_template {
unsigned no_write_same:1;
/*
+ * True if asynchronous aborts are not supported
+ */
+ unsigned no_async_abort:1;
+
+ /*
* Countdown for host blocking with no commands outstanding.
*/
unsigned int max_host_blocked;
@@ -690,6 +695,11 @@ struct Scsi_Host {
struct workqueue_struct *work_q;
/*
+ * Task management function work queue
+ */
+ struct workqueue_struct *tmf_work_q;
+
+ /*
* Host has rejected a command because it was busy.
*/
unsigned int host_blocked;