diff mbox series

[05/13] scsi: hisi_sas: Reset PHY again if phyup timeout

Message ID 20240926014332.3905399-6-liyihang9@huawei.com (mailing list archive)
State Superseded
Headers show
Series scsi: hisi_sas: Some fixes for hisi_sas | expand

Commit Message

Yihang Li Sept. 26, 2024, 1:43 a.m. UTC
In commit 89954f024c3a ("scsi: hisi_sas: Ensure all enabled PHYs up during
controller reset"), we enable PHYs in parallel through async operations
and wait for PHYs come up. However, for some directly attached SATA disks,
the PHY not come up after a timeout period and the hardware is not ready.
At this time, we should get the latest PHY hardware state, if the new PHY
state is not ready but the old PHY state is ready, call work
HISI_PHYE_LINK_RESET to give it another chance to phyup.

Signed-off-by: Yihang Li <liyihang9@huawei.com>
Reviewed-by: Xiang Chen <chenxiang66@hisilicon.com>
---
 drivers/scsi/hisi_sas/hisi_sas_main.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
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 85374800251a..452baf9d5a26 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -1384,6 +1384,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 +1398,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 +1411,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);
 		}
 	}
 }