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