1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/stdinc.h" 7 8 #include "scsi/task.c" 9 #include "scsi/scsi_bdev.c" 10 #include "common/lib/test_env.c" 11 12 #include "spdk_cunit.h" 13 14 #include "spdk_internal/mock.h" 15 #include "spdk/bdev_module.h" 16 17 SPDK_LOG_REGISTER_COMPONENT(scsi) 18 19 static uint64_t g_test_bdev_num_blocks; 20 21 TAILQ_HEAD(, spdk_bdev_io) g_bdev_io_queue; 22 int g_scsi_cb_called = 0; 23 24 TAILQ_HEAD(, spdk_bdev_io_wait_entry) g_io_wait_queue; 25 bool g_bdev_io_pool_full = false; 26 27 bool 28 spdk_bdev_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type io_type) 29 { 30 abort(); 31 return false; 32 } 33 34 DEFINE_STUB_V(spdk_bdev_free_io, (struct spdk_bdev_io *bdev_io)); 35 36 DEFINE_STUB(spdk_bdev_get_name, const char *, 37 (const struct spdk_bdev *bdev), "test"); 38 39 DEFINE_STUB(spdk_bdev_get_block_size, uint32_t, 40 (const struct spdk_bdev *bdev), 512); 41 42 DEFINE_STUB(spdk_bdev_get_md_size, uint32_t, 43 (const struct spdk_bdev *bdev), 8); 44 45 DEFINE_STUB(spdk_bdev_is_md_interleaved, bool, 46 (const struct spdk_bdev *bdev), false); 47 48 DEFINE_STUB(spdk_bdev_get_data_block_size, uint32_t, 49 (const struct spdk_bdev *bdev), 512); 50 51 DEFINE_STUB(spdk_bdev_get_physical_block_size, uint32_t, 52 (const struct spdk_bdev *bdev), 4096); 53 54 uint64_t 55 spdk_bdev_get_num_blocks(const struct spdk_bdev *bdev) 56 { 57 return g_test_bdev_num_blocks; 58 } 59 60 DEFINE_STUB(spdk_bdev_get_product_name, const char *, 61 (const struct spdk_bdev *bdev), "test product"); 62 63 DEFINE_STUB(spdk_bdev_has_write_cache, bool, 64 (const struct spdk_bdev *bdev), false); 65 66 DEFINE_STUB(spdk_bdev_get_dif_type, enum spdk_dif_type, 67 (const struct spdk_bdev *bdev), SPDK_DIF_DISABLE); 68 69 DEFINE_STUB(spdk_bdev_is_dif_head_of_md, bool, 70 (const struct spdk_bdev *bdev), false); 71 72 DEFINE_STUB(spdk_bdev_is_dif_check_enabled, bool, 73 (const struct spdk_bdev *bdev, enum spdk_dif_check_type check_type), false); 74 75 DEFINE_STUB(scsi_pr_out, int, (struct spdk_scsi_task *task, 76 uint8_t *cdb, uint8_t *data, uint16_t data_len), 0); 77 78 DEFINE_STUB(scsi_pr_in, int, (struct spdk_scsi_task *task, uint8_t *cdb, 79 uint8_t *data, uint16_t data_len), 0); 80 81 DEFINE_STUB(scsi2_reserve, int, (struct spdk_scsi_task *task, uint8_t *cdb), 0); 82 DEFINE_STUB(scsi2_release, int, (struct spdk_scsi_task *task), 0); 83 84 void 85 scsi_lun_complete_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task) 86 { 87 g_scsi_cb_called++; 88 } 89 90 DEFINE_STUB_V(scsi_lun_complete_reset_task, 91 (struct spdk_scsi_lun *lun, struct spdk_scsi_task *task)); 92 93 DEFINE_STUB(spdk_scsi_lun_id_int_to_fmt, uint64_t, (int lun_id), 0); 94 95 DEFINE_STUB(spdk_scsi_dev_get_first_lun, struct spdk_scsi_lun *, 96 (struct spdk_scsi_dev *dev), NULL); 97 98 DEFINE_STUB(spdk_scsi_dev_get_next_lun, struct spdk_scsi_lun *, 99 (struct spdk_scsi_lun *prev_lun), NULL); 100 101 static void 102 ut_put_task(struct spdk_scsi_task *task) 103 { 104 if (task->alloc_len) { 105 free(task->iov.iov_base); 106 } 107 108 task->iov.iov_base = NULL; 109 task->iov.iov_len = 0; 110 task->alloc_len = 0; 111 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue)); 112 } 113 114 static void 115 ut_init_task(struct spdk_scsi_task *task) 116 { 117 memset(task, 0xFF, sizeof(*task)); 118 task->iov.iov_base = NULL; 119 task->iovs = &task->iov; 120 task->iovcnt = 1; 121 task->alloc_len = 0; 122 task->dxfer_dir = SPDK_SCSI_DIR_NONE; 123 } 124 125 void 126 spdk_bdev_io_get_scsi_status(const struct spdk_bdev_io *bdev_io, 127 int *sc, int *sk, int *asc, int *ascq) 128 { 129 switch (bdev_io->internal.status) { 130 case SPDK_BDEV_IO_STATUS_SUCCESS: 131 *sc = SPDK_SCSI_STATUS_GOOD; 132 *sk = SPDK_SCSI_SENSE_NO_SENSE; 133 *asc = SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE; 134 *ascq = SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE; 135 break; 136 case SPDK_BDEV_IO_STATUS_SCSI_ERROR: 137 *sc = bdev_io->internal.error.scsi.sc; 138 *sk = bdev_io->internal.error.scsi.sk; 139 *asc = bdev_io->internal.error.scsi.asc; 140 *ascq = bdev_io->internal.error.scsi.ascq; 141 break; 142 default: 143 *sc = SPDK_SCSI_STATUS_CHECK_CONDITION; 144 *sk = SPDK_SCSI_SENSE_ABORTED_COMMAND; 145 *asc = SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE; 146 *ascq = SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE; 147 break; 148 } 149 } 150 151 void 152 spdk_bdev_io_get_iovec(struct spdk_bdev_io *bdev_io, struct iovec **iovp, int *iovcntp) 153 { 154 *iovp = NULL; 155 *iovcntp = 0; 156 } 157 158 static void 159 ut_bdev_io_flush(void) 160 { 161 struct spdk_bdev_io *bdev_io; 162 struct spdk_bdev_io_wait_entry *entry; 163 164 while (!TAILQ_EMPTY(&g_bdev_io_queue) || !TAILQ_EMPTY(&g_io_wait_queue)) { 165 while (!TAILQ_EMPTY(&g_bdev_io_queue)) { 166 bdev_io = TAILQ_FIRST(&g_bdev_io_queue); 167 TAILQ_REMOVE(&g_bdev_io_queue, bdev_io, internal.link); 168 bdev_io->internal.cb(bdev_io, true, bdev_io->internal.caller_ctx); 169 free(bdev_io); 170 } 171 172 while (!TAILQ_EMPTY(&g_io_wait_queue)) { 173 entry = TAILQ_FIRST(&g_io_wait_queue); 174 TAILQ_REMOVE(&g_io_wait_queue, entry, link); 175 entry->cb_fn(entry->cb_arg); 176 } 177 } 178 } 179 180 static int 181 _spdk_bdev_io_op(spdk_bdev_io_completion_cb cb, void *cb_arg) 182 { 183 struct spdk_bdev_io *bdev_io; 184 185 if (g_bdev_io_pool_full) { 186 g_bdev_io_pool_full = false; 187 return -ENOMEM; 188 } 189 190 bdev_io = calloc(1, sizeof(*bdev_io)); 191 SPDK_CU_ASSERT_FATAL(bdev_io != NULL); 192 bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS; 193 bdev_io->internal.cb = cb; 194 bdev_io->internal.caller_ctx = cb_arg; 195 196 TAILQ_INSERT_TAIL(&g_bdev_io_queue, bdev_io, internal.link); 197 198 return 0; 199 } 200 201 int 202 spdk_bdev_readv_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 203 struct iovec *iov, int iovcnt, 204 uint64_t offset_blocks, uint64_t num_blocks, 205 spdk_bdev_io_completion_cb cb, void *cb_arg) 206 { 207 return _spdk_bdev_io_op(cb, cb_arg); 208 } 209 210 int 211 spdk_bdev_writev_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 212 struct iovec *iov, int iovcnt, 213 uint64_t offset_blocks, uint64_t num_blocks, 214 spdk_bdev_io_completion_cb cb, void *cb_arg) 215 { 216 return _spdk_bdev_io_op(cb, cb_arg); 217 } 218 219 int 220 spdk_bdev_unmap_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 221 uint64_t offset_blocks, uint64_t num_blocks, 222 spdk_bdev_io_completion_cb cb, void *cb_arg) 223 { 224 return _spdk_bdev_io_op(cb, cb_arg); 225 } 226 227 int 228 spdk_bdev_reset(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 229 spdk_bdev_io_completion_cb cb, void *cb_arg) 230 { 231 return _spdk_bdev_io_op(cb, cb_arg); 232 } 233 234 int 235 spdk_bdev_flush_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 236 uint64_t offset_blocks, uint64_t num_blocks, 237 spdk_bdev_io_completion_cb cb, void *cb_arg) 238 { 239 return _spdk_bdev_io_op(cb, cb_arg); 240 } 241 242 int 243 spdk_bdev_queue_io_wait(struct spdk_bdev *bdev, struct spdk_io_channel *ch, 244 struct spdk_bdev_io_wait_entry *entry) 245 { 246 TAILQ_INSERT_TAIL(&g_io_wait_queue, entry, link); 247 return 0; 248 } 249 250 int 251 spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_size, 252 bool md_interleave, bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, 253 uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag, 254 uint32_t data_offset, uint16_t guard_seed) 255 { 256 ctx->init_ref_tag = init_ref_tag; 257 ctx->ref_tag_offset = data_offset / 512; 258 return 0; 259 } 260 261 /* 262 * This test specifically tests a mode select 6 command from the 263 * Windows SCSI compliance test that caused SPDK to crash. 264 */ 265 static void 266 mode_select_6_test(void) 267 { 268 struct spdk_bdev bdev; 269 struct spdk_scsi_task task; 270 struct spdk_scsi_lun lun; 271 struct spdk_scsi_dev dev; 272 char cdb[16]; 273 char data[24]; 274 int rc; 275 276 ut_init_task(&task); 277 278 cdb[0] = 0x15; 279 cdb[1] = 0x11; 280 cdb[2] = 0x00; 281 cdb[3] = 0x00; 282 cdb[4] = 0x18; 283 cdb[5] = 0x00; 284 task.cdb = cdb; 285 286 snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test"); 287 lun.bdev = &bdev; 288 lun.dev = &dev; 289 task.lun = &lun; 290 291 memset(data, 0, sizeof(data)); 292 data[4] = 0x08; 293 data[5] = 0x02; 294 spdk_scsi_task_set_data(&task, data, sizeof(data)); 295 296 rc = bdev_scsi_execute(&task); 297 298 CU_ASSERT_EQUAL(rc, 0); 299 300 ut_put_task(&task); 301 } 302 303 /* 304 * This test specifically tests a mode select 6 command which 305 * contains no mode pages. 306 */ 307 static void 308 mode_select_6_test2(void) 309 { 310 struct spdk_bdev bdev; 311 struct spdk_scsi_task task; 312 struct spdk_scsi_lun lun; 313 struct spdk_scsi_dev dev; 314 char cdb[16]; 315 int rc; 316 317 ut_init_task(&task); 318 319 cdb[0] = 0x15; 320 cdb[1] = 0x00; 321 cdb[2] = 0x00; 322 cdb[3] = 0x00; 323 cdb[4] = 0x00; 324 cdb[5] = 0x00; 325 task.cdb = cdb; 326 327 snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test"); 328 lun.bdev = &bdev; 329 lun.dev = &dev; 330 task.lun = &lun; 331 332 rc = bdev_scsi_execute(&task); 333 334 CU_ASSERT_EQUAL(rc, 0); 335 336 ut_put_task(&task); 337 } 338 339 /* 340 * This test specifically tests a mode sense 6 command which 341 * return all subpage 00h mode pages. 342 */ 343 static void 344 mode_sense_6_test(void) 345 { 346 struct spdk_bdev bdev; 347 struct spdk_scsi_task task; 348 struct spdk_scsi_lun lun; 349 struct spdk_scsi_dev dev; 350 char cdb[12]; 351 unsigned char *data; 352 int rc; 353 unsigned char mode_data_len = 0; 354 unsigned char medium_type = 0; 355 unsigned char dev_specific_param = 0; 356 unsigned char blk_descriptor_len = 0; 357 358 memset(&bdev, 0, sizeof(struct spdk_bdev)); 359 ut_init_task(&task); 360 memset(cdb, 0, sizeof(cdb)); 361 362 cdb[0] = 0x1A; 363 cdb[2] = 0x3F; 364 cdb[4] = 0xFF; 365 task.cdb = cdb; 366 367 snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test"); 368 lun.bdev = &bdev; 369 lun.dev = &dev; 370 task.lun = &lun; 371 372 rc = bdev_scsi_execute(&task); 373 SPDK_CU_ASSERT_FATAL(rc == 0); 374 375 data = task.iovs[0].iov_base; 376 mode_data_len = data[0]; 377 medium_type = data[1]; 378 dev_specific_param = data[2]; 379 blk_descriptor_len = data[3]; 380 381 CU_ASSERT(mode_data_len >= 11); 382 CU_ASSERT_EQUAL(medium_type, 0); 383 CU_ASSERT_EQUAL(dev_specific_param, 0); 384 CU_ASSERT_EQUAL(blk_descriptor_len, 8); 385 386 ut_put_task(&task); 387 } 388 389 /* 390 * This test specifically tests a mode sense 10 command which 391 * return all subpage 00h mode pages. 392 */ 393 static void 394 mode_sense_10_test(void) 395 { 396 struct spdk_bdev bdev; 397 struct spdk_scsi_task task; 398 struct spdk_scsi_lun lun; 399 struct spdk_scsi_dev dev; 400 char cdb[12]; 401 unsigned char *data; 402 int rc; 403 unsigned short mode_data_len = 0; 404 unsigned char medium_type = 0; 405 unsigned char dev_specific_param = 0; 406 unsigned short blk_descriptor_len = 0; 407 408 memset(&bdev, 0, sizeof(struct spdk_bdev)); 409 ut_init_task(&task); 410 memset(cdb, 0, sizeof(cdb)); 411 cdb[0] = 0x5A; 412 cdb[2] = 0x3F; 413 cdb[8] = 0xFF; 414 task.cdb = cdb; 415 416 snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test"); 417 lun.bdev = &bdev; 418 lun.dev = &dev; 419 task.lun = &lun; 420 421 rc = bdev_scsi_execute(&task); 422 SPDK_CU_ASSERT_FATAL(rc == 0); 423 424 data = task.iovs[0].iov_base; 425 mode_data_len = ((data[0] << 8) + data[1]); 426 medium_type = data[2]; 427 dev_specific_param = data[3]; 428 blk_descriptor_len = ((data[6] << 8) + data[7]); 429 430 CU_ASSERT(mode_data_len >= 14); 431 CU_ASSERT_EQUAL(medium_type, 0); 432 CU_ASSERT_EQUAL(dev_specific_param, 0); 433 CU_ASSERT_EQUAL(blk_descriptor_len, 8); 434 435 ut_put_task(&task); 436 } 437 438 /* 439 * This test specifically tests a scsi inquiry command from the 440 * Windows SCSI compliance test that failed to return the 441 * expected SCSI error sense code. 442 */ 443 static void 444 inquiry_evpd_test(void) 445 { 446 struct spdk_bdev bdev; 447 struct spdk_scsi_task task; 448 struct spdk_scsi_lun lun; 449 struct spdk_scsi_dev dev; 450 char cdb[6]; 451 int rc; 452 453 ut_init_task(&task); 454 455 cdb[0] = 0x12; 456 cdb[1] = 0x00; /* EVPD = 0 */ 457 cdb[2] = 0xff; /* PageCode non-zero */ 458 cdb[3] = 0x00; 459 cdb[4] = 0xff; 460 cdb[5] = 0x00; 461 task.cdb = cdb; 462 463 snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test"); 464 lun.bdev = &bdev; 465 lun.dev = &dev; 466 task.lun = &lun; 467 468 rc = bdev_scsi_execute(&task); 469 SPDK_CU_ASSERT_FATAL(rc == 0); 470 471 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION); 472 CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_ILLEGAL_REQUEST); 473 CU_ASSERT_EQUAL(task.sense_data[12], 0x24); 474 CU_ASSERT_EQUAL(task.sense_data[13], 0x0); 475 476 ut_put_task(&task); 477 } 478 479 /* 480 * This test is to verify specific return data for a standard scsi inquiry 481 * command: Version 482 */ 483 static void 484 inquiry_standard_test(void) 485 { 486 struct spdk_bdev bdev = { .blocklen = 512 }; 487 struct spdk_scsi_task task; 488 struct spdk_scsi_lun lun; 489 struct spdk_scsi_dev dev; 490 char cdb[6]; 491 char *data; 492 struct spdk_scsi_cdb_inquiry_data *inq_data; 493 int rc; 494 495 ut_init_task(&task); 496 497 cdb[0] = 0x12; 498 cdb[1] = 0x00; /* EVPD = 0 */ 499 cdb[2] = 0x00; /* PageCode zero - requesting standard inquiry */ 500 cdb[3] = 0x00; 501 cdb[4] = 0xff; /* Indicate data size used by conformance test */ 502 cdb[5] = 0x00; 503 task.cdb = cdb; 504 505 snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test"); 506 lun.bdev = &bdev; 507 lun.dev = &dev; 508 task.lun = &lun; 509 510 rc = bdev_scsi_execute(&task); 511 512 data = task.iovs[0].iov_base; 513 inq_data = (struct spdk_scsi_cdb_inquiry_data *)&data[0]; 514 515 CU_ASSERT_EQUAL(inq_data->version, SPDK_SPC_VERSION_SPC3); 516 CU_ASSERT_EQUAL(rc, 0); 517 518 ut_put_task(&task); 519 } 520 521 static void 522 _inquiry_overflow_test(uint8_t alloc_len) 523 { 524 struct spdk_bdev bdev = { .blocklen = 512 }; 525 struct spdk_scsi_task task; 526 struct spdk_scsi_lun lun; 527 struct spdk_scsi_dev dev; 528 uint8_t cdb[6]; 529 int rc; 530 /* expects a 4K internal data buffer */ 531 char data[4096], data_compare[4096]; 532 533 ut_init_task(&task); 534 535 cdb[0] = 0x12; 536 cdb[1] = 0x00; /* EVPD = 0 */ 537 cdb[2] = 0x00; /* PageCode zero - requesting standard inquiry */ 538 cdb[3] = 0x00; 539 cdb[4] = alloc_len; /* Indicate data size used by conformance test */ 540 cdb[5] = 0x00; 541 task.cdb = cdb; 542 543 snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test"); 544 lun.bdev = &bdev; 545 lun.dev = &dev; 546 task.lun = &lun; 547 548 memset(data, 0, sizeof(data)); 549 memset(data_compare, 0, sizeof(data_compare)); 550 551 spdk_scsi_task_set_data(&task, data, sizeof(data)); 552 553 rc = bdev_scsi_execute(&task); 554 SPDK_CU_ASSERT_FATAL(rc == 0); 555 556 CU_ASSERT_EQUAL(memcmp(data + alloc_len, data_compare + alloc_len, sizeof(data) - alloc_len), 0); 557 CU_ASSERT(task.data_transferred <= alloc_len); 558 559 ut_put_task(&task); 560 } 561 562 static void 563 inquiry_overflow_test(void) 564 { 565 int i; 566 567 for (i = 0; i < 256; i++) { 568 _inquiry_overflow_test(i); 569 } 570 } 571 572 static void 573 scsi_name_padding_test(void) 574 { 575 char name[SPDK_SCSI_DEV_MAX_NAME + 1]; 576 char buf[SPDK_SCSI_DEV_MAX_NAME + 1]; 577 int written, i; 578 579 /* case 1 */ 580 memset(name, '\0', sizeof(name)); 581 memset(name, 'x', 251); 582 written = bdev_scsi_pad_scsi_name(buf, name); 583 584 CU_ASSERT(written == 252); 585 CU_ASSERT(buf[250] == 'x'); 586 CU_ASSERT(buf[251] == '\0'); 587 588 /* case 2: */ 589 memset(name, '\0', sizeof(name)); 590 memset(name, 'x', 252); 591 written = bdev_scsi_pad_scsi_name(buf, name); 592 593 CU_ASSERT(written == 256); 594 CU_ASSERT(buf[251] == 'x'); 595 for (i = 252; i < 256; i++) { 596 CU_ASSERT(buf[i] == '\0'); 597 } 598 599 /* case 3 */ 600 memset(name, '\0', sizeof(name)); 601 memset(name, 'x', 255); 602 written = bdev_scsi_pad_scsi_name(buf, name); 603 604 CU_ASSERT(written == 256); 605 CU_ASSERT(buf[254] == 'x'); 606 CU_ASSERT(buf[255] == '\0'); 607 } 608 609 /* 610 * This test is to verify specific error translation from bdev to scsi. 611 */ 612 static void 613 task_complete_test(void) 614 { 615 struct spdk_scsi_task task; 616 struct spdk_bdev_io bdev_io = {}; 617 struct spdk_scsi_lun lun; 618 619 ut_init_task(&task); 620 621 TAILQ_INIT(&lun.tasks); 622 TAILQ_INSERT_TAIL(&lun.tasks, &task, scsi_link); 623 task.lun = &lun; 624 625 bdev_io.internal.status = SPDK_BDEV_IO_STATUS_SUCCESS; 626 bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.internal.status, &task); 627 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_GOOD); 628 CU_ASSERT(g_scsi_cb_called == 1); 629 g_scsi_cb_called = 0; 630 631 bdev_io.internal.status = SPDK_BDEV_IO_STATUS_SCSI_ERROR; 632 bdev_io.internal.error.scsi.sc = SPDK_SCSI_STATUS_CHECK_CONDITION; 633 bdev_io.internal.error.scsi.sk = SPDK_SCSI_SENSE_HARDWARE_ERROR; 634 bdev_io.internal.error.scsi.asc = SPDK_SCSI_ASC_WARNING; 635 bdev_io.internal.error.scsi.ascq = SPDK_SCSI_ASCQ_POWER_LOSS_EXPECTED; 636 bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.internal.status, &task); 637 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION); 638 CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_HARDWARE_ERROR); 639 CU_ASSERT_EQUAL(task.sense_data[12], SPDK_SCSI_ASC_WARNING); 640 CU_ASSERT_EQUAL(task.sense_data[13], SPDK_SCSI_ASCQ_POWER_LOSS_EXPECTED); 641 CU_ASSERT(g_scsi_cb_called == 1); 642 g_scsi_cb_called = 0; 643 644 bdev_io.internal.status = SPDK_BDEV_IO_STATUS_FAILED; 645 bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.internal.status, &task); 646 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION); 647 CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_ABORTED_COMMAND); 648 CU_ASSERT_EQUAL(task.sense_data[12], SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE); 649 CU_ASSERT_EQUAL(task.sense_data[13], SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE); 650 CU_ASSERT(g_scsi_cb_called == 1); 651 g_scsi_cb_called = 0; 652 653 ut_put_task(&task); 654 } 655 656 static void 657 lba_range_test(void) 658 { 659 struct spdk_bdev bdev = { .blocklen = 512 }; 660 struct spdk_scsi_lun lun; 661 struct spdk_scsi_task task; 662 uint8_t cdb[16]; 663 int rc; 664 665 lun.bdev = &bdev; 666 667 ut_init_task(&task); 668 task.lun = &lun; 669 task.lun->bdev_desc = NULL; 670 task.lun->io_channel = NULL; 671 task.cdb = cdb; 672 673 memset(cdb, 0, sizeof(cdb)); 674 cdb[0] = 0x88; /* READ (16) */ 675 676 /* Test block device size of 4 blocks */ 677 g_test_bdev_num_blocks = 4; 678 679 /* LBA = 0, length = 1 (in range) */ 680 to_be64(&cdb[2], 0); /* LBA */ 681 to_be32(&cdb[10], 1); /* transfer length */ 682 task.transfer_len = 1 * 512; 683 task.offset = 0; 684 task.length = 1 * 512; 685 rc = bdev_scsi_execute(&task); 686 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 687 CU_ASSERT(task.status == 0xFF); 688 SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue)); 689 ut_bdev_io_flush(); 690 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 691 CU_ASSERT(g_scsi_cb_called == 1); 692 g_scsi_cb_called = 0; 693 694 /* LBA = 4, length = 1 (LBA out of range) */ 695 to_be64(&cdb[2], 4); /* LBA */ 696 to_be32(&cdb[10], 1); /* transfer length */ 697 task.transfer_len = 1 * 512; 698 task.offset = 0; 699 task.length = 1 * 512; 700 rc = bdev_scsi_execute(&task); 701 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 702 CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION); 703 CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); 704 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue)); 705 706 /* LBA = 0, length = 4 (in range, max valid size) */ 707 to_be64(&cdb[2], 0); /* LBA */ 708 to_be32(&cdb[10], 4); /* transfer length */ 709 task.transfer_len = 4 * 512; 710 task.status = 0xFF; 711 task.offset = 0; 712 task.length = 1 * 512; 713 rc = bdev_scsi_execute(&task); 714 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 715 CU_ASSERT(task.status == 0xFF); 716 SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue)); 717 ut_bdev_io_flush(); 718 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 719 CU_ASSERT(g_scsi_cb_called == 1); 720 g_scsi_cb_called = 0; 721 722 /* LBA = 0, length = 5 (LBA in range, length beyond end of bdev) */ 723 to_be64(&cdb[2], 0); /* LBA */ 724 to_be32(&cdb[10], 5); /* transfer length */ 725 task.transfer_len = 5 * 512; 726 task.offset = 0; 727 task.length = 1 * 512; 728 rc = bdev_scsi_execute(&task); 729 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 730 CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION); 731 CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); 732 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue)); 733 734 ut_put_task(&task); 735 } 736 737 static void 738 xfer_len_test(void) 739 { 740 struct spdk_bdev bdev = { .blocklen = 512 }; 741 struct spdk_scsi_lun lun; 742 struct spdk_scsi_task task; 743 uint8_t cdb[16]; 744 int rc; 745 746 lun.bdev = &bdev; 747 748 ut_init_task(&task); 749 task.lun = &lun; 750 task.lun->bdev_desc = NULL; 751 task.lun->io_channel = NULL; 752 task.cdb = cdb; 753 754 memset(cdb, 0, sizeof(cdb)); 755 cdb[0] = 0x88; /* READ (16) */ 756 757 /* Test block device size of 512 MiB */ 758 g_test_bdev_num_blocks = 512 * 1024 * 1024; 759 760 /* 1 block */ 761 to_be64(&cdb[2], 0); /* LBA */ 762 to_be32(&cdb[10], 1); /* transfer length */ 763 task.transfer_len = 1 * 512; 764 task.offset = 0; 765 task.length = 1 * 512; 766 rc = bdev_scsi_execute(&task); 767 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 768 CU_ASSERT(task.status == 0xFF); 769 SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue)); 770 ut_bdev_io_flush(); 771 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 772 CU_ASSERT(g_scsi_cb_called == 1); 773 g_scsi_cb_called = 0; 774 775 /* max transfer length (as reported in block limits VPD page) */ 776 to_be64(&cdb[2], 0); /* LBA */ 777 to_be32(&cdb[10], SPDK_WORK_BLOCK_SIZE / 512); /* transfer length */ 778 task.transfer_len = SPDK_WORK_BLOCK_SIZE; 779 task.status = 0xFF; 780 task.offset = 0; 781 task.length = 1 * 512; 782 rc = bdev_scsi_execute(&task); 783 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 784 CU_ASSERT(task.status == 0xFF); 785 SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue)); 786 ut_bdev_io_flush(); 787 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 788 CU_ASSERT(g_scsi_cb_called == 1); 789 g_scsi_cb_called = 0; 790 791 /* max transfer length plus one block (invalid) */ 792 to_be64(&cdb[2], 0); /* LBA */ 793 to_be32(&cdb[10], SPDK_WORK_BLOCK_SIZE / 512 + 1); /* transfer length */ 794 task.transfer_len = SPDK_WORK_BLOCK_SIZE + 512; 795 task.offset = 0; 796 task.length = 1 * 512; 797 rc = bdev_scsi_execute(&task); 798 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 799 CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION); 800 CU_ASSERT((task.sense_data[2] & 0xf) == SPDK_SCSI_SENSE_ILLEGAL_REQUEST); 801 CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB); 802 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue)); 803 804 /* zero transfer length (valid) */ 805 to_be64(&cdb[2], 0); /* LBA */ 806 to_be32(&cdb[10], 0); /* transfer length */ 807 task.transfer_len = 0; 808 task.offset = 0; 809 task.length = 0; 810 rc = bdev_scsi_execute(&task); 811 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 812 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 813 CU_ASSERT(task.data_transferred == 0); 814 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue)); 815 816 /* zero transfer length past end of disk (invalid) */ 817 to_be64(&cdb[2], g_test_bdev_num_blocks); /* LBA */ 818 to_be32(&cdb[10], 0); /* transfer length */ 819 task.transfer_len = 0; 820 task.offset = 0; 821 task.length = 0; 822 rc = bdev_scsi_execute(&task); 823 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 824 CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION); 825 CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); 826 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue)); 827 828 ut_put_task(&task); 829 } 830 831 static void 832 _xfer_test(bool bdev_io_pool_full) 833 { 834 struct spdk_bdev bdev = { .blocklen = 512 }; 835 struct spdk_scsi_lun lun; 836 struct spdk_scsi_task task; 837 uint8_t cdb[16]; 838 char data[4096]; 839 int rc; 840 841 lun.bdev = &bdev; 842 843 /* Test block device size of 512 MiB */ 844 g_test_bdev_num_blocks = 512 * 1024 * 1024; 845 846 /* Read 1 block */ 847 ut_init_task(&task); 848 task.lun = &lun; 849 task.lun->bdev_desc = NULL; 850 task.lun->io_channel = NULL; 851 task.cdb = cdb; 852 memset(cdb, 0, sizeof(cdb)); 853 cdb[0] = 0x88; /* READ (16) */ 854 to_be64(&cdb[2], 0); /* LBA */ 855 to_be32(&cdb[10], 1); /* transfer length */ 856 task.transfer_len = 1 * 512; 857 task.offset = 0; 858 task.length = 1 * 512; 859 g_bdev_io_pool_full = bdev_io_pool_full; 860 rc = bdev_scsi_execute(&task); 861 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 862 CU_ASSERT(task.status == 0xFF); 863 864 ut_bdev_io_flush(); 865 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 866 CU_ASSERT(g_scsi_cb_called == 1); 867 g_scsi_cb_called = 0; 868 ut_put_task(&task); 869 870 /* Write 1 block */ 871 ut_init_task(&task); 872 task.lun = &lun; 873 task.cdb = cdb; 874 memset(cdb, 0, sizeof(cdb)); 875 cdb[0] = 0x8a; /* WRITE (16) */ 876 to_be64(&cdb[2], 0); /* LBA */ 877 to_be32(&cdb[10], 1); /* transfer length */ 878 task.transfer_len = 1 * 512; 879 task.offset = 0; 880 task.length = 1 * 512; 881 g_bdev_io_pool_full = bdev_io_pool_full; 882 rc = bdev_scsi_execute(&task); 883 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 884 CU_ASSERT(task.status == 0xFF); 885 886 ut_bdev_io_flush(); 887 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 888 CU_ASSERT(g_scsi_cb_called == 1); 889 g_scsi_cb_called = 0; 890 ut_put_task(&task); 891 892 /* Unmap 5 blocks using 2 descriptors */ 893 ut_init_task(&task); 894 task.lun = &lun; 895 task.cdb = cdb; 896 memset(cdb, 0, sizeof(cdb)); 897 cdb[0] = 0x42; /* UNMAP */ 898 to_be16(&data[7], 2); /* 2 parameters in list */ 899 memset(data, 0, sizeof(data)); 900 to_be16(&data[2], 32); /* 2 descriptors */ 901 to_be64(&data[8], 1); /* LBA 1 */ 902 to_be32(&data[16], 2); /* 2 blocks */ 903 to_be64(&data[24], 10); /* LBA 10 */ 904 to_be32(&data[32], 3); /* 3 blocks */ 905 spdk_scsi_task_set_data(&task, data, sizeof(data)); 906 task.status = SPDK_SCSI_STATUS_GOOD; 907 g_bdev_io_pool_full = bdev_io_pool_full; 908 rc = bdev_scsi_execute(&task); 909 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 910 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 911 912 ut_bdev_io_flush(); 913 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 914 CU_ASSERT(g_scsi_cb_called == 1); 915 g_scsi_cb_called = 0; 916 ut_put_task(&task); 917 918 /* Flush 1 block */ 919 ut_init_task(&task); 920 task.lun = &lun; 921 task.cdb = cdb; 922 memset(cdb, 0, sizeof(cdb)); 923 cdb[0] = 0x91; /* SYNCHRONIZE CACHE (16) */ 924 to_be64(&cdb[2], 0); /* LBA */ 925 to_be32(&cdb[10], 1); /* 1 blocks */ 926 g_bdev_io_pool_full = bdev_io_pool_full; 927 rc = bdev_scsi_execute(&task); 928 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 929 CU_ASSERT(task.status == 0xFF); 930 931 ut_bdev_io_flush(); 932 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 933 CU_ASSERT(g_scsi_cb_called == 1); 934 g_scsi_cb_called = 0; 935 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue)); 936 937 ut_put_task(&task); 938 } 939 940 static void 941 xfer_test(void) 942 { 943 _xfer_test(false); 944 _xfer_test(true); 945 } 946 947 static void 948 get_dif_ctx_test(void) 949 { 950 struct spdk_bdev bdev = {}; 951 struct spdk_scsi_task task = {}; 952 struct spdk_dif_ctx dif_ctx = {}; 953 uint8_t cdb[16]; 954 bool ret; 955 956 cdb[0] = SPDK_SBC_READ_6; 957 cdb[1] = 0x12; 958 cdb[2] = 0x34; 959 cdb[3] = 0x50; 960 task.cdb = cdb; 961 task.offset = 0x6 * 512; 962 963 ret = bdev_scsi_get_dif_ctx(&bdev, &task, &dif_ctx); 964 CU_ASSERT(ret == true); 965 CU_ASSERT(dif_ctx.init_ref_tag + dif_ctx.ref_tag_offset == 0x123456); 966 967 cdb[0] = SPDK_SBC_WRITE_12; 968 to_be32(&cdb[2], 0x12345670); 969 task.offset = 0x8 * 512; 970 971 ret = bdev_scsi_get_dif_ctx(&bdev, &task, &dif_ctx); 972 CU_ASSERT(ret == true); 973 CU_ASSERT(dif_ctx.init_ref_tag + dif_ctx.ref_tag_offset == 0x12345678); 974 975 cdb[0] = SPDK_SBC_WRITE_16; 976 to_be64(&cdb[2], 0x0000000012345670); 977 task.offset = 0x8 * 512; 978 979 ret = bdev_scsi_get_dif_ctx(&bdev, &task, &dif_ctx); 980 CU_ASSERT(ret == true); 981 CU_ASSERT(dif_ctx.init_ref_tag + dif_ctx.ref_tag_offset == 0x12345678); 982 } 983 984 int 985 main(int argc, char **argv) 986 { 987 CU_pSuite suite = NULL; 988 unsigned int num_failures; 989 990 TAILQ_INIT(&g_bdev_io_queue); 991 TAILQ_INIT(&g_io_wait_queue); 992 993 CU_set_error_action(CUEA_ABORT); 994 CU_initialize_registry(); 995 996 suite = CU_add_suite("translation_suite", NULL, NULL); 997 998 CU_ADD_TEST(suite, mode_select_6_test); 999 CU_ADD_TEST(suite, mode_select_6_test2); 1000 CU_ADD_TEST(suite, mode_sense_6_test); 1001 CU_ADD_TEST(suite, mode_sense_10_test); 1002 CU_ADD_TEST(suite, inquiry_evpd_test); 1003 CU_ADD_TEST(suite, inquiry_standard_test); 1004 CU_ADD_TEST(suite, inquiry_overflow_test); 1005 CU_ADD_TEST(suite, task_complete_test); 1006 CU_ADD_TEST(suite, lba_range_test); 1007 CU_ADD_TEST(suite, xfer_len_test); 1008 CU_ADD_TEST(suite, xfer_test); 1009 CU_ADD_TEST(suite, scsi_name_padding_test); 1010 CU_ADD_TEST(suite, get_dif_ctx_test); 1011 1012 CU_basic_set_mode(CU_BRM_VERBOSE); 1013 CU_basic_run_tests(); 1014 num_failures = CU_get_number_of_failures(); 1015 CU_cleanup_registry(); 1016 return num_failures; 1017 } 1018