diff options
author | Hannes Reinecke <hare@suse.de> | 2013-11-11 07:44:54 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-12-19 10:39:02 -0500 |
commit | e494f6a728394ab0df194342549ee20e6f0752df (patch) | |
tree | 2cbae9eea944540b2777e40f1787a90b78123334 /include | |
parent | 2451079bc2ae1334058be8babd44be03ecfa7041 (diff) |
[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')
-rw-r--r-- | include/scsi/scsi_cmnd.h | 1 | ||||
-rw-r--r-- | include/scsi/scsi_host.h | 10 |
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 { | |||
55 | struct scsi_device *device; | 55 | struct scsi_device *device; |
56 | struct list_head list; /* scsi_cmnd participates in queue lists */ | 56 | struct list_head list; /* scsi_cmnd participates in queue lists */ |
57 | struct list_head eh_entry; /* entry for the host eh_cmd_q */ | 57 | struct list_head eh_entry; /* entry for the host eh_cmd_q */ |
58 | struct delayed_work abort_work; | ||
58 | int eh_eflags; /* Used by error handlr */ | 59 | int eh_eflags; /* Used by error handlr */ |
59 | 60 | ||
60 | /* | 61 | /* |
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 { | |||
479 | unsigned no_write_same:1; | 479 | unsigned no_write_same:1; |
480 | 480 | ||
481 | /* | 481 | /* |
482 | * True if asynchronous aborts are not supported | ||
483 | */ | ||
484 | unsigned no_async_abort:1; | ||
485 | |||
486 | /* | ||
482 | * Countdown for host blocking with no commands outstanding. | 487 | * Countdown for host blocking with no commands outstanding. |
483 | */ | 488 | */ |
484 | unsigned int max_host_blocked; | 489 | unsigned int max_host_blocked; |
@@ -690,6 +695,11 @@ struct Scsi_Host { | |||
690 | struct workqueue_struct *work_q; | 695 | struct workqueue_struct *work_q; |
691 | 696 | ||
692 | /* | 697 | /* |
698 | * Task management function work queue | ||
699 | */ | ||
700 | struct workqueue_struct *tmf_work_q; | ||
701 | |||
702 | /* | ||
693 | * Host has rejected a command because it was busy. | 703 | * Host has rejected a command because it was busy. |
694 | */ | 704 | */ |
695 | unsigned int host_blocked; | 705 | unsigned int host_blocked; |