summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/port.c
diff options
context:
space:
mode:
authorJeff Skirvin <jeffrey.d.skirvin@intel.com>2012-03-10 05:46:46 +0000
committerDan Williams <dan.j.williams@intel.com>2012-05-17 14:33:43 -0700
commit397497dd61948b0d59d1d21812b93c97b0eeb2dd (patch)
treef156de22337932cba5d5a4dedbb80bfa0054dd4c /drivers/scsi/isci/port.c
parent87805162b6af20d2ad386a49aec13b753cca523a (diff)
downloadlinux-397497dd61948b0d59d1d21812b93c97b0eeb2dd.tar.bz2
isci: Check IDEV_GONE before performing abort path operations.
In the link fail path, set IDEV_GONE for every device on the domain when the last link in the port fails. In the abort path functions like isci_reset_device, make sure that there has not already been a detected domain failure with the device by checking IDEV_GONE, before performing any kind of hard reset, SMP phy control, or TMF operation. The check for IDEV_GONE makes sure that the device in the abort path really has control of the port with which it is associated. This prevents starting hard resets at incorrect times and scheduling unnecessary LUN resets for SATA devices. 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/port.c')
-rw-r--r--drivers/scsi/isci/port.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c
index da0c4e1b9b30..2fb85bf75449 100644
--- a/drivers/scsi/isci/port.c
+++ b/drivers/scsi/isci/port.c
@@ -240,9 +240,32 @@ static void isci_port_link_down(struct isci_host *isci_host,
struct isci_phy *isci_phy,
struct isci_port *isci_port)
{
+ struct isci_remote_device *isci_device;
+
dev_dbg(&isci_host->pdev->dev,
"%s: isci_port = %p\n", __func__, isci_port);
+ if (isci_port) {
+
+ /* check to see if this is the last phy on this port. */
+ if (isci_phy->sas_phy.port &&
+ isci_phy->sas_phy.port->num_phys == 1) {
+ /* change the state for all devices on this port. The
+ * next task sent to this device will be returned as
+ * SAS_TASK_UNDELIVERED, and the scsi mid layer will
+ * remove the target
+ */
+ list_for_each_entry(isci_device,
+ &isci_port->remote_dev_list,
+ node) {
+ dev_dbg(&isci_host->pdev->dev,
+ "%s: isci_device = %p\n",
+ __func__, isci_device);
+ set_bit(IDEV_GONE, &isci_device->flags);
+ }
+ }
+ }
+
/* Notify libsas of the borken link, this will trigger calls to our
* isci_port_deformed and isci_dev_gone functions.
*/