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