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