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