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