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 */
47 typedef 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 */
64 typedef 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
86 static 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
95 static uint32_t xfer_current_id;
96 static uint32_t xfer_wrapper_sig;
97 static uint32_t block_size = 512;
98
99 static struct libusb20_transfer *xfer_in;
100 static struct libusb20_transfer *xfer_out;
101 static struct libusb20_device *usb_pdev;
102 static uint8_t usb_iface;
103 static 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 */
110 static uint8_t mode_sense_6[0x6] = {0x1a, 0, 0x3f, 0, 0x0c};
111 static uint8_t read_capacity[0xA] = {0x25,};
112 static uint8_t request_sense[0xC] = {0x03, 0, 0, 0, 0x12};
113 static uint8_t test_unit_ready[0x6] = {0};
114 static uint8_t mode_page_inquiry[0x6] = {0x12, 1, 0x80, 0, 0xff, 0};
115 static uint8_t request_invalid[0xC] = {0xEA, 0, 0, 0, 0};
116 static uint8_t prevent_removal[0x6] = {0x1E, 0, 0, 0, 1};
117 static uint8_t read_toc[0xA] = {0x43, 0x02, 0, 0, 0, 0xAA, 0, 0x0C};
118
119 #define TIMEOUT_FILTER(x) (x)
120
121 static void usb_request_sense(uint8_t lun);
122
123 static void
do_msc_reset(uint8_t lun)124 do_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
149 static uint8_t
do_msc_cmd(uint8_t * pcmd,uint8_t cmdlen,void * pdata,uint32_t datalen,uint8_t isread,uint8_t isshort,uint8_t lun,uint8_t flags)150 do_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
257 static void
do_msc_shorter_cmd(uint8_t lun)258 do_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
286 static uint8_t
do_read_10(uint32_t lba,uint32_t len,void * buf,uint8_t lun)287 do_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
313 static uint8_t
do_write_10(uint32_t lba,uint32_t len,void * buf,uint8_t lun)314 do_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
343 static void
do_io_test(struct usb_msc_params * p,uint8_t lun,uint32_t lba_max,uint8_t * buffer,uint8_t * reference)344 do_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
476 static void
usb_request_sense(uint8_t lun)477 usb_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
492 static void
usb_msc_test(struct usb_msc_params * p)493 usb_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 }
718 retry_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
851 fail:
852 if (buffer)
853 free(buffer);
854 if (reference)
855 free(reference);
856 }
857
858 void
show_host_device_selection(uint8_t level,struct uaddr * puaddr)859 show_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
872 top:
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
916 struct libusb20_device *
find_usb_device(struct uaddr uaddr)917 find_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
946 void
find_usb_endpoints(struct libusb20_device * pdev,uint8_t class,uint8_t subclass,uint8_t protocol,uint8_t alt_setting,uint8_t * pif,uint8_t * in_ep,uint8_t * out_ep,uint8_t next_if)947 find_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
1007 static void
exec_host_msc_test(struct usb_msc_params * p,struct uaddr uaddr)1008 exec_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
1068 static void
set_defaults(struct usb_msc_params * p)1069 set_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
1080 static const char *
get_io_mode(const struct usb_msc_params * p)1081 get_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
1098 static const char *
get_io_pattern(const struct usb_msc_params * p)1099 get_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
1114 static const char *
get_io_size(const struct usb_msc_params * p)1115 get_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
1150 static const char *
get_io_delay(const struct usb_msc_params * p)1151 get_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
1170 static const char *
get_io_offset(const struct usb_msc_params * p)1171 get_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
1184 static const char *
get_io_area(const struct usb_msc_params * p)1185 get_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
1202 void
show_host_msc_test(uint8_t level,struct uaddr uaddr,uint32_t duration)1203 show_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