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