Merge branch 'vendor/MDOCML'
[dragonfly.git] / tools / tools / usbtest / usbtest.c
1 /* $FreeBSD: head/tools/tools/usbtest/usbtest.c 254159 2013-08-09 20:08:42Z hselasky $ */
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 <bus/u4b/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 }