xref: /freebsd/tools/tools/usbtest/usbtest.c (revision 2a63c3be158216222d89a073dcbd6a72ee4aab5a)
1 /*-
2  * Copyright (c) 2010-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 <err.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <stdarg.h>
32 #include <stdlib.h>
33 
34 #include <sys/types.h>
35 #include <sys/sysctl.h>
36 
37 #include <dev/usb/usb_ioctl.h>
38 
39 #include "usbtest.h"
40 
41 #include <g_keyboard.h>
42 #include <g_mouse.h>
43 #include <g_modem.h>
44 #include <g_audio.h>
45 
46 static uint8_t usb_ts_select[USB_TS_MAX_LEVELS];
47 
48 const char *indent[USB_TS_MAX_LEVELS] = {
49 	" ",
50 	"   ",
51 	"     ",
52 	"       ",
53 	"         ",
54 	"           ",
55 	"             ",
56 	"               ",
57 };
58 
59 /* a perceptual white noise generator (after HPS' invention) */
60 
61 int32_t
usb_ts_rand_noise(void)62 usb_ts_rand_noise(void)
63 {
64 	uint32_t temp;
65 	const uint32_t prime = 0xFFFF1D;
66 	static uint32_t noise_rem = 1;
67 
68 	if (noise_rem & 1) {
69 		noise_rem += prime;
70 	}
71 	noise_rem /= 2;
72 
73 	temp = noise_rem;
74 
75 	/* unsigned to signed conversion */
76 
77 	temp ^= 0x800000;
78 	if (temp & 0x800000) {
79 		temp |= (-0x800000);
80 	}
81 	return temp;
82 }
83 
84 uint8_t
usb_ts_show_menu(uint8_t level,const char * title,const char * fmt,...)85 usb_ts_show_menu(uint8_t level, const char *title, const char *fmt,...)
86 {
87 	va_list args;
88 	uint8_t x;
89 	uint8_t retval;
90 	char *pstr;
91 	char buf[16];
92 	char menu[80 * 20];
93 
94 	va_start(args, fmt);
95 	vsnprintf(menu, sizeof(menu), fmt, args);
96 	va_end(args);
97 
98 	printf("[");
99 
100 	for (x = 0; x != level; x++) {
101 		if ((x + 1) == level)
102 			printf("%d", usb_ts_select[x]);
103 		else
104 			printf("%d.", usb_ts_select[x]);
105 	}
106 
107 	printf("] - %s:\n\n", title);
108 
109 	x = 1;
110 	for (pstr = menu; *pstr; pstr++) {
111 		if (x != 0) {
112 			printf("%s", indent[level]);
113 			x = 0;
114 		}
115 		printf("%c", *pstr);
116 
117 		if (*pstr == '\n')
118 			x = 1;
119 	}
120 
121 	printf("\n>");
122 
123 	if (fgets(buf, sizeof(buf), stdin) == NULL)
124 		err(1, "Cannot read input");
125 
126 	if (buf[0] == 'x')
127 		retval = 255;
128 	else
129 		retval = atoi(buf);
130 
131 	usb_ts_select[level] = retval;
132 
133 	return (retval);
134 }
135 
136 void
get_string(char * ptr,int size)137 get_string(char *ptr, int size)
138 {
139 	printf("\nEnter string>");
140 
141 	if (fgets(ptr, size, stdin) == NULL)
142 		err(1, "Cannot read input");
143 
144 	ptr[size - 1] = 0;
145 
146 	size = strlen(ptr);
147 
148 	/* strip trailing newline, if any */
149 	if (size == 0)
150 		return;
151 	else if (ptr[size - 1] == '\n')
152 		ptr[size - 1] = 0;
153 }
154 
155 int
get_integer(void)156 get_integer(void)
157 {
158 	char buf[32];
159 
160 	printf("\nEnter integer value>");
161 
162 	if (fgets(buf, sizeof(buf), stdin) == NULL)
163 		err(1, "Cannot read input");
164 
165 	if (strcmp(buf, "x\n") == 0)
166 		return (-1);
167 	if (strcmp(buf, "r\n") == 0)
168 		return (-2);
169 
170 	return ((int)strtol(buf, 0, 0));
171 }
172 
173 static void
set_template(int template)174 set_template(int template)
175 {
176 	int error;
177 
178 	error = sysctlbyname("hw.usb.template", NULL, NULL,
179 	    &template, sizeof(template));
180 
181 	if (error != 0) {
182 		printf("WARNING: Could not set USB template "
183 		    "to %d (error=%d)\n", template, errno);
184 	}
185 }
186 
187 static void
show_default_audio_select(uint8_t level)188 show_default_audio_select(uint8_t level)
189 {
190 	int error;
191 	int retval;
192 	int mode = 0;
193 	int pattern_interval = 128;
194 	int throughput = 0;
195 	size_t len;
196 	char pattern[G_AUDIO_MAX_STRLEN] = {"0123456789abcdef"};
197 
198 	set_template(USB_TEMP_AUDIO);
199 
200 	while (1) {
201 
202 		error = sysctlbyname("hw.usb.g_audio.mode", NULL, NULL,
203 		    &mode, sizeof(mode));
204 
205 		if (error != 0) {
206 			printf("WARNING: Could not set audio mode "
207 			    "to %d (error=%d)\n", mode, errno);
208 		}
209 		error = sysctlbyname("hw.usb.g_audio.pattern_interval", NULL, NULL,
210 		    &pattern_interval, sizeof(pattern_interval));
211 
212 		if (error != 0) {
213 			printf("WARNING: Could not set pattern interval "
214 			    "to %d (error=%d)\n", pattern_interval, errno);
215 		}
216 		len = sizeof(throughput);
217 
218 		error = sysctlbyname("hw.usb.g_audio.throughput",
219 		    &throughput, &len, 0, 0);
220 
221 		if (error != 0) {
222 			printf("WARNING: Could not get throughput "
223 			    "(error=%d)\n", errno);
224 		}
225 		error = sysctlbyname("hw.usb.g_audio.pattern", NULL, NULL,
226 		    &pattern, strlen(pattern));
227 
228 		if (error != 0) {
229 			printf("WARNING: Could not set audio pattern "
230 			    "to '%s' (error=%d)\n", pattern, errno);
231 		}
232 		retval = usb_ts_show_menu(level, "Default Audio Settings",
233 		    "1) Set Silent mode %s\n"
234 		    "2) Set Dump mode %s\n"
235 		    "3) Set Loop mode %s\n"
236 		    "4) Set Pattern mode %s\n"
237 		    "5) Change DTMF pattern: '%s'\n"
238 		    "6) Change pattern advance interval: %d ms\n"
239 		    "x) Return to previous menu\n"
240 		    "s: Ready for enumeration\n"
241 		    "t: Throughput: %d bytes/second\n",
242 		    (mode == G_AUDIO_MODE_SILENT) ? "(selected)" : "",
243 		    (mode == G_AUDIO_MODE_DUMP) ? "(selected)" : "",
244 		    (mode == G_AUDIO_MODE_LOOP) ? "(selected)" : "",
245 		    (mode == G_AUDIO_MODE_PATTERN) ? "(selected)" : "",
246 		    pattern, pattern_interval, throughput);
247 
248 		switch (retval) {
249 		case 0:
250 			break;
251 		case 1:
252 			mode = G_AUDIO_MODE_SILENT;
253 			break;
254 		case 2:
255 			mode = G_AUDIO_MODE_DUMP;
256 			break;
257 		case 3:
258 			mode = G_AUDIO_MODE_LOOP;
259 			break;
260 		case 4:
261 			mode = G_AUDIO_MODE_PATTERN;
262 			break;
263 		case 5:
264 			get_string(pattern, sizeof(pattern));
265 			break;
266 		case 6:
267 			pattern_interval = get_integer();
268 			break;
269 		default:
270 			return;
271 		}
272 	}
273 }
274 
275 static void
show_device_audio_select(uint8_t level)276 show_device_audio_select(uint8_t level)
277 {
278 	uint8_t retval;
279 
280 	while (1) {
281 
282 		retval = usb_ts_show_menu(level, "Select Audio Device Model",
283 		    "1) Generic Audio Device\n"
284 		    "x) Return to previous menu\n");
285 
286 		switch (retval) {
287 		case 0:
288 			break;
289 		case 1:
290 			show_default_audio_select(level + 1);
291 			break;
292 		default:
293 			return;
294 		}
295 	}
296 }
297 
298 static void
show_device_msc_select(uint8_t level)299 show_device_msc_select(uint8_t level)
300 {
301 	set_template(USB_TEMP_MSC);
302 }
303 
304 static void
show_device_ethernet_select(uint8_t level)305 show_device_ethernet_select(uint8_t level)
306 {
307 	set_template(USB_TEMP_CDCE);
308 }
309 
310 static void
show_default_keyboard_select(uint8_t level)311 show_default_keyboard_select(uint8_t level)
312 {
313 	int error;
314 	int retval;
315 	int mode = 0;
316 	int interval = 1023;
317 	char pattern[G_KEYBOARD_MAX_STRLEN] = {"abcdefpattern"};
318 
319 	set_template(USB_TEMP_KBD);
320 
321 	while (1) {
322 
323 		error = sysctlbyname("hw.usb.g_keyboard.mode", NULL, NULL,
324 		    &mode, sizeof(mode));
325 
326 		if (error != 0) {
327 			printf("WARNING: Could not set keyboard mode "
328 			    " to %d (error=%d) \n", mode, errno);
329 		}
330 		error = sysctlbyname("hw.usb.g_keyboard.key_press_interval", NULL, NULL,
331 		    &interval, sizeof(interval));
332 
333 		if (error != 0) {
334 			printf("WARNING: Could not set key press interval "
335 			    "to %d (error=%d)\n", interval, errno);
336 		}
337 		error = sysctlbyname("hw.usb.g_keyboard.key_press_pattern", NULL, NULL,
338 		    &pattern, strlen(pattern));
339 
340 		if (error != 0) {
341 			printf("WARNING: Could not set key pattern "
342 			    "to '%s' (error=%d)\n", pattern, errno);
343 		}
344 		retval = usb_ts_show_menu(level, "Default Keyboard Settings",
345 		    "1) Set silent mode %s\n"
346 		    "2) Set pattern mode %s\n"
347 		    "3) Change pattern: '%s'\n"
348 		    "4) Change key press interval: %d ms\n"
349 		    "x) Return to previous menu\n"
350 		    "s: Ready for enumeration\n",
351 		    (mode == G_KEYBOARD_MODE_SILENT) ? "(selected)" : "",
352 		    (mode == G_KEYBOARD_MODE_PATTERN) ? "(selected)" : "",
353 		    pattern, interval);
354 
355 		switch (retval) {
356 		case 0:
357 			break;
358 		case 1:
359 			mode = G_KEYBOARD_MODE_SILENT;
360 			break;
361 		case 2:
362 			mode = G_KEYBOARD_MODE_PATTERN;
363 			break;
364 		case 3:
365 			get_string(pattern, sizeof(pattern));
366 			break;
367 		case 4:
368 			interval = get_integer();
369 			break;
370 		default:
371 			return;
372 		}
373 	}
374 }
375 
376 static void
show_device_keyboard_select(uint8_t level)377 show_device_keyboard_select(uint8_t level)
378 {
379 	uint8_t retval;
380 
381 	while (1) {
382 
383 		retval = usb_ts_show_menu(level, "Select Keyboard Model",
384 		    "1) Generic Keyboard \n"
385 		    "x) Return to previous menu \n");
386 
387 		switch (retval) {
388 		case 0:
389 			break;
390 		case 1:
391 			show_default_keyboard_select(level + 1);
392 			break;
393 		default:
394 			return;
395 		}
396 	}
397 }
398 
399 static void
show_default_mouse_select(uint8_t level)400 show_default_mouse_select(uint8_t level)
401 {
402 	int error;
403 	int retval;
404 	int mode = 0;
405 	int cursor_interval = 128;
406 	int cursor_radius = 75;
407 	int button_interval = 0;
408 
409 	set_template(USB_TEMP_MOUSE);
410 
411 	while (1) {
412 
413 		error = sysctlbyname("hw.usb.g_mouse.mode", NULL, NULL,
414 		    &mode, sizeof(mode));
415 
416 		if (error != 0) {
417 			printf("WARNING: Could not set mouse mode "
418 			    "to %d (error=%d)\n", mode, errno);
419 		}
420 		error = sysctlbyname("hw.usb.g_mouse.cursor_update_interval", NULL, NULL,
421 		    &cursor_interval, sizeof(cursor_interval));
422 
423 		if (error != 0) {
424 			printf("WARNING: Could not set cursor update interval "
425 			    "to %d (error=%d)\n", cursor_interval, errno);
426 		}
427 		error = sysctlbyname("hw.usb.g_mouse.button_press_interval", NULL, NULL,
428 		    &button_interval, sizeof(button_interval));
429 
430 		if (error != 0) {
431 			printf("WARNING: Could not set button press interval "
432 			    "to %d (error=%d)\n", button_interval, errno);
433 		}
434 		error = sysctlbyname("hw.usb.g_mouse.cursor_radius", NULL, NULL,
435 		    &cursor_radius, sizeof(cursor_radius));
436 
437 		if (error != 0) {
438 			printf("WARNING: Could not set cursor radius "
439 			    "to %d (error=%d)\n", cursor_radius, errno);
440 		}
441 		retval = usb_ts_show_menu(level, "Default Mouse Settings",
442 		    "1) Set Silent mode %s\n"
443 		    "2) Set Circle mode %s\n"
444 		    "3) Set Square mode %s\n"
445 		    "4) Set Spiral mode %s\n"
446 		    "5) Change cursor radius: %d pixels\n"
447 		    "6) Change cursor update interval: %d ms\n"
448 		    "7) Change button[0] press interval: %d ms\n"
449 		    "x) Return to previous menu\n"
450 		    "s: Ready for enumeration\n",
451 		    (mode == G_MOUSE_MODE_SILENT) ? "(selected)" : "",
452 		    (mode == G_MOUSE_MODE_CIRCLE) ? "(selected)" : "",
453 		    (mode == G_MOUSE_MODE_BOX) ? "(selected)" : "",
454 		    (mode == G_MOUSE_MODE_SPIRAL) ? "(selected)" : "",
455 		    cursor_radius, cursor_interval, button_interval);
456 
457 		switch (retval) {
458 		case 0:
459 			break;
460 		case 1:
461 			mode = G_MOUSE_MODE_SILENT;
462 			break;
463 		case 2:
464 			mode = G_MOUSE_MODE_CIRCLE;
465 			break;
466 		case 3:
467 			mode = G_MOUSE_MODE_BOX;
468 			break;
469 		case 4:
470 			mode = G_MOUSE_MODE_SPIRAL;
471 			break;
472 		case 5:
473 			cursor_radius = get_integer();
474 			break;
475 		case 6:
476 			cursor_interval = get_integer();
477 			break;
478 		case 7:
479 			button_interval = get_integer();
480 			break;
481 		default:
482 			return;
483 		}
484 	}
485 }
486 
487 static void
show_device_mouse_select(uint8_t level)488 show_device_mouse_select(uint8_t level)
489 {
490 	uint8_t retval;
491 
492 	while (1) {
493 
494 		retval = usb_ts_show_menu(level, "Select Mouse Model",
495 		    "1) Generic Mouse\n"
496 		    "x) Return to previous menu\n");
497 
498 		switch (retval) {
499 		case 0:
500 			break;
501 		case 1:
502 			show_default_mouse_select(level + 1);
503 			break;
504 		default:
505 			return;
506 		}
507 	}
508 }
509 
510 static void
show_device_mtp_select(uint8_t level)511 show_device_mtp_select(uint8_t level)
512 {
513 	set_template(USB_TEMP_MTP);
514 }
515 
516 static void
show_default_modem_select(uint8_t level)517 show_default_modem_select(uint8_t level)
518 {
519 	int error;
520 	int retval;
521 	int mode = 0;
522 	int pattern_interval = 128;
523 	int throughput = 0;
524 	size_t len;
525 	char pattern[G_MODEM_MAX_STRLEN] = {"abcdefpattern"};
526 
527 	set_template(USB_TEMP_MODEM);
528 
529 	while (1) {
530 
531 		error = sysctlbyname("hw.usb.g_modem.mode", NULL, NULL,
532 		    &mode, sizeof(mode));
533 
534 		if (error != 0) {
535 			printf("WARNING: Could not set modem mode "
536 			    "to %d (error=%d)\n", mode, errno);
537 		}
538 		error = sysctlbyname("hw.usb.g_modem.pattern_interval", NULL, NULL,
539 		    &pattern_interval, sizeof(pattern_interval));
540 
541 		if (error != 0) {
542 			printf("WARNING: Could not set pattern interval "
543 			    "to %d (error=%d)\n", pattern_interval, errno);
544 		}
545 		len = sizeof(throughput);
546 
547 		error = sysctlbyname("hw.usb.g_modem.throughput",
548 		    &throughput, &len, 0, 0);
549 
550 		if (error != 0) {
551 			printf("WARNING: Could not get throughput "
552 			    "(error=%d)\n", errno);
553 		}
554 		error = sysctlbyname("hw.usb.g_modem.pattern", NULL, NULL,
555 		    &pattern, strlen(pattern));
556 
557 		if (error != 0) {
558 			printf("WARNING: Could not set modem pattern "
559 			    "to '%s' (error=%d)\n", pattern, errno);
560 		}
561 		retval = usb_ts_show_menu(level, "Default Modem Settings",
562 		    "1) Set Silent mode %s\n"
563 		    "2) Set Dump mode %s\n"
564 		    "3) Set Loop mode %s\n"
565 		    "4) Set Pattern mode %s\n"
566 		    "5) Change test pattern: '%s'\n"
567 		    "6) Change data transmit interval: %d ms\n"
568 		    "x) Return to previous menu\n"
569 		    "s: Ready for enumeration\n"
570 		    "t: Throughput: %d bytes/second\n",
571 		    (mode == G_MODEM_MODE_SILENT) ? "(selected)" : "",
572 		    (mode == G_MODEM_MODE_DUMP) ? "(selected)" : "",
573 		    (mode == G_MODEM_MODE_LOOP) ? "(selected)" : "",
574 		    (mode == G_MODEM_MODE_PATTERN) ? "(selected)" : "",
575 		    pattern, pattern_interval, throughput);
576 
577 		switch (retval) {
578 		case 0:
579 			break;
580 		case 1:
581 			mode = G_MODEM_MODE_SILENT;
582 			break;
583 		case 2:
584 			mode = G_MODEM_MODE_DUMP;
585 			break;
586 		case 3:
587 			mode = G_MODEM_MODE_LOOP;
588 			break;
589 		case 4:
590 			mode = G_MODEM_MODE_PATTERN;
591 			break;
592 		case 5:
593 			get_string(pattern, sizeof(pattern));
594 			break;
595 		case 6:
596 			pattern_interval = get_integer();
597 			break;
598 		default:
599 			return;
600 		}
601 	}
602 }
603 
604 static void
show_device_modem_select(uint8_t level)605 show_device_modem_select(uint8_t level)
606 {
607 	uint8_t retval;
608 
609 	while (1) {
610 
611 		retval = usb_ts_show_menu(level, "Select Modem Model",
612 		    "1) Generic Modem\n"
613 		    "x) Return to previous menu\n");
614 
615 		switch (retval) {
616 		case 0:
617 			break;
618 		case 1:
619 			show_default_modem_select(level + 1);
620 			break;
621 		default:
622 			return;
623 		}
624 	}
625 }
626 
627 static void
show_device_generic_select(uint8_t level)628 show_device_generic_select(uint8_t level)
629 {
630 }
631 
632 static void
show_device_select(uint8_t level)633 show_device_select(uint8_t level)
634 {
635 	uint8_t retval;
636 
637 	while (1) {
638 
639 		retval = usb_ts_show_menu(level, "Select Device Mode Test Group",
640 		    "1) Audio (UAUDIO)\n"
641 		    "2) Mass Storage (MSC)\n"
642 		    "3) Ethernet (CDCE)\n"
643 		    "4) Keyboard Input Device (UKBD)\n"
644 		    "5) Mouse Input Device (UMS)\n"
645 		    "6) Message Transfer Protocol (MTP)\n"
646 		    "7) Modem (CDC)\n"
647 		    "8) Generic Endpoint Loopback (GENERIC)\n"
648 		    "x) Return to previous menu\n");
649 
650 		switch (retval) {
651 		case 0:
652 			break;
653 		case 1:
654 			show_device_audio_select(level + 1);
655 			break;
656 		case 2:
657 			show_device_msc_select(level + 1);
658 			break;
659 		case 3:
660 			show_device_ethernet_select(level + 1);
661 			break;
662 		case 4:
663 			show_device_keyboard_select(level + 1);
664 			break;
665 		case 5:
666 			show_device_mouse_select(level + 1);
667 			break;
668 		case 6:
669 			show_device_mtp_select(level + 1);
670 			break;
671 		case 7:
672 			show_device_modem_select(level + 1);
673 			break;
674 		case 8:
675 			show_device_generic_select(level + 1);
676 			break;
677 		default:
678 			return;
679 		}
680 	}
681 }
682 
683 static void
show_host_select(uint8_t level)684 show_host_select(uint8_t level)
685 {
686 	int force_fs = 0;
687 	int error;
688 	uint32_t duration = 60;
689 
690 	struct uaddr uaddr = {};
691 
692 	uint8_t retval;
693 
694 	while (1) {
695 
696 		error = sysctlbyname("hw.usb.ehci.no_hs", NULL, NULL,
697 		    &force_fs, sizeof(force_fs));
698 
699 		if (error != 0) {
700 			printf("WARNING: Could not set non-FS mode "
701 			    "to %d (error=%d)\n", force_fs, errno);
702 		}
703 		retval = usb_ts_show_menu(level, "Select Host Mode Test (via LibUSB)",
704 		    " 1) Select USB device (VID=0x%04x, PID=0x%04x, ugen%u.%u)\n"
705 		    " 2) Manually enter USB vendor and product ID\n"
706 		    " 3) Force FULL speed operation: <%s>\n"
707 		    " 4) Mass Storage (UMASS)\n"
708 		    " 5) Modem (UMODEM)\n"
709 		    "10) Start String Descriptor Test\n"
710 		    "11) Start Port Reset Test\n"
711 		    "12) Start Set Config Test\n"
712 		    "13) Start Get Descriptor Test\n"
713 		    "14) Start Suspend and Resume Test\n"
714 		    "15) Start Set and Clear Endpoint Stall Test\n"
715 		    "16) Start Set Alternate Interface Setting Test\n"
716 		    "17) Start Invalid Control Request Test\n"
717 		    "30) Duration: <%d> seconds\n"
718 		    "x) Return to previous menu\n",
719 		    uaddr.vid, uaddr.pid, uaddr.bus, uaddr.addr,
720 		    force_fs ? "YES" : "NO",
721 		    (int)duration);
722 
723 		switch (retval) {
724 		case 0:
725 			break;
726 		case 1:
727 			show_host_device_selection(level + 1, &uaddr);
728 			break;
729 		case 2:
730 			/* only match VID and PID */
731 			uaddr.vid = get_integer() & 0xFFFF;
732 			uaddr.pid = get_integer() & 0xFFFF;
733 			uaddr.bus = 0;
734 			uaddr.addr = 0;
735 			break;
736 		case 3:
737 			force_fs ^= 1;
738 			break;
739 		case 4:
740 			show_host_msc_test(level + 1, uaddr, duration);
741 			break;
742 		case 5:
743 			show_host_modem_test(level + 1, uaddr, duration);
744 			break;
745 		case 10:
746 			usb_get_string_desc_test(uaddr);
747 			break;
748 		case 11:
749 			usb_port_reset_test(uaddr, duration);
750 			break;
751 		case 12:
752 			usb_set_config_test(uaddr, duration);
753 			break;
754 		case 13:
755 			usb_get_descriptor_test(uaddr, duration);
756 			break;
757 		case 14:
758 			usb_suspend_resume_test(uaddr, duration);
759 			break;
760 		case 15:
761 			usb_set_and_clear_stall_test(uaddr);
762 			break;
763 		case 16:
764 			usb_set_alt_interface_test(uaddr);
765 			break;
766 		case 17:
767 			usb_control_ep_error_test(uaddr);
768 			break;
769 		case 30:
770 			duration = get_integer();
771 			break;
772 		default:
773 			return;
774 		}
775 	}
776 }
777 
778 static void
show_mode_select(uint8_t level)779 show_mode_select(uint8_t level)
780 {
781 	uint8_t retval;
782 
783 	while (1) {
784 
785 		retval = usb_ts_show_menu(level, "Select Computer Mode",
786 		    "1) This computer is Running the Device Side\n"
787 		    "2) This computer is Running the Host Side\n"
788 		    "x) Return to previous menu\n");
789 
790 		switch (retval) {
791 		case 0:
792 			break;
793 		case 1:
794 			show_device_select(level + 1);
795 			break;
796 		case 2:
797 			show_host_select(level + 1);
798 			break;
799 		default:
800 			return;
801 		}
802 	}
803 }
804 
805 int
main(int argc,char ** argv)806 main(int argc, char **argv)
807 {
808 	show_mode_select(1);
809 
810 	return (0);
811 }
812