diff --git a/hw/ufs/ufs.c b/hw/ufs/ufs.c index ee7eba6793..464fd465b3 100644 --- a/hw/ufs/ufs.c +++ b/hw/ufs/ufs.c @@ -520,6 +520,12 @@ static void ufs_mcq_process_cq(void *opaque) req->cqe.prdt_off = cpu_to_le16(prdt_off); req->cqe.status = status; req->cqe.error = 0; + /* + * From UFSHCI 4.1 the host derives the request tag from cqe.task_tag + * rather than decoding it from utp_addr. + */ + req->cqe.task_tag = req->req_upiu.header.task_tag; + req->cqe.lun = req->req_upiu.header.lun; ret = ufs_addr_write(u, cq->addr + tail, &req->cqe, sizeof(req->cqe)); if (ret) { diff --git a/include/block/ufs.h b/include/block/ufs.h index 66e8f35c0e..d19b3c65ef 100644 --- a/include/block/ufs.h +++ b/include/block/ufs.h @@ -1333,7 +1333,11 @@ typedef struct QEMU_PACKED UfsCqEntry { uint8_t status; uint8_t error; uint16_t rsvd1; - uint32_t rsvd2[3]; + uint8_t task_tag; + uint8_t lun; + uint8_t iid_ext_iid; + uint8_t rsvd2; + uint32_t rsvd3[2]; } UfsCqEntry; static inline void _ufs_check_size(void)