git: 9930150214d1 - main - ufshci: skip the reinit when the new link works

From: Jaeyoon Choi <jaeyoon_at_FreeBSD.org>
Date: Wed, 02 Sep 2026 02:08:00 UTC
The branch main has been updated by jaeyoon:

URL: https://cgit.FreeBSD.org/src/commit/?id=9930150214d1ca4ad21561d2e0afce9ebf2cdf6c

commit 9930150214d1ca4ad21561d2e0afce9ebf2cdf6c
Author:     Jaeyoon Choi <jaeyoon@FreeBSD.org>
AuthorDate: 2026-09-02 01:52:48 +0000
Commit:     Jaeyoon Choi <jaeyoon@FreeBSD.org>
CommitDate: 2026-09-02 02:05:10 +0000

    ufshci: skip the reinit when the new link works
    
    UFSHCI_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH always rebuilt the
    link after the gear switch. It threw away a working HS link and
    ended up in PWM. The reinit is only needed for a dead link.
    There the local side reports HS and the peer never answers. A
    local readback cannot tell the two apart. Peer traffic can.
    
    Probe the peer with DME_PEER_GET after the switch. Skip the
    reinit when the probe succeeds. Log it when the probe fails.
    
    Reviewed by:            imp (mentor)
    Sponsored by:           Samsung Electronics
    Differential Revision:  https://reviews.freebsd.org/D59299
---
 sys/dev/ufshci/ufshci_ctrlr.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/sys/dev/ufshci/ufshci_ctrlr.c b/sys/dev/ufshci/ufshci_ctrlr.c
index b3b9abbe867c..480bbfd43d81 100644
--- a/sys/dev/ufshci/ufshci_ctrlr.c
+++ b/sys/dev/ufshci/ufshci_ctrlr.c
@@ -127,10 +127,25 @@ ufshci_ctrlr_start(struct ufshci_controller *ctrlr, bool resetting)
 
 	ufshci_dev_init_uic_link_state(ctrlr);
 
-	if ((ctrlr->quirks & UFSHCI_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH) &&
-	    ufshci_ctrlr_reinit_after_max_gear_switch(ctrlr) != 0) {
-		ufshci_ctrlr_fail(ctrlr);
-		return;
+	if (ctrlr->quirks & UFSHCI_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH) {
+		uint32_t probe;
+
+		/*
+		 * The reinit is only needed when the link did not survive
+		 * the gear switch. A local readback still shows HS when the
+		 * peer is dead. Only peer traffic proves the link works.
+		 */
+		if (ufshci_uic_send_dme_peer_get(ctrlr, PA_Granularity,
+		    &probe) != 0) {
+			ufshci_printf(ctrlr,
+			    "link probe failed after the gear switch, "
+			    "reinitializing\n");
+			if (ufshci_ctrlr_reinit_after_max_gear_switch(
+			    ctrlr) != 0) {
+				ufshci_ctrlr_fail(ctrlr);
+				return;
+			}
+		}
 	}
 
 	/* Read Controller Descriptor (Device, Geometry) */