git: 746278a6ddc8 - main - ufshci: build valid fake responses for manual completion

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

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

commit 746278a6ddc80a98001f875cd975283d7c99b960
Author:     Jaeyoon Choi <jaeyoon@FreeBSD.org>
AuthorDate: 2026-08-27 05:02:10 +0000
Commit:     Jaeyoon Choi <jaeyoon@FreeBSD.org>
CommitDate: 2026-08-27 05:08:38 +0000

    ufshci: build valid fake responses for manual completion
    
    The manual completion wrote the fake response to the wrong
    descriptor for task management slots. It also left the task tag
    at zero, which tripped the task tag check under INVARIANTS.
    
    Write the fake response where the completion path reads it.
    Copy the task tag from the request.
    
    Reviewed by:            imp (mentor)
    Sponsored by:           Samsung Electronics
    Differential Revision:  https://reviews.freebsd.org/D58946
---
 sys/dev/ufshci/ufshci_req_queue.c | 26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/sys/dev/ufshci/ufshci_req_queue.c b/sys/dev/ufshci/ufshci_req_queue.c
index 97eccd082176..2e13d244daef 100644
--- a/sys/dev/ufshci/ufshci_req_queue.c
+++ b/sys/dev/ufshci/ufshci_req_queue.c
@@ -168,16 +168,30 @@ static void
 ufshci_req_queue_manual_complete_tracker(struct ufshci_tracker *tr, uint8_t ocs,
     uint8_t rc)
 {
-	struct ufshci_utp_xfer_req_desc *desc;
+	struct ufshci_req_queue *req_queue = tr->req_queue;
+	struct ufshci_hw_queue *hwq = tr->hwq;
 	struct ufshci_upiu_header *resp_header;
 
-	mtx_assert(&tr->hwq->qlock, MA_NOTOWNED);
+	mtx_assert(&hwq->qlock, MA_NOTOWNED);
 
-	resp_header = (struct ufshci_upiu_header *)tr->ucd->response_upiu;
+	/*
+	 * Write the fake response where the completion path reads it.
+	 */
+	if (req_queue->is_task_mgmt) {
+		resp_header = (struct ufshci_upiu_header *)
+		    hwq->utmrd[tr->slot_num].response_upiu;
+		hwq->utmrd[tr->slot_num].overall_command_status = ocs;
+	} else {
+		resp_header = (struct ufshci_upiu_header *)
+		    tr->ucd->response_upiu;
+		hwq->utrd[tr->slot_num].overall_command_status = ocs;
+	}
 	resp_header->response = rc;
-
-	desc = &tr->hwq->utrd[tr->slot_num];
-	desc->overall_command_status = ocs;
+	/*
+	 * The hardware never wrote a response. Copy the task tag from
+	 * the request so the completion checks pass.
+	 */
+	resp_header->task_tag = tr->req->request_upiu.header.task_tag;
 
 	ufshci_req_queue_complete_tracker(tr);
 }