@@ -540,6 +540,86 @@ static void ufstest_read_write(void *obj, void *data, QGuestAllocator *alloc)
ufs_exit(ufs, alloc);
}
+static void ufstest_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, ==, 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, ==, 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, ==, 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, ==, 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, ==, 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, ==, 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 drive_destroy(void *path)
{
unlink(path);
@@ -607,6 +687,7 @@ 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_flag_request, &io_test_opts);
}
libqos_init(ufs_register_nodes);