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