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 39 #include "spdk_cunit.h" 40 41 SPDK_LOG_REGISTER_COMPONENT("scsi", SPDK_LOG_SCSI) 42 43 struct spdk_scsi_globals g_spdk_scsi; 44 45 static uint64_t g_test_bdev_num_blocks; 46 47 void * 48 spdk_dma_malloc(size_t size, size_t align, uint64_t *phys_addr) 49 { 50 void *buf = malloc(size); 51 if (phys_addr) { 52 *phys_addr = (uint64_t)buf; 53 } 54 55 return buf; 56 } 57 58 void * 59 spdk_dma_zmalloc(size_t size, size_t align, uint64_t *phys_addr) 60 { 61 void *buf = calloc(size, 1); 62 if (phys_addr) { 63 *phys_addr = (uint64_t)buf; 64 } 65 66 return buf; 67 } 68 69 void 70 spdk_dma_free(void *buf) 71 { 72 free(buf); 73 } 74 75 bool 76 spdk_bdev_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type io_type) 77 { 78 abort(); 79 return false; 80 } 81 82 int 83 spdk_bdev_free_io(struct spdk_bdev_io *bdev_io) 84 { 85 CU_ASSERT(0); 86 return -1; 87 } 88 89 const char * 90 spdk_bdev_get_name(const struct spdk_bdev *bdev) 91 { 92 return "test"; 93 } 94 95 uint32_t 96 spdk_bdev_get_block_size(const struct spdk_bdev *bdev) 97 { 98 return 512; 99 } 100 101 uint64_t 102 spdk_bdev_get_num_blocks(const struct spdk_bdev *bdev) 103 { 104 return g_test_bdev_num_blocks; 105 } 106 107 const char * 108 spdk_bdev_get_product_name(const struct spdk_bdev *bdev) 109 { 110 return "test product"; 111 } 112 113 bool 114 spdk_bdev_has_write_cache(const struct spdk_bdev *bdev) 115 { 116 return false; 117 } 118 119 void 120 spdk_scsi_lun_complete_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task) 121 { 122 } 123 124 void 125 spdk_scsi_lun_complete_mgmt_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task) 126 { 127 } 128 129 static void 130 spdk_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 } 140 141 142 static void 143 spdk_init_task(struct spdk_scsi_task *task) 144 { 145 memset(task, 0, sizeof(*task)); 146 task->iovs = &task->iov; 147 task->iovcnt = 1; 148 } 149 150 void 151 spdk_bdev_io_get_scsi_status(const struct spdk_bdev_io *bdev_io, 152 int *sc, int *sk, int *asc, int *ascq) 153 { 154 switch (bdev_io->status) { 155 case SPDK_BDEV_IO_STATUS_SUCCESS: 156 *sc = SPDK_SCSI_STATUS_GOOD; 157 *sk = SPDK_SCSI_SENSE_NO_SENSE; 158 *asc = SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE; 159 *ascq = SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE; 160 break; 161 case SPDK_BDEV_IO_STATUS_SCSI_ERROR: 162 *sc = bdev_io->error.scsi.sc; 163 *sk = bdev_io->error.scsi.sk; 164 *asc = bdev_io->error.scsi.asc; 165 *ascq = bdev_io->error.scsi.ascq; 166 break; 167 default: 168 *sc = SPDK_SCSI_STATUS_CHECK_CONDITION; 169 *sk = SPDK_SCSI_SENSE_ABORTED_COMMAND; 170 *asc = SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE; 171 *ascq = SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE; 172 break; 173 } 174 } 175 176 void 177 spdk_bdev_io_get_iovec(struct spdk_bdev_io *bdev_io, struct iovec **iovp, int *iovcntp) 178 { 179 *iovp = NULL; 180 *iovcntp = 0; 181 } 182 183 int 184 spdk_bdev_read(struct spdk_bdev_desc *bdev_desc, struct spdk_io_channel *ch, 185 void *buf, uint64_t offset, uint64_t nbytes, 186 spdk_bdev_io_completion_cb cb, void *cb_arg) 187 { 188 return 0; 189 } 190 191 int 192 spdk_bdev_readv(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 193 struct iovec *iov, int iovcnt, uint64_t offset, uint64_t nbytes, 194 spdk_bdev_io_completion_cb cb, void *cb_arg) 195 { 196 return 0; 197 } 198 199 int 200 spdk_bdev_writev(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 201 struct iovec *iov, int iovcnt, 202 uint64_t offset, uint64_t len, 203 spdk_bdev_io_completion_cb cb, void *cb_arg) 204 { 205 return 0; 206 } 207 208 int 209 spdk_bdev_unmap_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 210 uint64_t offset_blocks, uint64_t num_blocks, 211 spdk_bdev_io_completion_cb cb, void *cb_arg) 212 { 213 return 0; 214 } 215 216 int 217 spdk_bdev_reset(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 218 spdk_bdev_io_completion_cb cb, void *cb_arg) 219 { 220 return 0; 221 } 222 223 int 224 spdk_bdev_flush_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 225 uint64_t offset_blocks, uint64_t num_blocks, 226 spdk_bdev_io_completion_cb cb, void *cb_arg) 227 { 228 return 0; 229 } 230 231 /* 232 * This test specifically tests a mode select 6 command from the 233 * Windows SCSI compliance test that caused SPDK to crash. 234 */ 235 static void 236 mode_select_6_test(void) 237 { 238 struct spdk_bdev bdev; 239 struct spdk_scsi_task task; 240 struct spdk_scsi_lun lun; 241 struct spdk_scsi_dev dev; 242 char cdb[16]; 243 char data[24]; 244 int rc; 245 246 spdk_init_task(&task); 247 248 cdb[0] = 0x15; 249 cdb[1] = 0x11; 250 cdb[2] = 0x00; 251 cdb[3] = 0x00; 252 cdb[4] = 0x18; 253 cdb[5] = 0x00; 254 task.cdb = cdb; 255 256 snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test"); 257 lun.bdev = &bdev; 258 lun.dev = &dev; 259 task.lun = &lun; 260 261 memset(data, 0, sizeof(data)); 262 data[4] = 0x08; 263 data[5] = 0x02; 264 spdk_scsi_task_set_data(&task, data, sizeof(data)); 265 266 rc = spdk_bdev_scsi_execute(&task); 267 268 CU_ASSERT_EQUAL(rc, 0); 269 270 spdk_put_task(&task); 271 } 272 273 /* 274 * This test specifically tests a mode select 6 command which 275 * contains no mode pages. 276 */ 277 static void 278 mode_select_6_test2(void) 279 { 280 struct spdk_bdev bdev; 281 struct spdk_scsi_task task; 282 struct spdk_scsi_lun lun; 283 struct spdk_scsi_dev dev; 284 char cdb[16]; 285 int rc; 286 287 spdk_init_task(&task); 288 289 cdb[0] = 0x15; 290 cdb[1] = 0x00; 291 cdb[2] = 0x00; 292 cdb[3] = 0x00; 293 cdb[4] = 0x00; 294 cdb[5] = 0x00; 295 task.cdb = cdb; 296 297 snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test"); 298 lun.bdev = &bdev; 299 lun.dev = &dev; 300 task.lun = &lun; 301 302 rc = spdk_bdev_scsi_execute(&task); 303 304 CU_ASSERT_EQUAL(rc, 0); 305 306 spdk_put_task(&task); 307 } 308 309 /* 310 * This test specifically tests a mode sense 6 command which 311 * return all subpage 00h mode pages. 312 */ 313 static void 314 mode_sense_6_test(void) 315 { 316 struct spdk_bdev bdev; 317 struct spdk_scsi_task task; 318 struct spdk_scsi_lun lun; 319 struct spdk_scsi_dev dev; 320 char cdb[12]; 321 unsigned char *data; 322 int rc; 323 unsigned char mode_data_len = 0; 324 unsigned char medium_type = 0; 325 unsigned char dev_specific_param = 0; 326 unsigned char blk_descriptor_len = 0; 327 328 memset(&bdev, 0, sizeof(struct spdk_bdev)); 329 spdk_init_task(&task); 330 memset(cdb, 0, sizeof(cdb)); 331 332 cdb[0] = 0x1A; 333 cdb[2] = 0x3F; 334 cdb[4] = 0xFF; 335 task.cdb = cdb; 336 337 snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test"); 338 lun.bdev = &bdev; 339 lun.dev = &dev; 340 task.lun = &lun; 341 342 rc = spdk_bdev_scsi_execute(&task); 343 SPDK_CU_ASSERT_FATAL(rc == 0); 344 345 data = task.iovs[0].iov_base; 346 mode_data_len = data[0]; 347 medium_type = data[1]; 348 dev_specific_param = data[2]; 349 blk_descriptor_len = data[3]; 350 351 CU_ASSERT(mode_data_len >= 11); 352 CU_ASSERT_EQUAL(medium_type, 0); 353 CU_ASSERT_EQUAL(dev_specific_param, 0); 354 CU_ASSERT_EQUAL(blk_descriptor_len, 8); 355 356 spdk_put_task(&task); 357 } 358 359 /* 360 * This test specifically tests a mode sense 10 command which 361 * return all subpage 00h mode pages. 362 */ 363 static void 364 mode_sense_10_test(void) 365 { 366 struct spdk_bdev bdev; 367 struct spdk_scsi_task task; 368 struct spdk_scsi_lun lun; 369 struct spdk_scsi_dev dev; 370 char cdb[12]; 371 unsigned char *data; 372 int rc; 373 unsigned short mode_data_len = 0; 374 unsigned char medium_type = 0; 375 unsigned char dev_specific_param = 0; 376 unsigned short blk_descriptor_len = 0; 377 378 memset(&bdev, 0, sizeof(struct spdk_bdev)); 379 spdk_init_task(&task); 380 memset(cdb, 0, sizeof(cdb)); 381 cdb[0] = 0x5A; 382 cdb[2] = 0x3F; 383 cdb[8] = 0xFF; 384 task.cdb = cdb; 385 386 snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test"); 387 lun.bdev = &bdev; 388 lun.dev = &dev; 389 task.lun = &lun; 390 391 rc = spdk_bdev_scsi_execute(&task); 392 SPDK_CU_ASSERT_FATAL(rc == 0); 393 394 data = task.iovs[0].iov_base; 395 mode_data_len = ((data[0] << 8) + data[1]); 396 medium_type = data[2]; 397 dev_specific_param = data[3]; 398 blk_descriptor_len = ((data[6] << 8) + data[7]); 399 400 CU_ASSERT(mode_data_len >= 14); 401 CU_ASSERT_EQUAL(medium_type, 0); 402 CU_ASSERT_EQUAL(dev_specific_param, 0); 403 CU_ASSERT_EQUAL(blk_descriptor_len, 8); 404 405 spdk_put_task(&task); 406 } 407 408 /* 409 * This test specifically tests a scsi inquiry command from the 410 * Windows SCSI compliance test that failed to return the 411 * expected SCSI error sense code. 412 */ 413 static void 414 inquiry_evpd_test(void) 415 { 416 struct spdk_bdev bdev; 417 struct spdk_scsi_task task; 418 struct spdk_scsi_lun lun; 419 struct spdk_scsi_dev dev; 420 char cdb[6]; 421 int rc; 422 423 spdk_init_task(&task); 424 425 cdb[0] = 0x12; 426 cdb[1] = 0x00; // EVPD = 0 427 cdb[2] = 0xff; // PageCode non-zero 428 cdb[3] = 0x00; 429 cdb[4] = 0xff; 430 cdb[5] = 0x00; 431 task.cdb = cdb; 432 433 snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test"); 434 lun.bdev = &bdev; 435 lun.dev = &dev; 436 task.lun = &lun; 437 438 rc = spdk_bdev_scsi_execute(&task); 439 SPDK_CU_ASSERT_FATAL(rc == 0); 440 441 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION); 442 CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_ILLEGAL_REQUEST); 443 CU_ASSERT_EQUAL(task.sense_data[12], 0x24); 444 CU_ASSERT_EQUAL(task.sense_data[13], 0x0); 445 446 spdk_put_task(&task); 447 } 448 449 /* 450 * This test is to verify specific return data for a standard scsi inquiry 451 * command: Version 452 */ 453 static void 454 inquiry_standard_test(void) 455 { 456 struct spdk_bdev bdev = { .blocklen = 512 }; 457 struct spdk_scsi_task task; 458 struct spdk_scsi_lun lun; 459 struct spdk_scsi_dev dev; 460 char cdb[6]; 461 char *data; 462 struct spdk_scsi_cdb_inquiry_data *inq_data; 463 int rc; 464 465 spdk_init_task(&task); 466 467 cdb[0] = 0x12; 468 cdb[1] = 0x00; // EVPD = 0 469 cdb[2] = 0x00; // PageCode zero - requesting standard inquiry 470 cdb[3] = 0x00; 471 cdb[4] = 0xff; // Indicate data size used by conformance test 472 cdb[5] = 0x00; 473 task.cdb = cdb; 474 475 snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test"); 476 lun.bdev = &bdev; 477 lun.dev = &dev; 478 task.lun = &lun; 479 480 rc = spdk_bdev_scsi_execute(&task); 481 482 data = task.iovs[0].iov_base; 483 inq_data = (struct spdk_scsi_cdb_inquiry_data *)&data[0]; 484 485 CU_ASSERT_EQUAL(inq_data->version, SPDK_SPC_VERSION_SPC3); 486 CU_ASSERT_EQUAL(rc, 0); 487 488 spdk_put_task(&task); 489 } 490 491 static void 492 _inquiry_overflow_test(uint8_t alloc_len) 493 { 494 struct spdk_bdev bdev = { .blocklen = 512 }; 495 struct spdk_scsi_task task; 496 struct spdk_scsi_lun lun; 497 struct spdk_scsi_dev dev; 498 uint8_t cdb[6]; 499 int rc; 500 /* expects a 4K internal data buffer */ 501 char data[4096], data_compare[4096]; 502 503 spdk_init_task(&task); 504 505 cdb[0] = 0x12; 506 cdb[1] = 0x00; // EVPD = 0 507 cdb[2] = 0x00; // PageCode zero - requesting standard inquiry 508 cdb[3] = 0x00; 509 cdb[4] = alloc_len; // Indicate data size used by conformance test 510 cdb[5] = 0x00; 511 task.cdb = cdb; 512 513 snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test"); 514 lun.bdev = &bdev; 515 lun.dev = &dev; 516 task.lun = &lun; 517 518 memset(data, 0, sizeof(data)); 519 memset(data_compare, 0, sizeof(data_compare)); 520 521 spdk_scsi_task_set_data(&task, data, sizeof(data)); 522 523 rc = spdk_bdev_scsi_execute(&task); 524 SPDK_CU_ASSERT_FATAL(rc == 0); 525 526 CU_ASSERT_EQUAL(memcmp(data + alloc_len, data_compare + alloc_len, sizeof(data) - alloc_len), 0); 527 CU_ASSERT(task.data_transferred <= alloc_len); 528 529 spdk_put_task(&task); 530 } 531 532 static void 533 inquiry_overflow_test(void) 534 { 535 int i; 536 537 for (i = 0; i < 256; i++) { 538 _inquiry_overflow_test(i); 539 } 540 } 541 542 static void 543 scsi_name_padding_test(void) 544 { 545 char name[SPDK_SCSI_DEV_MAX_NAME + 10]; 546 char buf[SPDK_SCSI_DEV_MAX_NAME + 1]; 547 int written, i; 548 549 /* case 1 */ 550 memset(name, '\0', sizeof(name)); 551 memset(name, 'x', 251); 552 written = spdk_bdev_scsi_pad_scsi_name(buf, name); 553 554 CU_ASSERT(written == 252); 555 CU_ASSERT(buf[250] == 'x'); 556 CU_ASSERT(buf[251] == '\0'); 557 558 /* case 2: */ 559 memset(name, '\0', sizeof(name)); 560 memset(name, 'x', 252); 561 written = spdk_bdev_scsi_pad_scsi_name(buf, name); 562 563 CU_ASSERT(written == 256); 564 CU_ASSERT(buf[251] == 'x'); 565 for (i = 252; i < 256; i++) { 566 CU_ASSERT(buf[i] == '\0'); 567 } 568 569 /* case 3 */ 570 memset(name, '\0', sizeof(name)); 571 memset(name, 'x', 255); 572 written = spdk_bdev_scsi_pad_scsi_name(buf, name); 573 574 CU_ASSERT(written == 256); 575 CU_ASSERT(buf[254] == 'x'); 576 CU_ASSERT(buf[255] == '\0'); 577 578 /* case 4 */ 579 memset(name, '\0', sizeof(name)); 580 memset(name, 'x', sizeof(name)); 581 written = spdk_bdev_scsi_pad_scsi_name(buf, name); 582 583 CU_ASSERT(written == 256); 584 CU_ASSERT(buf[254] == 'x'); 585 CU_ASSERT(buf[255] == '\0'); 586 } 587 588 /* 589 * This test is to verify specific error translation from bdev to scsi. 590 */ 591 static void 592 task_complete_test(void) 593 { 594 struct spdk_scsi_task task; 595 struct spdk_bdev_io bdev_io = {}; 596 struct spdk_scsi_lun lun; 597 598 spdk_init_task(&task); 599 600 TAILQ_INIT(&lun.tasks); 601 TAILQ_INSERT_TAIL(&lun.tasks, &task, scsi_link); 602 task.lun = &lun; 603 604 bdev_io.status = SPDK_BDEV_IO_STATUS_SUCCESS; 605 spdk_bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.status, &task); 606 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_GOOD); 607 608 bdev_io.status = SPDK_BDEV_IO_STATUS_SCSI_ERROR; 609 bdev_io.error.scsi.sc = SPDK_SCSI_STATUS_CHECK_CONDITION; 610 bdev_io.error.scsi.sk = SPDK_SCSI_SENSE_HARDWARE_ERROR; 611 bdev_io.error.scsi.asc = SPDK_SCSI_ASC_WARNING; 612 bdev_io.error.scsi.ascq = SPDK_SCSI_ASCQ_POWER_LOSS_EXPECTED; 613 spdk_bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.status, &task); 614 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION); 615 CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_HARDWARE_ERROR); 616 CU_ASSERT_EQUAL(task.sense_data[12], SPDK_SCSI_ASC_WARNING); 617 CU_ASSERT_EQUAL(task.sense_data[13], SPDK_SCSI_ASCQ_POWER_LOSS_EXPECTED); 618 619 bdev_io.status = SPDK_BDEV_IO_STATUS_FAILED; 620 spdk_bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.status, &task); 621 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION); 622 CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_ABORTED_COMMAND); 623 CU_ASSERT_EQUAL(task.sense_data[12], SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE); 624 CU_ASSERT_EQUAL(task.sense_data[13], SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE); 625 626 spdk_put_task(&task); 627 } 628 629 static void 630 lba_range_test(void) 631 { 632 struct spdk_bdev bdev; 633 struct spdk_scsi_lun lun; 634 struct spdk_scsi_task task; 635 uint8_t cdb[16]; 636 int rc; 637 638 lun.bdev = &bdev; 639 640 spdk_init_task(&task); 641 task.lun = &lun; 642 task.cdb = cdb; 643 644 memset(cdb, 0, sizeof(cdb)); 645 cdb[0] = 0x88; /* READ (16) */ 646 647 /* Test block device size of 4 blocks */ 648 g_test_bdev_num_blocks = 4; 649 650 /* LBA = 0, length = 1 (in range) */ 651 to_be64(&cdb[2], 0); /* LBA */ 652 to_be32(&cdb[10], 1); /* transfer length */ 653 task.transfer_len = 1 * 512; 654 rc = spdk_bdev_scsi_execute(&task); 655 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 656 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 657 658 /* LBA = 4, length = 1 (LBA out of range) */ 659 to_be64(&cdb[2], 4); /* LBA */ 660 to_be32(&cdb[10], 1); /* transfer length */ 661 task.transfer_len = 1 * 512; 662 rc = spdk_bdev_scsi_execute(&task); 663 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 664 CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION); 665 CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); 666 667 /* LBA = 0, length = 4 (in range, max valid size) */ 668 to_be64(&cdb[2], 0); /* LBA */ 669 to_be32(&cdb[10], 4); /* transfer length */ 670 task.transfer_len = 4 * 512; 671 rc = spdk_bdev_scsi_execute(&task); 672 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 673 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 674 675 /* LBA = 0, length = 5 (LBA in range, length beyond end of bdev) */ 676 to_be64(&cdb[2], 0); /* LBA */ 677 to_be32(&cdb[10], 5); /* transfer length */ 678 task.transfer_len = 5 * 512; 679 rc = spdk_bdev_scsi_execute(&task); 680 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 681 CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION); 682 CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); 683 684 spdk_put_task(&task); 685 } 686 687 static void 688 xfer_len_test(void) 689 { 690 struct spdk_bdev bdev; 691 struct spdk_scsi_lun lun; 692 struct spdk_scsi_task task; 693 uint8_t cdb[16]; 694 int rc; 695 696 lun.bdev = &bdev; 697 698 spdk_init_task(&task); 699 task.lun = &lun; 700 task.cdb = cdb; 701 702 memset(cdb, 0, sizeof(cdb)); 703 cdb[0] = 0x88; /* READ (16) */ 704 705 /* Test block device size of 512 MiB */ 706 g_test_bdev_num_blocks = 512 * 1024 * 1024; 707 708 /* 1 block */ 709 to_be64(&cdb[2], 0); /* LBA */ 710 to_be32(&cdb[10], 1); /* transfer length */ 711 task.transfer_len = 1 * 512; 712 rc = spdk_bdev_scsi_execute(&task); 713 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 714 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 715 716 /* max transfer length (as reported in block limits VPD page) */ 717 to_be64(&cdb[2], 0); /* LBA */ 718 to_be32(&cdb[10], SPDK_WORK_BLOCK_SIZE / 512); /* transfer length */ 719 task.transfer_len = SPDK_WORK_BLOCK_SIZE; 720 rc = spdk_bdev_scsi_execute(&task); 721 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 722 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 723 724 /* max transfer length plus one block (invalid) */ 725 to_be64(&cdb[2], 0); /* LBA */ 726 to_be32(&cdb[10], SPDK_WORK_BLOCK_SIZE / 512 + 1); /* transfer length */ 727 task.transfer_len = SPDK_WORK_BLOCK_SIZE + 512; 728 rc = spdk_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[2] & 0xf) == SPDK_SCSI_SENSE_ILLEGAL_REQUEST); 732 CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB); 733 734 /* zero transfer length (valid) */ 735 to_be64(&cdb[2], 0); /* LBA */ 736 to_be32(&cdb[10], 0); /* transfer length */ 737 task.transfer_len = 0; 738 rc = spdk_bdev_scsi_execute(&task); 739 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 740 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 741 CU_ASSERT(task.data_transferred == 0); 742 743 /* zero transfer length past end of disk (invalid) */ 744 to_be64(&cdb[2], g_test_bdev_num_blocks); /* LBA */ 745 to_be32(&cdb[10], 0); /* transfer length */ 746 task.transfer_len = 0; 747 rc = spdk_bdev_scsi_execute(&task); 748 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 749 CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION); 750 CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); 751 752 spdk_put_task(&task); 753 } 754 755 int 756 main(int argc, char **argv) 757 { 758 CU_pSuite suite = NULL; 759 unsigned int num_failures; 760 761 if (CU_initialize_registry() != CUE_SUCCESS) { 762 return CU_get_error(); 763 } 764 765 suite = CU_add_suite("translation_suite", NULL, NULL); 766 if (suite == NULL) { 767 CU_cleanup_registry(); 768 return CU_get_error(); 769 } 770 771 if ( 772 CU_add_test(suite, "mode select 6 test", mode_select_6_test) == NULL 773 || CU_add_test(suite, "mode select 6 test2", mode_select_6_test2) == NULL 774 || CU_add_test(suite, "mode sense 6 test", mode_sense_6_test) == NULL 775 || CU_add_test(suite, "mode sense 10 test", mode_sense_10_test) == NULL 776 || CU_add_test(suite, "inquiry evpd test", inquiry_evpd_test) == NULL 777 || CU_add_test(suite, "inquiry standard test", inquiry_standard_test) == NULL 778 || CU_add_test(suite, "inquiry overflow test", inquiry_overflow_test) == NULL 779 || CU_add_test(suite, "task complete test", task_complete_test) == NULL 780 || CU_add_test(suite, "LBA range test", lba_range_test) == NULL 781 || CU_add_test(suite, "transfer length test", xfer_len_test) == NULL 782 || CU_add_test(suite, "scsi name padding test", scsi_name_padding_test) == NULL 783 ) { 784 CU_cleanup_registry(); 785 return CU_get_error(); 786 } 787 788 CU_basic_set_mode(CU_BRM_VERBOSE); 789 CU_basic_run_tests(); 790 num_failures = CU_get_number_of_failures(); 791 CU_cleanup_registry(); 792 return num_failures; 793 } 794