mirror of
https://gitlab.com/qemu-project/qemu.git
synced 2026-10-28 14:04:39 +08:00
hw/ufs: Skip nullified MCQ submission queue entries with OCS_ABORTED
Per JEDEC UFSHCI (JESD223G Section 6.1.1 and Section 4.4.6 Step 2B), host software in MCQ mode may stop a Submission Queue and nullify an unfetched SQE by setting its UTRD Command Type (DW0 bits 31:28) to 0xF. When the Submission Queue is resumed, the host controller shall skip execution of the nullified transfer request and post a Completion Queue Entry (CQE) to the Completion Queue with OCS = ABORTED (0x06). In ufs_mcq_process_sq(), check for UFS_UTP_CMD_TYPE_NULL (0xF), read the Request UPIU header on a best-effort basis via ufs_dma_read_req_upiu() to populate cqe.task_tag and cqe.lun for UFSHCI 4.1+ completion decoding, and unconditionally post a CQE with UFS_OCS_ABORTED without executing the command or writing a Response UPIU for the nullified entry. 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>
This commit is contained in:
1 parent
5791c5832f
commit
92d01b9ee2
2 files changed
+17
-1
No files matched your search
+16
-1
@@ -36,6 +36,7 @@
|
||||
|
||||
static void ufs_exec_req(UfsRequest *req);
|
||||
static void ufs_clear_req(UfsRequest *req);
|
||||
static void ufs_mcq_process_cq(void *opaque);
|
||||
|
||||
static inline uint64_t ufs_mcq_reg_addr(UfsHc *u, int qid)
|
||||
{
|
||||
@@ -474,6 +475,17 @@ static void ufs_mcq_process_sq(void *opaque)
|
||||
ufs_mcq_init_req(sq->u, req, sq);
|
||||
memcpy(&req->utrd, &sqe, sizeof(req->utrd));
|
||||
|
||||
if ((le32_to_cpu(sqe.header.dword_0) >> 28) == UFS_UTP_CMD_TYPE_NULL) {
|
||||
ufs_dma_read_req_upiu(req);
|
||||
req->utrd.header.dword_2 = cpu_to_le32(
|
||||
(le32_to_cpu(req->utrd.header.dword_2) & ~UFS_MASK_OCS) |
|
||||
UFS_OCS_ABORTED);
|
||||
req->state = UFS_REQUEST_COMPLETE;
|
||||
QTAILQ_INSERT_TAIL(&sq->cq->req_list, req, entry);
|
||||
ufs_mcq_process_cq(sq->cq);
|
||||
continue;
|
||||
}
|
||||
|
||||
req->state = UFS_REQUEST_RUNNING;
|
||||
ufs_exec_req(req);
|
||||
}
|
||||
@@ -493,7 +505,10 @@ static void ufs_mcq_process_cq(void *opaque)
|
||||
break;
|
||||
}
|
||||
|
||||
ufs_dma_write_rsp_upiu(req);
|
||||
if ((le32_to_cpu(req->utrd.header.dword_0) >> 28) !=
|
||||
UFS_UTP_CMD_TYPE_NULL) {
|
||||
ufs_dma_write_rsp_upiu(req);
|
||||
}
|
||||
|
||||
/* UTRD/CQE are LE; round-trip through host to keep BE correct. */
|
||||
uint64_t ucdba =
|
||||
|
||||
@@ -665,6 +665,7 @@ enum {
|
||||
UFS_UTP_CMD_TYPE_SCSI = 0x0,
|
||||
UFS_UTP_CMD_TYPE_UFS = 0x1,
|
||||
UFS_UTP_CMD_TYPE_DEV_MANAGE = 0x2,
|
||||
UFS_UTP_CMD_TYPE_NULL = 0xf,
|
||||
};
|
||||
|
||||
/* To accommodate UFS2.0 required Command type */
|
||||
|
||||
Reference in new issue
Block a user