1 /* 2 * QTest testcase for UFS 3 * 4 * Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved. 5 * 6 * SPDX-License-Identifier: GPL-2.0-or-later 7 */ 8 9 #include "qemu/osdep.h" 10 #include "qemu/module.h" 11 #include "qemu/units.h" 12 #include "libqtest.h" 13 #include "libqos/qgraph.h" 14 #include "libqos/pci.h" 15 #include "scsi/constants.h" 16 #include "block/ufs.h" 17 18 /* Test images sizes in Bytes */ 19 #define TEST_IMAGE_SIZE (64 * 1024 * 1024) 20 /* Timeout for various operations, in seconds. */ 21 #define TIMEOUT_SECONDS 10 22 /* Maximum PRD entry count */ 23 #define MAX_PRD_ENTRY_COUNT 10 24 #define PRD_ENTRY_DATA_SIZE 4096 25 /* Constants to build upiu */ 26 #define UTP_COMMAND_DESCRIPTOR_SIZE 4096 27 #define UTP_RESPONSE_UPIU_OFFSET 1024 28 #define UTP_PRDT_UPIU_OFFSET 2048 29 30 typedef struct QUfs QUfs; 31 32 struct QUfs { 33 QOSGraphObject obj; 34 QPCIDevice dev; 35 QPCIBar bar; 36 37 uint64_t utrlba; 38 uint64_t utmrlba; 39 uint64_t cmd_desc_addr; 40 uint64_t data_buffer_addr; 41 42 bool enabled; 43 }; 44 45 static inline uint32_t ufs_rreg(QUfs *ufs, size_t offset) 46 { 47 return qpci_io_readl(&ufs->dev, ufs->bar, offset); 48 } 49 50 static inline void ufs_wreg(QUfs *ufs, size_t offset, uint32_t value) 51 { 52 qpci_io_writel(&ufs->dev, ufs->bar, offset, value); 53 } 54 55 static void ufs_wait_for_irq(QUfs *ufs) 56 { 57 uint64_t end_time; 58 uint32_t is; 59 /* Wait for device to reset as the linux driver does. */ 60 end_time = g_get_monotonic_time() + TIMEOUT_SECONDS * G_TIME_SPAN_SECOND; 61 do { 62 qtest_clock_step(ufs->dev.bus->qts, 100); 63 is = ufs_rreg(ufs, A_IS); 64 } while (is == 0 && g_get_monotonic_time() < end_time); 65 } 66 67 static UtpTransferReqDesc ufs_build_req_utrd(uint64_t cmd_desc_addr, 68 uint8_t slot, 69 uint32_t data_direction, 70 uint16_t prd_table_length) 71 { 72 UtpTransferReqDesc req = { 0 }; 73 uint64_t command_desc_base_addr = 74 cmd_desc_addr + slot * UTP_COMMAND_DESCRIPTOR_SIZE; 75 76 req.header.dword_0 = 77 cpu_to_le32(1 << 28 | data_direction | UFS_UTP_REQ_DESC_INT_CMD); 78 req.header.dword_2 = cpu_to_le32(UFS_OCS_INVALID_COMMAND_STATUS); 79 80 req.command_desc_base_addr_hi = cpu_to_le32(command_desc_base_addr >> 32); 81 req.command_desc_base_addr_lo = 82 cpu_to_le32(command_desc_base_addr & 0xffffffff); 83 req.response_upiu_offset = 84 cpu_to_le16(UTP_RESPONSE_UPIU_OFFSET / sizeof(uint32_t)); 85 req.response_upiu_length = cpu_to_le16(sizeof(UtpUpiuRsp)); 86 req.prd_table_offset = cpu_to_le16(UTP_PRDT_UPIU_OFFSET / sizeof(uint32_t)); 87 req.prd_table_length = cpu_to_le16(prd_table_length); 88 return req; 89 } 90 91 static void ufs_send_nop_out(QUfs *ufs, uint8_t slot, 92 UtpTransferReqDesc *utrd_out, UtpUpiuRsp *rsp_out) 93 { 94 /* Build up utp transfer request descriptor */ 95 UtpTransferReqDesc utrd = ufs_build_req_utrd(ufs->cmd_desc_addr, slot, 96 UFS_UTP_NO_DATA_TRANSFER, 0); 97 uint64_t utrd_addr = ufs->utrlba + slot * sizeof(UtpTransferReqDesc); 98 uint64_t req_upiu_addr = 99 ufs->cmd_desc_addr + slot * UTP_COMMAND_DESCRIPTOR_SIZE; 100 uint64_t rsp_upiu_addr = req_upiu_addr + UTP_RESPONSE_UPIU_OFFSET; 101 qtest_memwrite(ufs->dev.bus->qts, utrd_addr, &utrd, sizeof(utrd)); 102 103 /* Build up request upiu */ 104 UtpUpiuReq req_upiu = { 0 }; 105 req_upiu.header.trans_type = UFS_UPIU_TRANSACTION_NOP_OUT; 106 req_upiu.header.task_tag = slot; 107 qtest_memwrite(ufs->dev.bus->qts, req_upiu_addr, &req_upiu, 108 sizeof(req_upiu)); 109 110 /* Ring Doorbell */ 111 ufs_wreg(ufs, A_UTRLDBR, 1); 112 ufs_wait_for_irq(ufs); 113 g_assert_true(FIELD_EX32(ufs_rreg(ufs, A_IS), IS, UTRCS)); 114 ufs_wreg(ufs, A_IS, FIELD_DP32(0, IS, UTRCS, 1)); 115 116 qtest_memread(ufs->dev.bus->qts, utrd_addr, utrd_out, sizeof(*utrd_out)); 117 qtest_memread(ufs->dev.bus->qts, rsp_upiu_addr, rsp_out, sizeof(*rsp_out)); 118 } 119 120 static void ufs_send_query(QUfs *ufs, uint8_t slot, uint8_t query_function, 121 uint8_t query_opcode, uint8_t idn, uint8_t index, 122 uint8_t selector, uint32_t attr_value, 123 UtpTransferReqDesc *utrd_out, UtpUpiuRsp *rsp_out) 124 { 125 /* Build up utp transfer request descriptor */ 126 UtpTransferReqDesc utrd = ufs_build_req_utrd(ufs->cmd_desc_addr, slot, 127 UFS_UTP_NO_DATA_TRANSFER, 0); 128 uint64_t utrd_addr = ufs->utrlba + slot * sizeof(UtpTransferReqDesc); 129 uint64_t req_upiu_addr = 130 ufs->cmd_desc_addr + slot * UTP_COMMAND_DESCRIPTOR_SIZE; 131 uint64_t rsp_upiu_addr = req_upiu_addr + UTP_RESPONSE_UPIU_OFFSET; 132 qtest_memwrite(ufs->dev.bus->qts, utrd_addr, &utrd, sizeof(utrd)); 133 134 /* Build up request upiu */ 135 UtpUpiuReq req_upiu = { 0 }; 136 req_upiu.header.trans_type = UFS_UPIU_TRANSACTION_QUERY_REQ; 137 req_upiu.header.query_func = query_function; 138 req_upiu.header.task_tag = slot; 139 /* 140 * QEMU UFS does not currently support Write descriptor, 141 * so the value of data_segment_length is always 0. 142 */ 143 req_upiu.header.data_segment_length = 0; 144 req_upiu.qr.opcode = query_opcode; 145 req_upiu.qr.idn = idn; 146 req_upiu.qr.index = index; 147 req_upiu.qr.selector = selector; 148 req_upiu.qr.value = attr_value; 149 req_upiu.qr.length = UFS_QUERY_DESC_MAX_SIZE; 150 qtest_memwrite(ufs->dev.bus->qts, req_upiu_addr, &req_upiu, 151 sizeof(req_upiu)); 152 153 /* Ring Doorbell */ 154 ufs_wreg(ufs, A_UTRLDBR, 1); 155 ufs_wait_for_irq(ufs); 156 g_assert_true(FIELD_EX32(ufs_rreg(ufs, A_IS), IS, UTRCS)); 157 ufs_wreg(ufs, A_IS, FIELD_DP32(0, IS, UTRCS, 1)); 158 159 qtest_memread(ufs->dev.bus->qts, utrd_addr, utrd_out, sizeof(*utrd_out)); 160 qtest_memread(ufs->dev.bus->qts, rsp_upiu_addr, rsp_out, sizeof(*rsp_out)); 161 } 162 163 static void ufs_send_scsi_command(QUfs *ufs, uint8_t slot, uint8_t lun, 164 const uint8_t *cdb, const uint8_t *data_in, 165 size_t data_in_len, uint8_t *data_out, 166 size_t data_out_len, 167 UtpTransferReqDesc *utrd_out, 168 UtpUpiuRsp *rsp_out) 169 170 { 171 /* Build up PRDT */ 172 UfshcdSgEntry entries[MAX_PRD_ENTRY_COUNT] = { 173 0, 174 }; 175 uint8_t flags; 176 uint16_t prd_table_length, i; 177 uint32_t data_direction, data_len; 178 uint64_t req_upiu_addr = 179 ufs->cmd_desc_addr + slot * UTP_COMMAND_DESCRIPTOR_SIZE; 180 uint64_t prdt_addr = req_upiu_addr + UTP_PRDT_UPIU_OFFSET; 181 182 g_assert_true(data_in_len < MAX_PRD_ENTRY_COUNT * PRD_ENTRY_DATA_SIZE); 183 g_assert_true(data_out_len < MAX_PRD_ENTRY_COUNT * PRD_ENTRY_DATA_SIZE); 184 if (data_in_len > 0) { 185 g_assert_nonnull(data_in); 186 data_direction = UFS_UTP_HOST_TO_DEVICE; 187 data_len = data_in_len; 188 flags = UFS_UPIU_CMD_FLAGS_WRITE; 189 } else if (data_out_len > 0) { 190 g_assert_nonnull(data_out); 191 data_direction = UFS_UTP_DEVICE_TO_HOST; 192 data_len = data_out_len; 193 flags = UFS_UPIU_CMD_FLAGS_READ; 194 } else { 195 data_direction = UFS_UTP_NO_DATA_TRANSFER; 196 data_len = 0; 197 flags = UFS_UPIU_CMD_FLAGS_NONE; 198 } 199 prd_table_length = DIV_ROUND_UP(data_len, PRD_ENTRY_DATA_SIZE); 200 201 qtest_memset(ufs->dev.bus->qts, ufs->data_buffer_addr, 0, 202 MAX_PRD_ENTRY_COUNT * PRD_ENTRY_DATA_SIZE); 203 if (data_in_len) { 204 qtest_memwrite(ufs->dev.bus->qts, ufs->data_buffer_addr, data_in, 205 data_in_len); 206 } 207 208 for (i = 0; i < prd_table_length; i++) { 209 entries[i].addr = 210 cpu_to_le64(ufs->data_buffer_addr + i * sizeof(UfshcdSgEntry)); 211 if (i + 1 != prd_table_length) { 212 entries[i].size = cpu_to_le32(PRD_ENTRY_DATA_SIZE - 1); 213 } else { 214 entries[i].size = cpu_to_le32( 215 data_len - (PRD_ENTRY_DATA_SIZE * (prd_table_length - 1)) - 1); 216 } 217 } 218 qtest_memwrite(ufs->dev.bus->qts, prdt_addr, entries, 219 prd_table_length * sizeof(UfshcdSgEntry)); 220 221 /* Build up utp transfer request descriptor */ 222 UtpTransferReqDesc utrd = ufs_build_req_utrd( 223 ufs->cmd_desc_addr, slot, data_direction, prd_table_length); 224 uint64_t utrd_addr = ufs->utrlba + slot * sizeof(UtpTransferReqDesc); 225 uint64_t rsp_upiu_addr = req_upiu_addr + UTP_RESPONSE_UPIU_OFFSET; 226 qtest_memwrite(ufs->dev.bus->qts, utrd_addr, &utrd, sizeof(utrd)); 227 228 /* Build up request upiu */ 229 UtpUpiuReq req_upiu = { 0 }; 230 req_upiu.header.trans_type = UFS_UPIU_TRANSACTION_COMMAND; 231 req_upiu.header.flags = flags; 232 req_upiu.header.lun = lun; 233 req_upiu.header.task_tag = slot; 234 req_upiu.sc.exp_data_transfer_len = cpu_to_be32(data_len); 235 memcpy(req_upiu.sc.cdb, cdb, UFS_CDB_SIZE); 236 qtest_memwrite(ufs->dev.bus->qts, req_upiu_addr, &req_upiu, 237 sizeof(req_upiu)); 238 239 /* Ring Doorbell */ 240 ufs_wreg(ufs, A_UTRLDBR, 1); 241 ufs_wait_for_irq(ufs); 242 g_assert_true(FIELD_EX32(ufs_rreg(ufs, A_IS), IS, UTRCS)); 243 ufs_wreg(ufs, A_IS, FIELD_DP32(0, IS, UTRCS, 1)); 244 245 qtest_memread(ufs->dev.bus->qts, utrd_addr, utrd_out, sizeof(*utrd_out)); 246 qtest_memread(ufs->dev.bus->qts, rsp_upiu_addr, rsp_out, sizeof(*rsp_out)); 247 if (data_out_len) { 248 qtest_memread(ufs->dev.bus->qts, ufs->data_buffer_addr, data_out, 249 data_out_len); 250 } 251 } 252 253 /** 254 * Initialize Ufs host controller and logical unit. 255 * After running this function, you can make a transfer request to the UFS. 256 */ 257 static void ufs_init(QUfs *ufs, QGuestAllocator *alloc) 258 { 259 uint64_t end_time; 260 uint32_t nutrs, nutmrs; 261 uint32_t hcs, is, ucmdarg2, cap; 262 uint32_t hce = 0, ie = 0; 263 UtpTransferReqDesc utrd; 264 UtpUpiuRsp rsp_upiu; 265 266 ufs->bar = qpci_iomap(&ufs->dev, 0, NULL); 267 qpci_device_enable(&ufs->dev); 268 269 /* Start host controller initialization */ 270 hce = FIELD_DP32(hce, HCE, HCE, 1); 271 ufs_wreg(ufs, A_HCE, hce); 272 273 /* Wait for device to reset */ 274 end_time = g_get_monotonic_time() + TIMEOUT_SECONDS * G_TIME_SPAN_SECOND; 275 do { 276 qtest_clock_step(ufs->dev.bus->qts, 100); 277 hce = FIELD_EX32(ufs_rreg(ufs, A_HCE), HCE, HCE); 278 } while (hce == 0 && g_get_monotonic_time() < end_time); 279 g_assert_cmpuint(hce, ==, 1); 280 281 /* Enable interrupt */ 282 ie = FIELD_DP32(ie, IE, UCCE, 1); 283 ie = FIELD_DP32(ie, IE, UHESE, 1); 284 ie = FIELD_DP32(ie, IE, UHXSE, 1); 285 ie = FIELD_DP32(ie, IE, UPMSE, 1); 286 ufs_wreg(ufs, A_IE, ie); 287 288 /* Send DME_LINK_STARTUP uic command */ 289 hcs = ufs_rreg(ufs, A_HCS); 290 g_assert_true(FIELD_EX32(hcs, HCS, UCRDY)); 291 292 ufs_wreg(ufs, A_UCMDARG1, 0); 293 ufs_wreg(ufs, A_UCMDARG2, 0); 294 ufs_wreg(ufs, A_UCMDARG3, 0); 295 ufs_wreg(ufs, A_UICCMD, UFS_UIC_CMD_DME_LINK_STARTUP); 296 297 is = ufs_rreg(ufs, A_IS); 298 g_assert_true(FIELD_EX32(is, IS, UCCS)); 299 ufs_wreg(ufs, A_IS, FIELD_DP32(0, IS, UCCS, 1)); 300 301 ucmdarg2 = ufs_rreg(ufs, A_UCMDARG2); 302 g_assert_cmpuint(ucmdarg2, ==, 0); 303 is = ufs_rreg(ufs, A_IS); 304 g_assert_cmpuint(is, ==, 0); 305 hcs = ufs_rreg(ufs, A_HCS); 306 g_assert_true(FIELD_EX32(hcs, HCS, DP)); 307 g_assert_true(FIELD_EX32(hcs, HCS, UTRLRDY)); 308 g_assert_true(FIELD_EX32(hcs, HCS, UTMRLRDY)); 309 g_assert_true(FIELD_EX32(hcs, HCS, UCRDY)); 310 311 /* Enable all interrupt functions */ 312 ie = FIELD_DP32(ie, IE, UTRCE, 1); 313 ie = FIELD_DP32(ie, IE, UEE, 1); 314 ie = FIELD_DP32(ie, IE, UPMSE, 1); 315 ie = FIELD_DP32(ie, IE, UHXSE, 1); 316 ie = FIELD_DP32(ie, IE, UHESE, 1); 317 ie = FIELD_DP32(ie, IE, UTMRCE, 1); 318 ie = FIELD_DP32(ie, IE, UCCE, 1); 319 ie = FIELD_DP32(ie, IE, DFEE, 1); 320 ie = FIELD_DP32(ie, IE, HCFEE, 1); 321 ie = FIELD_DP32(ie, IE, SBFEE, 1); 322 ie = FIELD_DP32(ie, IE, CEFEE, 1); 323 ufs_wreg(ufs, A_IE, ie); 324 ufs_wreg(ufs, A_UTRIACR, 0); 325 326 /* Enable transfer request and task management request */ 327 cap = ufs_rreg(ufs, A_CAP); 328 nutrs = FIELD_EX32(cap, CAP, NUTRS) + 1; 329 nutmrs = FIELD_EX32(cap, CAP, NUTMRS) + 1; 330 ufs->cmd_desc_addr = 331 guest_alloc(alloc, nutrs * UTP_COMMAND_DESCRIPTOR_SIZE); 332 ufs->data_buffer_addr = 333 guest_alloc(alloc, MAX_PRD_ENTRY_COUNT * PRD_ENTRY_DATA_SIZE); 334 ufs->utrlba = guest_alloc(alloc, nutrs * sizeof(UtpTransferReqDesc)); 335 ufs->utmrlba = guest_alloc(alloc, nutmrs * sizeof(UtpTaskReqDesc)); 336 337 ufs_wreg(ufs, A_UTRLBA, ufs->utrlba & 0xffffffff); 338 ufs_wreg(ufs, A_UTRLBAU, ufs->utrlba >> 32); 339 ufs_wreg(ufs, A_UTMRLBA, ufs->utmrlba & 0xffffffff); 340 ufs_wreg(ufs, A_UTMRLBAU, ufs->utmrlba >> 32); 341 ufs_wreg(ufs, A_UTRLRSR, 1); 342 ufs_wreg(ufs, A_UTMRLRSR, 1); 343 344 /* Send nop out to test transfer request */ 345 ufs_send_nop_out(ufs, 0, &utrd, &rsp_upiu); 346 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 347 348 /* Set fDeviceInit flag via query request */ 349 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST, 350 UFS_UPIU_QUERY_OPCODE_SET_FLAG, 351 UFS_QUERY_FLAG_IDN_FDEVICEINIT, 0, 0, 0, &utrd, &rsp_upiu); 352 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 353 354 /* Wait for device to reset */ 355 end_time = g_get_monotonic_time() + TIMEOUT_SECONDS * G_TIME_SPAN_SECOND; 356 do { 357 qtest_clock_step(ufs->dev.bus->qts, 100); 358 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 359 UFS_UPIU_QUERY_OPCODE_READ_FLAG, 360 UFS_QUERY_FLAG_IDN_FDEVICEINIT, 0, 0, 0, &utrd, 361 &rsp_upiu); 362 } while (be32_to_cpu(rsp_upiu.qr.value) != 0 && 363 g_get_monotonic_time() < end_time); 364 g_assert_cmpuint(be32_to_cpu(rsp_upiu.qr.value), ==, 0); 365 366 ufs->enabled = true; 367 } 368 369 static void ufs_exit(QUfs *ufs, QGuestAllocator *alloc) 370 { 371 if (ufs->enabled) { 372 guest_free(alloc, ufs->utrlba); 373 guest_free(alloc, ufs->utmrlba); 374 guest_free(alloc, ufs->cmd_desc_addr); 375 guest_free(alloc, ufs->data_buffer_addr); 376 } 377 378 qpci_iounmap(&ufs->dev, ufs->bar); 379 } 380 381 static void *ufs_get_driver(void *obj, const char *interface) 382 { 383 QUfs *ufs = obj; 384 385 if (!g_strcmp0(interface, "pci-device")) { 386 return &ufs->dev; 387 } 388 389 fprintf(stderr, "%s not present in ufs\n", interface); 390 g_assert_not_reached(); 391 } 392 393 static void *ufs_create(void *pci_bus, QGuestAllocator *alloc, void *addr) 394 { 395 QUfs *ufs = g_new0(QUfs, 1); 396 QPCIBus *bus = pci_bus; 397 398 qpci_device_init(&ufs->dev, bus, addr); 399 ufs->obj.get_driver = ufs_get_driver; 400 401 return &ufs->obj; 402 } 403 404 static void ufstest_reg_read(void *obj, void *data, QGuestAllocator *alloc) 405 { 406 QUfs *ufs = obj; 407 uint32_t cap; 408 409 ufs->bar = qpci_iomap(&ufs->dev, 0, NULL); 410 qpci_device_enable(&ufs->dev); 411 412 cap = ufs_rreg(ufs, A_CAP); 413 g_assert_cmpuint(FIELD_EX32(cap, CAP, NUTRS), ==, 31); 414 g_assert_cmpuint(FIELD_EX32(cap, CAP, NUTMRS), ==, 7); 415 g_assert_cmpuint(FIELD_EX32(cap, CAP, 64AS), ==, 1); 416 417 qpci_iounmap(&ufs->dev, ufs->bar); 418 } 419 420 static void ufstest_init(void *obj, void *data, QGuestAllocator *alloc) 421 { 422 QUfs *ufs = obj; 423 424 uint8_t buf[4096] = { 0 }; 425 const uint8_t report_luns_cdb[UFS_CDB_SIZE] = { 426 /* allocation length 4096 */ 427 REPORT_LUNS, 0x00, 0x00, 0x00, 0x00, 0x00, 428 0x00, 0x00, 0x10, 0x00, 0x00, 0x00 429 }; 430 const uint8_t test_unit_ready_cdb[UFS_CDB_SIZE] = { 431 TEST_UNIT_READY, 432 }; 433 const uint8_t request_sense_cdb[UFS_CDB_SIZE] = { 434 REQUEST_SENSE, 435 }; 436 UtpTransferReqDesc utrd; 437 UtpUpiuRsp rsp_upiu; 438 439 ufs_init(ufs, alloc); 440 441 /* Check REPORT_LUNS */ 442 ufs_send_scsi_command(ufs, 0, 0, report_luns_cdb, NULL, 0, buf, sizeof(buf), 443 &utrd, &rsp_upiu); 444 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 445 g_assert_cmpuint(rsp_upiu.header.scsi_status, ==, GOOD); 446 /* LUN LIST LENGTH should be 8, in big endian */ 447 g_assert_cmpuint(buf[3], ==, 8); 448 /* There is one logical unit whose lun is 0 */ 449 g_assert_cmpuint(buf[9], ==, 0); 450 451 /* Clear Unit Attention */ 452 ufs_send_scsi_command(ufs, 0, 0, request_sense_cdb, NULL, 0, buf, 453 sizeof(buf), &utrd, &rsp_upiu); 454 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 455 g_assert_cmpuint(rsp_upiu.header.scsi_status, ==, CHECK_CONDITION); 456 457 /* Check TEST_UNIT_READY */ 458 ufs_send_scsi_command(ufs, 0, 0, test_unit_ready_cdb, NULL, 0, NULL, 0, 459 &utrd, &rsp_upiu); 460 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 461 g_assert_cmpuint(rsp_upiu.header.scsi_status, ==, GOOD); 462 463 ufs_exit(ufs, alloc); 464 } 465 466 static void ufstest_read_write(void *obj, void *data, QGuestAllocator *alloc) 467 { 468 QUfs *ufs = obj; 469 uint8_t read_buf[4096] = { 0 }; 470 uint8_t write_buf[4096] = { 0 }; 471 const uint8_t read_capacity_cdb[UFS_CDB_SIZE] = { 472 /* allocation length 4096 */ 473 SERVICE_ACTION_IN_16, 474 SAI_READ_CAPACITY_16, 475 0x00, 476 0x00, 477 0x00, 478 0x00, 479 0x00, 480 0x00, 481 0x00, 482 0x00, 483 0x00, 484 0x00, 485 0x10, 486 0x00, 487 0x00, 488 0x00 489 }; 490 const uint8_t request_sense_cdb[UFS_CDB_SIZE] = { 491 REQUEST_SENSE, 492 }; 493 const uint8_t read_cdb[UFS_CDB_SIZE] = { 494 /* READ(10) to LBA 0, transfer length 1 */ 495 READ_10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 496 }; 497 const uint8_t write_cdb[UFS_CDB_SIZE] = { 498 /* WRITE(10) to LBA 0, transfer length 1 */ 499 WRITE_10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 500 }; 501 uint32_t block_size; 502 UtpTransferReqDesc utrd; 503 UtpUpiuRsp rsp_upiu; 504 const int test_lun = 1; 505 506 ufs_init(ufs, alloc); 507 508 /* Clear Unit Attention */ 509 ufs_send_scsi_command(ufs, 0, test_lun, request_sense_cdb, NULL, 0, 510 read_buf, sizeof(read_buf), &utrd, &rsp_upiu); 511 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 512 g_assert_cmpuint(rsp_upiu.header.scsi_status, ==, CHECK_CONDITION); 513 514 /* Read capacity */ 515 ufs_send_scsi_command(ufs, 0, test_lun, read_capacity_cdb, NULL, 0, 516 read_buf, sizeof(read_buf), &utrd, &rsp_upiu); 517 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 518 g_assert_cmpuint(rsp_upiu.header.scsi_status, ==, 519 UFS_COMMAND_RESULT_SUCCESS); 520 block_size = ldl_be_p(&read_buf[8]); 521 g_assert_cmpuint(block_size, ==, 4096); 522 523 /* Write data */ 524 memset(write_buf, 0xab, block_size); 525 ufs_send_scsi_command(ufs, 0, test_lun, write_cdb, write_buf, block_size, 526 NULL, 0, &utrd, &rsp_upiu); 527 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 528 g_assert_cmpuint(rsp_upiu.header.scsi_status, ==, 529 UFS_COMMAND_RESULT_SUCCESS); 530 531 /* Read data and verify */ 532 ufs_send_scsi_command(ufs, 0, test_lun, read_cdb, NULL, 0, read_buf, 533 block_size, &utrd, &rsp_upiu); 534 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 535 g_assert_cmpuint(rsp_upiu.header.scsi_status, ==, 536 UFS_COMMAND_RESULT_SUCCESS); 537 g_assert_cmpint(memcmp(read_buf, write_buf, block_size), ==, 0); 538 539 ufs_exit(ufs, alloc); 540 } 541 542 static void ufstest_query_flag_request(void *obj, void *data, 543 QGuestAllocator *alloc) 544 { 545 QUfs *ufs = obj; 546 547 UtpTransferReqDesc utrd; 548 UtpUpiuRsp rsp_upiu; 549 ufs_init(ufs, alloc); 550 551 /* Read read-only flag */ 552 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 553 UFS_UPIU_QUERY_OPCODE_READ_FLAG, 554 UFS_QUERY_FLAG_IDN_FDEVICEINIT, 0, 0, 0, &utrd, &rsp_upiu); 555 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 556 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 557 g_assert_cmpuint(rsp_upiu.qr.opcode, ==, UFS_UPIU_QUERY_OPCODE_READ_FLAG); 558 g_assert_cmpuint(rsp_upiu.qr.idn, ==, UFS_QUERY_FLAG_IDN_FDEVICEINIT); 559 g_assert_cmpuint(rsp_upiu.qr.value, ==, be32_to_cpu(0)); 560 561 /* Flag Set, Clear, Toggle Test with fDeviceLifeSpanModeEn */ 562 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 563 UFS_UPIU_QUERY_OPCODE_READ_FLAG, 564 UFS_QUERY_FLAG_IDN_LIFE_SPAN_MODE_ENABLE, 0, 0, 0, &utrd, 565 &rsp_upiu); 566 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 567 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 568 g_assert_cmpuint(rsp_upiu.qr.value, ==, be32_to_cpu(0)); 569 570 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST, 571 UFS_UPIU_QUERY_OPCODE_SET_FLAG, 572 UFS_QUERY_FLAG_IDN_LIFE_SPAN_MODE_ENABLE, 0, 0, 0, &utrd, 573 &rsp_upiu); 574 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 575 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 576 g_assert_cmpuint(rsp_upiu.qr.value, ==, be32_to_cpu(1)); 577 578 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST, 579 UFS_UPIU_QUERY_OPCODE_CLEAR_FLAG, 580 UFS_QUERY_FLAG_IDN_LIFE_SPAN_MODE_ENABLE, 0, 0, 0, &utrd, 581 &rsp_upiu); 582 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 583 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 584 g_assert_cmpuint(rsp_upiu.qr.value, ==, be32_to_cpu(0)); 585 586 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST, 587 UFS_UPIU_QUERY_OPCODE_TOGGLE_FLAG, 588 UFS_QUERY_FLAG_IDN_LIFE_SPAN_MODE_ENABLE, 0, 0, 0, &utrd, 589 &rsp_upiu); 590 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 591 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 592 g_assert_cmpuint(rsp_upiu.qr.value, ==, be32_to_cpu(1)); 593 594 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST, 595 UFS_UPIU_QUERY_OPCODE_TOGGLE_FLAG, 596 UFS_QUERY_FLAG_IDN_LIFE_SPAN_MODE_ENABLE, 0, 0, 0, &utrd, 597 &rsp_upiu); 598 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 599 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 600 g_assert_cmpuint(rsp_upiu.qr.value, ==, be32_to_cpu(0)); 601 602 /* Read Write-only Flag (Intended Failure) */ 603 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 604 UFS_UPIU_QUERY_OPCODE_READ_FLAG, 605 UFS_QUERY_FLAG_IDN_PURGE_ENABLE, 0, 0, 0, &utrd, &rsp_upiu); 606 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, 607 UFS_OCS_INVALID_CMD_TABLE_ATTR); 608 g_assert_cmpuint(rsp_upiu.header.response, ==, 609 UFS_QUERY_RESULT_NOT_READABLE); 610 611 /* Write Read-Only Flag (Intended Failure) */ 612 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST, 613 UFS_UPIU_QUERY_OPCODE_SET_FLAG, UFS_QUERY_FLAG_IDN_BUSY_RTC, 614 0, 0, 0, &utrd, &rsp_upiu); 615 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, 616 UFS_OCS_INVALID_CMD_TABLE_ATTR); 617 g_assert_cmpuint(rsp_upiu.header.response, ==, 618 UFS_QUERY_RESULT_NOT_WRITEABLE); 619 620 ufs_exit(ufs, alloc); 621 } 622 623 static void ufstest_query_attr_request(void *obj, void *data, 624 QGuestAllocator *alloc) 625 { 626 QUfs *ufs = obj; 627 628 UtpTransferReqDesc utrd; 629 UtpUpiuRsp rsp_upiu; 630 ufs_init(ufs, alloc); 631 632 /* Read Readable Attributes*/ 633 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 634 UFS_UPIU_QUERY_OPCODE_READ_ATTR, 635 UFS_QUERY_ATTR_IDN_BOOT_LU_EN, 0, 0, 0, &utrd, &rsp_upiu); 636 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 637 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 638 g_assert_cmpuint(rsp_upiu.qr.opcode, ==, UFS_UPIU_QUERY_OPCODE_READ_ATTR); 639 g_assert_cmpuint(rsp_upiu.qr.idn, ==, UFS_QUERY_ATTR_IDN_BOOT_LU_EN); 640 g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x00)); 641 642 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 643 UFS_UPIU_QUERY_OPCODE_READ_ATTR, 644 UFS_QUERY_ATTR_IDN_BKOPS_STATUS, 0, 0, 0, &utrd, &rsp_upiu); 645 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 646 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 647 g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x00)); 648 649 /* Write Writable Attributes & Read Again */ 650 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST, 651 UFS_UPIU_QUERY_OPCODE_WRITE_ATTR, 652 UFS_QUERY_ATTR_IDN_ACTIVE_ICC_LVL, 0, 0, 0x03, &utrd, 653 &rsp_upiu); 654 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 655 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 656 g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x03)); 657 658 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST, 659 UFS_UPIU_QUERY_OPCODE_WRITE_ATTR, 660 UFS_QUERY_ATTR_IDN_EE_CONTROL, 0, 0, 0x07, &utrd, &rsp_upiu); 661 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 662 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 663 g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x07)); 664 665 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 666 UFS_UPIU_QUERY_OPCODE_READ_ATTR, 667 UFS_QUERY_ATTR_IDN_ACTIVE_ICC_LVL, 0, 0, 0, &utrd, 668 &rsp_upiu); 669 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 670 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 671 g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x03)); 672 673 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 674 UFS_UPIU_QUERY_OPCODE_READ_ATTR, 675 UFS_QUERY_ATTR_IDN_EE_CONTROL, 0, 0, 0, &utrd, &rsp_upiu); 676 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 677 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 678 g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x07)); 679 680 /* Write Invalid Value (Intended Error) */ 681 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST, 682 UFS_UPIU_QUERY_OPCODE_WRITE_ATTR, 683 UFS_QUERY_ATTR_IDN_ACTIVE_ICC_LVL, 0, 0, 0x10, &utrd, 684 &rsp_upiu); 685 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, 686 UFS_OCS_INVALID_CMD_TABLE_ATTR); 687 g_assert_cmpuint(rsp_upiu.header.response, ==, 688 UFS_QUERY_RESULT_INVALID_VALUE); 689 690 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 691 UFS_UPIU_QUERY_OPCODE_READ_ATTR, 692 UFS_QUERY_ATTR_IDN_ACTIVE_ICC_LVL, 0, 0, 0, &utrd, 693 &rsp_upiu); 694 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 695 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 696 g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x03)); 697 698 /* Read Write-Only Attribute (Intended Error) */ 699 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 700 UFS_UPIU_QUERY_OPCODE_READ_ATTR, 701 UFS_QUERY_ATTR_IDN_SECONDS_PASSED, 0, 0, 0, &utrd, 702 &rsp_upiu); 703 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, 704 UFS_OCS_INVALID_CMD_TABLE_ATTR); 705 g_assert_cmpuint(rsp_upiu.header.response, ==, 706 UFS_QUERY_RESULT_NOT_READABLE); 707 708 /* Write Read-Only Attribute (Intended Error) */ 709 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST, 710 UFS_UPIU_QUERY_OPCODE_WRITE_ATTR, 711 UFS_QUERY_ATTR_IDN_POWER_MODE, 0, 0, 0x01, &utrd, &rsp_upiu); 712 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, 713 UFS_OCS_INVALID_CMD_TABLE_ATTR); 714 g_assert_cmpuint(rsp_upiu.header.response, ==, 715 UFS_QUERY_RESULT_NOT_WRITEABLE); 716 717 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 718 UFS_UPIU_QUERY_OPCODE_READ_ATTR, 719 UFS_QUERY_ATTR_IDN_POWER_MODE, 0, 0, 0, &utrd, &rsp_upiu); 720 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 721 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 722 g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x00)); 723 724 /* Reset Written Attributes */ 725 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST, 726 UFS_UPIU_QUERY_OPCODE_WRITE_ATTR, 727 UFS_QUERY_ATTR_IDN_ACTIVE_ICC_LVL, 0, 0, 0, &utrd, 728 &rsp_upiu); 729 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 730 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 731 g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x00)); 732 733 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST, 734 UFS_UPIU_QUERY_OPCODE_WRITE_ATTR, 735 UFS_QUERY_ATTR_IDN_EE_CONTROL, 0, 0, 0, &utrd, &rsp_upiu); 736 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 737 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 738 g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x00)); 739 740 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 741 UFS_UPIU_QUERY_OPCODE_READ_ATTR, 742 UFS_QUERY_ATTR_IDN_ACTIVE_ICC_LVL, 0, 0, 0, &utrd, 743 &rsp_upiu); 744 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 745 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 746 g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x00)); 747 748 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 749 UFS_UPIU_QUERY_OPCODE_READ_ATTR, 750 UFS_QUERY_ATTR_IDN_EE_CONTROL, 0, 0, 0, &utrd, &rsp_upiu); 751 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 752 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 753 g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x00)); 754 755 ufs_exit(ufs, alloc); 756 } 757 758 static void ufstest_query_desc_request(void *obj, void *data, 759 QGuestAllocator *alloc) 760 { 761 QUfs *ufs = obj; 762 763 UtpTransferReqDesc utrd; 764 UtpUpiuRsp rsp_upiu; 765 ufs_init(ufs, alloc); 766 767 /* Write Descriptor is not supported yet */ 768 769 /* Read Device Descriptor */ 770 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 771 UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_DEVICE, 772 0, 0, 0, &utrd, &rsp_upiu); 773 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 774 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 775 g_assert_cmpuint(rsp_upiu.qr.opcode, ==, UFS_UPIU_QUERY_OPCODE_READ_DESC); 776 g_assert_cmpuint(rsp_upiu.qr.idn, ==, UFS_QUERY_DESC_IDN_DEVICE); 777 g_assert_cmpuint(rsp_upiu.qr.data[0], ==, sizeof(DeviceDescriptor)); 778 g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_DEVICE); 779 780 /* Read Configuration Descriptor is not supported yet*/ 781 782 /* Read Unit Descriptor */ 783 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 784 UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_UNIT, 0, 785 0, 0, &utrd, &rsp_upiu); 786 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 787 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 788 g_assert_cmpuint(rsp_upiu.qr.data[0], ==, sizeof(UnitDescriptor)); 789 g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_UNIT); 790 g_assert_cmpuint(rsp_upiu.qr.data[2], ==, 0); 791 792 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 793 UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_UNIT, 1, 794 0, 0, &utrd, &rsp_upiu); 795 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 796 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 797 g_assert_cmpuint(rsp_upiu.qr.data[0], ==, sizeof(UnitDescriptor)); 798 g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_UNIT); 799 g_assert_cmpuint(rsp_upiu.qr.data[2], ==, 1); 800 801 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 802 UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_UNIT, 803 UFS_UPIU_RPMB_WLUN, 0, 0, &utrd, &rsp_upiu); 804 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 805 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 806 g_assert_cmpuint(rsp_upiu.qr.data[0], ==, sizeof(RpmbUnitDescriptor)); 807 g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_UNIT); 808 g_assert_cmpuint(rsp_upiu.qr.data[2], ==, UFS_UPIU_RPMB_WLUN); 809 810 /* Read Interconnect Descriptor */ 811 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 812 UFS_UPIU_QUERY_OPCODE_READ_DESC, 813 UFS_QUERY_DESC_IDN_INTERCONNECT, 0, 0, 0, &utrd, &rsp_upiu); 814 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 815 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 816 g_assert_cmpuint(rsp_upiu.qr.data[0], ==, sizeof(InterconnectDescriptor)); 817 g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_INTERCONNECT); 818 819 /* Read String Descriptor */ 820 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 821 UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_STRING, 822 0, 0, 0, &utrd, &rsp_upiu); 823 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 824 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 825 g_assert_cmpuint(rsp_upiu.qr.data[0], ==, 0x12); 826 g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_STRING); 827 828 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 829 UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_STRING, 830 1, 0, 0, &utrd, &rsp_upiu); 831 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 832 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 833 g_assert_cmpuint(rsp_upiu.qr.data[0], ==, 0x22); 834 g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_STRING); 835 836 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 837 UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_STRING, 838 4, 0, 0, &utrd, &rsp_upiu); 839 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 840 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 841 g_assert_cmpuint(rsp_upiu.qr.data[0], ==, 0x0a); 842 g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_STRING); 843 844 /* Read Geometry Descriptor */ 845 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 846 UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_GEOMETRY, 847 0, 0, 0, &utrd, &rsp_upiu); 848 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 849 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 850 g_assert_cmpuint(rsp_upiu.qr.data[0], ==, sizeof(GeometryDescriptor)); 851 g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_GEOMETRY); 852 853 /* Read Power Descriptor */ 854 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 855 UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_POWER, 0, 856 0, 0, &utrd, &rsp_upiu); 857 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 858 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 859 g_assert_cmpuint(rsp_upiu.qr.data[0], ==, 860 sizeof(PowerParametersDescriptor)); 861 g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_POWER); 862 863 /* Read Health Descriptor */ 864 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 865 UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_HEALTH, 866 0, 0, 0, &utrd, &rsp_upiu); 867 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); 868 g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS); 869 g_assert_cmpuint(rsp_upiu.qr.data[0], ==, sizeof(DeviceHealthDescriptor)); 870 g_assert_cmpuint(rsp_upiu.qr.data[1], ==, UFS_QUERY_DESC_IDN_HEALTH); 871 872 /* Invalid Index (Intended Failure) */ 873 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 874 UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_UNIT, 4, 875 0, 0, &utrd, &rsp_upiu); 876 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, 877 UFS_OCS_INVALID_CMD_TABLE_ATTR); 878 g_assert_cmpuint(rsp_upiu.header.response, ==, 879 UFS_QUERY_RESULT_INVALID_INDEX); 880 881 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 882 UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_STRING, 883 5, 0, 0, &utrd, &rsp_upiu); 884 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, 885 UFS_OCS_INVALID_CMD_TABLE_ATTR); 886 g_assert_cmpuint(rsp_upiu.header.response, ==, 887 UFS_QUERY_RESULT_INVALID_INDEX); 888 889 /* Invalid Selector (Intended Failure) */ 890 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 891 UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_DEVICE, 892 0, 1, 0, &utrd, &rsp_upiu); 893 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, 894 UFS_OCS_INVALID_CMD_TABLE_ATTR); 895 g_assert_cmpuint(rsp_upiu.header.response, ==, 896 UFS_QUERY_RESULT_INVALID_SELECTOR); 897 898 ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, 899 UFS_UPIU_QUERY_OPCODE_READ_DESC, UFS_QUERY_DESC_IDN_STRING, 900 0, 1, 0, &utrd, &rsp_upiu); 901 g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, 902 UFS_OCS_INVALID_CMD_TABLE_ATTR); 903 g_assert_cmpuint(rsp_upiu.header.response, ==, 904 UFS_QUERY_RESULT_INVALID_SELECTOR); 905 906 ufs_exit(ufs, alloc); 907 } 908 909 static void drive_destroy(void *path) 910 { 911 unlink(path); 912 g_free(path); 913 qos_invalidate_command_line(); 914 } 915 916 static char *drive_create(void) 917 { 918 int fd, ret; 919 char *t_path; 920 921 /* Create a temporary raw image */ 922 fd = g_file_open_tmp("qtest-ufs.XXXXXX", &t_path, NULL); 923 g_assert_cmpint(fd, >=, 0); 924 ret = ftruncate(fd, TEST_IMAGE_SIZE); 925 g_assert_cmpint(ret, ==, 0); 926 close(fd); 927 928 g_test_queue_destroy(drive_destroy, t_path); 929 return t_path; 930 } 931 932 static void *ufs_blk_test_setup(GString *cmd_line, void *arg) 933 { 934 char *tmp_path = drive_create(); 935 936 g_string_append_printf(cmd_line, 937 " -blockdev file,filename=%s,node-name=drv1 " 938 "-device ufs-lu,bus=ufs0,drive=drv1,lun=1 ", 939 tmp_path); 940 941 return arg; 942 } 943 944 static void ufs_register_nodes(void) 945 { 946 const char *arch; 947 QOSGraphEdgeOptions edge_opts = { 948 .before_cmd_line = "-blockdev null-co,node-name=drv0,read-zeroes=on", 949 .after_cmd_line = "-device ufs-lu,bus=ufs0,drive=drv0,lun=0", 950 .extra_device_opts = "addr=04.0,id=ufs0,nutrs=32,nutmrs=8" 951 }; 952 953 QOSGraphTestOptions io_test_opts = { 954 .before = ufs_blk_test_setup, 955 }; 956 957 add_qpci_address(&edge_opts, &(QPCIAddress){ .devfn = QPCI_DEVFN(4, 0) }); 958 959 qos_node_create_driver("ufs", ufs_create); 960 qos_node_consumes("ufs", "pci-bus", &edge_opts); 961 qos_node_produces("ufs", "pci-device"); 962 963 qos_add_test("reg-read", "ufs", ufstest_reg_read, NULL); 964 965 /* 966 * Check architecture 967 * TODO: Enable ufs io tests for ppc64 968 */ 969 arch = qtest_get_arch(); 970 if (!strcmp(arch, "ppc64")) { 971 g_test_message("Skipping ufs io tests for ppc64"); 972 return; 973 } 974 qos_add_test("init", "ufs", ufstest_init, NULL); 975 qos_add_test("read-write", "ufs", ufstest_read_write, &io_test_opts); 976 qos_add_test("flag read-write", "ufs", 977 ufstest_query_flag_request, &io_test_opts); 978 qos_add_test("attr read-write", "ufs", 979 ufstest_query_attr_request, &io_test_opts); 980 qos_add_test("desc read-write", "ufs", 981 ufstest_query_desc_request, &io_test_opts); 982 } 983 984 libqos_init(ufs_register_nodes); 985