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 "task.c" 37 #include "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(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 210 uint64_t offset, uint64_t length, 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(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 225 uint64_t offset, uint64_t length, 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.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(&bdev, &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.dev = &dev; 298 task.lun = &lun; 299 300 rc = spdk_bdev_scsi_execute(&bdev, &task); 301 302 CU_ASSERT_EQUAL(rc, 0); 303 304 spdk_put_task(&task); 305 } 306 307 /* 308 * This test specifically tests a mode sense 6 command which 309 * return all subpage 00h mode pages. 310 */ 311 static void 312 mode_sense_6_test(void) 313 { 314 struct spdk_bdev bdev; 315 struct spdk_scsi_task task; 316 struct spdk_scsi_lun lun; 317 struct spdk_scsi_dev dev; 318 char cdb[12]; 319 unsigned char *data; 320 int rc; 321 unsigned char mode_data_len = 0; 322 unsigned char medium_type = 0; 323 unsigned char dev_specific_param = 0; 324 unsigned char blk_descriptor_len = 0; 325 326 memset(&bdev, 0, sizeof(struct spdk_bdev)); 327 spdk_init_task(&task); 328 memset(cdb, 0, sizeof(cdb)); 329 330 cdb[0] = 0x1A; 331 cdb[2] = 0x3F; 332 cdb[4] = 0xFF; 333 task.cdb = cdb; 334 335 snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test"); 336 lun.dev = &dev; 337 task.lun = &lun; 338 339 rc = spdk_bdev_scsi_execute(&bdev, &task); 340 SPDK_CU_ASSERT_FATAL(rc == 0); 341 342 data = task.iovs[0].iov_base; 343 mode_data_len = data[0]; 344 medium_type = data[1]; 345 dev_specific_param = data[2]; 346 blk_descriptor_len = data[3]; 347 348 CU_ASSERT(mode_data_len >= 11); 349 CU_ASSERT_EQUAL(medium_type, 0); 350 CU_ASSERT_EQUAL(dev_specific_param, 0); 351 CU_ASSERT_EQUAL(blk_descriptor_len, 8); 352 353 spdk_put_task(&task); 354 } 355 356 /* 357 * This test specifically tests a mode sense 10 command which 358 * return all subpage 00h mode pages. 359 */ 360 static void 361 mode_sense_10_test(void) 362 { 363 struct spdk_bdev bdev; 364 struct spdk_scsi_task task; 365 struct spdk_scsi_lun lun; 366 struct spdk_scsi_dev dev; 367 char cdb[12]; 368 unsigned char *data; 369 int rc; 370 unsigned short mode_data_len = 0; 371 unsigned char medium_type = 0; 372 unsigned char dev_specific_param = 0; 373 unsigned short blk_descriptor_len = 0; 374 375 memset(&bdev, 0, sizeof(struct spdk_bdev)); 376 spdk_init_task(&task); 377 memset(cdb, 0, sizeof(cdb)); 378 cdb[0] = 0x5A; 379 cdb[2] = 0x3F; 380 cdb[8] = 0xFF; 381 task.cdb = cdb; 382 383 snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test"); 384 lun.dev = &dev; 385 task.lun = &lun; 386 387 rc = spdk_bdev_scsi_execute(&bdev, &task); 388 SPDK_CU_ASSERT_FATAL(rc == 0); 389 390 data = task.iovs[0].iov_base; 391 mode_data_len = ((data[0] << 8) + data[1]); 392 medium_type = data[2]; 393 dev_specific_param = data[3]; 394 blk_descriptor_len = ((data[6] << 8) + data[7]); 395 396 CU_ASSERT(mode_data_len >= 14); 397 CU_ASSERT_EQUAL(medium_type, 0); 398 CU_ASSERT_EQUAL(dev_specific_param, 0); 399 CU_ASSERT_EQUAL(blk_descriptor_len, 8); 400 401 spdk_put_task(&task); 402 } 403 404 /* 405 * This test specifically tests a scsi inquiry command from the 406 * Windows SCSI compliance test that failed to return the 407 * expected SCSI error sense code. 408 */ 409 static void 410 inquiry_evpd_test(void) 411 { 412 struct spdk_bdev bdev; 413 struct spdk_scsi_task task; 414 struct spdk_scsi_lun lun; 415 struct spdk_scsi_dev dev; 416 char cdb[6]; 417 int rc; 418 419 spdk_init_task(&task); 420 421 cdb[0] = 0x12; 422 cdb[1] = 0x00; // EVPD = 0 423 cdb[2] = 0xff; // PageCode non-zero 424 cdb[3] = 0x00; 425 cdb[4] = 0xff; 426 cdb[5] = 0x00; 427 task.cdb = cdb; 428 429 snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test"); 430 lun.dev = &dev; 431 task.lun = &lun; 432 433 rc = spdk_bdev_scsi_execute(&bdev, &task); 434 SPDK_CU_ASSERT_FATAL(rc == 0); 435 436 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION); 437 CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_ILLEGAL_REQUEST); 438 CU_ASSERT_EQUAL(task.sense_data[12], 0x24); 439 CU_ASSERT_EQUAL(task.sense_data[13], 0x0); 440 441 spdk_put_task(&task); 442 } 443 444 /* 445 * This test is to verify specific return data for a standard scsi inquiry 446 * command: Version 447 */ 448 static void 449 inquiry_standard_test(void) 450 { 451 struct spdk_bdev bdev = { .blocklen = 512 }; 452 struct spdk_scsi_task task; 453 struct spdk_scsi_lun lun; 454 struct spdk_scsi_dev dev; 455 char cdb[6]; 456 char *data; 457 struct spdk_scsi_cdb_inquiry_data *inq_data; 458 int rc; 459 460 spdk_init_task(&task); 461 462 cdb[0] = 0x12; 463 cdb[1] = 0x00; // EVPD = 0 464 cdb[2] = 0x00; // PageCode zero - requesting standard inquiry 465 cdb[3] = 0x00; 466 cdb[4] = 0xff; // Indicate data size used by conformance test 467 cdb[5] = 0x00; 468 task.cdb = cdb; 469 470 snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test"); 471 lun.dev = &dev; 472 task.lun = &lun; 473 474 rc = spdk_bdev_scsi_execute(&bdev, &task); 475 476 data = task.iovs[0].iov_base; 477 inq_data = (struct spdk_scsi_cdb_inquiry_data *)&data[0]; 478 479 CU_ASSERT_EQUAL(inq_data->version, SPDK_SPC_VERSION_SPC3); 480 CU_ASSERT_EQUAL(rc, 0); 481 482 spdk_put_task(&task); 483 } 484 485 static void 486 _inquiry_overflow_test(uint8_t alloc_len) 487 { 488 struct spdk_bdev bdev = { .blocklen = 512 }; 489 struct spdk_scsi_task task; 490 struct spdk_scsi_lun lun; 491 struct spdk_scsi_dev dev; 492 uint8_t cdb[6]; 493 int rc; 494 /* expects a 4K internal data buffer */ 495 char data[4096], data_compare[4096]; 496 497 spdk_init_task(&task); 498 499 cdb[0] = 0x12; 500 cdb[1] = 0x00; // EVPD = 0 501 cdb[2] = 0x00; // PageCode zero - requesting standard inquiry 502 cdb[3] = 0x00; 503 cdb[4] = alloc_len; // Indicate data size used by conformance test 504 cdb[5] = 0x00; 505 task.cdb = cdb; 506 507 snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test"); 508 lun.dev = &dev; 509 task.lun = &lun; 510 511 memset(data, 0, sizeof(data)); 512 memset(data_compare, 0, sizeof(data_compare)); 513 514 spdk_scsi_task_set_data(&task, data, sizeof(data)); 515 516 rc = spdk_bdev_scsi_execute(&bdev, &task); 517 SPDK_CU_ASSERT_FATAL(rc == 0); 518 519 CU_ASSERT_EQUAL(memcmp(data + alloc_len, data_compare + alloc_len, sizeof(data) - alloc_len), 0); 520 CU_ASSERT(task.data_transferred <= alloc_len); 521 522 spdk_put_task(&task); 523 } 524 525 static void 526 inquiry_overflow_test(void) 527 { 528 int i; 529 530 for (i = 0; i < 256; i++) { 531 _inquiry_overflow_test(i); 532 } 533 } 534 535 /* 536 * This test is to verify specific error translation from bdev to scsi. 537 */ 538 static void 539 task_complete_test(void) 540 { 541 struct spdk_scsi_task task; 542 struct spdk_bdev_io bdev_io = {}; 543 struct spdk_scsi_lun lun; 544 545 spdk_init_task(&task); 546 547 TAILQ_INIT(&lun.tasks); 548 TAILQ_INSERT_TAIL(&lun.tasks, &task, scsi_link); 549 task.lun = &lun; 550 551 bdev_io.status = SPDK_BDEV_IO_STATUS_SUCCESS; 552 spdk_bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.status, &task); 553 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_GOOD); 554 555 bdev_io.status = SPDK_BDEV_IO_STATUS_SCSI_ERROR; 556 bdev_io.error.scsi.sc = SPDK_SCSI_STATUS_CHECK_CONDITION; 557 bdev_io.error.scsi.sk = SPDK_SCSI_SENSE_HARDWARE_ERROR; 558 bdev_io.error.scsi.asc = SPDK_SCSI_ASC_WARNING; 559 bdev_io.error.scsi.ascq = SPDK_SCSI_ASCQ_POWER_LOSS_EXPECTED; 560 spdk_bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.status, &task); 561 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION); 562 CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_HARDWARE_ERROR); 563 CU_ASSERT_EQUAL(task.sense_data[12], SPDK_SCSI_ASC_WARNING); 564 CU_ASSERT_EQUAL(task.sense_data[13], SPDK_SCSI_ASCQ_POWER_LOSS_EXPECTED); 565 566 bdev_io.status = SPDK_BDEV_IO_STATUS_FAILED; 567 spdk_bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.status, &task); 568 CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION); 569 CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_ABORTED_COMMAND); 570 CU_ASSERT_EQUAL(task.sense_data[12], SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE); 571 CU_ASSERT_EQUAL(task.sense_data[13], SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE); 572 573 spdk_put_task(&task); 574 } 575 576 static void 577 lba_range_test(void) 578 { 579 struct spdk_bdev bdev; 580 struct spdk_scsi_task task; 581 uint8_t cdb[16]; 582 int rc; 583 584 spdk_init_task(&task); 585 task.cdb = cdb; 586 587 memset(cdb, 0, sizeof(cdb)); 588 cdb[0] = 0x88; /* READ (16) */ 589 590 /* Test block device size of 4 blocks */ 591 g_test_bdev_num_blocks = 4; 592 593 /* LBA = 0, length = 1 (in range) */ 594 to_be64(&cdb[2], 0); /* LBA */ 595 to_be32(&cdb[10], 1); /* transfer length */ 596 task.transfer_len = 1 * 512; 597 rc = spdk_bdev_scsi_execute(&bdev, &task); 598 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 599 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 600 601 /* LBA = 4, length = 1 (LBA out of range) */ 602 to_be64(&cdb[2], 4); /* LBA */ 603 to_be32(&cdb[10], 1); /* transfer length */ 604 task.transfer_len = 1 * 512; 605 rc = spdk_bdev_scsi_execute(&bdev, &task); 606 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 607 CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION); 608 CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); 609 610 /* LBA = 0, length = 4 (in range, max valid size) */ 611 to_be64(&cdb[2], 0); /* LBA */ 612 to_be32(&cdb[10], 4); /* transfer length */ 613 task.transfer_len = 4 * 512; 614 rc = spdk_bdev_scsi_execute(&bdev, &task); 615 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 616 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 617 618 /* LBA = 0, length = 5 (LBA in range, length beyond end of bdev) */ 619 to_be64(&cdb[2], 0); /* LBA */ 620 to_be32(&cdb[10], 5); /* transfer length */ 621 task.transfer_len = 5 * 512; 622 rc = spdk_bdev_scsi_execute(&bdev, &task); 623 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 624 CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION); 625 CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); 626 627 spdk_put_task(&task); 628 } 629 630 static void 631 xfer_len_test(void) 632 { 633 struct spdk_bdev bdev; 634 struct spdk_scsi_task task; 635 uint8_t cdb[16]; 636 int rc; 637 638 spdk_init_task(&task); 639 task.cdb = cdb; 640 641 memset(cdb, 0, sizeof(cdb)); 642 cdb[0] = 0x88; /* READ (16) */ 643 644 /* Test block device size of 512 MiB */ 645 g_test_bdev_num_blocks = 512 * 1024 * 1024; 646 647 /* 1 block */ 648 to_be64(&cdb[2], 0); /* LBA */ 649 to_be32(&cdb[10], 1); /* transfer length */ 650 task.transfer_len = 1 * 512; 651 rc = spdk_bdev_scsi_execute(&bdev, &task); 652 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 653 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 654 655 /* max transfer length (as reported in block limits VPD page) */ 656 to_be64(&cdb[2], 0); /* LBA */ 657 to_be32(&cdb[10], SPDK_WORK_BLOCK_SIZE / 512); /* transfer length */ 658 task.transfer_len = SPDK_WORK_BLOCK_SIZE; 659 rc = spdk_bdev_scsi_execute(&bdev, &task); 660 CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING); 661 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 662 663 /* max transfer length plus one block (invalid) */ 664 to_be64(&cdb[2], 0); /* LBA */ 665 to_be32(&cdb[10], SPDK_WORK_BLOCK_SIZE / 512 + 1); /* transfer length */ 666 task.transfer_len = SPDK_WORK_BLOCK_SIZE + 512; 667 rc = spdk_bdev_scsi_execute(&bdev, &task); 668 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 669 CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION); 670 CU_ASSERT((task.sense_data[2] & 0xf) == SPDK_SCSI_SENSE_ILLEGAL_REQUEST); 671 CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB); 672 673 /* zero transfer length (valid) */ 674 to_be64(&cdb[2], 0); /* LBA */ 675 to_be32(&cdb[10], 0); /* transfer length */ 676 task.transfer_len = 0; 677 rc = spdk_bdev_scsi_execute(&bdev, &task); 678 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 679 CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD); 680 CU_ASSERT(task.data_transferred == 0); 681 682 /* zero transfer length past end of disk (invalid) */ 683 to_be64(&cdb[2], g_test_bdev_num_blocks); /* LBA */ 684 to_be32(&cdb[10], 0); /* transfer length */ 685 task.transfer_len = 0; 686 rc = spdk_bdev_scsi_execute(&bdev, &task); 687 CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE); 688 CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION); 689 CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); 690 691 spdk_put_task(&task); 692 } 693 694 int 695 main(int argc, char **argv) 696 { 697 CU_pSuite suite = NULL; 698 unsigned int num_failures; 699 700 if (CU_initialize_registry() != CUE_SUCCESS) { 701 return CU_get_error(); 702 } 703 704 suite = CU_add_suite("translation_suite", NULL, NULL); 705 if (suite == NULL) { 706 CU_cleanup_registry(); 707 return CU_get_error(); 708 } 709 710 if ( 711 CU_add_test(suite, "mode select 6 test", mode_select_6_test) == NULL 712 || CU_add_test(suite, "mode select 6 test2", mode_select_6_test2) == NULL 713 || CU_add_test(suite, "mode sense 6 test", mode_sense_6_test) == NULL 714 || CU_add_test(suite, "mode sense 10 test", mode_sense_10_test) == NULL 715 || CU_add_test(suite, "inquiry evpd test", inquiry_evpd_test) == NULL 716 || CU_add_test(suite, "inquiry standard test", inquiry_standard_test) == NULL 717 || CU_add_test(suite, "inquiry overflow test", inquiry_overflow_test) == NULL 718 || CU_add_test(suite, "task complete test", task_complete_test) == NULL 719 || CU_add_test(suite, "LBA range test", lba_range_test) == NULL 720 || CU_add_test(suite, "transfer length test", xfer_len_test) == NULL 721 ) { 722 CU_cleanup_registry(); 723 return CU_get_error(); 724 } 725 726 CU_basic_set_mode(CU_BRM_VERBOSE); 727 CU_basic_run_tests(); 728 num_failures = CU_get_number_of_failures(); 729 CU_cleanup_registry(); 730 return num_failures; 731 } 732