return status;
}
+static void isci_remote_device_resume_from_abort_complete(void *cbparam)
+{
+ struct isci_remote_device *idev = cbparam;
+ struct isci_host *ihost = idev->owning_port->owning_controller;
+ scics_sds_remote_node_context_callback abort_resume_cb =
+ idev->abort_resume_cb;
+
+ dev_dbg(scirdev_to_dev(idev), "%s: passing-along resume: %p\n",
+ __func__, abort_resume_cb);
+
+ if (abort_resume_cb != NULL) {
+ idev->abort_resume_cb = NULL;
+ abort_resume_cb(idev->abort_resume_cbparam);
+ }
+ clear_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags);
+ wake_up(&ihost->eventq);
+}
+
+
+void isci_remote_device_wait_for_resume_from_abort(
+ struct isci_host *ihost,
+ struct isci_remote_device *idev)
+{
+ dev_dbg(scirdev_to_dev(idev), "%s: starting resume wait: %p\n",
+ __func__, idev);
+
+ #define MAX_RESUME_MSECS 5
+ if (!wait_event_timeout(ihost->eventq,
+ (!test_bit(IDEV_ABORT_PATH_RESUME_PENDING,
+ &idev->flags)
+ || test_bit(IDEV_STOP_PENDING, &idev->flags)),
+ msecs_to_jiffies(MAX_RESUME_MSECS))) {
+
+ dev_warn(scirdev_to_dev(idev), "%s: #### Timeout waiting for "
+ "resume: %p\n", __func__, idev);
+ }
+ clear_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags);
+
+ dev_dbg(scirdev_to_dev(idev), "%s: resume wait done: %p\n",
+ __func__, idev);
+}
+
enum sci_status isci_remote_device_resume_from_abort(
struct isci_host *ihost,
struct isci_remote_device *idev)
/* Preserve any current resume callbacks, for instance from other
* resumptions.
*/
+ idev->abort_resume_cb = idev->rnc.user_callback;
+ idev->abort_resume_cbparam = idev->rnc.user_cookie;
+ set_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags);
clear_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags);
- status = sci_remote_device_resume(idev, idev->rnc.user_callback,
- idev->rnc.user_cookie);
+ status = sci_remote_device_resume(
+ idev, isci_remote_device_resume_from_abort_complete,
+ idev);
spin_unlock_irqrestore(&ihost->scic_lock, flags);
+ isci_remote_device_wait_for_resume_from_abort(ihost, idev);
return status;
}
+
/**
* sci_remote_device_start() - This method will start the supplied remote
* device. This method enables normal IO requests to flow through to the