Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 Mar 2026 04:46:54 +0000
From:      Jaeyoon Choi <jaeyoon@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: c4386988baa2 - main - ufshci: fix bug in ufshci_req_sdb_enable
Message-ID:  <69c368be.36bbe.6582e4ba@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by jaeyoon:

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

commit c4386988baa2ecdcb482c8ccace183dc643d097c
Author:     Jaeyoon Choi <jaeyoon@FreeBSD.org>
AuthorDate: 2026-03-24 05:12:14 +0000
Commit:     Jaeyoon Choi <jaeyoon@FreeBSD.org>
CommitDate: 2026-03-24 16:45:27 +0000

    ufshci: fix bug in ufshci_req_sdb_enable
    
    When enabling the request queue, safely reset the list base address.
    This was added due to a quirk in the Qualcomm UFS controller during
    the process of activating it.
    
    Sponsored by:           Samsung Electronics
    Reviewed by:            imp (mentor)
    Differential Revision:  https://reviews.freebsd.org/D55984
---
 sys/dev/ufshci/ufshci_req_sdb.c | 40 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/sys/dev/ufshci/ufshci_req_sdb.c b/sys/dev/ufshci/ufshci_req_sdb.c
index ca47aa159c5b..54542f48b32c 100644
--- a/sys/dev/ufshci/ufshci_req_sdb.c
+++ b/sys/dev/ufshci/ufshci_req_sdb.c
@@ -374,34 +374,63 @@ ufshci_req_sdb_enable(struct ufshci_controller *ctrlr,
     struct ufshci_req_queue *req_queue)
 {
 	struct ufshci_hw_queue *hwq = &req_queue->hwq[UFSHCI_SDB_Q];
+	int error = 0;
+
+	mtx_lock(&hwq->recovery_lock);
+	mtx_lock(&hwq->qlock);
 
 	if (req_queue->is_task_mgmt) {
 		uint32_t hcs, utmrldbr, utmrlrsr;
+		uint32_t utmrlba, utmrlbau;
+
+		/*
+		 * Some controllers require re-enabling. When a controller is
+		 * re-enabled, the utmrlba registers are initialized, and these
+		 * must be reconfigured upon re-enabling.
+		 */
+		utmrlba = hwq->req_queue_addr & 0xffffffff;
+		utmrlbau = hwq->req_queue_addr >> 32;
+		ufshci_mmio_write_4(ctrlr, utmrlba, utmrlba);
+		ufshci_mmio_write_4(ctrlr, utmrlbau, utmrlbau);
 
 		hcs = ufshci_mmio_read_4(ctrlr, hcs);
 		if (!(hcs & UFSHCIM(UFSHCI_HCS_REG_UTMRLRDY))) {
 			ufshci_printf(ctrlr,
 			    "UTP task management request list is not ready\n");
-			return (ENXIO);
+			error = ENXIO;
+			goto out;
 		}
 
 		utmrldbr = ufshci_mmio_read_4(ctrlr, utmrldbr);
 		if (utmrldbr != 0) {
 			ufshci_printf(ctrlr,
 			    "UTP task management request list door bell is not ready\n");
-			return (ENXIO);
+			error = ENXIO;
+			goto out;
 		}
 
 		utmrlrsr = UFSHCIM(UFSHCI_UTMRLRSR_REG_UTMRLRSR);
 		ufshci_mmio_write_4(ctrlr, utmrlrsr, utmrlrsr);
 	} else {
 		uint32_t hcs, utrldbr, utrlcnr, utrlrsr;
+		uint32_t utrlba, utrlbau;
+
+		/*
+		 * Some controllers require re-enabling. When a controller is
+		 * re-enabled, the utrlba registers are initialized, and these
+		 * must be reconfigured upon re-enabling.
+		 */
+		utrlba = hwq->req_queue_addr & 0xffffffff;
+		utrlbau = hwq->req_queue_addr >> 32;
+		ufshci_mmio_write_4(ctrlr, utrlba, utrlba);
+		ufshci_mmio_write_4(ctrlr, utrlbau, utrlbau);
 
 		hcs = ufshci_mmio_read_4(ctrlr, hcs);
 		if (!(hcs & UFSHCIM(UFSHCI_HCS_REG_UTRLRDY))) {
 			ufshci_printf(ctrlr,
 			    "UTP transfer request list is not ready\n");
-			return (ENXIO);
+			error = ENXIO;
+			goto out;
 		}
 
 		utrldbr = ufshci_mmio_read_4(ctrlr, utrldbr);
@@ -434,7 +463,10 @@ ufshci_req_sdb_enable(struct ufshci_controller *ctrlr,
 
 	hwq->recovery_state = RECOVERY_NONE;
 
-	return (0);
+out:
+	mtx_unlock(&hwq->qlock);
+	mtx_unlock(&hwq->recovery_lock);
+	return (error);
 }
 
 int


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69c368be.36bbe.6582e4ba>