git: 3ecee9314d88 - main - ufshci: reject new requests on a failed controller

From: Jaeyoon Choi <jaeyoon_at_FreeBSD.org>
Date: Thu, 27 Aug 2026 05:12:50 UTC
The branch main has been updated by jaeyoon:

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

commit 3ecee9314d88e2bb277b365d9413e219fd9a1283
Author:     Jaeyoon Choi <jaeyoon@FreeBSD.org>
AuthorDate: 2026-08-27 05:04:11 +0000
Commit:     Jaeyoon Choi <jaeyoon@FreeBSD.org>
CommitDate: 2026-08-27 05:08:38 +0000

    ufshci: reject new requests on a failed controller
    
    A failed controller accepted new requests, but nothing ever
    completed them, so the caller waited forever. The admin retry
    path could also resubmit a request to a dead queue.
    
    Reject new submits and admin retries on a failed controller.
    The submit check runs under the queue lock, so it cannot race
    with the queue walk in the fail path.
    
    Reviewed by:            imp (mentor)
    Sponsored by:           Samsung Electronics
    Differential Revision:  https://reviews.freebsd.org/D58948
---
 sys/dev/ufshci/ufshci_req_queue.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/sys/dev/ufshci/ufshci_req_queue.c b/sys/dev/ufshci/ufshci_req_queue.c
index 2e13d244daef..886cf9aff77f 100644
--- a/sys/dev/ufshci/ufshci_req_queue.c
+++ b/sys/dev/ufshci/ufshci_req_queue.c
@@ -270,8 +270,8 @@ ufshci_req_queue_complete_tracker(struct ufshci_tracker *tr)
 	error = ufshci_req_queue_response_is_error(req_queue, ocs,
 	    &cpl.response_upiu);
 
-	/* Retry for admin commands */
-	retriable = req->is_admin;
+	/* Retry for admin commands. A failed controller must not retry. */
+	retriable = req->is_admin && !req_queue->ctrlr->is_failed;
 	retry = error && retriable &&
 	    req->retries < req_queue->ctrlr->retry_count;
 	if (retry)
@@ -765,6 +765,9 @@ _ufshci_req_queue_submit_request(struct ufshci_req_queue *req_queue,
 
 	mtx_assert(&req_queue->qops.get_hw_queue(req_queue)->qlock, MA_OWNED);
 
+	if (req_queue->ctrlr->is_failed)
+		return (ENXIO);
+
 	error = req_queue->qops.reserve_slot(req_queue, &tr);
 	if (error != 0) {
 		ufshci_printf(req_queue->ctrlr, "Failed to get tracker");