aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci
diff options
context:
space:
mode:
authorJeff Skirvin <jeffrey.d.skirvin@intel.com>2012-03-09 01:41:52 -0500
committerDan Williams <dan.j.williams@intel.com>2012-05-17 17:33:37 -0400
commit23ec2aa947e83d0a172220f361166b8224875221 (patch)
tree747e299efb5c534d99bc84b9631dedec02b033aa /drivers/scsi/isci
parent5b6bf225e7fc249c703e19bf2c983d1a59178874 (diff)
isci: Remote device must be suspended for NCQ cleanup.
When the remote device enters the NCQ error state, the device must be suspended so that the I/O terminations can take place. 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.c25
1 files changed, 12 insertions, 13 deletions
diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c
index 4f76dcd1cec2..f40d429d2cc0 100644
--- a/drivers/scsi/isci/remote_device.c
+++ b/drivers/scsi/isci/remote_device.c
@@ -72,6 +72,14 @@ const char *dev_state_name(enum sci_remote_device_states state)
72} 72}
73#undef C 73#undef C
74 74
75static enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev)
76{
77 return sci_remote_node_context_suspend(&idev->rnc,
78 SCI_SOFTWARE_SUSPENSION,
79 SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT,
80 NULL, NULL);
81}
82
75/** 83/**
76 * isci_remote_device_not_ready() - This function is called by the ihost when 84 * isci_remote_device_not_ready() - This function is called by the ihost when
77 * the remote device is not ready. We mark the isci device as ready (not 85 * the remote device is not ready. We mark the isci device as ready (not
@@ -96,6 +104,9 @@ static void isci_remote_device_not_ready(struct isci_host *ihost,
96 case SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED: 104 case SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED:
97 set_bit(IDEV_IO_NCQERROR, &idev->flags); 105 set_bit(IDEV_IO_NCQERROR, &idev->flags);
98 106
107 /* Suspend the remote device so the I/O can be terminated. */
108 sci_remote_device_suspend(idev);
109
99 /* Kill all outstanding requests for the device. */ 110 /* Kill all outstanding requests for the device. */
100 list_for_each_entry(ireq, &idev->reqs_in_process, dev_node) { 111 list_for_each_entry(ireq, &idev->reqs_in_process, dev_node) {
101 112
@@ -103,9 +114,7 @@ static void isci_remote_device_not_ready(struct isci_host *ihost,
103 "%s: isci_device = %p request = %p\n", 114 "%s: isci_device = %p request = %p\n",
104 __func__, idev, ireq); 115 __func__, idev, ireq);
105 116
106 sci_controller_terminate_request(ihost, 117 sci_controller_terminate_request(ihost, idev, ireq);
107 idev,
108 ireq);
109 } 118 }
110 /* Fall through into the default case... */ 119 /* Fall through into the default case... */
111 default: 120 default:
@@ -133,16 +142,6 @@ static void isci_remote_device_ready(struct isci_host *ihost, struct isci_remote
133 wake_up(&ihost->eventq); 142 wake_up(&ihost->eventq);
134} 143}
135 144
136static enum sci_status sci_remote_device_suspend(
137 struct isci_remote_device *idev)
138{
139 return sci_remote_node_context_suspend(
140 &idev->rnc,
141 SCI_SOFTWARE_SUSPENSION,
142 SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT,
143 NULL, NULL);
144}
145
146static int isci_remote_device_suspendcheck(struct isci_remote_device *idev) 145static int isci_remote_device_suspendcheck(struct isci_remote_device *idev)
147{ 146{
148 return test_bit(IDEV_TXRX_SUSPENDED, &idev->flags) 147 return test_bit(IDEV_TXRX_SUSPENDED, &idev->flags)