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