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