1 /* $FreeBSD$ */ 2 /*- 3 * Copyright (c) 2007-2022 Hans Petter Selasky 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <stdio.h> 28 #include <stdint.h> 29 #include <stdlib.h> 30 #include <err.h> 31 #include <string.h> 32 #include <errno.h> 33 #include <unistd.h> 34 35 #include <sys/sysctl.h> 36 #include <sys/time.h> 37 38 #include <libusb20.h> 39 #include <libusb20_desc.h> 40 41 #include <dev/usb/usb_endian.h> 42 43 #include "usbtest.h" 44 45 #include "usb_msc_test.h" 46 47 /* Command Block Wrapper */ 48 typedef struct { 49 uDWord dCBWSignature; 50 #define CBWSIGNATURE 0x43425355 51 uDWord dCBWTag; 52 uDWord dCBWDataTransferLength; 53 uByte bCBWFlags; 54 #define CBWFLAGS_OUT 0x00 55 #define CBWFLAGS_IN 0x80 56 uByte bCBWLUN; 57 uByte bCDBLength; 58 #define CBWCDBLENGTH 16 59 uByte CBWCDB[CBWCDBLENGTH]; 60 } umass_bbb_cbw_t; 61 62 #define UMASS_BBB_CBW_SIZE 31 63 64 /* Command Status Wrapper */ 65 typedef struct { 66 uDWord dCSWSignature; 67 #define CSWSIGNATURE 0x53425355 68 #define CSWSIGNATURE_IMAGINATION_DBX1 0x43425355 69 #define CSWSIGNATURE_OLYMPUS_C1 0x55425355 70 uDWord dCSWTag; 71 uDWord dCSWDataResidue; 72 uByte bCSWStatus; 73 #define CSWSTATUS_GOOD 0x0 74 #define CSWSTATUS_FAILED 0x1 75 #define CSWSTATUS_PHASE 0x2 76 } umass_bbb_csw_t; 77 78 #define UMASS_BBB_CSW_SIZE 13 79 80 #define SC_READ_6 0x08 81 #define SC_READ_10 0x28 82 #define SC_READ_12 0xa8 83 #define SC_WRITE_6 0x0a 84 #define SC_WRITE_10 0x2a 85 #define SC_WRITE_12 0xaa 86 87 static struct stats { 88 uint64_t xfer_error; 89 uint64_t xfer_success; 90 uint64_t xfer_reset; 91 uint64_t xfer_rx_bytes; 92 uint64_t xfer_tx_bytes; 93 uint64_t data_error; 94 } stats; 95 96 static uint32_t xfer_current_id; 97 static uint32_t xfer_wrapper_sig; 98 static uint32_t block_size = 512; 99 100 static struct libusb20_transfer *xfer_in; 101 static struct libusb20_transfer *xfer_out; 102 static struct libusb20_device *usb_pdev; 103 static uint8_t usb_iface; 104 static int sense_recurse; 105 106 /* 107 * SCSI commands sniffed off the wire - LUN maybe needs to be 108 * adjusted! Refer to "dev/usb/storage/ustorage_fs.c" for more 109 * information. 110 */ 111 static uint8_t mode_sense_6[0x6] = {0x1a, 0, 0x3f, 0, 0x0c}; 112 static uint8_t read_capacity[0xA] = {0x25,}; 113 static uint8_t request_sense[0xC] = {0x03, 0, 0, 0, 0x12}; 114 static uint8_t test_unit_ready[0x6] = {0}; 115 static uint8_t mode_page_inquiry[0x6] = {0x12, 1, 0x80, 0, 0xff, 0}; 116 static uint8_t request_invalid[0xC] = {0xEA, 0, 0, 0, 0}; 117 static uint8_t prevent_removal[0x6] = {0x1E, 0, 0, 0, 1}; 118 static uint8_t read_toc[0xA] = {0x43, 0x02, 0, 0, 0, 0xAA, 0, 0x0C}; 119 120 #define TIMEOUT_FILTER(x) (x) 121 122 static void usb_request_sense(uint8_t lun); 123 124 static void 125 do_msc_reset(uint8_t lun) 126 { 127 struct LIBUSB20_CONTROL_SETUP_DECODED setup; 128 129 LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &setup); 130 131 setup.bmRequestType = LIBUSB20_REQUEST_TYPE_CLASS | 132 LIBUSB20_RECIPIENT_INTERFACE; 133 setup.bRequest = 0xFF; /* BBB reset */ 134 setup.wValue = 0; 135 setup.wIndex = usb_iface; 136 setup.wLength = 0; 137 138 if (libusb20_dev_request_sync(usb_pdev, &setup, NULL, NULL, 5000, 0)) { 139 printf("ERROR: %s\n", __FUNCTION__); 140 stats.xfer_error++; 141 } 142 libusb20_tr_clear_stall_sync(xfer_in); 143 libusb20_tr_clear_stall_sync(xfer_out); 144 145 stats.xfer_reset++; 146 147 usb_request_sense(lun); 148 } 149 150 static uint8_t 151 do_msc_cmd(uint8_t *pcmd, uint8_t cmdlen, void *pdata, uint32_t datalen, 152 uint8_t isread, uint8_t isshort, uint8_t lun, uint8_t flags) 153 { 154 umass_bbb_cbw_t cbw; 155 umass_bbb_csw_t csw; 156 struct libusb20_transfer *xfer_io; 157 uint32_t actlen; 158 uint32_t timeout; 159 int error; 160 161 memset(&cbw, 0, sizeof(cbw)); 162 163 USETDW(cbw.dCBWSignature, xfer_wrapper_sig); 164 USETDW(cbw.dCBWTag, xfer_current_id); 165 xfer_current_id++; 166 USETDW(cbw.dCBWDataTransferLength, datalen); 167 cbw.bCBWFlags = (isread ? CBWFLAGS_IN : CBWFLAGS_OUT); 168 cbw.bCBWLUN = lun; 169 cbw.bCDBLength = cmdlen; 170 bcopy(pcmd, cbw.CBWCDB, cmdlen); 171 172 actlen = 0; 173 174 timeout = ((datalen + 299999) / 300000) * 1000; 175 timeout += 5000; 176 177 if ((error = libusb20_tr_bulk_intr_sync(xfer_out, 178 &cbw, sizeof(cbw), &actlen, TIMEOUT_FILTER(1000)))) { 179 printf("ERROR: CBW reception: %d\n", error); 180 do_msc_reset(lun); 181 return (1); 182 } 183 if (actlen != sizeof(cbw)) { 184 printf("ERROR: CBW length: %d != %d\n", 185 actlen, (int)sizeof(cbw)); 186 do_msc_reset(lun); 187 return (1); 188 } 189 if (flags & 1) 190 datalen /= 2; 191 192 if (datalen != 0) { 193 xfer_io = isread ? xfer_in : xfer_out; 194 195 if ((error = libusb20_tr_bulk_intr_sync(xfer_io, 196 pdata, datalen, &actlen, TIMEOUT_FILTER(timeout)))) { 197 printf("ERROR: Data transfer: %d\n", error); 198 do_msc_reset(lun); 199 return (1); 200 } 201 if ((actlen != datalen) && (!isshort)) { 202 printf("ERROR: Short data: %d of %d bytes\n", 203 actlen, datalen); 204 do_msc_reset(lun); 205 return (1); 206 } 207 } 208 actlen = 0; 209 timeout = 8; 210 211 do { 212 error = libusb20_tr_bulk_intr_sync(xfer_in, &csw, 213 sizeof(csw), &actlen, TIMEOUT_FILTER(1000)); 214 if (error) { 215 if (error == LIBUSB20_TRANSFER_TIMED_OUT) { 216 printf("TIMEOUT: Trying to get CSW again. " 217 "%d tries left.\n", timeout); 218 } else { 219 break; 220 } 221 } else { 222 break; 223 } 224 } while (--timeout); 225 226 if (error) { 227 libusb20_tr_clear_stall_sync(xfer_in); 228 error = libusb20_tr_bulk_intr_sync(xfer_in, &csw, 229 sizeof(csw), &actlen, TIMEOUT_FILTER(1000)); 230 if (error) { 231 libusb20_tr_clear_stall_sync(xfer_in); 232 printf("ERROR: Could not read CSW: Stalled or " 233 "timeout (%d).\n", error); 234 do_msc_reset(lun); 235 return (1); 236 } 237 } 238 if (UGETDW(csw.dCSWSignature) != CSWSIGNATURE) { 239 printf("ERROR: Wrong CSW signature\n"); 240 do_msc_reset(lun); 241 return (1); 242 } 243 if (actlen != sizeof(csw)) { 244 printf("ERROR: Wrong CSW length: %d != %d\n", 245 actlen, (int)sizeof(csw)); 246 do_msc_reset(lun); 247 return (1); 248 } 249 if (csw.bCSWStatus != 0) { 250 printf("ERROR: CSW status: %d\n", (int)csw.bCSWStatus); 251 return (1); 252 } else { 253 stats.xfer_success++; 254 return (0); 255 } 256 } 257 258 static void 259 do_msc_shorter_cmd(uint8_t lun) 260 { 261 uint8_t buffer[sizeof(umass_bbb_cbw_t)]; 262 int actlen; 263 int error; 264 int x; 265 266 memset(buffer, 0, sizeof(buffer)); 267 268 for (x = 0; x != (sizeof(buffer) - 1); x++) { 269 error = libusb20_tr_bulk_intr_sync(xfer_out, 270 buffer, x, &actlen, 250); 271 272 printf("Sent short %d of %d bytes wrapper block, " 273 "status = %d\n", x, (int)(sizeof(buffer) - 1), 274 error); 275 276 do_msc_reset(lun); 277 278 if (error != 0) { 279 printf("ERROR: Too short command wrapper " 280 "was not accepted\n"); 281 stats.xfer_error++; 282 break; 283 } 284 } 285 } 286 287 static uint8_t 288 do_read_10(uint32_t lba, uint32_t len, void *buf, uint8_t lun) 289 { 290 static uint8_t cmd[10]; 291 uint8_t retval; 292 293 cmd[0] = SC_READ_10; 294 295 len /= block_size; 296 297 cmd[2] = lba >> 24; 298 cmd[3] = lba >> 16; 299 cmd[4] = lba >> 8; 300 cmd[5] = lba >> 0; 301 302 cmd[7] = len >> 8; 303 cmd[8] = len; 304 305 retval = do_msc_cmd(cmd, 10, buf, len * block_size, 1, 0, lun, 0); 306 307 if (retval) { 308 printf("ERROR: %s\n", __FUNCTION__); 309 stats.xfer_error++; 310 } 311 return (retval); 312 } 313 314 static uint8_t 315 do_write_10(uint32_t lba, uint32_t len, void *buf, uint8_t lun) 316 { 317 static uint8_t cmd[10]; 318 uint8_t retval; 319 uint8_t abort; 320 321 cmd[0] = SC_WRITE_10; 322 323 abort = len & 1; 324 325 len /= block_size; 326 327 cmd[2] = lba >> 24; 328 cmd[3] = lba >> 16; 329 cmd[4] = lba >> 8; 330 cmd[5] = lba >> 0; 331 332 cmd[7] = len >> 8; 333 cmd[8] = len; 334 335 retval = do_msc_cmd(cmd, 10, buf, (len * block_size), 0, 0, lun, abort); 336 337 if (retval) { 338 printf("ERROR: %s\n", __FUNCTION__); 339 stats.xfer_error++; 340 } 341 return (retval); 342 } 343 344 static void 345 do_io_test(struct usb_msc_params *p, uint8_t lun, uint32_t lba_max, 346 uint8_t *buffer, uint8_t *reference) 347 { 348 uint32_t io_offset; 349 uint32_t io_size; 350 uint32_t temp; 351 uint8_t do_read; 352 uint8_t retval; 353 354 switch (p->io_mode) { 355 case USB_MSC_IO_MODE_WRITE_ONLY: 356 do_read = 0; 357 break; 358 case USB_MSC_IO_MODE_READ_WRITE: 359 do_read = (usb_ts_rand_noise() & 1); 360 break; 361 default: 362 do_read = 1; 363 break; 364 } 365 366 switch (p->io_offset) { 367 case USB_MSC_IO_OFF_RANDOM: 368 io_offset = usb_ts_rand_noise(); 369 break; 370 default: 371 io_offset = 0; 372 break; 373 } 374 375 switch (p->io_delay) { 376 case USB_MSC_IO_DELAY_RANDOM_10MS: 377 usleep(((uint32_t)usb_ts_rand_noise()) % 10000U); 378 break; 379 case USB_MSC_IO_DELAY_RANDOM_100MS: 380 usleep(((uint32_t)usb_ts_rand_noise()) % 100000U); 381 break; 382 case USB_MSC_IO_DELAY_FIXED_10MS: 383 usleep(10000); 384 break; 385 case USB_MSC_IO_DELAY_FIXED_100MS: 386 usleep(100000); 387 break; 388 default: 389 break; 390 } 391 392 switch (p->io_size) { 393 case USB_MSC_IO_SIZE_RANDOM: 394 io_size = ((uint32_t)usb_ts_rand_noise()) & 65535U; 395 break; 396 case USB_MSC_IO_SIZE_INCREASING: 397 io_size = (xfer_current_id & 65535U); 398 break; 399 case USB_MSC_IO_SIZE_FIXED_1BLK: 400 io_size = 1; 401 break; 402 case USB_MSC_IO_SIZE_FIXED_2BLK: 403 io_size = 2; 404 break; 405 case USB_MSC_IO_SIZE_FIXED_4BLK: 406 io_size = 4; 407 break; 408 case USB_MSC_IO_SIZE_FIXED_8BLK: 409 io_size = 8; 410 break; 411 case USB_MSC_IO_SIZE_FIXED_16BLK: 412 io_size = 16; 413 break; 414 case USB_MSC_IO_SIZE_FIXED_32BLK: 415 io_size = 32; 416 break; 417 case USB_MSC_IO_SIZE_FIXED_64BLK: 418 io_size = 64; 419 break; 420 case USB_MSC_IO_SIZE_FIXED_128BLK: 421 io_size = 128; 422 break; 423 case USB_MSC_IO_SIZE_FIXED_256BLK: 424 io_size = 256; 425 break; 426 case USB_MSC_IO_SIZE_FIXED_512BLK: 427 io_size = 512; 428 break; 429 case USB_MSC_IO_SIZE_FIXED_1024BLK: 430 io_size = 1024; 431 break; 432 default: 433 io_size = 1; 434 break; 435 } 436 437 if (io_size == 0) 438 io_size = 1; 439 440 io_offset %= lba_max; 441 442 temp = (lba_max - io_offset); 443 444 if (io_size > temp) 445 io_size = temp; 446 447 if (do_read) { 448 retval = do_read_10(io_offset, io_size * block_size, 449 buffer + (io_offset * block_size), lun); 450 451 if (retval == 0) { 452 if (bcmp(buffer + (io_offset * block_size), 453 reference + (io_offset * block_size), 454 io_size * block_size)) { 455 printf("ERROR: Data comparison failure\n"); 456 stats.data_error++; 457 retval = 1; 458 } 459 } 460 stats.xfer_rx_bytes += (io_size * block_size); 461 462 } else { 463 464 retval = do_write_10(io_offset, io_size * block_size, 465 reference + (io_offset * block_size), lun); 466 467 stats.xfer_tx_bytes += (io_size * block_size); 468 } 469 470 if ((stats.xfer_error + stats.data_error + 471 stats.xfer_reset) >= p->max_errors) { 472 printf("Maximum number of errors exceeded\n"); 473 p->done = 1; 474 } 475 } 476 477 static void 478 usb_request_sense(uint8_t lun) 479 { 480 uint8_t dummy_buf[255]; 481 482 if (sense_recurse) 483 return; 484 485 sense_recurse++; 486 487 do_msc_cmd(request_sense, sizeof(request_sense), 488 dummy_buf, 255, 1, 1, lun, 0); 489 490 sense_recurse--; 491 } 492 493 static void 494 usb_msc_test(struct usb_msc_params *p) 495 { 496 struct stats last_stat; 497 struct timeval sub_tv; 498 struct timeval ref_tv; 499 struct timeval res_tv; 500 uint8_t *buffer = NULL; 501 uint8_t *reference = NULL; 502 uint32_t dummy_buf[65536 / 4]; 503 uint32_t lba_max; 504 uint32_t x; 505 uint32_t y; 506 uint32_t capacity_lba; 507 uint32_t capacity_bs; 508 time_t last_sec; 509 uint8_t lun; 510 int tries; 511 512 memset(&last_stat, 0, sizeof(last_stat)); 513 514 switch (p->io_lun) { 515 case USB_MSC_IO_LUN_0: 516 lun = 0; 517 break; 518 case USB_MSC_IO_LUN_1: 519 lun = 1; 520 break; 521 case USB_MSC_IO_LUN_2: 522 lun = 2; 523 break; 524 case USB_MSC_IO_LUN_3: 525 lun = 3; 526 break; 527 default: 528 lun = 0; 529 break; 530 } 531 532 p->done = 0; 533 534 sense_recurse = p->try_sense_on_error ? 0 : 1; 535 536 printf("Resetting device ...\n"); 537 538 do_msc_reset(lun); 539 540 printf("Testing SCSI commands ...\n"); 541 542 if (p->try_all_lun) { 543 printf("Requesting sense from LUN 0..255 ... "); 544 for (x = y = 0; x != 256; x++) { 545 if (do_msc_cmd(mode_sense_6, sizeof(mode_sense_6), 546 dummy_buf, 255, 1, 1, x, 0)) 547 y++; 548 549 if (libusb20_dev_check_connected(usb_pdev) != 0) { 550 printf(" disconnect "); 551 break; 552 } 553 } 554 printf("Passed=%d, Failed=%d\n", 256 - y, y); 555 } 556 do_msc_cmd(mode_sense_6, sizeof(mode_sense_6), 557 dummy_buf, 255, 1, 1, lun, 0); 558 do_msc_cmd(request_sense, sizeof(request_sense), 559 dummy_buf, 255, 1, 1, lun, 0); 560 561 for (tries = 0; tries != 4; tries++) { 562 563 memset(dummy_buf, 0, sizeof(dummy_buf)); 564 565 if (do_msc_cmd(read_capacity, sizeof(read_capacity), 566 dummy_buf, 255, 1, 1, lun, 0) != 0) { 567 printf("Cannot read disk capacity (%u / 4)\n", tries); 568 if (tries == 3) 569 return; 570 usleep(50000); 571 continue; 572 } else { 573 break; 574 } 575 } 576 577 capacity_lba = be32toh(dummy_buf[0]); 578 capacity_bs = be32toh(dummy_buf[1]); 579 580 printf("Disk reports a capacity of LBA=%u and BS=%u\n", 581 capacity_lba, capacity_bs); 582 583 block_size = capacity_bs; 584 585 if (capacity_bs > 65535) { 586 printf("Blocksize is too big\n"); 587 return; 588 } 589 if (capacity_bs < 1) { 590 printf("Blocksize is too small\n"); 591 return; 592 } 593 if (capacity_bs != 512) 594 printf("INFO: Blocksize is not 512 bytes\n"); 595 596 if (p->try_shorter_wrapper_block) { 597 printf("Trying too short command wrapper:\n"); 598 do_msc_shorter_cmd(lun); 599 } 600 601 if (p->try_invalid_scsi_command) { 602 int status; 603 604 for (tries = 0; tries != 4; tries++) { 605 606 printf("Trying invalid SCSI command: "); 607 608 status = do_msc_cmd(request_invalid, 609 sizeof(request_invalid), dummy_buf, 610 255, 1, 1, lun, 0); 611 612 printf("Result%s as expected\n", status ? "" : " NOT"); 613 614 usleep(50000); 615 } 616 } 617 if (p->try_invalid_wrapper_block) { 618 int status; 619 620 for (tries = 0; tries != 4; tries++) { 621 622 printf("Trying invalid USB wrapper block signature: "); 623 624 xfer_wrapper_sig = 0x55663322; 625 626 status = do_msc_cmd(read_capacity, 627 sizeof(read_capacity), dummy_buf, 628 255, 1, 1, lun, 0); 629 630 printf("Result%s as expected\n", status ? "" : " NOT"); 631 632 xfer_wrapper_sig = CBWSIGNATURE; 633 634 usleep(50000); 635 } 636 } 637 do_msc_cmd(request_sense, sizeof(request_sense), dummy_buf, 255, 1, 1, lun, 0); 638 do_msc_cmd(read_capacity, sizeof(read_capacity), dummy_buf, 255, 1, 1, lun, 0); 639 do_msc_cmd(request_sense, sizeof(request_sense), dummy_buf, 255, 1, 1, lun, 0); 640 do_msc_cmd(test_unit_ready, sizeof(test_unit_ready), 0, 0, 1, 1, lun, 0); 641 do_msc_cmd(test_unit_ready, sizeof(test_unit_ready), 0, 0, 1, 1, lun, 0); 642 do_msc_cmd(request_sense, sizeof(request_sense), dummy_buf, 255, 1, 1, lun, 0); 643 do_msc_cmd(test_unit_ready, sizeof(test_unit_ready), 0, 0, 1, 1, lun, 0); 644 do_msc_cmd(request_sense, sizeof(request_sense), dummy_buf, 255, 1, 1, lun, 0); 645 do_msc_cmd(test_unit_ready, sizeof(test_unit_ready), 0, 0, 1, 1, lun, 0); 646 do_msc_cmd(test_unit_ready, sizeof(test_unit_ready), 0, 0, 1, 1, lun, 0); 647 do_msc_cmd(test_unit_ready, sizeof(test_unit_ready), 0, 0, 1, 1, lun, 0); 648 do_msc_cmd(request_sense, sizeof(request_sense), dummy_buf, 255, 1, 1, lun, 0); 649 do_msc_cmd(test_unit_ready, sizeof(test_unit_ready), 0, 0, 1, 1, lun, 0); 650 do_msc_cmd(read_capacity, sizeof(read_capacity), dummy_buf, 255, 1, 1, lun, 0); 651 do_msc_cmd(mode_page_inquiry, sizeof(mode_page_inquiry), dummy_buf, 255, 1, 1, lun, 0); 652 do_msc_cmd(mode_page_inquiry, sizeof(mode_page_inquiry), dummy_buf, 255, 1, 1, lun, 0); 653 654 if (do_msc_cmd(prevent_removal, sizeof(prevent_removal), 655 0, 0, 1, 1, lun, 0)) { 656 printf("INFO: Prevent medium removal failed\n"); 657 } 658 if (do_msc_cmd(read_toc, sizeof(read_toc), 659 dummy_buf, 255, 1, 1, lun, 0)) { 660 printf("INFO: Read Table Of Content failed\n"); 661 } 662 if (p->try_last_lba) { 663 664 for (y = 0, x = (1UL << 31); x; x >>= 1) { 665 if (do_read_10(x | y, block_size, dummy_buf, lun) == 0) 666 y |= x; 667 } 668 669 printf("Highest readable LBA: %u (%s), " 670 "Capacity is %u MBytes\n", y, 671 (capacity_lba != y) ? "WRONG" : "OK", 672 (int)((((uint64_t)(y) * (uint64_t)block_size) + 673 (uint64_t)block_size) / 1000000ULL)); 674 } else { 675 676 y = capacity_lba; 677 678 printf("Highest readable LBA: %u (not " 679 "verified), Capacity is %u MBytes\n", y, 680 (int)((((uint64_t)(y) * (uint64_t)block_size) + 681 (uint64_t)block_size) / 1000000ULL)); 682 } 683 684 if (y != 0xFFFFFFFFU) 685 y++; 686 687 lba_max = y; 688 689 switch (p->io_area) { 690 case USB_MSC_IO_AREA_1MB: 691 lba_max = 1024; 692 break; 693 case USB_MSC_IO_AREA_16MB: 694 lba_max = 1024 * 16; 695 break; 696 case USB_MSC_IO_AREA_256MB: 697 lba_max = 1024 * 256; 698 break; 699 case USB_MSC_IO_AREA_COMPLETE: 700 default: 701 break; 702 } 703 704 if (lba_max > 65535) 705 lba_max = 65535; 706 707 printf("Highest testable LBA: %u\n", (int)lba_max); 708 709 buffer = malloc(block_size * lba_max); 710 if (buffer == NULL) { 711 printf("ERROR: Could not allocate memory\n"); 712 goto fail; 713 } 714 reference = malloc(block_size * lba_max); 715 if (reference == NULL) { 716 printf("ERROR: Could not allocate memory\n"); 717 goto fail; 718 } 719 retry_read_init: 720 721 printf("Setting up initial data pattern, " 722 "LBA limit = %u ... ", lba_max); 723 724 switch (p->io_mode) { 725 case USB_MSC_IO_MODE_WRITE_ONCE_READ_ONLY: 726 case USB_MSC_IO_MODE_WRITE_ONLY: 727 case USB_MSC_IO_MODE_READ_WRITE: 728 729 switch (p->io_pattern) { 730 case USB_MSC_IO_PATTERN_FIXED: 731 for (x = 0; x != (block_size * lba_max); x += 8) { 732 reference[x + 0] = x >> 24; 733 reference[x + 1] = x >> 16; 734 reference[x + 2] = x >> 8; 735 reference[x + 3] = x >> 0; 736 reference[x + 4] = 0xFF; 737 reference[x + 5] = 0x00; 738 reference[x + 6] = 0xFF; 739 reference[x + 7] = 0x00; 740 } 741 if (do_write_10(0, lba_max * block_size, 742 reference, lun)) { 743 printf("FAILED\n"); 744 lba_max /= 2; 745 if (lba_max) 746 goto retry_read_init; 747 goto fail; 748 } 749 printf("SUCCESS\n"); 750 break; 751 case USB_MSC_IO_PATTERN_RANDOM: 752 for (x = 0; x != (block_size * lba_max); x++) { 753 reference[x] = usb_ts_rand_noise() % 255U; 754 } 755 if (do_write_10(0, lba_max * block_size, 756 reference, lun)) { 757 printf("FAILED\n"); 758 lba_max /= 2; 759 if (lba_max) 760 goto retry_read_init; 761 goto fail; 762 } 763 printf("SUCCESS\n"); 764 break; 765 default: 766 if (do_read_10(0, lba_max * block_size, 767 reference, lun)) { 768 printf("FAILED\n"); 769 lba_max /= 2; 770 if (lba_max) 771 goto retry_read_init; 772 goto fail; 773 } 774 printf("SUCCESS\n"); 775 break; 776 } 777 break; 778 779 default: 780 if (do_read_10(0, lba_max * block_size, reference, lun)) { 781 printf("FAILED\n"); 782 lba_max /= 2; 783 if (lba_max) 784 goto retry_read_init; 785 goto fail; 786 } 787 printf("SUCCESS\n"); 788 break; 789 } 790 791 792 if (p->try_abort_data_write) { 793 if (do_write_10(0, (2 * block_size) | 1, reference, lun)) 794 printf("Aborted data write failed (OK)!\n"); 795 else 796 printf("Aborted data write did not fail (ERROR)!\n"); 797 798 if (do_read_10(0, (2 * block_size), reference, lun)) 799 printf("Post-aborted data read failed (ERROR)\n"); 800 else 801 printf("Post-aborted data read success (OK)!\n"); 802 } 803 printf("Starting test ...\n"); 804 805 gettimeofday(&ref_tv, 0); 806 807 last_sec = ref_tv.tv_sec; 808 809 printf("\n"); 810 811 while (1) { 812 813 gettimeofday(&sub_tv, 0); 814 815 if (last_sec != sub_tv.tv_sec) { 816 817 printf("STATUS: ID=%u, RX=%u bytes/sec, " 818 "TX=%u bytes/sec, ERR=%u, RST=%u, DERR=%u\n", 819 (int)xfer_current_id, 820 (int)(stats.xfer_rx_bytes - 821 last_stat.xfer_rx_bytes), 822 (int)(stats.xfer_tx_bytes - 823 last_stat.xfer_tx_bytes), 824 (int)(stats.xfer_error), 825 (int)(stats.xfer_reset), 826 (int)(stats.data_error)); 827 828 fflush(stdout); 829 830 last_sec = sub_tv.tv_sec; 831 last_stat = stats; 832 } 833 timersub(&sub_tv, &ref_tv, &res_tv); 834 835 if ((res_tv.tv_sec < 0) || (res_tv.tv_sec >= (int)p->duration)) 836 break; 837 838 do_io_test(p, lun, lba_max, buffer, reference); 839 840 if (libusb20_dev_check_connected(usb_pdev) != 0) { 841 printf("Device disconnected\n"); 842 break; 843 } 844 if (p->done) { 845 printf("Maximum number of errors exceeded\n"); 846 break; 847 } 848 } 849 850 printf("\nTest done!\n"); 851 852 fail: 853 if (buffer) 854 free(buffer); 855 if (reference) 856 free(reference); 857 } 858 859 void 860 show_host_device_selection(uint8_t level, struct uaddr *puaddr) 861 { 862 struct libusb20_backend *pbe; 863 struct libusb20_device *pdev; 864 struct LIBUSB20_DEVICE_DESC_DECODED *ddesc; 865 866 struct uaddr uaddr[USB_DEVICES_MAX]; 867 868 int index; 869 int sel; 870 871 const char *ptr; 872 873 top: 874 pbe = libusb20_be_alloc_default(); 875 pdev = NULL; 876 index = 0; 877 878 printf("\n[] Select USB device:\n"); 879 880 while ((pdev = libusb20_be_device_foreach(pbe, pdev))) { 881 882 if (libusb20_dev_get_mode(pdev) != LIBUSB20_MODE_HOST) 883 continue; 884 885 if (index < USB_DEVICES_MAX) { 886 ddesc = libusb20_dev_get_device_desc(pdev); 887 ptr = libusb20_dev_get_desc(pdev); 888 printf("%s%d) %s\n", indent[level], index, ptr); 889 uaddr[index].vid = ddesc->idVendor; 890 uaddr[index].pid = ddesc->idProduct; 891 uaddr[index].bus = libusb20_dev_get_bus_number(pdev); 892 uaddr[index].addr = libusb20_dev_get_address(pdev); 893 index++; 894 } else { 895 break; 896 } 897 } 898 899 printf("%sr) Refresh device list\n", indent[level]); 900 printf("%sx) Return to previous menu\n", indent[level]); 901 902 /* release data */ 903 libusb20_be_free(pbe); 904 905 sel = get_integer(); 906 907 if (sel == -2) 908 goto top; 909 910 if ((sel < 0) || (sel >= index)) { 911 memset(puaddr, 0, sizeof(*puaddr)); 912 } else { 913 *puaddr = uaddr[sel]; 914 } 915 } 916 917 struct libusb20_device * 918 find_usb_device(struct uaddr uaddr) 919 { 920 struct libusb20_backend *pbe = libusb20_be_alloc_default(); 921 struct libusb20_device *pdev = NULL; 922 struct LIBUSB20_DEVICE_DESC_DECODED *ddesc; 923 924 while ((pdev = libusb20_be_device_foreach(pbe, pdev))) { 925 926 if (libusb20_dev_get_mode(pdev) != LIBUSB20_MODE_HOST) 927 continue; 928 929 ddesc = libusb20_dev_get_device_desc(pdev); 930 931 if ((uaddr.vid == ddesc->idVendor) && 932 (uaddr.pid == ddesc->idProduct) && 933 (uaddr.addr == 0 || 934 (uaddr.addr == libusb20_dev_get_address(pdev) && 935 uaddr.bus == libusb20_dev_get_bus_number(pdev)))) { 936 libusb20_be_dequeue_device(pbe, pdev); 937 break; 938 } 939 } 940 941 /* release data */ 942 libusb20_be_free(pbe); 943 944 return (pdev); 945 } 946 947 void 948 find_usb_endpoints(struct libusb20_device *pdev, uint8_t class, 949 uint8_t subclass, uint8_t protocol, uint8_t alt_setting, 950 uint8_t *pif, uint8_t *in_ep, uint8_t *out_ep, uint8_t next_if) 951 { 952 struct libusb20_config *pcfg; 953 struct libusb20_interface *iface; 954 struct libusb20_endpoint *ep; 955 uint8_t x; 956 uint8_t y; 957 uint8_t z; 958 959 *in_ep = 0; 960 *out_ep = 0; 961 *pif = 0; 962 963 pcfg = libusb20_dev_alloc_config(pdev, 964 libusb20_dev_get_config_index(pdev)); 965 966 if (pcfg == NULL) 967 return; 968 969 for (x = 0; x != pcfg->num_interface; x++) { 970 971 y = alt_setting; 972 973 iface = (pcfg->interface + x); 974 975 if ((iface->desc.bInterfaceClass == class) && 976 (iface->desc.bInterfaceSubClass == subclass || 977 subclass == 255) && 978 (iface->desc.bInterfaceProtocol == protocol || 979 protocol == 255)) { 980 981 if (next_if) { 982 x++; 983 if (x == pcfg->num_interface) 984 break; 985 iface = (pcfg->interface + x); 986 } 987 *pif = x; 988 989 for (z = 0; z != iface->num_endpoints; z++) { 990 ep = iface->endpoints + z; 991 992 /* BULK only */ 993 if ((ep->desc.bmAttributes & 3) != 2) 994 continue; 995 996 if (ep->desc.bEndpointAddress & 0x80) 997 *in_ep = ep->desc.bEndpointAddress; 998 else 999 *out_ep = ep->desc.bEndpointAddress; 1000 } 1001 break; 1002 } 1003 } 1004 1005 free(pcfg); 1006 } 1007 1008 static void 1009 exec_host_msc_test(struct usb_msc_params *p, struct uaddr uaddr) 1010 { 1011 struct libusb20_device *pdev; 1012 1013 uint8_t in_ep; 1014 uint8_t out_ep; 1015 uint8_t iface; 1016 1017 int error; 1018 1019 memset(&stats, 0, sizeof(stats)); 1020 1021 xfer_current_id = 0; 1022 xfer_wrapper_sig = CBWSIGNATURE; 1023 1024 pdev = find_usb_device(uaddr); 1025 if (pdev == NULL) { 1026 printf("USB device not found\n"); 1027 return; 1028 } 1029 find_usb_endpoints(pdev, 8, 6, 0x50, 0, &iface, &in_ep, &out_ep, 0); 1030 1031 if ((in_ep == 0) || (out_ep == 0)) { 1032 printf("Could not find USB endpoints\n"); 1033 libusb20_dev_free(pdev); 1034 return; 1035 } 1036 printf("Attaching to: %s @ iface %d\n", 1037 libusb20_dev_get_desc(pdev), iface); 1038 1039 if (libusb20_dev_open(pdev, 2)) { 1040 printf("Could not open USB device\n"); 1041 libusb20_dev_free(pdev); 1042 return; 1043 } 1044 if (libusb20_dev_detach_kernel_driver(pdev, iface)) { 1045 printf("WARNING: Could not detach kernel driver\n"); 1046 } 1047 xfer_in = libusb20_tr_get_pointer(pdev, 0); 1048 error = libusb20_tr_open(xfer_in, 65536, 1, in_ep); 1049 if (error) { 1050 printf("Could not open USB endpoint %d\n", in_ep); 1051 libusb20_dev_free(pdev); 1052 return; 1053 } 1054 xfer_out = libusb20_tr_get_pointer(pdev, 1); 1055 error = libusb20_tr_open(xfer_out, 65536, 1, out_ep); 1056 if (error) { 1057 printf("Could not open USB endpoint %d\n", out_ep); 1058 libusb20_dev_free(pdev); 1059 return; 1060 } 1061 usb_pdev = pdev; 1062 usb_iface = iface; 1063 1064 usb_msc_test(p); 1065 1066 libusb20_dev_free(pdev); 1067 } 1068 1069 static void 1070 set_defaults(struct usb_msc_params *p) 1071 { 1072 memset(p, 0, sizeof(*p)); 1073 1074 p->duration = 60; /* seconds */ 1075 p->try_invalid_scsi_command = 1; 1076 p->try_invalid_wrapper_block = 1; 1077 p->try_last_lba = 1; 1078 p->max_errors = -1; 1079 } 1080 1081 static const char * 1082 get_io_mode(const struct usb_msc_params *p) 1083 { 1084 ; /* indent fix */ 1085 switch (p->io_mode) { 1086 case USB_MSC_IO_MODE_READ_ONLY: 1087 return ("Read Only"); 1088 case USB_MSC_IO_MODE_WRITE_ONCE_READ_ONLY: 1089 return ("Write Once, Read Only"); 1090 case USB_MSC_IO_MODE_WRITE_ONLY: 1091 return ("Write Only"); 1092 case USB_MSC_IO_MODE_READ_WRITE: 1093 return ("Read and Write"); 1094 default: 1095 return ("Unknown"); 1096 } 1097 } 1098 1099 static const char * 1100 get_io_pattern(const struct usb_msc_params *p) 1101 { 1102 ; /* indent fix */ 1103 switch (p->io_pattern) { 1104 case USB_MSC_IO_PATTERN_FIXED: 1105 return ("Fixed"); 1106 case USB_MSC_IO_PATTERN_RANDOM: 1107 return ("Random"); 1108 case USB_MSC_IO_PATTERN_PRESERVE: 1109 return ("Preserve"); 1110 default: 1111 return ("Unknown"); 1112 } 1113 } 1114 1115 static const char * 1116 get_io_size(const struct usb_msc_params *p) 1117 { 1118 ; /* indent fix */ 1119 switch (p->io_size) { 1120 case USB_MSC_IO_SIZE_RANDOM: 1121 return ("Random"); 1122 case USB_MSC_IO_SIZE_INCREASING: 1123 return ("Increasing"); 1124 case USB_MSC_IO_SIZE_FIXED_1BLK: 1125 return ("Single block"); 1126 case USB_MSC_IO_SIZE_FIXED_2BLK: 1127 return ("2 blocks"); 1128 case USB_MSC_IO_SIZE_FIXED_4BLK: 1129 return ("4 blocks"); 1130 case USB_MSC_IO_SIZE_FIXED_8BLK: 1131 return ("8 blocks"); 1132 case USB_MSC_IO_SIZE_FIXED_16BLK: 1133 return ("16 blocks"); 1134 case USB_MSC_IO_SIZE_FIXED_32BLK: 1135 return ("32 blocks"); 1136 case USB_MSC_IO_SIZE_FIXED_64BLK: 1137 return ("64 blocks"); 1138 case USB_MSC_IO_SIZE_FIXED_128BLK: 1139 return ("128 blocks"); 1140 case USB_MSC_IO_SIZE_FIXED_256BLK: 1141 return ("256 blocks"); 1142 case USB_MSC_IO_SIZE_FIXED_512BLK: 1143 return ("512 blocks"); 1144 case USB_MSC_IO_SIZE_FIXED_1024BLK: 1145 return ("1024 blocks"); 1146 default: 1147 return ("Unknown"); 1148 } 1149 } 1150 1151 static const char * 1152 get_io_delay(const struct usb_msc_params *p) 1153 { 1154 ; /* indent fix */ 1155 switch (p->io_delay) { 1156 case USB_MSC_IO_DELAY_NONE: 1157 return ("None"); 1158 case USB_MSC_IO_DELAY_RANDOM_10MS: 1159 return ("Random 10ms"); 1160 case USB_MSC_IO_DELAY_RANDOM_100MS: 1161 return ("Random 100ms"); 1162 case USB_MSC_IO_DELAY_FIXED_10MS: 1163 return ("Fixed 10ms"); 1164 case USB_MSC_IO_DELAY_FIXED_100MS: 1165 return ("Fixed 100ms"); 1166 default: 1167 return ("Unknown"); 1168 } 1169 } 1170 1171 static const char * 1172 get_io_offset(const struct usb_msc_params *p) 1173 { 1174 ; /* indent fix */ 1175 switch (p->io_offset) { 1176 case USB_MSC_IO_OFF_START_OF_DISK: 1177 return ("Start Of Disk"); 1178 case USB_MSC_IO_OFF_RANDOM: 1179 return ("Random Offset"); 1180 default: 1181 return ("Unknown"); 1182 } 1183 } 1184 1185 static const char * 1186 get_io_area(const struct usb_msc_params *p) 1187 { 1188 ; /* indent fix */ 1189 switch (p->io_area) { 1190 case USB_MSC_IO_AREA_COMPLETE: 1191 return ("Complete Disk"); 1192 case USB_MSC_IO_AREA_1MB: 1193 return ("First MegaByte"); 1194 case USB_MSC_IO_AREA_16MB: 1195 return ("First 16 MegaBytes"); 1196 case USB_MSC_IO_AREA_256MB: 1197 return ("First 256 MegaBytes"); 1198 default: 1199 return ("Unknown"); 1200 } 1201 } 1202 1203 void 1204 show_host_msc_test(uint8_t level, struct uaddr uaddr, uint32_t duration) 1205 { 1206 struct usb_msc_params params; 1207 uint8_t retval; 1208 1209 set_defaults(¶ms); 1210 1211 params.duration = duration; 1212 1213 while (1) { 1214 1215 retval = usb_ts_show_menu(level, 1216 "Mass Storage Test Parameters", 1217 " 1) Toggle I/O mode: <%s>\n" 1218 " 2) Toggle I/O size: <%s>\n" 1219 " 3) Toggle I/O delay: <%s>\n" 1220 " 4) Toggle I/O offset: <%s>\n" 1221 " 5) Toggle I/O area: <%s>\n" 1222 " 6) Toggle I/O pattern: <%s>\n" 1223 " 7) Toggle try invalid SCSI command: <%s>\n" 1224 " 8) Toggle try invalid wrapper block: <%s>\n" 1225 " 9) Toggle try invalid MaxPacketSize: <%s>\n" 1226 "10) Toggle try last Logical Block Address: <%s>\n" 1227 "11) Toggle I/O lun: <%d>\n" 1228 "12) Set maximum number of errors: <%d>\n" 1229 "13) Set test duration: <%d> seconds\n" 1230 "14) Toggle try aborted write transfer: <%s>\n" 1231 "15) Toggle request sense on error: <%s>\n" 1232 "16) Toggle try all LUN: <%s>\n" 1233 "17) Toggle try too short wrapper block: <%s>\n" 1234 "20) Reset parameters\n" 1235 "30) Start test (VID=0x%04x, PID=0x%04x)\n" 1236 "40) Select another device\n" 1237 " x) Return to previous menu \n", 1238 get_io_mode(¶ms), 1239 get_io_size(¶ms), 1240 get_io_delay(¶ms), 1241 get_io_offset(¶ms), 1242 get_io_area(¶ms), 1243 get_io_pattern(¶ms), 1244 (params.try_invalid_scsi_command ? "YES" : "NO"), 1245 (params.try_invalid_wrapper_block ? "YES" : "NO"), 1246 (params.try_invalid_max_packet_size ? "YES" : "NO"), 1247 (params.try_last_lba ? "YES" : "NO"), 1248 params.io_lun, 1249 (int)params.max_errors, 1250 (int)params.duration, 1251 (params.try_abort_data_write ? "YES" : "NO"), 1252 (params.try_sense_on_error ? "YES" : "NO"), 1253 (params.try_all_lun ? "YES" : "NO"), 1254 (params.try_shorter_wrapper_block ? "YES" : "NO"), 1255 uaddr.vid, uaddr.pid); 1256 switch (retval) { 1257 case 0: 1258 break; 1259 case 1: 1260 params.io_mode++; 1261 params.io_mode %= USB_MSC_IO_MODE_MAX; 1262 break; 1263 case 2: 1264 params.io_size++; 1265 params.io_size %= USB_MSC_IO_SIZE_MAX; 1266 break; 1267 case 3: 1268 params.io_delay++; 1269 params.io_delay %= USB_MSC_IO_DELAY_MAX; 1270 break; 1271 case 4: 1272 params.io_offset++; 1273 params.io_offset %= USB_MSC_IO_OFF_MAX; 1274 break; 1275 case 5: 1276 params.io_area++; 1277 params.io_area %= USB_MSC_IO_AREA_MAX; 1278 break; 1279 case 6: 1280 params.io_pattern++; 1281 params.io_pattern %= USB_MSC_IO_PATTERN_MAX; 1282 break; 1283 case 7: 1284 params.try_invalid_scsi_command ^= 1; 1285 break; 1286 case 8: 1287 params.try_invalid_wrapper_block ^= 1; 1288 break; 1289 case 9: 1290 params.try_invalid_max_packet_size ^= 1; 1291 break; 1292 case 10: 1293 params.try_last_lba ^= 1; 1294 break; 1295 case 11: 1296 params.io_lun++; 1297 params.io_lun %= USB_MSC_IO_LUN_MAX; 1298 break; 1299 case 12: 1300 params.max_errors = get_integer(); 1301 break; 1302 case 13: 1303 params.duration = get_integer(); 1304 break; 1305 case 14: 1306 params.try_abort_data_write ^= 1; 1307 break; 1308 case 15: 1309 params.try_sense_on_error ^= 1; 1310 break; 1311 case 16: 1312 params.try_all_lun ^= 1; 1313 break; 1314 case 17: 1315 params.try_shorter_wrapper_block ^= 1; 1316 break; 1317 case 20: 1318 set_defaults(¶ms); 1319 break; 1320 case 30: 1321 exec_host_msc_test(¶ms, uaddr); 1322 break; 1323 case 40: 1324 show_host_device_selection(level + 1, &uaddr); 1325 break; 1326 default: 1327 return; 1328 } 1329 } 1330 } 1331