diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-02-18 12:25:07 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 06:55:27 -0400 |
commit | 0cf89d1d27c1bdd0abf1714096f98ea44704dcff (patch) | |
tree | 0bee9fa05aba8a6e1fe4b6b50a3bfc6d0793356f /drivers/scsi/isci/host.h | |
parent | c7ef4031f01301298bbaba2666740183cd399f8c (diff) |
isci: cleanup "starting" state handling
The lldd actively disallows requests in the "starting" state. Retrying
or holding off commands in this state is sub-optimal:
1/ it adds another state check to the fast path
2/ retrying can cause libsas to give up
However, isci's ->lldd_dev_found() routine already waits for controller
start to complete before allowing further progress. Checking the
"starting" state in isci_task_execute_task and the isr is redundant and
misleading. Clean this up and introduce a controller-wide event queue
to start reeling in "completion" proliferation in the driver.
The "stopping" state cleanups are in a similar vein, rely on the the isr
and other paths being precluded from occurring rather than implementing
state checking logic.
Reported-by: Christoph Hellwig <hch@infradead.org>
Cc: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Edmund Nadolski <edmund.nadolski@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi/isci/host.h')
-rw-r--r-- | drivers/scsi/isci/host.h | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h index 421d3debdaed..26768c5bbe01 100644 --- a/drivers/scsi/isci/host.h +++ b/drivers/scsi/isci/host.h | |||
@@ -109,13 +109,15 @@ struct isci_host { | |||
109 | u8 sas_addr[SAS_ADDR_SIZE]; | 109 | u8 sas_addr[SAS_ADDR_SIZE]; |
110 | 110 | ||
111 | enum isci_status status; | 111 | enum isci_status status; |
112 | #define IHOST_START_PENDING 0 | ||
113 | #define IHOST_STOP_PENDING 1 | ||
114 | unsigned long flags; | ||
115 | wait_queue_head_t eventq; | ||
112 | struct Scsi_Host *shost; | 116 | struct Scsi_Host *shost; |
113 | struct tasklet_struct completion_tasklet; | 117 | struct tasklet_struct completion_tasklet; |
114 | struct list_head mdl_struct_list; | 118 | struct list_head mdl_struct_list; |
115 | struct list_head requests_to_complete; | 119 | struct list_head requests_to_complete; |
116 | struct list_head requests_to_abort; | 120 | struct list_head requests_to_abort; |
117 | struct completion stop_complete; | ||
118 | struct completion start_complete; | ||
119 | spinlock_t scic_lock; | 121 | spinlock_t scic_lock; |
120 | struct isci_host *next; | 122 | struct isci_host *next; |
121 | }; | 123 | }; |
@@ -202,6 +204,17 @@ static inline void isci_host_can_dequeue( | |||
202 | spin_unlock_irqrestore(&isci_host->queue_lock, flags); | 204 | spin_unlock_irqrestore(&isci_host->queue_lock, flags); |
203 | } | 205 | } |
204 | 206 | ||
207 | static inline void wait_for_start(struct isci_host *ihost) | ||
208 | { | ||
209 | wait_event(ihost->eventq, !test_bit(IHOST_START_PENDING, &ihost->flags)); | ||
210 | } | ||
211 | |||
212 | static inline void wait_for_stop(struct isci_host *ihost) | ||
213 | { | ||
214 | wait_event(ihost->eventq, !test_bit(IHOST_STOP_PENDING, &ihost->flags)); | ||
215 | } | ||
216 | |||
217 | |||
205 | /** | 218 | /** |
206 | * isci_host_from_sas_ha() - This accessor retrieves the isci_host object | 219 | * isci_host_from_sas_ha() - This accessor retrieves the isci_host object |
207 | * reference from the Linux sas_ha_struct reference. | 220 | * reference from the Linux sas_ha_struct reference. |