Commit cd8fecdaef for qemu.org
commit cd8fecdaefdfa143526d87a48cf32ea9c01e79a6
Author: Stanley Jhu <stanleyjhu@google.com>
Date: Mon Oct 5 19:03:12 2026 +0800
hw/ufs: Track SCSIRequest and cancel pending requests in ufs_clear_req
Existing callers of ufs_clear_req() only invoke it after requests are no
longer in flight. In preparation for Task Management Request (TMR) task
abort and MCQ queue cleanup support, where individual in-flight requests
are aborted without purging the entire SCSI device, track the active
SCSIRequest in UfsRequest and cancel any pending request via
scsi_req_cancel() in ufs_clear_req().
Signed-off-by: Stanley Jhu <stanleyjhu@google.com>
Reviewed-by: Jeuk Kim <jeuk20.kim@samsung.com>
Signed-off-by: Jeuk Kim <jeuk20.kim@samsung.com>
diff --git a/hw/ufs/lu.c b/hw/ufs/lu.c
index bdb1650851..5905c49fac 100644
--- a/hw/ufs/lu.c
+++ b/hw/ufs/lu.c
@@ -173,6 +173,9 @@ static void ufs_scsi_command_complete(SCSIRequest *scsi_req, size_t resid)
int16_t status = scsi_req->status;
uint32_t transfered_len = scsi_req->cmd.xfer - resid;
+ assert(req != NULL);
+ req->sreq = NULL;
+
/* WB / HID accounting should only happen for successful commands */
if (status == GOOD) {
ufs_wb_process_write_req(req, transfered_len);
@@ -190,6 +193,10 @@ static void ufs_scsi_command_complete(SCSIRequest *scsi_req, size_t resid)
static void ufs_scsi_command_cancelled(SCSIRequest *scsi_req)
{
+ UfsRequest *req = scsi_req->hba_private;
+
+ assert(req != NULL);
+ req->sreq = NULL;
scsi_req->hba_private = NULL;
scsi_req_unref(scsi_req);
}
@@ -389,6 +396,7 @@ static UfsReqResult ufs_process_scsi_cmd(UfsLu *lu, UfsRequest *req)
SCSIRequest *scsi_req =
scsi_req_new(lu->scsi_dev, task_tag, lu->lun, req->req_upiu.sc.cdb,
UFS_CDB_SIZE, req);
+ req->sreq = scsi_req;
uint32_t len = scsi_req_enqueue(scsi_req);
if (len) {
diff --git a/hw/ufs/ufs.c b/hw/ufs/ufs.c
index 3c4d7424da..adae6639e1 100644
--- a/hw/ufs/ufs.c
+++ b/hw/ufs/ufs.c
@@ -2221,6 +2221,12 @@ void ufs_complete_req(UfsRequest *req, UfsReqResult req_result)
static void ufs_clear_req(UfsRequest *req)
{
+ if (req->sreq != NULL) {
+ SCSIRequest *sreq = req->sreq;
+ req->sreq = NULL;
+ scsi_req_cancel(sreq);
+ }
+
if (req->sg != NULL) {
qemu_sglist_destroy(req->sg);
g_free(req->sg);
diff --git a/hw/ufs/ufs.h b/hw/ufs/ufs.h
index 6f2693b7ca..265a43faaa 100644
--- a/hw/ufs/ufs.h
+++ b/hw/ufs/ufs.h
@@ -60,6 +60,7 @@ typedef struct UfsRequest {
UtpUpiuRsp rsp_upiu;
/* for scsi command */
+ SCSIRequest *sreq;
QEMUSGList *sg;
uint32_t data_len;