Commit 4da9629dd6 for qemu.org
commit 4da9629dd63c9d92056608b9bbea446004f55431
Author: Stanley Jhu <stanleyjhu@google.com>
Date: Fri Oct 23 19:38:27 2026 +0800
tests/qtest/ufs-test: Add TMR and async MCQ SCSI submission helpers
Add ufs_send_tmr() and ufs_mcq_send_scsi_cmd_async() helper functions
in preparation for UTMRL task management and QOM fault injection unit
tests.
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/tests/qtest/ufs-test.c b/tests/qtest/ufs-test.c
index e8993e8c24..2914723430 100644
--- a/tests/qtest/ufs-test.c
+++ b/tests/qtest/ufs-test.c
@@ -1899,6 +1899,59 @@ static void ufstest_hid(void *obj, void *data, QGuestAllocator *alloc)
ufs_exit(ufs, alloc);
}
+static G_GNUC_UNUSED void ufs_send_tmr(QUfs *ufs, uint64_t utmrlba, int slot,
+ uint8_t tm_func, uint8_t lun,
+ uint32_t task_tag,
+ UtpTaskReqDesc *utrd_out)
+{
+ uint64_t desc_addr = utmrlba + slot * sizeof(UtpTaskReqDesc);
+ UtpTaskReqDesc desc = { 0 };
+
+ desc.header.dword_0 = cpu_to_le32(UFS_UTP_REQ_DESC_INT_CMD);
+ desc.header.dword_2 = cpu_to_le32(UFS_OCS_INVALID_COMMAND_STATUS);
+
+ desc.upiu_req.req_header.trans_type = UFS_UPIU_TRANSACTION_TASK_REQ;
+ desc.upiu_req.req_header.query_func = tm_func;
+ desc.upiu_req.req_header.lun = lun;
+ desc.upiu_req.req_header.task_tag = 0x10 + slot;
+ desc.upiu_req.input_param1 = cpu_to_be32(lun);
+ desc.upiu_req.input_param2 = cpu_to_be32(task_tag);
+
+ qtest_memwrite(ufs->dev.bus->qts, desc_addr, &desc, sizeof(desc));
+
+ ufs_wreg(ufs, A_UTMRLDBR, 1 << slot);
+ ufs_wait_for_irq(ufs);
+ g_assert_true(FIELD_EX32(ufs_rreg(ufs, A_IS), IS, UTMRCS));
+ ufs_wreg(ufs, A_IS, FIELD_DP32(0, IS, UTMRCS, 1));
+ g_assert_cmpuint(ufs_rreg(ufs, A_UTMRLDBR) & (1 << slot), ==, 0);
+
+ qtest_memread(ufs->dev.bus->qts, desc_addr, utrd_out, sizeof(*utrd_out));
+}
+
+static G_GNUC_UNUSED int ufs_mcq_send_scsi_cmd_async(QUfs *ufs, uint8_t lun,
+ const uint8_t *cdb)
+{
+ int cmd_desc_slot = alloc_cmd_desc_slot(ufs);
+ uint64_t req_upiu_addr =
+ ufs->cmd_desc_addr + cmd_desc_slot * UTP_COMMAND_DESCRIPTOR_SIZE;
+ UtpUpiuReq req_upiu = { 0 };
+ UtpTransferReqDesc utrd;
+
+ req_upiu.header.trans_type = UFS_UPIU_TRANSACTION_COMMAND;
+ req_upiu.header.flags = UFS_UPIU_CMD_FLAGS_NONE;
+ req_upiu.header.lun = lun;
+ req_upiu.header.task_tag = cmd_desc_slot;
+ memcpy(req_upiu.sc.cdb, cdb, UFS_CDB_SIZE);
+ qtest_memwrite(ufs->dev.bus->qts, req_upiu_addr, &req_upiu,
+ sizeof(req_upiu));
+
+ utrd = ufs_build_req_utrd(req_upiu_addr, UFS_UTP_NO_DATA_TRANSFER, 0);
+ __ufs_send_transfer_request_mcq_async(ufs, lun, &utrd);
+
+ return cmd_desc_slot;
+}
+
+
static void ufs_register_nodes(void)
{
const char *arch;