diff options
author | Jeff Skirvin <jeffrey.d.skirvin@intel.com> | 2012-03-13 20:15:11 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2012-05-17 17:33:44 -0400 |
commit | de2eb4d5c5c25e8fb75d1e19092f24b83cb7d8d5 (patch) | |
tree | 537fae73fbf34d34b5e83151a467275986ffb6b5 /drivers | |
parent | 6c6aacbb7787dccc6fb662bae66e599bbf0f07b5 (diff) |
isci: End the RNC resumption wait when the RNC is destroyed.
While the RNC is suspended for I/O cleanup, the remote device can be
stopped and the RNC setup for destruction. These changes accomodate that
case in the abort path.
Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/isci/host.h | 5 | ||||
-rw-r--r-- | drivers/scsi/isci/remote_device.c | 29 | ||||
-rw-r--r-- | drivers/scsi/isci/remote_node_context.c | 4 | ||||
-rw-r--r-- | drivers/scsi/isci/remote_node_context.h | 6 |
4 files changed, 33 insertions, 11 deletions
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h index 8e8b46322c64..9ab58e0540e7 100644 --- a/drivers/scsi/isci/host.h +++ b/drivers/scsi/isci/host.h | |||
@@ -340,6 +340,11 @@ static inline struct isci_host *dev_to_ihost(struct domain_device *dev) | |||
340 | return dev->port->ha->lldd_ha; | 340 | return dev->port->ha->lldd_ha; |
341 | } | 341 | } |
342 | 342 | ||
343 | static inline struct isci_host *idev_to_ihost(struct isci_remote_device *idev) | ||
344 | { | ||
345 | return dev_to_ihost(idev->domain_dev); | ||
346 | } | ||
347 | |||
343 | /* we always use protocol engine group zero */ | 348 | /* we always use protocol engine group zero */ |
344 | #define ISCI_PEG 0 | 349 | #define ISCI_PEG 0 |
345 | 350 | ||
diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c index a3a6487264ea..c3aa6c5457b9 100644 --- a/drivers/scsi/isci/remote_device.c +++ b/drivers/scsi/isci/remote_device.c | |||
@@ -1368,27 +1368,40 @@ static void isci_remote_device_resume_from_abort_complete(void *cbparam) | |||
1368 | wake_up(&ihost->eventq); | 1368 | wake_up(&ihost->eventq); |
1369 | } | 1369 | } |
1370 | 1370 | ||
1371 | static bool isci_remote_device_test_resume_done( | ||
1372 | struct isci_host *ihost, | ||
1373 | struct isci_remote_device *idev) | ||
1374 | { | ||
1375 | unsigned long flags; | ||
1376 | bool done; | ||
1377 | |||
1378 | spin_lock_irqsave(&ihost->scic_lock, flags); | ||
1379 | done = !test_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags) | ||
1380 | || test_bit(IDEV_STOP_PENDING, &idev->flags) | ||
1381 | || sci_remote_node_context_is_being_destroyed(&idev->rnc); | ||
1382 | spin_unlock_irqrestore(&ihost->scic_lock, flags); | ||
1383 | |||
1384 | return done; | ||
1385 | } | ||
1371 | 1386 | ||
1372 | void isci_remote_device_wait_for_resume_from_abort( | 1387 | void isci_remote_device_wait_for_resume_from_abort( |
1373 | struct isci_host *ihost, | 1388 | struct isci_host *ihost, |
1374 | struct isci_remote_device *idev) | 1389 | struct isci_remote_device *idev) |
1375 | { | 1390 | { |
1376 | dev_dbg(scirdev_to_dev(idev), "%s: starting resume wait: %p\n", | 1391 | dev_dbg(&ihost->pdev->dev, "%s: starting resume wait: %p\n", |
1377 | __func__, idev); | 1392 | __func__, idev); |
1378 | 1393 | ||
1379 | #define MAX_RESUME_MSECS 10000 | 1394 | #define MAX_RESUME_MSECS 10000 |
1380 | if (!wait_event_timeout(ihost->eventq, | 1395 | if (!wait_event_timeout(ihost->eventq, |
1381 | (!test_bit(IDEV_ABORT_PATH_RESUME_PENDING, | 1396 | isci_remote_device_test_resume_done(ihost, idev), |
1382 | &idev->flags) | 1397 | msecs_to_jiffies(MAX_RESUME_MSECS))) { |
1383 | || test_bit(IDEV_STOP_PENDING, &idev->flags)), | ||
1384 | msecs_to_jiffies(MAX_RESUME_MSECS))) { | ||
1385 | 1398 | ||
1386 | dev_warn(scirdev_to_dev(idev), "%s: #### Timeout waiting for " | 1399 | dev_warn(&ihost->pdev->dev, "%s: #### Timeout waiting for " |
1387 | "resume: %p\n", __func__, idev); | 1400 | "resume: %p\n", __func__, idev); |
1388 | } | 1401 | } |
1389 | clear_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags); | 1402 | clear_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags); |
1390 | 1403 | ||
1391 | dev_dbg(scirdev_to_dev(idev), "%s: resume wait done: %p\n", | 1404 | dev_dbg(&ihost->pdev->dev, "%s: resume wait done: %p\n", |
1392 | __func__, idev); | 1405 | __func__, idev); |
1393 | } | 1406 | } |
1394 | 1407 | ||
@@ -1414,7 +1427,7 @@ enum sci_status isci_remote_device_resume_from_abort( | |||
1414 | idev, isci_remote_device_resume_from_abort_complete, | 1427 | idev, isci_remote_device_resume_from_abort_complete, |
1415 | idev); | 1428 | idev); |
1416 | spin_unlock_irqrestore(&ihost->scic_lock, flags); | 1429 | spin_unlock_irqrestore(&ihost->scic_lock, flags); |
1417 | if (!destroyed) | 1430 | if (!destroyed && (status == SCI_SUCCESS)) |
1418 | isci_remote_device_wait_for_resume_from_abort(ihost, idev); | 1431 | isci_remote_device_wait_for_resume_from_abort(ihost, idev); |
1419 | else | 1432 | else |
1420 | clear_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags); | 1433 | clear_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags); |
diff --git a/drivers/scsi/isci/remote_node_context.c b/drivers/scsi/isci/remote_node_context.c index f5792a901e02..1910100638a2 100644 --- a/drivers/scsi/isci/remote_node_context.c +++ b/drivers/scsi/isci/remote_node_context.c | |||
@@ -190,9 +190,13 @@ static void sci_remote_node_context_setup_to_destroy( | |||
190 | scics_sds_remote_node_context_callback callback, | 190 | scics_sds_remote_node_context_callback callback, |
191 | void *callback_parameter) | 191 | void *callback_parameter) |
192 | { | 192 | { |
193 | struct isci_host *ihost = idev_to_ihost(rnc_to_dev(sci_rnc)); | ||
194 | |||
193 | sci_rnc->destination_state = RNC_DEST_FINAL; | 195 | sci_rnc->destination_state = RNC_DEST_FINAL; |
194 | sci_rnc->user_callback = callback; | 196 | sci_rnc->user_callback = callback; |
195 | sci_rnc->user_cookie = callback_parameter; | 197 | sci_rnc->user_cookie = callback_parameter; |
198 | |||
199 | wake_up(&ihost->eventq); | ||
196 | } | 200 | } |
197 | 201 | ||
198 | /** | 202 | /** |
diff --git a/drivers/scsi/isci/remote_node_context.h b/drivers/scsi/isci/remote_node_context.h index 0d4a24d647b4..a703b9ce0c2c 100644 --- a/drivers/scsi/isci/remote_node_context.h +++ b/drivers/scsi/isci/remote_node_context.h | |||
@@ -229,8 +229,8 @@ int sci_remote_node_context_is_safe_to_abort( | |||
229 | static inline bool sci_remote_node_context_is_being_destroyed( | 229 | static inline bool sci_remote_node_context_is_being_destroyed( |
230 | struct sci_remote_node_context *sci_rnc) | 230 | struct sci_remote_node_context *sci_rnc) |
231 | { | 231 | { |
232 | return ((sci_rnc->sm.current_state_id == SCI_RNC_INVALIDATING) | 232 | return (sci_rnc->destination_state == RNC_DEST_FINAL) |
233 | && (sci_rnc->destination_state == RNC_DEST_FINAL)) | 233 | || ((sci_rnc->sm.current_state_id == SCI_RNC_INITIAL) |
234 | || (sci_rnc->sm.current_state_id == SCI_RNC_INITIAL); | 234 | && (sci_rnc->destination_state == RNC_DEST_UNSPECIFIED)); |
235 | } | 235 | } |
236 | #endif /* _SCIC_SDS_REMOTE_NODE_CONTEXT_H_ */ | 236 | #endif /* _SCIC_SDS_REMOTE_NODE_CONTEXT_H_ */ |