isci: Terminate dev requests on FIS err bit rx in NCQ
When the remote device transitions to a not-ready state because of an NCQ error condition, all outstanding requests to that device are terminated and completed to libsas on the normal path. The device then waits for a READ LOG EXT command to issue on the task management path. Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:

committed by
Dan Williams

parent
4cffe13e0d
commit
9274f45ea5
@@ -68,17 +68,39 @@
|
||||
* @isci_host: This parameter specifies the isci host object.
|
||||
* @isci_device: This parameter specifies the remote device
|
||||
*
|
||||
* scic_lock is held on entrance to this function.
|
||||
*/
|
||||
static void isci_remote_device_not_ready(struct isci_host *ihost,
|
||||
struct isci_remote_device *idev, u32 reason)
|
||||
{
|
||||
struct isci_request * ireq;
|
||||
|
||||
dev_dbg(&ihost->pdev->dev,
|
||||
"%s: isci_device = %p\n", __func__, idev);
|
||||
|
||||
if (reason == SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED)
|
||||
switch (reason) {
|
||||
case SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED:
|
||||
set_bit(IDEV_GONE, &idev->flags);
|
||||
else
|
||||
break;
|
||||
case SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED:
|
||||
set_bit(IDEV_IO_NCQERROR, &idev->flags);
|
||||
|
||||
/* Kill all outstanding requests for the device. */
|
||||
list_for_each_entry(ireq, &idev->reqs_in_process, dev_node) {
|
||||
|
||||
dev_dbg(&ihost->pdev->dev,
|
||||
"%s: isci_device = %p request = %p\n",
|
||||
__func__, idev, ireq);
|
||||
|
||||
scic_controller_terminate_request(&ihost->sci,
|
||||
&idev->sci,
|
||||
&ireq->sci);
|
||||
}
|
||||
/* Fall through into the default case... */
|
||||
default:
|
||||
clear_bit(IDEV_IO_READY, &idev->flags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,6 +116,7 @@ static void isci_remote_device_ready(struct isci_host *ihost, struct isci_remote
|
||||
dev_dbg(&ihost->pdev->dev,
|
||||
"%s: idev = %p\n", __func__, idev);
|
||||
|
||||
clear_bit(IDEV_IO_NCQERROR, &idev->flags);
|
||||
set_bit(IDEV_IO_READY, &idev->flags);
|
||||
if (test_and_clear_bit(IDEV_START_PENDING, &idev->flags))
|
||||
wake_up(&ihost->eventq);
|
||||
|
Reference in New Issue
Block a user