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