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