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 + 1]; 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 579 /* 580 * This test is to verify specific error translation from bdev to scsi. 581 */ 582 static void 583 task_complete_test(void) 584 { 585 struct spdk_scsi_task task; 586 struct spdk_bdev_io bdev_io = {}; 587 struct spdk_scsi_lun lun; 588 589 spdk_init_task(&task); 590 591 TAILQ_INIT(&lun.tasks); 592 TAILQ_INSERT_TAIL(&lun.tasks, &task, scsi_link); 593 task.lun = &lun; 594 595 bdev_io.status = SPDK_BDEV_IO_STATUS_SUCCESS; 596 spdk_bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.status, &task); 597 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_GOOD); 598 599 bdev_io.status = SPDK_BDEV_IO_STATUS_SCSI_ERROR; 600 bdev_io.error.scsi.sc = SPDK_SCSI_STATUS_CHECK_CONDITION; 601 bdev_io.error.scsi.sk = SPDK_SCSI_SENSE_HARDWARE_ERROR; 602 bdev_io.error.scsi.asc = SPDK_SCSI_ASC_WARNING; 603 bdev_io.error.scsi.ascq = SPDK_SCSI_ASCQ_POWER_LOSS_EXPECTED; 604 spdk_bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.status, &task); 605 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION); 606 CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_HARDWARE_ERROR); 607 CU_ASSERT_EQUAL(task.sense_data[12], SPDK_SCSI_ASC_WARNING); 608 CU_ASSERT_EQUAL(task.sense_data[13], SPDK_SCSI_ASCQ_POWER_LOSS_EXPECTED); 609 610 bdev_io.status = SPDK_BDEV_IO_STATUS_FAILED; 611 spdk_bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.status, &task); 612 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION); 613 CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_ABORTED_COMMAND); 614 CU_ASSERT_EQUAL(task.sense_data[12], SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE); 615 CU_ASSERT_EQUAL(task.sense_data[13], SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE); 616 617 spdk_put_task(&task); 618 } 619 620 static void 621 lba_range_test(void) 622 { 623 struct spdk_bdev bdev; 624 struct spdk_scsi_lun lun; 625 struct spdk_scsi_task task; 626 uint8_t cdb[16]; 627 int rc; 628 629 lun.bdev = &bdev; 630 631 spdk_init_task(&task); 632 task.lun = &lun; 633 task.cdb = cdb; 634 635 memset(cdb, 0, sizeof(cdb)); 636 cdb[0] = 0x88; /* READ (16) */ 637 638 /* Test block device size of 4 blocks */ 639 g_test_bdev_num_blocks = 4; 640 641 /* LBA = 0, length = 1 (in range) */ 642 to_be64(&cdb[2], 0); /* LBA */ 643 to_be32(&cdb[10], 1); /* transfer length */ 644 task.transfer_len = 1 * 512; 645 rc = spdk_bdev_scsi_execute(&task); 646 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 647 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 648 649 /* LBA = 4, length = 1 (LBA out of range) */ 650 to_be64(&cdb[2], 4); /* LBA */ 651 to_be32(&cdb[10], 1); /* transfer length */ 652 task.transfer_len = 1 * 512; 653 rc = spdk_bdev_scsi_execute(&task); 654 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 655 CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION); 656 CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); 657 658 /* LBA = 0, length = 4 (in range, max valid size) */ 659 to_be64(&cdb[2], 0); /* LBA */ 660 to_be32(&cdb[10], 4); /* transfer length */ 661 task.transfer_len = 4 * 512; 662 rc = spdk_bdev_scsi_execute(&task); 663 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 664 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 665 666 /* LBA = 0, length = 5 (LBA in range, length beyond end of bdev) */ 667 to_be64(&cdb[2], 0); /* LBA */ 668 to_be32(&cdb[10], 5); /* transfer length */ 669 task.transfer_len = 5 * 512; 670 rc = spdk_bdev_scsi_execute(&task); 671 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 672 CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION); 673 CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); 674 675 spdk_put_task(&task); 676 } 677 678 static void 679 xfer_len_test(void) 680 { 681 struct spdk_bdev bdev; 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 spdk_init_task(&task); 690 task.lun = &lun; 691 task.cdb = cdb; 692 693 memset(cdb, 0, sizeof(cdb)); 694 cdb[0] = 0x88; /* READ (16) */ 695 696 /* Test block device size of 512 MiB */ 697 g_test_bdev_num_blocks = 512 * 1024 * 1024; 698 699 /* 1 block */ 700 to_be64(&cdb[2], 0); /* LBA */ 701 to_be32(&cdb[10], 1); /* transfer length */ 702 task.transfer_len = 1 * 512; 703 rc = spdk_bdev_scsi_execute(&task); 704 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 705 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 706 707 /* max transfer length (as reported in block limits VPD page) */ 708 to_be64(&cdb[2], 0); /* LBA */ 709 to_be32(&cdb[10], SPDK_WORK_BLOCK_SIZE / 512); /* transfer length */ 710 task.transfer_len = SPDK_WORK_BLOCK_SIZE; 711 rc = spdk_bdev_scsi_execute(&task); 712 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 713 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 714 715 /* max transfer length plus one block (invalid) */ 716 to_be64(&cdb[2], 0); /* LBA */ 717 to_be32(&cdb[10], SPDK_WORK_BLOCK_SIZE / 512 + 1); /* transfer length */ 718 task.transfer_len = SPDK_WORK_BLOCK_SIZE + 512; 719 rc = spdk_bdev_scsi_execute(&task); 720 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 721 CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION); 722 CU_ASSERT((task.sense_data[2] & 0xf) == SPDK_SCSI_SENSE_ILLEGAL_REQUEST); 723 CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB); 724 725 /* zero transfer length (valid) */ 726 to_be64(&cdb[2], 0); /* LBA */ 727 to_be32(&cdb[10], 0); /* transfer length */ 728 task.transfer_len = 0; 729 rc = spdk_bdev_scsi_execute(&task); 730 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 731 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 732 CU_ASSERT(task.data_transferred == 0); 733 734 /* zero transfer length past end of disk (invalid) */ 735 to_be64(&cdb[2], g_test_bdev_num_blocks); /* 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_CHECK_CONDITION); 741 CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); 742 743 spdk_put_task(&task); 744 } 745 746 int 747 main(int argc, char **argv) 748 { 749 CU_pSuite suite = NULL; 750 unsigned int num_failures; 751 752 if (CU_initialize_registry() != CUE_SUCCESS) { 753 return CU_get_error(); 754 } 755 756 suite = CU_add_suite("translation_suite", NULL, NULL); 757 if (suite == NULL) { 758 CU_cleanup_registry(); 759 return CU_get_error(); 760 } 761 762 if ( 763 CU_add_test(suite, "mode select 6 test", mode_select_6_test) == NULL 764 || CU_add_test(suite, "mode select 6 test2", mode_select_6_test2) == NULL 765 || CU_add_test(suite, "mode sense 6 test", mode_sense_6_test) == NULL 766 || CU_add_test(suite, "mode sense 10 test", mode_sense_10_test) == NULL 767 || CU_add_test(suite, "inquiry evpd test", inquiry_evpd_test) == NULL 768 || CU_add_test(suite, "inquiry standard test", inquiry_standard_test) == NULL 769 || CU_add_test(suite, "inquiry overflow test", inquiry_overflow_test) == NULL 770 || CU_add_test(suite, "task complete test", task_complete_test) == NULL 771 || CU_add_test(suite, "LBA range test", lba_range_test) == NULL 772 || CU_add_test(suite, "transfer length test", xfer_len_test) == NULL 773 || CU_add_test(suite, "scsi name padding test", scsi_name_padding_test) == NULL 774 ) { 775 CU_cleanup_registry(); 776 return CU_get_error(); 777 } 778 779 CU_basic_set_mode(CU_BRM_VERBOSE); 780 CU_basic_run_tests(); 781 num_failures = CU_get_number_of_failures(); 782 CU_cleanup_registry(); 783 return num_failures; 784 } 785