]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
scsi: hisi_sas: Init disks after controller reset
authorXiaofei Tan <tanxiaofei@huawei.com>
Mon, 21 May 2018 10:09:19 +0000 (18:09 +0800)
committerKhalid Elmously <khalid.elmously@canonical.com>
Wed, 6 Jun 2018 19:13:29 +0000 (15:13 -0400)
BugLink: https://bugs.launchpad.net/bugs/1774466
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>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
(cherry picked from commit 6175abdeaeaf2602f3e92bd4eca5916e98efe996 linux-next)
Signed-off-by: dann frazier <dann.frazier@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
drivers/scsi/hisi_sas/hisi_sas_main.c

index 7a0875bb7c919d34edcba7fed837ed0c1e7a4a68..c1624c1aa7a760b286e8c709906db8d1f3a42481 100644 (file)
@@ -1233,6 +1233,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;
@@ -1261,7 +1278,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);
 
@@ -1269,6 +1285,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);