xref: /freebsd/tools/tools/usbtest/usb_msc_test.c (revision 2a63c3be158216222d89a073dcbd6a72ee4aab5a)
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(&params);
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(&params),
1238 		    get_io_size(&params),
1239 		    get_io_delay(&params),
1240 		    get_io_offset(&params),
1241 		    get_io_area(&params),
1242 		    get_io_pattern(&params),
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(&params);
1318 			break;
1319 		case 30:
1320 			exec_host_msc_test(&params, uaddr);
1321 			break;
1322 		case 40:
1323 			show_host_device_selection(level + 1, &uaddr);
1324 			break;
1325 		default:
1326 			return;
1327 		}
1328 	}
1329 }
1330