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