From: Jeff Skirvin Date: Fri, 9 Mar 2012 06:42:00 +0000 (-0800) Subject: isci: Manage the LLHANG timer enable/disable per-device. X-Git-Tag: next-20120417~47^2^3~19 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=876f3f84f55a28e846ef30ec828576d31c48cf94;p=karo-tx-linux.git 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 Signed-off-by: Dan Williams --- diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c index 1a85e9edef6a..86aca11120f3 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 8b7817cf4352..ef563e5360a3 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 2ac92608cc2d..48565de50016 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(