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