diff options
-rw-r--r-- | drivers/scsi/isci/port.h | 1 | ||||
-rw-r--r-- | drivers/scsi/isci/remote_device.c | 27 | ||||
-rw-r--r-- | drivers/scsi/isci/remote_device.h | 22 | ||||
-rw-r--r-- | drivers/scsi/isci/task.c | 49 |
4 files changed, 8 insertions, 91 deletions
diff --git a/drivers/scsi/isci/port.h b/drivers/scsi/isci/port.h index b01b0c63e53f..b864d70363e7 100644 --- a/drivers/scsi/isci/port.h +++ b/drivers/scsi/isci/port.h | |||
@@ -73,7 +73,6 @@ enum isci_status { | |||
73 | isci_ready_for_io = 0x03, | 73 | isci_ready_for_io = 0x03, |
74 | isci_stopping = 0x04, | 74 | isci_stopping = 0x04, |
75 | isci_stopped = 0x05, | 75 | isci_stopped = 0x05, |
76 | isci_host_quiesce = 0x06 | ||
77 | }; | 76 | }; |
78 | 77 | ||
79 | /** | 78 | /** |
diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c index 0eb5c7330fac..fc1f24449170 100644 --- a/drivers/scsi/isci/remote_device.c +++ b/drivers/scsi/isci/remote_device.c | |||
@@ -267,36 +267,13 @@ isci_remote_device_alloc(struct isci_host *isci_host, struct isci_port *port) | |||
267 | 267 | ||
268 | INIT_LIST_HEAD(&isci_device->reqs_in_process); | 268 | INIT_LIST_HEAD(&isci_device->reqs_in_process); |
269 | INIT_LIST_HEAD(&isci_device->node); | 269 | INIT_LIST_HEAD(&isci_device->node); |
270 | isci_device->host_quiesce = false; | ||
271 | 270 | ||
272 | spin_lock_init(&isci_device->state_lock); | 271 | spin_lock_init(&isci_device->state_lock); |
273 | spin_lock_init(&isci_device->host_quiesce_lock); | ||
274 | isci_remote_device_change_state(isci_device, isci_freed); | 272 | isci_remote_device_change_state(isci_device, isci_freed); |
275 | 273 | ||
276 | return isci_device; | 274 | return isci_device; |
277 | 275 | ||
278 | } | 276 | } |
279 | /** | ||
280 | * isci_device_set_host_quiesce_lock_state() - This function sets the host I/O | ||
281 | * quiesce lock state for the remote_device object. | ||
282 | * @isci_device,: This parameter points to the isci_remote_device object | ||
283 | * @isci_device: This parameter specifies the new quiesce state. | ||
284 | * | ||
285 | */ | ||
286 | void isci_device_set_host_quiesce_lock_state( | ||
287 | struct isci_remote_device *isci_device, | ||
288 | bool lock_state) | ||
289 | { | ||
290 | unsigned long flags; | ||
291 | |||
292 | dev_dbg(&isci_device->isci_port->isci_host->pdev->dev, | ||
293 | "%s: isci_device=%p, lock_state=%d\n", | ||
294 | __func__, isci_device, lock_state); | ||
295 | |||
296 | spin_lock_irqsave(&isci_device->host_quiesce_lock, flags); | ||
297 | isci_device->host_quiesce = lock_state; | ||
298 | spin_unlock_irqrestore(&isci_device->host_quiesce_lock, flags); | ||
299 | } | ||
300 | 277 | ||
301 | /** | 278 | /** |
302 | * isci_remote_device_ready() - This function is called by the scic when the | 279 | * isci_remote_device_ready() - This function is called by the scic when the |
@@ -314,8 +291,8 @@ void isci_remote_device_ready(struct isci_remote_device *isci_device) | |||
314 | "%s: isci_device = %p\n", __func__, isci_device); | 291 | "%s: isci_device = %p\n", __func__, isci_device); |
315 | 292 | ||
316 | /* device ready is actually a "ready for io" state. */ | 293 | /* device ready is actually a "ready for io" state. */ |
317 | if ((isci_starting == isci_remote_device_get_state(isci_device)) || | 294 | if (isci_device->status == isci_starting || |
318 | (isci_ready == isci_remote_device_get_state(isci_device))) { | 295 | isci_device->status == isci_ready) { |
319 | spin_lock_irqsave(&isci_device->isci_port->remote_device_lock, | 296 | spin_lock_irqsave(&isci_device->isci_port->remote_device_lock, |
320 | flags); | 297 | flags); |
321 | isci_remote_device_change_state(isci_device, isci_ready_for_io); | 298 | isci_remote_device_change_state(isci_device, isci_ready_for_io); |
diff --git a/drivers/scsi/isci/remote_device.h b/drivers/scsi/isci/remote_device.h index cd43c15f009d..af03039c12f1 100644 --- a/drivers/scsi/isci/remote_device.h +++ b/drivers/scsi/isci/remote_device.h | |||
@@ -68,8 +68,6 @@ struct isci_remote_device { | |||
68 | struct list_head reqs_in_process; | 68 | struct list_head reqs_in_process; |
69 | struct work_struct stop_work; | 69 | struct work_struct stop_work; |
70 | spinlock_t state_lock; | 70 | spinlock_t state_lock; |
71 | spinlock_t host_quiesce_lock; | ||
72 | bool host_quiesce; | ||
73 | }; | 71 | }; |
74 | 72 | ||
75 | static inline struct scic_sds_remote_device *to_sci_dev(struct isci_remote_device *idev) | 73 | static inline struct scic_sds_remote_device *to_sci_dev(struct isci_remote_device *idev) |
@@ -85,22 +83,6 @@ static inline struct scic_sds_remote_device *to_sci_dev(struct isci_remote_devic | |||
85 | 83 | ||
86 | 84 | ||
87 | /** | 85 | /** |
88 | * This function gets the status of the remote_device object. | ||
89 | * @isci_device: This parameter points to the isci_remote_device object | ||
90 | * | ||
91 | * status of the object as a isci_status enum. | ||
92 | */ | ||
93 | static inline | ||
94 | enum isci_status isci_remote_device_get_state( | ||
95 | struct isci_remote_device *isci_device) | ||
96 | { | ||
97 | return (isci_device->host_quiesce) | ||
98 | ? isci_host_quiesce | ||
99 | : isci_device->status; | ||
100 | } | ||
101 | |||
102 | |||
103 | /** | ||
104 | * isci_dev_from_domain_dev() - This accessor retrieves the remote_device | 86 | * isci_dev_from_domain_dev() - This accessor retrieves the remote_device |
105 | * object reference from the Linux domain_device reference. | 87 | * object reference from the Linux domain_device reference. |
106 | * @domdev,: This parameter points to the Linux domain_device object . | 88 | * @domdev,: This parameter points to the Linux domain_device object . |
@@ -146,10 +128,6 @@ bool isci_device_is_reset_pending( | |||
146 | void isci_device_clear_reset_pending( | 128 | void isci_device_clear_reset_pending( |
147 | struct isci_remote_device *isci_device); | 129 | struct isci_remote_device *isci_device); |
148 | 130 | ||
149 | void isci_device_set_host_quiesce_lock_state( | ||
150 | struct isci_remote_device *isci_device, | ||
151 | bool lock_state); | ||
152 | |||
153 | void isci_remote_device_change_state( | 131 | void isci_remote_device_change_state( |
154 | struct isci_remote_device *isci_device, | 132 | struct isci_remote_device *isci_device, |
155 | enum isci_status status); | 133 | enum isci_status status); |
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c index c637bbc215c6..98204b031649 100644 --- a/drivers/scsi/isci/task.c +++ b/drivers/scsi/isci/task.c | |||
@@ -81,7 +81,6 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) | |||
81 | struct isci_request *request = NULL; | 81 | struct isci_request *request = NULL; |
82 | struct isci_remote_device *device; | 82 | struct isci_remote_device *device; |
83 | unsigned long flags; | 83 | unsigned long flags; |
84 | unsigned long quiesce_flags = 0; | ||
85 | int ret; | 84 | int ret; |
86 | enum sci_status status; | 85 | enum sci_status status; |
87 | 86 | ||
@@ -151,21 +150,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) | |||
151 | 150 | ||
152 | isci_host = isci_host_from_sas_ha(task->dev->port->ha); | 151 | isci_host = isci_host_from_sas_ha(task->dev->port->ha); |
153 | 152 | ||
154 | /* check if the controller hasn't started or if the device | 153 | if (device && device->status == isci_ready) { |
155 | * is ready but not accepting IO. | ||
156 | */ | ||
157 | if (device) { | ||
158 | |||
159 | spin_lock_irqsave(&device->host_quiesce_lock, | ||
160 | quiesce_flags); | ||
161 | } | ||
162 | /* From this point onward, any process that needs to guarantee | ||
163 | * that there is no kernel I/O being started will have to wait | ||
164 | * for the quiesce spinlock. | ||
165 | */ | ||
166 | |||
167 | if ((device && ((isci_remote_device_get_state(device) == isci_ready) || | ||
168 | (isci_remote_device_get_state(device) == isci_host_quiesce)))) { | ||
169 | 154 | ||
170 | /* Forces a retry from scsi mid layer. */ | 155 | /* Forces a retry from scsi mid layer. */ |
171 | dev_warn(task->dev->port->ha->dev, | 156 | dev_warn(task->dev->port->ha->dev, |
@@ -179,8 +164,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) | |||
179 | if (device) | 164 | if (device) |
180 | dev_dbg(task->dev->port->ha->dev, | 165 | dev_dbg(task->dev->port->ha->dev, |
181 | "%s: device->status = 0x%x\n", | 166 | "%s: device->status = 0x%x\n", |
182 | __func__, | 167 | __func__, device->status); |
183 | isci_remote_device_get_state(device)); | ||
184 | 168 | ||
185 | /* Indicate QUEUE_FULL so that the scsi midlayer | 169 | /* Indicate QUEUE_FULL so that the scsi midlayer |
186 | * retries. | 170 | * retries. |
@@ -194,7 +178,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) | |||
194 | isci_host_can_dequeue(isci_host, 1); | 178 | isci_host_can_dequeue(isci_host, 1); |
195 | } | 179 | } |
196 | /* the device is going down... */ | 180 | /* the device is going down... */ |
197 | else if (!device || (isci_ready_for_io != isci_remote_device_get_state(device))) { | 181 | else if (!device || device->status != isci_ready_for_io) { |
198 | 182 | ||
199 | dev_dbg(task->dev->port->ha->dev, | 183 | dev_dbg(task->dev->port->ha->dev, |
200 | "%s: task %p: isci_host->status = %d, " | 184 | "%s: task %p: isci_host->status = %d, " |
@@ -207,8 +191,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) | |||
207 | if (device) | 191 | if (device) |
208 | dev_dbg(task->dev->port->ha->dev, | 192 | dev_dbg(task->dev->port->ha->dev, |
209 | "%s: device->status = 0x%x\n", | 193 | "%s: device->status = 0x%x\n", |
210 | __func__, | 194 | __func__, device->status); |
211 | isci_remote_device_get_state(device)); | ||
212 | 195 | ||
213 | /* Indicate SAS_TASK_UNDELIVERED, so that the scsi | 196 | /* Indicate SAS_TASK_UNDELIVERED, so that the scsi |
214 | * midlayer removes the target. | 197 | * midlayer removes the target. |
@@ -247,11 +230,6 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) | |||
247 | isci_host_can_dequeue(isci_host, 1); | 230 | isci_host_can_dequeue(isci_host, 1); |
248 | } | 231 | } |
249 | } | 232 | } |
250 | if (device) { | ||
251 | spin_unlock_irqrestore(&device->host_quiesce_lock, | ||
252 | quiesce_flags | ||
253 | ); | ||
254 | } | ||
255 | task = list_entry(task->list.next, struct sas_task, list); | 233 | task = list_entry(task->list.next, struct sas_task, list); |
256 | } while (--num > 0); | 234 | } while (--num > 0); |
257 | return 0; | 235 | return 0; |
@@ -442,14 +420,11 @@ int isci_task_execute_tmf( | |||
442 | /* sanity check, return TMF_RESP_FUNC_FAILED | 420 | /* sanity check, return TMF_RESP_FUNC_FAILED |
443 | * if the device is not there and ready. | 421 | * if the device is not there and ready. |
444 | */ | 422 | */ |
445 | if (!isci_device || | 423 | if (!isci_device || isci_device->status != isci_ready_for_io) { |
446 | ((isci_ready_for_io != isci_remote_device_get_state(isci_device)) && | ||
447 | (isci_host_quiesce != isci_remote_device_get_state(isci_device)))) { | ||
448 | dev_dbg(&isci_host->pdev->dev, | 424 | dev_dbg(&isci_host->pdev->dev, |
449 | "%s: isci_device = %p not ready (%d)\n", | 425 | "%s: isci_device = %p not ready (%d)\n", |
450 | __func__, | 426 | __func__, |
451 | isci_device, | 427 | isci_device, isci_device->status); |
452 | isci_remote_device_get_state(isci_device)); | ||
453 | return TMF_RESP_FUNC_FAILED; | 428 | return TMF_RESP_FUNC_FAILED; |
454 | } else | 429 | } else |
455 | dev_dbg(&isci_host->pdev->dev, | 430 | dev_dbg(&isci_host->pdev->dev, |
@@ -986,9 +961,6 @@ int isci_task_lu_reset( | |||
986 | return TMF_RESP_FUNC_FAILED; | 961 | return TMF_RESP_FUNC_FAILED; |
987 | } | 962 | } |
988 | 963 | ||
989 | /* Stop I/O to the remote device. */ | ||
990 | isci_device_set_host_quiesce_lock_state(isci_device, true); | ||
991 | |||
992 | /* Send the task management part of the reset. */ | 964 | /* Send the task management part of the reset. */ |
993 | if (sas_protocol_ata(domain_device->tproto)) { | 965 | if (sas_protocol_ata(domain_device->tproto)) { |
994 | ret = isci_task_send_lu_reset_sata( | 966 | ret = isci_task_send_lu_reset_sata( |
@@ -1004,9 +976,6 @@ int isci_task_lu_reset( | |||
1004 | isci_device, | 976 | isci_device, |
1005 | terminating); | 977 | terminating); |
1006 | 978 | ||
1007 | /* Resume I/O to the remote device. */ | ||
1008 | isci_device_set_host_quiesce_lock_state(isci_device, false); | ||
1009 | |||
1010 | return ret; | 979 | return ret; |
1011 | } | 980 | } |
1012 | 981 | ||
@@ -1627,9 +1596,6 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd) | |||
1627 | if (isci_host != NULL) | 1596 | if (isci_host != NULL) |
1628 | spin_unlock_irqrestore(&isci_host->scic_lock, flags); | 1597 | spin_unlock_irqrestore(&isci_host->scic_lock, flags); |
1629 | 1598 | ||
1630 | /* Stop I/O to the remote device. */ | ||
1631 | isci_device_set_host_quiesce_lock_state(isci_dev, true); | ||
1632 | |||
1633 | /* Make sure all pending requests are able to be fully terminated. */ | 1599 | /* Make sure all pending requests are able to be fully terminated. */ |
1634 | isci_device_clear_reset_pending(isci_dev); | 1600 | isci_device_clear_reset_pending(isci_dev); |
1635 | 1601 | ||
@@ -1671,8 +1637,5 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd) | |||
1671 | "%s: cmd %p, isci_dev %p complete.\n", | 1637 | "%s: cmd %p, isci_dev %p complete.\n", |
1672 | __func__, cmd, isci_dev); | 1638 | __func__, cmd, isci_dev); |
1673 | 1639 | ||
1674 | /* Resume I/O to the remote device. */ | ||
1675 | isci_device_set_host_quiesce_lock_state(isci_dev, false); | ||
1676 | |||
1677 | return TMF_RESP_FUNC_COMPLETE; | 1640 | return TMF_RESP_FUNC_COMPLETE; |
1678 | } | 1641 | } |