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