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