1 /* $FreeBSD: head/tools/tools/usbtest/usb_msc_test.c 260587 2014-01-13 13:27:00Z hselasky $ */ 2 /*- 3 * Copyright (c) 2007-2012 Hans Petter Selasky. All rights reserved. 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 <bus/u4b/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 "bus/u4b/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, uint16_t *pvid, uint16_t *ppid) 861 { 862 struct libusb20_backend *pbe; 863 struct libusb20_device *pdev; 864 struct LIBUSB20_DEVICE_DESC_DECODED *ddesc; 865 866 uint16_t vid[USB_DEVICES_MAX]; 867 uint16_t pid[USB_DEVICES_MAX]; 868 869 int index; 870 int sel; 871 872 const char *ptr; 873 874 top: 875 pbe = libusb20_be_alloc_default(); 876 pdev = NULL; 877 index = 0; 878 879 printf("\n[] Select USB device:\n"); 880 881 while ((pdev = libusb20_be_device_foreach(pbe, pdev))) { 882 883 if (libusb20_dev_get_mode(pdev) != LIBUSB20_MODE_HOST) 884 continue; 885 886 if (index < USB_DEVICES_MAX) { 887 ddesc = libusb20_dev_get_device_desc(pdev); 888 ptr = libusb20_dev_get_desc(pdev); 889 printf("%s%d) %s\n", indent[level], index, ptr); 890 vid[index] = ddesc->idVendor; 891 pid[index] = ddesc->idProduct; 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 *pvid = 0; 911 *ppid = 0; 912 return; 913 } 914 *pvid = vid[sel]; 915 *ppid = pid[sel]; 916 } 917 918 struct libusb20_device * 919 find_usb_device(uint16_t vid, uint16_t pid) 920 { 921 struct libusb20_backend *pbe = libusb20_be_alloc_default(); 922 struct libusb20_device *pdev = NULL; 923 struct LIBUSB20_DEVICE_DESC_DECODED *ddesc; 924 925 while ((pdev = libusb20_be_device_foreach(pbe, pdev))) { 926 927 if (libusb20_dev_get_mode(pdev) != LIBUSB20_MODE_HOST) 928 continue; 929 930 ddesc = libusb20_dev_get_device_desc(pdev); 931 932 if ((vid == ddesc->idVendor) && 933 (pid == ddesc->idProduct)) { 934 libusb20_be_dequeue_device(pbe, pdev); 935 break; 936 } 937 } 938 939 /* release data */ 940 libusb20_be_free(pbe); 941 942 return (pdev); 943 } 944 945 void 946 find_usb_endpoints(struct libusb20_device *pdev, uint8_t class, 947 uint8_t subclass, uint8_t protocol, uint8_t alt_setting, 948 uint8_t *pif, uint8_t *in_ep, uint8_t *out_ep, uint8_t next_if) 949 { 950 struct libusb20_config *pcfg; 951 struct libusb20_interface *iface; 952 struct libusb20_endpoint *ep; 953 uint8_t x; 954 uint8_t y; 955 uint8_t z; 956 957 *in_ep = 0; 958 *out_ep = 0; 959 *pif = 0; 960 961 pcfg = libusb20_dev_alloc_config(pdev, 962 libusb20_dev_get_config_index(pdev)); 963 964 if (pcfg == NULL) 965 return; 966 967 for (x = 0; x != pcfg->num_interface; x++) { 968 969 y = alt_setting; 970 971 iface = (pcfg->interface + x); 972 973 if ((iface->desc.bInterfaceClass == class) && 974 (iface->desc.bInterfaceSubClass == subclass || 975 subclass == 255) && 976 (iface->desc.bInterfaceProtocol == protocol || 977 protocol == 255)) { 978 979 if (next_if) { 980 x++; 981 if (x == pcfg->num_interface) 982 break; 983 iface = (pcfg->interface + x); 984 } 985 *pif = x; 986 987 for (z = 0; z != iface->num_endpoints; z++) { 988 ep = iface->endpoints + z; 989 990 /* BULK only */ 991 if ((ep->desc.bmAttributes & 3) != 2) 992 continue; 993 994 if (ep->desc.bEndpointAddress & 0x80) 995 *in_ep = ep->desc.bEndpointAddress; 996 else 997 *out_ep = ep->desc.bEndpointAddress; 998 } 999 break; 1000 } 1001 } 1002 1003 free(pcfg); 1004 } 1005 1006 static void 1007 exec_host_msc_test(struct usb_msc_params *p, uint16_t vid, uint16_t pid) 1008 { 1009 struct libusb20_device *pdev; 1010 1011 uint8_t in_ep; 1012 uint8_t out_ep; 1013 uint8_t iface; 1014 1015 int error; 1016 1017 memset(&stats, 0, sizeof(stats)); 1018 1019 xfer_current_id = 0; 1020 xfer_wrapper_sig = CBWSIGNATURE; 1021 1022 pdev = find_usb_device(vid, pid); 1023 if (pdev == NULL) { 1024 printf("USB device not found\n"); 1025 return; 1026 } 1027 find_usb_endpoints(pdev, 8, 6, 0x50, 0, &iface, &in_ep, &out_ep, 0); 1028 1029 if ((in_ep == 0) || (out_ep == 0)) { 1030 printf("Could not find USB endpoints\n"); 1031 libusb20_dev_free(pdev); 1032 return; 1033 } 1034 printf("Attaching to: %s @ iface %d\n", 1035 libusb20_dev_get_desc(pdev), iface); 1036 1037 if (libusb20_dev_open(pdev, 2)) { 1038 printf("Could not open USB device\n"); 1039 libusb20_dev_free(pdev); 1040 return; 1041 } 1042 if (libusb20_dev_detach_kernel_driver(pdev, iface)) { 1043 printf("WARNING: Could not detach kernel driver\n"); 1044 } 1045 xfer_in = libusb20_tr_get_pointer(pdev, 0); 1046 error = libusb20_tr_open(xfer_in, 65536, 1, in_ep); 1047 if (error) { 1048 printf("Could not open USB endpoint %d\n", in_ep); 1049 libusb20_dev_free(pdev); 1050 return; 1051 } 1052 xfer_out = libusb20_tr_get_pointer(pdev, 1); 1053 error = libusb20_tr_open(xfer_out, 65536, 1, out_ep); 1054 if (error) { 1055 printf("Could not open USB endpoint %d\n", out_ep); 1056 libusb20_dev_free(pdev); 1057 return; 1058 } 1059 usb_pdev = pdev; 1060 usb_iface = iface; 1061 1062 usb_msc_test(p); 1063 1064 libusb20_dev_free(pdev); 1065 } 1066 1067 static void 1068 set_defaults(struct usb_msc_params *p) 1069 { 1070 memset(p, 0, sizeof(*p)); 1071 1072 p->duration = 60; /* seconds */ 1073 p->try_invalid_scsi_command = 1; 1074 p->try_invalid_wrapper_block = 1; 1075 p->try_last_lba = 1; 1076 p->max_errors = -1; 1077 } 1078 1079 static const char * 1080 get_io_mode(const struct usb_msc_params *p) 1081 { 1082 ; /* indent fix */ 1083 switch (p->io_mode) { 1084 case USB_MSC_IO_MODE_READ_ONLY: 1085 return ("Read Only"); 1086 case USB_MSC_IO_MODE_WRITE_ONCE_READ_ONLY: 1087 return ("Write Once, Read Only"); 1088 case USB_MSC_IO_MODE_WRITE_ONLY: 1089 return ("Write Only"); 1090 case USB_MSC_IO_MODE_READ_WRITE: 1091 return ("Read and Write"); 1092 default: 1093 return ("Unknown"); 1094 } 1095 } 1096 1097 static const char * 1098 get_io_pattern(const struct usb_msc_params *p) 1099 { 1100 ; /* indent fix */ 1101 switch (p->io_pattern) { 1102 case USB_MSC_IO_PATTERN_FIXED: 1103 return ("Fixed"); 1104 case USB_MSC_IO_PATTERN_RANDOM: 1105 return ("Random"); 1106 case USB_MSC_IO_PATTERN_PRESERVE: 1107 return ("Preserve"); 1108 default: 1109 return ("Unknown"); 1110 } 1111 } 1112 1113 static const char * 1114 get_io_size(const struct usb_msc_params *p) 1115 { 1116 ; /* indent fix */ 1117 switch (p->io_size) { 1118 case USB_MSC_IO_SIZE_RANDOM: 1119 return ("Random"); 1120 case USB_MSC_IO_SIZE_INCREASING: 1121 return ("Increasing"); 1122 case USB_MSC_IO_SIZE_FIXED_1BLK: 1123 return ("Single block"); 1124 case USB_MSC_IO_SIZE_FIXED_2BLK: 1125 return ("2 blocks"); 1126 case USB_MSC_IO_SIZE_FIXED_4BLK: 1127 return ("4 blocks"); 1128 case USB_MSC_IO_SIZE_FIXED_8BLK: 1129 return ("8 blocks"); 1130 case USB_MSC_IO_SIZE_FIXED_16BLK: 1131 return ("16 blocks"); 1132 case USB_MSC_IO_SIZE_FIXED_32BLK: 1133 return ("32 blocks"); 1134 case USB_MSC_IO_SIZE_FIXED_64BLK: 1135 return ("64 blocks"); 1136 case USB_MSC_IO_SIZE_FIXED_128BLK: 1137 return ("128 blocks"); 1138 case USB_MSC_IO_SIZE_FIXED_256BLK: 1139 return ("256 blocks"); 1140 case USB_MSC_IO_SIZE_FIXED_512BLK: 1141 return ("512 blocks"); 1142 case USB_MSC_IO_SIZE_FIXED_1024BLK: 1143 return ("1024 blocks"); 1144 default: 1145 return ("Unknown"); 1146 } 1147 } 1148 1149 static const char * 1150 get_io_delay(const struct usb_msc_params *p) 1151 { 1152 ; /* indent fix */ 1153 switch (p->io_delay) { 1154 case USB_MSC_IO_DELAY_NONE: 1155 return ("None"); 1156 case USB_MSC_IO_DELAY_RANDOM_10MS: 1157 return ("Random 10ms"); 1158 case USB_MSC_IO_DELAY_RANDOM_100MS: 1159 return ("Random 100ms"); 1160 case USB_MSC_IO_DELAY_FIXED_10MS: 1161 return ("Fixed 10ms"); 1162 case USB_MSC_IO_DELAY_FIXED_100MS: 1163 return ("Fixed 100ms"); 1164 default: 1165 return ("Unknown"); 1166 } 1167 } 1168 1169 static const char * 1170 get_io_offset(const struct usb_msc_params *p) 1171 { 1172 ; /* indent fix */ 1173 switch (p->io_offset) { 1174 case USB_MSC_IO_OFF_START_OF_DISK: 1175 return ("Start Of Disk"); 1176 case USB_MSC_IO_OFF_RANDOM: 1177 return ("Random Offset"); 1178 default: 1179 return ("Unknown"); 1180 } 1181 } 1182 1183 static const char * 1184 get_io_area(const struct usb_msc_params *p) 1185 { 1186 ; /* indent fix */ 1187 switch (p->io_area) { 1188 case USB_MSC_IO_AREA_COMPLETE: 1189 return ("Complete Disk"); 1190 case USB_MSC_IO_AREA_1MB: 1191 return ("First MegaByte"); 1192 case USB_MSC_IO_AREA_16MB: 1193 return ("First 16 MegaBytes"); 1194 case USB_MSC_IO_AREA_256MB: 1195 return ("First 256 MegaBytes"); 1196 default: 1197 return ("Unknown"); 1198 } 1199 } 1200 1201 void 1202 show_host_msc_test(uint8_t level, uint16_t vid, 1203 uint16_t pid, 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 vid, 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, vid, pid); 1321 break; 1322 case 40: 1323 show_host_device_selection(level + 1, &vid, &pid); 1324 break; 1325 default: 1326 return; 1327 } 1328 } 1329 } 1330