aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/isci
diff options
context:
space:
mode:
authorJeff Skirvin <jeffrey.d.skirvin@intel.com>2012-03-08 22:42:00 -0800
committerDan Williams <dan.j.williams@intel.com>2012-05-17 14:33:40 -0700
commit9608b6408e637abeec101abb6aebd3343f0ebac4 (patch)
tree4c06b2ed04c61c2e76dd7d663a54b7cc1ae0717f /drivers/scsi/isci
parent447bfbcee070a0b43dd6abc743063d7a02fe65ca (diff)
isci: Manage the LLHANG timer enable/disable per-device.
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>
Diffstat (limited to 'drivers/scsi/isci')
-rw-r--r--drivers/scsi/isci/remote_device.c17
-rw-r--r--drivers/scsi/isci/remote_device.h8
-rw-r--r--drivers/scsi/isci/remote_node_context.c3
3 files changed, 20 insertions, 8 deletions
diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c
index 1a85e9edef6..86aca11120f 100644
--- a/drivers/scsi/isci/remote_device.c
+++ b/drivers/scsi/isci/remote_device.c
@@ -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);
+ }
+}
diff --git a/drivers/scsi/isci/remote_device.h b/drivers/scsi/isci/remote_device.h
index 8b7817cf435..ef563e5360a 100644
--- a/drivers/scsi/isci/remote_device.h
+++ b/drivers/scsi/isci/remote_device.h
@@ -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,
diff --git a/drivers/scsi/isci/remote_node_context.c b/drivers/scsi/isci/remote_node_context.c
index 2ac92608cc2..48565de5001 100644
--- a/drivers/scsi/isci/remote_node_context.c
+++ b/drivers/scsi/isci/remote_node_context.c
@@ -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(