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