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