]> Pileus Git - ~andy/linux/commitdiff
isci: Manage the LLHANG timer enable/disable per-device.
authorJeff Skirvin <jeffrey.d.skirvin@intel.com>
Fri, 9 Mar 2012 06:42:00 +0000 (22:42 -0800)
committerDan Williams <dan.j.williams@intel.com>
Thu, 17 May 2012 21:33:40 +0000 (14:33 -0700)
The LLHANG timer should be enabled once per device.  This patch corrects
both the timer enable and the timer disable for the remote device.

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
drivers/scsi/isci/remote_device.h
drivers/scsi/isci/remote_node_context.c

index 1a85e9edef6ad30a7d658a1e378b16b3367c18c6..86aca11120f3f0a27bde9743e87af4aaf18bb300 100644 (file)
@@ -1520,3 +1520,20 @@ enum sci_status isci_remote_device_reset_complete(
        return status;
 }
 
+void isci_dev_set_hang_detection_timeout(
+       struct isci_remote_device *idev,
+       u32 timeout)
+{
+       if (dev_is_sata(idev->domain_dev)) {
+               if (timeout) {
+                       if (test_and_set_bit(IDEV_RNC_LLHANG_ENABLED,
+                                            &idev->flags))
+                               return;  /* Already enabled. */
+               } else if (!test_and_clear_bit(IDEV_RNC_LLHANG_ENABLED,
+                                              &idev->flags))
+                       return;  /* Not enabled. */
+
+               sci_port_set_hang_detection_timeout(idev->owning_port,
+                                                   timeout);
+       }
+}
index 8b7817cf4352f635f1182c69828c788c9255d099..ef563e5360a3c5264061dc7fdfe383086948b841 100644 (file)
@@ -85,6 +85,7 @@ struct isci_remote_device {
        #define IDEV_GONE 3
        #define IDEV_IO_READY 4
        #define IDEV_IO_NCQERROR 5
+       #define IDEV_RNC_LLHANG_ENABLED 6
        unsigned long flags;
        struct kref kref;
        struct isci_port *isci_port;
@@ -308,12 +309,7 @@ static inline void sci_remote_device_decrement_request_count(struct isci_remote_
                idev->started_request_count--;
 }
 
-static inline void isci_dev_set_hang_detection_timeout(
-       struct isci_remote_device *idev,
-       u32 timeout)
-{
-       sci_port_set_hang_detection_timeout(idev->owning_port, timeout);
-}
+void isci_dev_set_hang_detection_timeout(struct isci_remote_device *idev, u32 timeout);
 
 enum sci_status sci_remote_device_frame_handler(
        struct isci_remote_device *idev,
index 2ac92608cc2d5b121475f83ee347a67465f22ea6..48565de50016cc35e874289ad1baebc49c66fd25 100644 (file)
@@ -615,8 +615,7 @@ enum sci_status sci_remote_node_context_suspend(
        if ((suspend_reason == SCI_SW_SUSPEND_NORMAL) ||
            (suspend_reason == SCI_SW_SUSPEND_LINKHANG_DETECT)) {
 
-               if ((suspend_reason == SCI_SW_SUSPEND_LINKHANG_DETECT)
-                && dev_is_sata(idev->domain_dev))
+               if (suspend_reason == SCI_SW_SUSPEND_LINKHANG_DETECT)
                        isci_dev_set_hang_detection_timeout(idev, 0x00000001);
 
                sci_remote_device_post_request(