]> Pileus Git - ~andy/linux/commitdiff
isci: Fixed RNC bug that lost the suspension or resumption during destroy
authorJeff Skirvin <jeffrey.d.skirvin@intel.com>
Wed, 14 Mar 2012 00:03:00 +0000 (17:03 -0700)
committerDan Williams <dan.j.williams@intel.com>
Thu, 17 May 2012 21:33:44 +0000 (14:33 -0700)
This fix corrects the saving of resume parameters when the destruction
of the RNC has already been directed, and makes sure not to overwrite
the RNC destruction callbacks.

Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
drivers/scsi/isci/remote_node_context.c

index 6f0b61b2cca820defae3bdd0a3782621834d2762..f5792a901e0205707b8278cb48a0b3c0bc563ebd 100644 (file)
@@ -160,15 +160,6 @@ static void sci_remote_node_context_construct_buffer(struct sci_remote_node_cont
        rnc->ssp.oaf_source_zone_group = 0;
        rnc->ssp.oaf_more_compatibility_features = 0;
 }
-
-static void sci_remote_node_context_save_cbparams(
-       struct sci_remote_node_context *sci_rnc,
-       scics_sds_remote_node_context_callback callback,
-       void *callback_parameter)
-{
-       sci_rnc->user_callback = callback;
-       sci_rnc->user_cookie   = callback_parameter;
-}
 /**
  *
  * @sci_rnc:
@@ -187,9 +178,10 @@ static void sci_remote_node_context_setup_to_resume(
 {
        if (sci_rnc->destination_state != RNC_DEST_FINAL) {
                sci_rnc->destination_state = dest_param;
-               if (callback != NULL)
-                       sci_remote_node_context_save_cbparams(
-                               sci_rnc, callback, callback_parameter);
+               if (callback != NULL) {
+                       sci_rnc->user_callback = callback;
+                       sci_rnc->user_cookie   = callback_parameter;
+               }
        }
 }
 
@@ -610,7 +602,8 @@ enum sci_status sci_remote_node_context_suspend(
                 * entry into the SCI_RNC_READY state that a suspension
                 * needs to be done immediately.
                 */
-               sci_rnc->destination_state = RNC_DEST_SUSPENDED;
+               if (sci_rnc->destination_state != RNC_DEST_FINAL)
+                       sci_rnc->destination_state = RNC_DEST_SUSPENDED;
                sci_rnc->suspend_type = suspend_type;
                sci_rnc->suspend_reason = suspend_reason;
                return SCI_SUCCESS;
@@ -680,12 +673,9 @@ enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *s
                if (sci_rnc->remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX)
                        return SCI_FAILURE_INVALID_STATE;
 
-               if (test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags))
-                       sci_remote_node_context_save_cbparams(sci_rnc, cb_fn,
-                                                             cb_p);
-               else {
-                       sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn,
-                                                       cb_p, RNC_DEST_READY);
+               sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p,
+                                                       RNC_DEST_READY);
+               if (!test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) {
                        sci_remote_node_context_construct_buffer(sci_rnc);
                        sci_change_state(&sci_rnc->sm, SCI_RNC_POSTING);
                }
@@ -694,38 +684,30 @@ enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *s
        case SCI_RNC_POSTING:
        case SCI_RNC_INVALIDATING:
        case SCI_RNC_RESUMING:
-               if (test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags))
-                       sci_remote_node_context_save_cbparams(sci_rnc, cb_fn,
-                                                             cb_p);
-               else {
-                       /* We are still waiting to post when a resume was
-                        * requested.
+               /* We are still waiting to post when a resume was
+                * requested.
+                */
+               switch (sci_rnc->destination_state) {
+               case RNC_DEST_SUSPENDED:
+               case RNC_DEST_SUSPENDED_RESUME:
+                       /* Previously waiting to suspend after posting.
+                        * Now continue onto resumption.
                         */
-                       switch (sci_rnc->destination_state) {
-                       case RNC_DEST_SUSPENDED:
-                       case RNC_DEST_SUSPENDED_RESUME:
-                               /* Previously waiting to suspend after posting.
-                                * Now continue onto resumption.
-                                */
-                               sci_remote_node_context_setup_to_resume(
-                                       sci_rnc, cb_fn, cb_p,
-                                       RNC_DEST_SUSPENDED_RESUME);
-                               break;
-                       default:
-                               sci_remote_node_context_setup_to_resume(
-                                       sci_rnc, cb_fn, cb_p,
-                                       RNC_DEST_READY);
-                               break;
-                       }
+                       sci_remote_node_context_setup_to_resume(
+                               sci_rnc, cb_fn, cb_p,
+                               RNC_DEST_SUSPENDED_RESUME);
+                       break;
+               default:
+                       sci_remote_node_context_setup_to_resume(
+                               sci_rnc, cb_fn, cb_p,
+                               RNC_DEST_READY);
+                       break;
                }
                return SCI_SUCCESS;
 
        case SCI_RNC_TX_SUSPENDED:
        case SCI_RNC_TX_RX_SUSPENDED:
-               if (test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags))
-                       sci_remote_node_context_save_cbparams(sci_rnc, cb_fn,
-                                                             cb_p);
-               else {
+               {
                        struct domain_device *dev = idev->domain_dev;
                        /* If this is an expander attached SATA device we must
                         * invalidate and repost the RNC since this is the only
@@ -735,23 +717,21 @@ enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *s
                        sci_remote_node_context_setup_to_resume(
                                sci_rnc, cb_fn, cb_p, RNC_DEST_READY);
 
-                       if (dev_is_sata(dev) && dev->parent)
-                               sci_change_state(&sci_rnc->sm,
-                                                SCI_RNC_INVALIDATING);
-                       else
-                               sci_change_state(&sci_rnc->sm,
-                                                SCI_RNC_RESUMING);
+                       if (!test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) {
+                               if ((dev_is_sata(dev) && dev->parent) ||
+                                   (sci_rnc->destination_state == RNC_DEST_FINAL))
+                                       sci_change_state(&sci_rnc->sm,
+                                                        SCI_RNC_INVALIDATING);
+                               else
+                                       sci_change_state(&sci_rnc->sm,
+                                                        SCI_RNC_RESUMING);
+                       }
                }
                return SCI_SUCCESS;
 
        case SCI_RNC_AWAIT_SUSPENSION:
-               if (test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags))
-                       sci_remote_node_context_save_cbparams(sci_rnc, cb_fn,
-                                                             cb_p);
-               else
-                       sci_remote_node_context_setup_to_resume(
-                               sci_rnc, cb_fn, cb_p,
-                               RNC_DEST_SUSPENDED_RESUME);
+               sci_remote_node_context_setup_to_resume(
+                       sci_rnc, cb_fn, cb_p, RNC_DEST_SUSPENDED_RESUME);
                return SCI_SUCCESS;
        default:
                dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),