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
commit83884014eaaa68834ced39d1c75f1bc20d618ec0 (patch)
tree1a54f8c3b64b95938d0499412a37c780ecb84c5f /drivers/scsi/isci
parent23ec2aa947e83d0a172220f361166b8224875221 (diff)
isci: Remote device stop also suspends the RNC and terminates I/O.
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>
Diffstat (limited to 'drivers/scsi/isci')
-rw-r--r--drivers/scsi/isci/remote_device.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c
index f40d429d2cc0..3048e02aeb7b 100644
--- a/drivers/scsi/isci/remote_device.c
+++ b/drivers/scsi/isci/remote_device.c
@@ -263,13 +263,15 @@ enum sci_status sci_remote_device_stop(struct isci_remote_device *idev,
263 case SCI_SMP_DEV_IDLE: 263 case SCI_SMP_DEV_IDLE:
264 case SCI_SMP_DEV_CMD: 264 case SCI_SMP_DEV_CMD:
265 sci_change_state(sm, SCI_DEV_STOPPING); 265 sci_change_state(sm, SCI_DEV_STOPPING);
266 if (idev->started_request_count == 0) { 266 if (idev->started_request_count == 0)
267 sci_remote_node_context_destruct(&idev->rnc, 267 sci_remote_node_context_destruct(&idev->rnc,
268 rnc_destruct_done, idev); 268 rnc_destruct_done,
269 return SCI_SUCCESS; 269 idev);
270 } else 270 else {
271 return sci_remote_device_terminate_requests(idev); 271 sci_remote_device_suspend(idev);
272 break; 272 sci_remote_device_terminate_requests(idev);
273 }
274 return SCI_SUCCESS;
273 case SCI_DEV_STOPPING: 275 case SCI_DEV_STOPPING:
274 /* All requests should have been terminated, but if there is an 276 /* All requests should have been terminated, but if there is an
275 * attempt to stop a device already in the stopping state, then 277 * 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
1403 spin_lock_irqsave(&ihost->scic_lock, flags); 1405 spin_lock_irqsave(&ihost->scic_lock, flags);
1404 idev->domain_dev->lldd_dev = NULL; /* disable new lookups */ 1406 idev->domain_dev->lldd_dev = NULL; /* disable new lookups */
1405 set_bit(IDEV_GONE, &idev->flags); 1407 set_bit(IDEV_GONE, &idev->flags);
1406 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1407
1408 /* Kill all outstanding requests. */
1409 isci_remote_device_nuke_requests(ihost, idev);
1410 1408
1411 set_bit(IDEV_STOP_PENDING, &idev->flags); 1409 set_bit(IDEV_STOP_PENDING, &idev->flags);
1412
1413 spin_lock_irqsave(&ihost->scic_lock, flags);
1414 status = sci_remote_device_stop(idev, 50); 1410 status = sci_remote_device_stop(idev, 50);
1415 spin_unlock_irqrestore(&ihost->scic_lock, flags); 1411 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1416 1412
@@ -1420,6 +1416,9 @@ enum sci_status isci_remote_device_stop(struct isci_host *ihost, struct isci_rem
1420 else 1416 else
1421 wait_for_device_stop(ihost, idev); 1417 wait_for_device_stop(ihost, idev);
1422 1418
1419 dev_dbg(&ihost->pdev->dev,
1420 "%s: isci_device = %p, waiting done.\n", __func__, idev);
1421
1423 return status; 1422 return status;
1424} 1423}
1425 1424