ufs queue
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEUBfYMVl8eKPZB+73EuIgTA5dtgIFAmba268ACgkQEuIgTA5d tgLndA//T7zvQboCWE2Aw+al4/cJmpfc/BP7pKrCvrwskhAo2H5JvbJ20WZ+/I6E sLqXjsAQ4qPWUNi46aty/tCCmFWatBRKIyWOg1E8w1N1PCqM/aKFElENgi28iclj 3TlIU+++a6VJXMtKKqGb/d6cxXM9QtRgkfpGEnVTCD4sRX25WuWcWu+hwCipgzsr dul1Ez+mp62SfHN2QLPUd+Ft0SvyxybDA65JP9fCEJPJ+2dtLWPN9XGY+6PzW4dT UEfUEV2V5k3w/QHTR8yG2i5s56wWVUhtQEhazbkj1VqgUSJ8PvIvBLhQpi4Gd51G 62/xHJaHXPxgVrVE6Or/5QF9npo1moG7UrLgP+FYX5kto280wEyh3KxNhlan+lmI IGo7V3Xv6UgGudJ/ZjR4dw24atFDcaqmdnWAOOp7mwxUIAq/5xLeDw2fzvuUw78a cc732SF4XwTJfXwgiXkJXa/Si248fDtecvlD+lQ9wezSIJZq8Ojpe9uFREA4jPVY jfgXEoopvam4w4ZKFRg93/0QErgwsYaJKKIKD8wZ99pi8/zrWlq5W1ujefQuvujt FL4IbF/8g6i22fZgBr8AlkRn3epxx4oRGV+Rr8OXoFYjNR/E7rjKZYfbsJx/gDbO zEMzSImQ48Tlxl9vkIx5kkUDxw3d7MDvrXEORcTMSW53CUDXJyA= =U151 -----END PGP SIGNATURE----- Merge tag 'pull-ufs-20240906' of https://gitlab.com/jeuk20.kim/qemu into staging ufs queue # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCgAdFiEEUBfYMVl8eKPZB+73EuIgTA5dtgIFAmba268ACgkQEuIgTA5d # tgLndA//T7zvQboCWE2Aw+al4/cJmpfc/BP7pKrCvrwskhAo2H5JvbJ20WZ+/I6E # sLqXjsAQ4qPWUNi46aty/tCCmFWatBRKIyWOg1E8w1N1PCqM/aKFElENgi28iclj # 3TlIU+++a6VJXMtKKqGb/d6cxXM9QtRgkfpGEnVTCD4sRX25WuWcWu+hwCipgzsr # dul1Ez+mp62SfHN2QLPUd+Ft0SvyxybDA65JP9fCEJPJ+2dtLWPN9XGY+6PzW4dT # UEfUEV2V5k3w/QHTR8yG2i5s56wWVUhtQEhazbkj1VqgUSJ8PvIvBLhQpi4Gd51G # 62/xHJaHXPxgVrVE6Or/5QF9npo1moG7UrLgP+FYX5kto280wEyh3KxNhlan+lmI # IGo7V3Xv6UgGudJ/ZjR4dw24atFDcaqmdnWAOOp7mwxUIAq/5xLeDw2fzvuUw78a # cc732SF4XwTJfXwgiXkJXa/Si248fDtecvlD+lQ9wezSIJZq8Ojpe9uFREA4jPVY # jfgXEoopvam4w4ZKFRg93/0QErgwsYaJKKIKD8wZ99pi8/zrWlq5W1ujefQuvujt # FL4IbF/8g6i22fZgBr8AlkRn3epxx4oRGV+Rr8OXoFYjNR/E7rjKZYfbsJx/gDbO # zEMzSImQ48Tlxl9vkIx5kkUDxw3d7MDvrXEORcTMSW53CUDXJyA= # =U151 # -----END PGP SIGNATURE----- # gpg: Signature made Fri 06 Sep 2024 11:38:39 BST # gpg: using RSA key 5017D831597C78A3D907EEF712E2204C0E5DB602 # gpg: Good signature from "Jeuk Kim <jeuk20.kim@samsung.com>" [unknown] # gpg: aka "Jeuk Kim <jeuk20.kim@gmail.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 5017 D831 597C 78A3 D907 EEF7 12E2 204C 0E5D B602 * tag 'pull-ufs-20240906' of https://gitlab.com/jeuk20.kim/qemu: hw/ufs: ufs descriptor read test implemented hw/ufs: ufs attribute read/write test implemented hw/ufs: ufs flag read/write test implemented hw/ufs: minor bug fixes related to ufs-test hw/ufs: add basic info of query response upiu Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
1581a0bc92
32
hw/ufs/ufs.c
32
hw/ufs/ufs.c
@ -851,6 +851,14 @@ void ufs_build_upiu_header(UfsRequest *req, uint8_t trans_type, uint8_t flags,
|
||||
req->rsp_upiu.header.data_segment_length = cpu_to_be16(data_segment_length);
|
||||
}
|
||||
|
||||
void ufs_build_query_response(UfsRequest *req)
|
||||
{
|
||||
req->rsp_upiu.qr.opcode = req->req_upiu.qr.opcode;
|
||||
req->rsp_upiu.qr.idn = req->req_upiu.qr.idn;
|
||||
req->rsp_upiu.qr.index = req->req_upiu.qr.index;
|
||||
req->rsp_upiu.qr.selector = req->req_upiu.qr.selector;
|
||||
}
|
||||
|
||||
static UfsReqResult ufs_exec_scsi_cmd(UfsRequest *req)
|
||||
{
|
||||
UfsHc *u = req->hc;
|
||||
@ -1103,10 +1111,13 @@ static uint32_t ufs_read_attr_value(UfsHc *u, uint8_t idn)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ufs_write_attr_value(UfsHc *u, uint8_t idn, uint32_t value)
|
||||
static QueryRespCode ufs_write_attr_value(UfsHc *u, uint8_t idn, uint32_t value)
|
||||
{
|
||||
switch (idn) {
|
||||
case UFS_QUERY_ATTR_IDN_ACTIVE_ICC_LVL:
|
||||
if (value > UFS_QUERY_ATTR_ACTIVE_ICC_MAXVALUE) {
|
||||
return UFS_QUERY_RESULT_INVALID_VALUE;
|
||||
}
|
||||
u->attributes.active_icc_level = value;
|
||||
break;
|
||||
case UFS_QUERY_ATTR_IDN_MAX_DATA_IN:
|
||||
@ -1134,6 +1145,7 @@ static void ufs_write_attr_value(UfsHc *u, uint8_t idn, uint32_t value)
|
||||
u->attributes.psa_data_size = cpu_to_be32(value);
|
||||
break;
|
||||
}
|
||||
return UFS_QUERY_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
static QueryRespCode ufs_exec_query_attr(UfsRequest *req, int op)
|
||||
@ -1150,13 +1162,13 @@ static QueryRespCode ufs_exec_query_attr(UfsRequest *req, int op)
|
||||
|
||||
if (op == UFS_QUERY_ATTR_READ) {
|
||||
value = ufs_read_attr_value(u, idn);
|
||||
ret = UFS_QUERY_RESULT_SUCCESS;
|
||||
} else {
|
||||
value = be32_to_cpu(req->req_upiu.qr.value);
|
||||
ufs_write_attr_value(u, idn, value);
|
||||
value = req->req_upiu.qr.value;
|
||||
ret = ufs_write_attr_value(u, idn, value);
|
||||
}
|
||||
|
||||
req->rsp_upiu.qr.value = cpu_to_be32(value);
|
||||
return UFS_QUERY_RESULT_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const RpmbUnitDescriptor rpmb_unit_desc = {
|
||||
@ -1279,9 +1291,12 @@ static QueryRespCode ufs_read_desc(UfsRequest *req)
|
||||
UfsHc *u = req->hc;
|
||||
QueryRespCode status;
|
||||
uint8_t idn = req->req_upiu.qr.idn;
|
||||
uint8_t selector = req->req_upiu.qr.selector;
|
||||
uint16_t length = be16_to_cpu(req->req_upiu.qr.length);
|
||||
InterconnectDescriptor desc;
|
||||
|
||||
if (selector != 0) {
|
||||
return UFS_QUERY_RESULT_INVALID_SELECTOR;
|
||||
}
|
||||
switch (idn) {
|
||||
case UFS_QUERY_DESC_IDN_DEVICE:
|
||||
memcpy(&req->rsp_upiu.qr.data, &u->device_desc, sizeof(u->device_desc));
|
||||
@ -1327,10 +1342,6 @@ static QueryRespCode ufs_read_desc(UfsRequest *req)
|
||||
if (length > req->rsp_upiu.qr.data[0]) {
|
||||
length = req->rsp_upiu.qr.data[0];
|
||||
}
|
||||
req->rsp_upiu.qr.opcode = req->req_upiu.qr.opcode;
|
||||
req->rsp_upiu.qr.idn = req->req_upiu.qr.idn;
|
||||
req->rsp_upiu.qr.index = req->req_upiu.qr.index;
|
||||
req->rsp_upiu.qr.selector = req->req_upiu.qr.selector;
|
||||
req->rsp_upiu.qr.length = cpu_to_be16(length);
|
||||
|
||||
return status;
|
||||
@ -1411,6 +1422,7 @@ static UfsReqResult ufs_exec_query_cmd(UfsRequest *req)
|
||||
data_segment_length = be16_to_cpu(req->rsp_upiu.qr.length);
|
||||
ufs_build_upiu_header(req, UFS_UPIU_TRANSACTION_QUERY_RSP, 0, status, 0,
|
||||
data_segment_length);
|
||||
ufs_build_query_response(req);
|
||||
|
||||
if (status != UFS_QUERY_RESULT_SUCCESS) {
|
||||
return UFS_REQUEST_FAIL;
|
||||
|
@ -228,6 +228,7 @@ static inline bool is_wlun(uint8_t lun)
|
||||
void ufs_build_upiu_header(UfsRequest *req, uint8_t trans_type, uint8_t flags,
|
||||
uint8_t response, uint8_t scsi_status,
|
||||
uint16_t data_segment_length);
|
||||
void ufs_build_query_response(UfsRequest *req);
|
||||
void ufs_complete_req(UfsRequest *req, UfsReqResult req_result);
|
||||
void ufs_init_wlu(UfsLu *wlu, uint8_t wlun);
|
||||
#endif /* HW_UFS_UFS_H */
|
||||
|
@ -763,6 +763,12 @@ typedef struct QEMU_PACKED UtpTaskReqDesc {
|
||||
*/
|
||||
#define UFS_WB_EXCEED_LIFETIME 0x0B
|
||||
|
||||
/*
|
||||
* The range of valid value of Active ICC attritbute
|
||||
* is from 0x00 to 0x0F.
|
||||
*/
|
||||
#define UFS_QUERY_ATTR_ACTIVE_ICC_MAXVALUE 0x0F
|
||||
|
||||
/*
|
||||
* In UFS Spec, the Extra Header Segment (EHS) starts from byte 32 in UPIU
|
||||
* request/response packet
|
||||
|
@ -119,6 +119,7 @@ static void ufs_send_nop_out(QUfs *ufs, uint8_t slot,
|
||||
|
||||
static void ufs_send_query(QUfs *ufs, uint8_t slot, uint8_t query_function,
|
||||
uint8_t query_opcode, uint8_t idn, uint8_t index,
|
||||
uint8_t selector, uint32_t attr_value,
|
||||
UtpTransferReqDesc *utrd_out, UtpUpiuRsp *rsp_out)
|
||||
{
|
||||
/* Build up utp transfer request descriptor */
|
||||
@ -136,13 +137,16 @@ static void ufs_send_query(QUfs *ufs, uint8_t slot, uint8_t query_function,
|
||||
req_upiu.header.query_func = query_function;
|
||||
req_upiu.header.task_tag = slot;
|
||||
/*
|
||||
* QEMU UFS does not currently support Write descriptor and Write attribute,
|
||||
* QEMU UFS does not currently support Write descriptor,
|
||||
* so the value of data_segment_length is always 0.
|
||||
*/
|
||||
req_upiu.header.data_segment_length = 0;
|
||||
req_upiu.qr.opcode = query_opcode;
|
||||
req_upiu.qr.idn = idn;
|
||||
req_upiu.qr.index = index;
|
||||
req_upiu.qr.selector = selector;
|
||||
req_upiu.qr.value = attr_value;
|
||||
req_upiu.qr.length = UFS_QUERY_DESC_MAX_SIZE;
|
||||
qtest_memwrite(ufs->dev.bus->qts, req_upiu_addr, &req_upiu,
|
||||
sizeof(req_upiu));
|
||||
|
||||
@ -344,7 +348,7 @@ static void ufs_init(QUfs *ufs, QGuestAllocator *alloc)
|
||||
/* Set fDeviceInit flag via query request */
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_SET_FLAG,
|
||||
UFS_QUERY_FLAG_IDN_FDEVICEINIT, 0, &utrd, &rsp_upiu);
|
||||
UFS_QUERY_FLAG_IDN_FDEVICEINIT, 0, 0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
|
||||
/* Wait for device to reset */
|
||||
@ -353,7 +357,8 @@ static void ufs_init(QUfs *ufs, QGuestAllocator *alloc)
|
||||
qtest_clock_step(ufs->dev.bus->qts, 100);
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_FLAG,
|
||||
UFS_QUERY_FLAG_IDN_FDEVICEINIT, 0, &utrd, &rsp_upiu);
|
||||
UFS_QUERY_FLAG_IDN_FDEVICEINIT, 0, 0, 0, &utrd,
|
||||
&rsp_upiu);
|
||||
} while (be32_to_cpu(rsp_upiu.qr.value) != 0 &&
|
||||
g_get_monotonic_time() < end_time);
|
||||
g_assert_cmpuint(be32_to_cpu(rsp_upiu.qr.value), ==, 0);
|
||||
@ -534,6 +539,373 @@ static void ufstest_read_write(void *obj, void *data, QGuestAllocator *alloc)
|
||||
ufs_exit(ufs, alloc);
|
||||
}
|
||||
|
||||
static void ufstest_query_flag_request(void *obj, void *data,
|
||||
QGuestAllocator *alloc)
|
||||
{
|
||||
QUfs *ufs = obj;
|
||||
|
||||
UtpTransferReqDesc utrd;
|
||||
UtpUpiuRsp rsp_upiu;
|
||||
ufs_init(ufs, alloc);
|
||||
|
||||
/* Read read-only flag */
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_FLAG,
|
||||
UFS_QUERY_FLAG_IDN_FDEVICEINIT, 0, 0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.opcode, ==, UFS_UPIU_QUERY_OPCODE_READ_FLAG);
|
||||
g_assert_cmpuint(rsp_upiu.qr.idn, ==, UFS_QUERY_FLAG_IDN_FDEVICEINIT);
|
||||
g_assert_cmpuint(rsp_upiu.qr.value, ==, be32_to_cpu(0));
|
||||
|
||||
/* Flag Set, Clear, Toggle Test with fDeviceLifeSpanModeEn */
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_FLAG,
|
||||
UFS_QUERY_FLAG_IDN_LIFE_SPAN_MODE_ENABLE, 0, 0, 0, &utrd,
|
||||
&rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.value, ==, be32_to_cpu(0));
|
||||
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_SET_FLAG,
|
||||
UFS_QUERY_FLAG_IDN_LIFE_SPAN_MODE_ENABLE, 0, 0, 0, &utrd,
|
||||
&rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.value, ==, be32_to_cpu(1));
|
||||
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_CLEAR_FLAG,
|
||||
UFS_QUERY_FLAG_IDN_LIFE_SPAN_MODE_ENABLE, 0, 0, 0, &utrd,
|
||||
&rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.value, ==, be32_to_cpu(0));
|
||||
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_TOGGLE_FLAG,
|
||||
UFS_QUERY_FLAG_IDN_LIFE_SPAN_MODE_ENABLE, 0, 0, 0, &utrd,
|
||||
&rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.value, ==, be32_to_cpu(1));
|
||||
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_TOGGLE_FLAG,
|
||||
UFS_QUERY_FLAG_IDN_LIFE_SPAN_MODE_ENABLE, 0, 0, 0, &utrd,
|
||||
&rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.value, ==, be32_to_cpu(0));
|
||||
|
||||
/* Read Write-only Flag (Intended Failure) */
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_FLAG,
|
||||
UFS_QUERY_FLAG_IDN_PURGE_ENABLE, 0, 0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==,
|
||||
UFS_OCS_INVALID_CMD_TABLE_ATTR);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==,
|
||||
UFS_QUERY_RESULT_NOT_READABLE);
|
||||
|
||||
/* Write Read-Only Flag (Intended Failure) */
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_SET_FLAG, UFS_QUERY_FLAG_IDN_BUSY_RTC,
|
||||
0, 0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==,
|
||||
UFS_OCS_INVALID_CMD_TABLE_ATTR);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==,
|
||||
UFS_QUERY_RESULT_NOT_WRITEABLE);
|
||||
|
||||
ufs_exit(ufs, alloc);
|
||||
}
|
||||
|
||||
static void ufstest_query_attr_request(void *obj, void *data,
|
||||
QGuestAllocator *alloc)
|
||||
{
|
||||
QUfs *ufs = obj;
|
||||
|
||||
UtpTransferReqDesc utrd;
|
||||
UtpUpiuRsp rsp_upiu;
|
||||
ufs_init(ufs, alloc);
|
||||
|
||||
/* Read Readable Attributes*/
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_ATTR,
|
||||
UFS_QUERY_ATTR_IDN_BOOT_LU_EN, 0, 0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.opcode, ==, UFS_UPIU_QUERY_OPCODE_READ_ATTR);
|
||||
g_assert_cmpuint(rsp_upiu.qr.idn, ==, UFS_QUERY_ATTR_IDN_BOOT_LU_EN);
|
||||
g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x00));
|
||||
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_ATTR,
|
||||
UFS_QUERY_ATTR_IDN_BKOPS_STATUS, 0, 0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x00));
|
||||
|
||||
/* Write Writable Attributes & Read Again */
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_WRITE_ATTR,
|
||||
UFS_QUERY_ATTR_IDN_ACTIVE_ICC_LVL, 0, 0, 0x03, &utrd,
|
||||
&rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x03));
|
||||
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_WRITE_ATTR,
|
||||
UFS_QUERY_ATTR_IDN_EE_CONTROL, 0, 0, 0x07, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x07));
|
||||
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_ATTR,
|
||||
UFS_QUERY_ATTR_IDN_ACTIVE_ICC_LVL, 0, 0, 0, &utrd,
|
||||
&rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x03));
|
||||
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_ATTR,
|
||||
UFS_QUERY_ATTR_IDN_EE_CONTROL, 0, 0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x07));
|
||||
|
||||
/* Write Invalid Value (Intended Error) */
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_WRITE_ATTR,
|
||||
UFS_QUERY_ATTR_IDN_ACTIVE_ICC_LVL, 0, 0, 0x10, &utrd,
|
||||
&rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==,
|
||||
UFS_OCS_INVALID_CMD_TABLE_ATTR);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==,
|
||||
UFS_QUERY_RESULT_INVALID_VALUE);
|
||||
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_ATTR,
|
||||
UFS_QUERY_ATTR_IDN_ACTIVE_ICC_LVL, 0, 0, 0, &utrd,
|
||||
&rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x03));
|
||||
|
||||
/* Read Write-Only Attribute (Intended Error) */
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_ATTR,
|
||||
UFS_QUERY_ATTR_IDN_SECONDS_PASSED, 0, 0, 0, &utrd,
|
||||
&rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==,
|
||||
UFS_OCS_INVALID_CMD_TABLE_ATTR);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==,
|
||||
UFS_QUERY_RESULT_NOT_READABLE);
|
||||
|
||||
/* Write Read-Only Attribute (Intended Error) */
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_WRITE_ATTR,
|
||||
UFS_QUERY_ATTR_IDN_POWER_MODE, 0, 0, 0x01, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==,
|
||||
UFS_OCS_INVALID_CMD_TABLE_ATTR);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==,
|
||||
UFS_QUERY_RESULT_NOT_WRITEABLE);
|
||||
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_ATTR,
|
||||
UFS_QUERY_ATTR_IDN_POWER_MODE, 0, 0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x00));
|
||||
|
||||
/* Reset Written Attributes */
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_WRITE_ATTR,
|
||||
UFS_QUERY_ATTR_IDN_ACTIVE_ICC_LVL, 0, 0, 0, &utrd,
|
||||
&rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x00));
|
||||
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_WRITE_ATTR,
|
||||
UFS_QUERY_ATTR_IDN_EE_CONTROL, 0, 0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x00));
|
||||
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_ATTR,
|
||||
UFS_QUERY_ATTR_IDN_ACTIVE_ICC_LVL, 0, 0, 0, &utrd,
|
||||
&rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x00));
|
||||
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_ATTR,
|
||||
UFS_QUERY_ATTR_IDN_EE_CONTROL, 0, 0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x00));
|
||||
|
||||
ufs_exit(ufs, alloc);
|
||||
}
|
||||
|
||||
static void ufstest_query_desc_request(void *obj, void *data,
|
||||
QGuestAllocator *alloc)
|
||||
{
|
||||
QUfs *ufs = obj;
|
||||
|
||||
UtpTransferReqDesc utrd;
|
||||
UtpUpiuRsp rsp_upiu;
|
||||
ufs_init(ufs, alloc);
|
||||
|
||||
/* Write Descriptor is not supported yet */
|
||||
|
||||
/* Read Device Descriptor */
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_DEVICE,
|
||||
0, 0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.opcode, ==, UFS_UPIU_QUERY_OPCODE_READ_DESC);
|
||||
g_assert_cmpuint(rsp_upiu.qr.idn, ==, UFS_QUERY_DESC_IDN_DEVICE);
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[0], ==, sizeof(DeviceDescriptor));
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_DEVICE);
|
||||
|
||||
/* Read Configuration Descriptor is not supported yet*/
|
||||
|
||||
/* Read Unit Descriptor */
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_UNIT, 0,
|
||||
0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[0], ==, sizeof(UnitDescriptor));
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_UNIT);
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[2], ==, 0);
|
||||
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_UNIT, 1,
|
||||
0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[0], ==, sizeof(UnitDescriptor));
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_UNIT);
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[2], ==, 1);
|
||||
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_UNIT,
|
||||
UFS_UPIU_RPMB_WLUN, 0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[0], ==, sizeof(RpmbUnitDescriptor));
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_UNIT);
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[2], ==, UFS_UPIU_RPMB_WLUN);
|
||||
|
||||
/* Read Interconnect Descriptor */
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_DESC,
|
||||
UFS_QUERY_DESC_IDN_INTERCONNECT, 0, 0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[0], ==, sizeof(InterconnectDescriptor));
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_INTERCONNECT);
|
||||
|
||||
/* Read String Descriptor */
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_STRING,
|
||||
0, 0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[0], ==, 0x12);
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_STRING);
|
||||
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_STRING,
|
||||
1, 0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[0], ==, 0x22);
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_STRING);
|
||||
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_STRING,
|
||||
4, 0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[0], ==, 0x0a);
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_STRING);
|
||||
|
||||
/* Read Geometry Descriptor */
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_GEOMETRY,
|
||||
0, 0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[0], ==, sizeof(GeometryDescriptor));
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_GEOMETRY);
|
||||
|
||||
/* Read Power Descriptor */
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_POWER, 0,
|
||||
0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[0], ==,
|
||||
sizeof(PowerParametersDescriptor));
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_POWER);
|
||||
|
||||
/* Read Health Descriptor */
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_HEALTH,
|
||||
0, 0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[0], ==, sizeof(DeviceHealthDescriptor));
|
||||
g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_HEALTH);
|
||||
|
||||
/* Invalid Index (Intended Failure) */
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_UNIT, 4,
|
||||
0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==,
|
||||
UFS_OCS_INVALID_CMD_TABLE_ATTR);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==,
|
||||
UFS_QUERY_RESULT_INVALID_INDEX);
|
||||
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_STRING,
|
||||
5, 0, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==,
|
||||
UFS_OCS_INVALID_CMD_TABLE_ATTR);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==,
|
||||
UFS_QUERY_RESULT_INVALID_INDEX);
|
||||
|
||||
/* Invalid Selector (Intended Failure) */
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_DEVICE,
|
||||
0, 1, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==,
|
||||
UFS_OCS_INVALID_CMD_TABLE_ATTR);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==,
|
||||
UFS_QUERY_RESULT_INVALID_SELECTOR);
|
||||
|
||||
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
|
||||
UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_STRING,
|
||||
0, 1, 0, &utrd, &rsp_upiu);
|
||||
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==,
|
||||
UFS_OCS_INVALID_CMD_TABLE_ATTR);
|
||||
g_assert_cmpuint(rsp_upiu.header.response, ==,
|
||||
UFS_QUERY_RESULT_INVALID_SELECTOR);
|
||||
|
||||
ufs_exit(ufs, alloc);
|
||||
}
|
||||
|
||||
static void drive_destroy(void *path)
|
||||
{
|
||||
unlink(path);
|
||||
@ -601,6 +973,12 @@ static void ufs_register_nodes(void)
|
||||
}
|
||||
qos_add_test("init", "ufs", ufstest_init, NULL);
|
||||
qos_add_test("read-write", "ufs", ufstest_read_write, &io_test_opts);
|
||||
qos_add_test("flag read-write", "ufs",
|
||||
ufstest_query_flag_request, &io_test_opts);
|
||||
qos_add_test("attr read-write", "ufs",
|
||||
ufstest_query_attr_request, &io_test_opts);
|
||||
qos_add_test("desc read-write", "ufs",
|
||||
ufstest_query_desc_request, &io_test_opts);
|
||||
}
|
||||
|
||||
libqos_init(ufs_register_nodes);
|
||||
|
Loading…
x
Reference in New Issue
Block a user