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