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.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 rc = spdk_bdev_scsi_execute(&task); 705 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 706 CU_ASSERT(task.status == 0xFF); 707 SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue)); 708 ut_bdev_io_flush(); 709 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 710 CU_ASSERT(g_scsi_cb_called == 1); 711 g_scsi_cb_called = 0; 712 713 /* LBA = 4, length = 1 (LBA out of range) */ 714 to_be64(&cdb[2], 4); /* LBA */ 715 to_be32(&cdb[10], 1); /* transfer length */ 716 task.transfer_len = 1 * 512; 717 rc = spdk_bdev_scsi_execute(&task); 718 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 719 CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION); 720 CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); 721 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue)); 722 723 /* LBA = 0, length = 4 (in range, max valid size) */ 724 to_be64(&cdb[2], 0); /* LBA */ 725 to_be32(&cdb[10], 4); /* transfer length */ 726 task.transfer_len = 4 * 512; 727 task.status = 0xFF; 728 rc = spdk_bdev_scsi_execute(&task); 729 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 730 CU_ASSERT(task.status == 0xFF); 731 SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue)); 732 ut_bdev_io_flush(); 733 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 734 CU_ASSERT(g_scsi_cb_called == 1); 735 g_scsi_cb_called = 0; 736 737 /* LBA = 0, length = 5 (LBA in range, length beyond end of bdev) */ 738 to_be64(&cdb[2], 0); /* LBA */ 739 to_be32(&cdb[10], 5); /* transfer length */ 740 task.transfer_len = 5 * 512; 741 rc = spdk_bdev_scsi_execute(&task); 742 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 743 CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION); 744 CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); 745 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue)); 746 747 ut_put_task(&task); 748 } 749 750 static void 751 xfer_len_test(void) 752 { 753 struct spdk_bdev bdev; 754 struct spdk_scsi_lun lun; 755 struct spdk_scsi_task task; 756 uint8_t cdb[16]; 757 int rc; 758 759 lun.bdev = &bdev; 760 761 ut_init_task(&task); 762 task.lun = &lun; 763 task.cdb = cdb; 764 765 memset(cdb, 0, sizeof(cdb)); 766 cdb[0] = 0x88; /* READ (16) */ 767 768 /* Test block device size of 512 MiB */ 769 g_test_bdev_num_blocks = 512 * 1024 * 1024; 770 771 /* 1 block */ 772 to_be64(&cdb[2], 0); /* LBA */ 773 to_be32(&cdb[10], 1); /* transfer length */ 774 task.transfer_len = 1 * 512; 775 rc = spdk_bdev_scsi_execute(&task); 776 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 777 CU_ASSERT(task.status == 0xFF); 778 SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue)); 779 ut_bdev_io_flush(); 780 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 781 CU_ASSERT(g_scsi_cb_called == 1); 782 g_scsi_cb_called = 0; 783 784 /* max transfer length (as reported in block limits VPD page) */ 785 to_be64(&cdb[2], 0); /* LBA */ 786 to_be32(&cdb[10], SPDK_WORK_BLOCK_SIZE / 512); /* transfer length */ 787 task.transfer_len = SPDK_WORK_BLOCK_SIZE; 788 task.status = 0xFF; 789 rc = spdk_bdev_scsi_execute(&task); 790 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 791 CU_ASSERT(task.status == 0xFF); 792 SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue)); 793 ut_bdev_io_flush(); 794 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 795 CU_ASSERT(g_scsi_cb_called == 1); 796 g_scsi_cb_called = 0; 797 798 /* max transfer length plus one block (invalid) */ 799 to_be64(&cdb[2], 0); /* LBA */ 800 to_be32(&cdb[10], SPDK_WORK_BLOCK_SIZE / 512 + 1); /* transfer length */ 801 task.transfer_len = SPDK_WORK_BLOCK_SIZE + 512; 802 rc = spdk_bdev_scsi_execute(&task); 803 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 804 CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION); 805 CU_ASSERT((task.sense_data[2] & 0xf) == SPDK_SCSI_SENSE_ILLEGAL_REQUEST); 806 CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB); 807 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue)); 808 809 /* zero transfer length (valid) */ 810 to_be64(&cdb[2], 0); /* LBA */ 811 to_be32(&cdb[10], 0); /* transfer length */ 812 task.transfer_len = 0; 813 rc = spdk_bdev_scsi_execute(&task); 814 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 815 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 816 CU_ASSERT(task.data_transferred == 0); 817 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue)); 818 819 /* zero transfer length past end of disk (invalid) */ 820 to_be64(&cdb[2], g_test_bdev_num_blocks); /* LBA */ 821 to_be32(&cdb[10], 0); /* transfer length */ 822 task.transfer_len = 0; 823 rc = spdk_bdev_scsi_execute(&task); 824 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 825 CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION); 826 CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); 827 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue)); 828 829 ut_put_task(&task); 830 } 831 832 static void 833 _xfer_test(bool bdev_io_pool_full) 834 { 835 struct spdk_bdev bdev; 836 struct spdk_scsi_lun lun; 837 struct spdk_scsi_task task; 838 uint8_t cdb[16]; 839 char data[4096]; 840 int rc; 841 842 lun.bdev = &bdev; 843 844 /* Test block device size of 512 MiB */ 845 g_test_bdev_num_blocks = 512 * 1024 * 1024; 846 847 /* Read 1 block */ 848 ut_init_task(&task); 849 task.lun = &lun; 850 task.cdb = cdb; 851 memset(cdb, 0, sizeof(cdb)); 852 cdb[0] = 0x88; /* READ (16) */ 853 to_be64(&cdb[2], 0); /* LBA */ 854 to_be32(&cdb[10], 1); /* transfer length */ 855 task.transfer_len = 1 * 512; 856 g_bdev_io_pool_full = bdev_io_pool_full; 857 rc = spdk_bdev_scsi_execute(&task); 858 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 859 CU_ASSERT(task.status == 0xFF); 860 861 ut_bdev_io_flush(); 862 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 863 CU_ASSERT(g_scsi_cb_called == 1); 864 g_scsi_cb_called = 0; 865 ut_put_task(&task); 866 867 /* Write 1 block */ 868 ut_init_task(&task); 869 task.lun = &lun; 870 task.cdb = cdb; 871 memset(cdb, 0, sizeof(cdb)); 872 cdb[0] = 0x8a; /* WRITE (16) */ 873 to_be64(&cdb[2], 0); /* LBA */ 874 to_be32(&cdb[10], 1); /* transfer length */ 875 task.transfer_len = 1 * 512; 876 g_bdev_io_pool_full = bdev_io_pool_full; 877 rc = spdk_bdev_scsi_execute(&task); 878 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 879 CU_ASSERT(task.status == 0xFF); 880 881 ut_bdev_io_flush(); 882 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 883 CU_ASSERT(g_scsi_cb_called == 1); 884 g_scsi_cb_called = 0; 885 ut_put_task(&task); 886 887 /* Unmap 5 blocks using 2 descriptors */ 888 ut_init_task(&task); 889 task.lun = &lun; 890 task.cdb = cdb; 891 memset(cdb, 0, sizeof(cdb)); 892 cdb[0] = 0x42; /* UNMAP */ 893 to_be16(&data[7], 2); /* 2 parameters in list */ 894 memset(data, 0, sizeof(data)); 895 to_be16(&data[2], 32); /* 2 descriptors */ 896 to_be64(&data[8], 1); /* LBA 1 */ 897 to_be32(&data[16], 2); /* 2 blocks */ 898 to_be64(&data[24], 10); /* LBA 10 */ 899 to_be32(&data[32], 3); /* 3 blocks */ 900 spdk_scsi_task_set_data(&task, data, sizeof(data)); 901 task.status = SPDK_SCSI_STATUS_GOOD; 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 == SPDK_SCSI_STATUS_GOOD); 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 /* Flush 1 block */ 914 ut_init_task(&task); 915 task.lun = &lun; 916 task.cdb = cdb; 917 memset(cdb, 0, sizeof(cdb)); 918 cdb[0] = 0x91; /* SYNCHRONIZE CACHE (16) */ 919 to_be64(&cdb[2], 0); /* LBA */ 920 to_be32(&cdb[10], 1); /* 1 blocks */ 921 g_bdev_io_pool_full = bdev_io_pool_full; 922 rc = spdk_bdev_scsi_execute(&task); 923 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 924 CU_ASSERT(task.status == 0xFF); 925 926 ut_bdev_io_flush(); 927 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 928 CU_ASSERT(g_scsi_cb_called == 1); 929 g_scsi_cb_called = 0; 930 ut_put_task(&task); 931 } 932 933 static void 934 xfer_test(void) 935 { 936 _xfer_test(false); 937 _xfer_test(true); 938 } 939 940 int 941 main(int argc, char **argv) 942 { 943 CU_pSuite suite = NULL; 944 unsigned int num_failures; 945 946 TAILQ_INIT(&g_bdev_io_queue); 947 TAILQ_INIT(&g_io_wait_queue); 948 949 if (CU_initialize_registry() != CUE_SUCCESS) { 950 return CU_get_error(); 951 } 952 953 suite = CU_add_suite("translation_suite", NULL, NULL); 954 if (suite == NULL) { 955 CU_cleanup_registry(); 956 return CU_get_error(); 957 } 958 959 if ( 960 CU_add_test(suite, "mode select 6 test", mode_select_6_test) == NULL 961 || CU_add_test(suite, "mode select 6 test2", mode_select_6_test2) == NULL 962 || CU_add_test(suite, "mode sense 6 test", mode_sense_6_test) == NULL 963 || CU_add_test(suite, "mode sense 10 test", mode_sense_10_test) == NULL 964 || CU_add_test(suite, "inquiry evpd test", inquiry_evpd_test) == NULL 965 || CU_add_test(suite, "inquiry standard test", inquiry_standard_test) == NULL 966 || CU_add_test(suite, "inquiry overflow test", inquiry_overflow_test) == NULL 967 || CU_add_test(suite, "task complete test", task_complete_test) == NULL 968 || CU_add_test(suite, "LBA range test", lba_range_test) == NULL 969 || CU_add_test(suite, "transfer length test", xfer_len_test) == NULL 970 || CU_add_test(suite, "transfer test", xfer_test) == NULL 971 || CU_add_test(suite, "scsi name padding test", scsi_name_padding_test) == NULL 972 ) { 973 CU_cleanup_registry(); 974 return CU_get_error(); 975 } 976 977 CU_basic_set_mode(CU_BRM_VERBOSE); 978 CU_basic_run_tests(); 979 num_failures = CU_get_number_of_failures(); 980 CU_cleanup_registry(); 981 return num_failures; 982 } 983