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 DEFINE_STUB_V(spdk_bdev_free_io, (struct spdk_bdev_io *bdev_io)); 64 65 DEFINE_STUB(spdk_bdev_get_name, const char *, 66 (const struct spdk_bdev *bdev), "test"); 67 68 DEFINE_STUB(spdk_bdev_get_block_size, uint32_t, 69 (const struct spdk_bdev *bdev), 512); 70 71 DEFINE_STUB(spdk_bdev_get_md_size, uint32_t, 72 (const struct spdk_bdev *bdev), 8); 73 74 DEFINE_STUB(spdk_bdev_is_md_interleaved, bool, 75 (const struct spdk_bdev *bdev), false); 76 77 DEFINE_STUB(spdk_bdev_get_data_block_size, uint32_t, 78 (const struct spdk_bdev *bdev), 512); 79 80 uint64_t 81 spdk_bdev_get_num_blocks(const struct spdk_bdev *bdev) 82 { 83 return g_test_bdev_num_blocks; 84 } 85 86 DEFINE_STUB(spdk_bdev_get_product_name, const char *, 87 (const struct spdk_bdev *bdev), "test product"); 88 89 DEFINE_STUB(spdk_bdev_has_write_cache, bool, 90 (const struct spdk_bdev *bdev), false); 91 92 DEFINE_STUB(spdk_bdev_get_dif_type, enum spdk_dif_type, 93 (const struct spdk_bdev *bdev), SPDK_DIF_DISABLE); 94 95 DEFINE_STUB(spdk_bdev_is_dif_head_of_md, bool, 96 (const struct spdk_bdev *bdev), false); 97 98 DEFINE_STUB(spdk_bdev_is_dif_check_enabled, bool, 99 (const struct spdk_bdev *bdev, enum spdk_dif_check_type check_type), false); 100 101 DEFINE_STUB(spdk_scsi_pr_out, int, (struct spdk_scsi_task *task, 102 uint8_t *cdb, uint8_t *data, uint16_t data_len), 0); 103 104 DEFINE_STUB(spdk_scsi_pr_in, int, (struct spdk_scsi_task *task, uint8_t *cdb, 105 uint8_t *data, uint16_t data_len), 0); 106 107 void 108 spdk_scsi_lun_complete_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task) 109 { 110 g_scsi_cb_called++; 111 } 112 113 DEFINE_STUB_V(spdk_scsi_lun_complete_reset_task, 114 (struct spdk_scsi_lun *lun, struct spdk_scsi_task *task)); 115 116 DEFINE_STUB(spdk_scsi_lun_id_int_to_fmt, uint64_t, (int lun_id), 0); 117 118 static void 119 ut_put_task(struct spdk_scsi_task *task) 120 { 121 if (task->alloc_len) { 122 free(task->iov.iov_base); 123 } 124 125 task->iov.iov_base = NULL; 126 task->iov.iov_len = 0; 127 task->alloc_len = 0; 128 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue)); 129 } 130 131 static void 132 ut_init_task(struct spdk_scsi_task *task) 133 { 134 memset(task, 0xFF, sizeof(*task)); 135 task->iov.iov_base = NULL; 136 task->iovs = &task->iov; 137 task->iovcnt = 1; 138 task->alloc_len = 0; 139 task->dxfer_dir = SPDK_SCSI_DIR_NONE; 140 } 141 142 void 143 spdk_bdev_io_get_scsi_status(const struct spdk_bdev_io *bdev_io, 144 int *sc, int *sk, int *asc, int *ascq) 145 { 146 switch (bdev_io->internal.status) { 147 case SPDK_BDEV_IO_STATUS_SUCCESS: 148 *sc = SPDK_SCSI_STATUS_GOOD; 149 *sk = SPDK_SCSI_SENSE_NO_SENSE; 150 *asc = SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE; 151 *ascq = SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE; 152 break; 153 case SPDK_BDEV_IO_STATUS_SCSI_ERROR: 154 *sc = bdev_io->internal.error.scsi.sc; 155 *sk = bdev_io->internal.error.scsi.sk; 156 *asc = bdev_io->internal.error.scsi.asc; 157 *ascq = bdev_io->internal.error.scsi.ascq; 158 break; 159 default: 160 *sc = SPDK_SCSI_STATUS_CHECK_CONDITION; 161 *sk = SPDK_SCSI_SENSE_ABORTED_COMMAND; 162 *asc = SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE; 163 *ascq = SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE; 164 break; 165 } 166 } 167 168 void 169 spdk_bdev_io_get_iovec(struct spdk_bdev_io *bdev_io, struct iovec **iovp, int *iovcntp) 170 { 171 *iovp = NULL; 172 *iovcntp = 0; 173 } 174 175 static void 176 ut_bdev_io_flush(void) 177 { 178 struct spdk_bdev_io *bdev_io; 179 struct spdk_bdev_io_wait_entry *entry; 180 181 while (!TAILQ_EMPTY(&g_bdev_io_queue) || !TAILQ_EMPTY(&g_io_wait_queue)) { 182 while (!TAILQ_EMPTY(&g_bdev_io_queue)) { 183 bdev_io = TAILQ_FIRST(&g_bdev_io_queue); 184 TAILQ_REMOVE(&g_bdev_io_queue, bdev_io, internal.link); 185 bdev_io->internal.cb(bdev_io, true, bdev_io->internal.caller_ctx); 186 free(bdev_io); 187 } 188 189 while (!TAILQ_EMPTY(&g_io_wait_queue)) { 190 entry = TAILQ_FIRST(&g_io_wait_queue); 191 TAILQ_REMOVE(&g_io_wait_queue, entry, link); 192 entry->cb_fn(entry->cb_arg); 193 } 194 } 195 } 196 197 static int 198 _spdk_bdev_io_op(spdk_bdev_io_completion_cb cb, void *cb_arg) 199 { 200 struct spdk_bdev_io *bdev_io; 201 202 if (g_bdev_io_pool_full) { 203 g_bdev_io_pool_full = false; 204 return -ENOMEM; 205 } 206 207 bdev_io = calloc(1, sizeof(*bdev_io)); 208 SPDK_CU_ASSERT_FATAL(bdev_io != NULL); 209 bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS; 210 bdev_io->internal.cb = cb; 211 bdev_io->internal.caller_ctx = cb_arg; 212 213 TAILQ_INSERT_TAIL(&g_bdev_io_queue, bdev_io, internal.link); 214 215 return 0; 216 } 217 218 int 219 spdk_bdev_readv_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 220 struct iovec *iov, int iovcnt, 221 uint64_t offset_blocks, uint64_t num_blocks, 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_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 229 struct iovec *iov, int iovcnt, 230 uint64_t offset_blocks, uint64_t num_blocks, 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 int 260 spdk_bdev_queue_io_wait(struct spdk_bdev *bdev, struct spdk_io_channel *ch, 261 struct spdk_bdev_io_wait_entry *entry) 262 { 263 TAILQ_INSERT_TAIL(&g_io_wait_queue, entry, link); 264 return 0; 265 } 266 267 int 268 spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_size, 269 bool md_interleave, bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, 270 uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag, 271 uint32_t data_offset, uint16_t guard_seed) 272 { 273 ctx->init_ref_tag = init_ref_tag; 274 ctx->ref_tag_offset = data_offset / 512; 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 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue)); 953 954 ut_put_task(&task); 955 } 956 957 static void 958 xfer_test(void) 959 { 960 _xfer_test(false); 961 _xfer_test(true); 962 } 963 964 static void 965 get_dif_ctx_test(void) 966 { 967 struct spdk_bdev bdev = {}; 968 struct spdk_scsi_task task = {}; 969 struct spdk_dif_ctx dif_ctx = {}; 970 uint8_t cdb[16]; 971 bool ret; 972 973 cdb[0] = SPDK_SBC_READ_6; 974 cdb[1] = 0x12; 975 cdb[2] = 0x34; 976 cdb[3] = 0x50; 977 task.cdb = cdb; 978 task.offset = 0x6 * 512; 979 980 ret = spdk_scsi_bdev_get_dif_ctx(&bdev, &task, &dif_ctx); 981 CU_ASSERT(ret == true); 982 CU_ASSERT(dif_ctx.init_ref_tag + dif_ctx.ref_tag_offset == 0x123456); 983 984 cdb[0] = SPDK_SBC_WRITE_12; 985 to_be32(&cdb[2], 0x12345670); 986 task.offset = 0x8 * 512; 987 988 ret = spdk_scsi_bdev_get_dif_ctx(&bdev, &task, &dif_ctx); 989 CU_ASSERT(ret == true); 990 CU_ASSERT(dif_ctx.init_ref_tag + dif_ctx.ref_tag_offset == 0x12345678); 991 992 cdb[0] = SPDK_SBC_WRITE_16; 993 to_be64(&cdb[2], 0x0000000012345670); 994 task.offset = 0x8 * 512; 995 996 ret = spdk_scsi_bdev_get_dif_ctx(&bdev, &task, &dif_ctx); 997 CU_ASSERT(ret == true); 998 CU_ASSERT(dif_ctx.init_ref_tag + dif_ctx.ref_tag_offset == 0x12345678); 999 } 1000 1001 int 1002 main(int argc, char **argv) 1003 { 1004 CU_pSuite suite = NULL; 1005 unsigned int num_failures; 1006 1007 TAILQ_INIT(&g_bdev_io_queue); 1008 TAILQ_INIT(&g_io_wait_queue); 1009 1010 CU_set_error_action(CUEA_ABORT); 1011 CU_initialize_registry(); 1012 1013 suite = CU_add_suite("translation_suite", NULL, NULL); 1014 1015 CU_ADD_TEST(suite, mode_select_6_test); 1016 CU_ADD_TEST(suite, mode_select_6_test2); 1017 CU_ADD_TEST(suite, mode_sense_6_test); 1018 CU_ADD_TEST(suite, mode_sense_10_test); 1019 CU_ADD_TEST(suite, inquiry_evpd_test); 1020 CU_ADD_TEST(suite, inquiry_standard_test); 1021 CU_ADD_TEST(suite, inquiry_overflow_test); 1022 CU_ADD_TEST(suite, task_complete_test); 1023 CU_ADD_TEST(suite, lba_range_test); 1024 CU_ADD_TEST(suite, xfer_len_test); 1025 CU_ADD_TEST(suite, xfer_test); 1026 CU_ADD_TEST(suite, scsi_name_padding_test); 1027 CU_ADD_TEST(suite, get_dif_ctx_test); 1028 1029 CU_basic_set_mode(CU_BRM_VERBOSE); 1030 CU_basic_run_tests(); 1031 num_failures = CU_get_number_of_failures(); 1032 CU_cleanup_registry(); 1033 return num_failures; 1034 } 1035