summaryrefslogtreecommitdiff
path: root/drivers/scsi/hisi_sas/hisi_sas_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/hisi_sas/hisi_sas_main.c')
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_main.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 6219807ce3b9..53cb15f6714b 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -1321,6 +1321,7 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device)
}
if (rc == TMF_RESP_FUNC_COMPLETE) {
+ usleep_range(900, 1000);
ata_for_each_link(link, ap, EDGE) {
int pmp = sata_srst_pmp(link);
@@ -1384,6 +1385,7 @@ static void hisi_sas_refresh_port_id(struct hisi_hba *hisi_hba)
static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state)
{
+ u32 new_state = hisi_hba->hw->get_phys_state(hisi_hba);
struct asd_sas_port *_sas_port = NULL;
int phy_no;
@@ -1397,7 +1399,7 @@ static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state)
continue;
/* Report PHY state change to libsas */
- if (state & BIT(phy_no)) {
+ if (new_state & BIT(phy_no)) {
if (do_port_check && sas_port && sas_port->port_dev) {
struct domain_device *dev = sas_port->port_dev;
@@ -1410,6 +1412,16 @@ static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state)
}
} else {
hisi_sas_phy_down(hisi_hba, phy_no, 0, GFP_KERNEL);
+
+ /*
+ * The new_state is not ready but old_state is ready,
+ * the two possible causes:
+ * 1. The connected device is removed
+ * 2. Device exists but phyup timed out
+ */
+ if (state & BIT(phy_no))
+ hisi_sas_notify_phy_event(phy,
+ HISI_PHYE_LINK_RESET);
}
}
}
@@ -1545,9 +1557,15 @@ void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba)
/* Init and wait for PHYs to come up and all libsas event finished. */
for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) {
struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
+ struct asd_sas_phy *sas_phy = &phy->sas_phy;
- if (!(hisi_hba->phy_state & BIT(phy_no)))
+ if (!sas_phy->phy->enabled)
+ continue;
+
+ if (!(hisi_hba->phy_state & BIT(phy_no))) {
+ hisi_sas_phy_enable(hisi_hba, phy_no, 1);
continue;
+ }
async_schedule_domain(hisi_sas_async_init_wait_phyup,
phy, &async);
@@ -2450,6 +2468,11 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev,
if (hisi_sas_get_fw_info(hisi_hba) < 0)
goto err_out;
+ if (hisi_hba->hw->fw_info_check) {
+ if (hisi_hba->hw->fw_info_check(hisi_hba))
+ goto err_out;
+ }
+
error = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
if (error) {
dev_err(dev, "No usable DMA addressing method\n");
@@ -2630,10 +2653,10 @@ static __init int hisi_sas_init(void)
static __exit void hisi_sas_exit(void)
{
- sas_release_transport(hisi_sas_stt);
-
if (hisi_sas_debugfs_enable)
debugfs_remove(hisi_sas_debugfs_dir);
+
+ sas_release_transport(hisi_sas_stt);
}
module_init(hisi_sas_init);