scsi: hisi_sas: fix probe ordering problem
authorXiang Chen <chenxiang66@hisilicon.com>
Fri, 20 Jan 2017 12:45:23 +0000 (20:45 +0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Sat, 21 Jan 2017 00:10:42 +0000 (19:10 -0500)
There is a potential probe issue in how we trigger the hw initialisation.
Although we use 1s timer to delay hw initialisation, there is still a
potential that sas_register_ha() is not be finished before we start
the PHY init from hw->hw_init().
To avoid this issue, initialise the hw after sas_register_ha() in the
same probe context.
Note: it is not necessary to use 1s timer now (modified v2 hw only).

Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: John Garry <john.garry@huawei.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/hisi_sas/hisi_sas_main.c
drivers/scsi/hisi_sas/hisi_sas_v2_hw.c

index b2782ce04542953f32c9b75cb561241b8b058d08..8601cec296a83c857bb66830bf30fe04481457cd 100644 (file)
@@ -1552,10 +1552,6 @@ int hisi_sas_probe(struct platform_device *pdev,
 
        hisi_sas_init_add(hisi_hba);
 
-       rc = hisi_hba->hw->hw_init(hisi_hba);
-       if (rc)
-               goto err_out_ha;
-
        rc = scsi_add_host(shost, &pdev->dev);
        if (rc)
                goto err_out_ha;
@@ -1564,6 +1560,10 @@ int hisi_sas_probe(struct platform_device *pdev,
        if (rc)
                goto err_out_register_ha;
 
+       rc = hisi_hba->hw->hw_init(hisi_hba);
+       if (rc)
+               goto err_out_register_ha;
+
        scsi_scan_host(shost);
 
        return 0;
index 2e776b70be8fd9d91ab809337daaf4259f6f8380..9e16f42944bcff3900fc33054f80c44acd565924 100644 (file)
@@ -1093,9 +1093,8 @@ static void phy_hard_reset_v2_hw(struct hisi_hba *hisi_hba, int phy_no)
        start_phy_v2_hw(hisi_hba, phy_no);
 }
 
-static void start_phys_v2_hw(unsigned long data)
+static void start_phys_v2_hw(struct hisi_hba *hisi_hba)
 {
-       struct hisi_hba *hisi_hba = (struct hisi_hba *)data;
        int i;
 
        for (i = 0; i < hisi_hba->n_phy; i++)
@@ -1104,10 +1103,7 @@ static void start_phys_v2_hw(unsigned long data)
 
 static void phys_init_v2_hw(struct hisi_hba *hisi_hba)
 {
-       struct timer_list *timer = &hisi_hba->timer;
-
-       setup_timer(timer, start_phys_v2_hw, (unsigned long)hisi_hba);
-       mod_timer(timer, jiffies + HZ);
+       start_phys_v2_hw(hisi_hba);
 }
 
 static void sl_notify_v2_hw(struct hisi_hba *hisi_hba, int phy_no)