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