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
do_msc_reset(uint8_t lun)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
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)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
do_msc_shorter_cmd(uint8_t lun)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
do_read_10(uint32_t lba,uint32_t len,void * buf,uint8_t lun)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
do_write_10(uint32_t lba,uint32_t len,void * buf,uint8_t lun)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
do_io_test(struct usb_msc_params * p,uint8_t lun,uint32_t lba_max,uint8_t * buffer,uint8_t * reference)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
usb_request_sense(uint8_t lun)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
usb_msc_test(struct usb_msc_params * p)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
show_host_device_selection(uint8_t level,uint16_t * pvid,uint16_t * ppid)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 *
find_usb_device(uint16_t vid,uint16_t pid)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
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)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
exec_host_msc_test(struct usb_msc_params * p,uint16_t vid,uint16_t pid)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
set_defaults(struct usb_msc_params * p)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 *
get_io_mode(const struct usb_msc_params * p)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 *
get_io_pattern(const struct usb_msc_params * p)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 *
get_io_size(const struct usb_msc_params * p)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 *
get_io_delay(const struct usb_msc_params * p)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 *
get_io_offset(const struct usb_msc_params * p)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 *
get_io_area(const struct usb_msc_params * p)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
show_host_msc_test(uint8_t level,uint16_t vid,uint16_t pid,uint32_t duration)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