diff mbox series

[07/13] scsi: hisi_sas: Init disks after controller reset

Message ID 1526897365-228549-8-git-send-email-john.garry@huawei.com
State New
Headers show
Series hisi_sas: Misc improvements, bugfixes, etc. | expand

Commit Message

John Garry May 21, 2018, 10:09 a.m. UTC
From: Xiaofei Tan <tanxiaofei@huawei.com>


After the controller is reset, it is possible that the
disks attached still have outstanding IO to complete.

Thus, when the PHYs come back up after controller reset, it
is possible that these IOs complete at some unknown point
later.

We want to ensure that all IOs are complete after the
controller reset so that all associated IPTT and other
resources can be recycled safely.

To achieve this, re-init the disks by TMF or softreset
(in case of ATA devices).

If the init fails - maybe because the device was removed
or link has not come up - then do not release the device
resources, but rather rely on SCSI EH to handle the timeout
for these resources later on.

This patch also does some cleanup to hisi_sas_init_disk(), including
removing superfluous cases in the switch statement.

Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>

Signed-off-by: John Garry <john.garry@huawei.com>

---
 drivers/scsi/hisi_sas/hisi_sas_main.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

-- 
1.9.1
diff mbox series

Patch

diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 7b8623b..0dfefdf 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -1259,6 +1259,23 @@  static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 old_state,
 	}
 }
 
+static void hisi_sas_reset_init_all_devices(struct hisi_hba *hisi_hba)
+{
+	struct hisi_sas_device *sas_dev;
+	struct domain_device *device;
+	int i;
+
+	for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) {
+		sas_dev = &hisi_hba->devices[i];
+		device = sas_dev->sas_device;
+
+		if ((sas_dev->dev_type == SAS_PHY_UNUSED) || !device)
+			continue;
+
+		hisi_sas_init_device(device);
+	}
+}
+
 static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
 {
 	struct device *dev = hisi_hba->dev;
@@ -1287,7 +1304,6 @@  static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
 		scsi_unblock_requests(shost);
 		goto out;
 	}
-	hisi_sas_release_tasks(hisi_hba);
 
 	clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
 
@@ -1295,6 +1311,7 @@  static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
 	hisi_hba->hw->phys_init(hisi_hba);
 	msleep(1000);
 	hisi_sas_refresh_port_id(hisi_hba);
+	hisi_sas_reset_init_all_devices(hisi_hba);
 	scsi_unblock_requests(shost);
 
 	state = hisi_hba->hw->get_phys_state(hisi_hba);