git: 4861ef4e8245 - main - ufshci: try the link startup more than once
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 03 Nov 2026 04:33:52 UTC
The branch main has been updated by jaeyoon:
URL: https://cgit.FreeBSD.org/src/commit/?id=4861ef4e82451bfb1e5fd58d02a38f6baf20eb24
commit 4861ef4e82451bfb1e5fd58d02a38f6baf20eb24
Author: Jaeyoon Choi <jaeyoon@FreeBSD.org>
AuthorDate: 2026-11-03 04:26:00 +0000
Commit: Jaeyoon Choi <jaeyoon@FreeBSD.org>
CommitDate: 2026-11-03 04:29:46 +0000
ufshci: try the link startup more than once
A device that is still powering on may not answer the first
DME_LINKSTARTUP, and the driver gave up after one try.
Try up to three times. Both attach and reset use this path.
Reviewed by: imp
Sponsored by: Samsung Electronics
Differential Revision: https://reviews.freebsd.org/D61121
---
sys/dev/ufshci/ufshci_ctrlr.c | 33 +++++++++++++++++++++------------
sys/dev/ufshci/ufshci_private.h | 3 +++
2 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/sys/dev/ufshci/ufshci_ctrlr.c b/sys/dev/ufshci/ufshci_ctrlr.c
index e37764f874b9..32c85f87ffcc 100644
--- a/sys/dev/ufshci/ufshci_ctrlr.c
+++ b/sys/dev/ufshci/ufshci_ctrlr.c
@@ -287,7 +287,7 @@ ufshci_ctrlr_disable(struct ufshci_controller *ctrlr)
int
ufshci_ctrlr_enable(struct ufshci_controller *ctrlr)
{
- uint32_t ie, hcs;
+ uint32_t ie, hcs, attempt;
int error;
error = ufshci_ctrlr_enable_host_ctrlr(ctrlr);
@@ -295,18 +295,27 @@ ufshci_ctrlr_enable(struct ufshci_controller *ctrlr)
return (error);
/* Send DME_LINKSTARTUP command to start the link startup procedure */
- error = ufshci_uic_send_dme_link_startup(ctrlr);
- if (error)
- return (error);
+ for (attempt = 0; attempt < UFSHCI_MAX_LINK_STARTUP_ATTEMPTS;
+ attempt++) {
+ error = ufshci_uic_send_dme_link_startup(ctrlr);
+ if (error) {
+ ufshci_printf(ctrlr,
+ "DME_LINKSTARTUP attempt %u failed: %d\n",
+ attempt + 1, error);
+ continue;
+ }
- /*
- * The device_present(UFSHCI_HCS_REG_DP) bit becomes true if the host
- * controller has successfully received a Link Startup UIC command
- * response and the UFS device has found a physical link to the
- * controller.
- */
- hcs = ufshci_mmio_read_4(ctrlr, hcs);
- if (!UFSHCIV(UFSHCI_HCS_REG_DP, hcs)) {
+ /*
+ * The device_present(UFSHCI_HCS_REG_DP) bit becomes true if
+ * the host controller has successfully received a Link
+ * Startup UIC command response and the UFS device has found
+ * a physical link to the controller.
+ */
+ hcs = ufshci_mmio_read_4(ctrlr, hcs);
+ if (UFSHCIV(UFSHCI_HCS_REG_DP, hcs))
+ break;
+ }
+ if (attempt == UFSHCI_MAX_LINK_STARTUP_ATTEMPTS) {
ufshci_printf(ctrlr, "UFS device not found\n");
return (ENXIO);
}
diff --git a/sys/dev/ufshci/ufshci_private.h b/sys/dev/ufshci/ufshci_private.h
index 69ff9c7f8f51..c75044f39d7f 100644
--- a/sys/dev/ufshci/ufshci_private.h
+++ b/sys/dev/ufshci/ufshci_private.h
@@ -47,6 +47,9 @@ MALLOC_DECLARE(M_UFSHCI);
#define UFSHCI_DEFAULT_RETRY_COUNT (4)
+/* A device that is still powering on does not answer the first one. */
+#define UFSHCI_MAX_LINK_STARTUP_ATTEMPTS (3)
+
#define UFSHCI_UTR_ENTRIES (32)
#define UFSHCI_UTRM_ENTRIES (8)