diff options
| -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_ */ |
