]> Pileus Git - ~andy/linux/commitdiff
isci: Remote device stop also suspends the RNC and terminates I/O.
authorJeff Skirvin <jeffrey.d.skirvin@intel.com>
Fri, 9 Mar 2012 06:41:52 +0000 (22:41 -0800)
committerDan Williams <dan.j.williams@intel.com>
Thu, 17 May 2012 21:33:37 +0000 (14:33 -0700)
Fixing the remote device state machine to suspend and terminate
all outstanding I/O before the device stopped state is reached.

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

index f40d429d2cc0ae040bc3ee55ef52f3cca89bedf4..3048e02aeb7b1bc155c46505658005e4d13f384e 100644 (file)
@@ -263,13 +263,15 @@ enum sci_status sci_remote_device_stop(struct isci_remote_device *idev,
        case SCI_SMP_DEV_IDLE:
        case SCI_SMP_DEV_CMD:
                sci_change_state(sm, SCI_DEV_STOPPING);
-               if (idev->started_request_count == 0) {
+               if (idev->started_request_count == 0)
                        sci_remote_node_context_destruct(&idev->rnc,
-                                                             rnc_destruct_done, idev);
-                       return SCI_SUCCESS;
-               } else
-                       return sci_remote_device_terminate_requests(idev);
-               break;
+                                                        rnc_destruct_done,
+                                                        idev);
+               else {
+                       sci_remote_device_suspend(idev);
+                       sci_remote_device_terminate_requests(idev);
+               }
+               return SCI_SUCCESS;
        case SCI_DEV_STOPPING:
                /* All requests should have been terminated, but if there is an
                 * attempt to stop a device already in the stopping state, then
@@ -1403,14 +1405,8 @@ enum sci_status isci_remote_device_stop(struct isci_host *ihost, struct isci_rem
        spin_lock_irqsave(&ihost->scic_lock, flags);
        idev->domain_dev->lldd_dev = NULL; /* disable new lookups */
        set_bit(IDEV_GONE, &idev->flags);
-       spin_unlock_irqrestore(&ihost->scic_lock, flags);
-
-       /* Kill all outstanding requests. */
-       isci_remote_device_nuke_requests(ihost, idev);
 
        set_bit(IDEV_STOP_PENDING, &idev->flags);
-
-       spin_lock_irqsave(&ihost->scic_lock, flags);
        status = sci_remote_device_stop(idev, 50);
        spin_unlock_irqrestore(&ihost->scic_lock, flags);
 
@@ -1420,6 +1416,9 @@ enum sci_status isci_remote_device_stop(struct isci_host *ihost, struct isci_rem
        else
                wait_for_device_stop(ihost, idev);
 
+       dev_dbg(&ihost->pdev->dev,
+               "%s: isci_device = %p, waiting done.\n", __func__, idev);
+
        return status;
 }