aboutsummaryrefslogtreecommitdiffstats
path: root/tools/usb
diff options
context:
space:
mode:
authorDavid Brownell <dbrownell@users.sourceforge.net>2010-05-05 06:53:17 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-20 16:21:43 -0400
commit2201d6b1620a1d9feac78e9ff12b7246227c8b17 (patch)
tree0d655fa6a26ebdce962525906e776160f650d93f /tools/usb
parent93f2aa4ddd25caac2b9a09538da54308dbda44e2 (diff)
USB: testusb: an USB testing application
The testusb program just issues ioctls to perform the tests implemented by the kernel driver. It can generate a variety of transfer patterns; you should make sure to test both regular streaming and mixes of transfer sizes (including short transfers). For more information on how this can be used and on USB testing refer to <URL:http://www.linux-usb.org/usbtest/>. Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com> Cc: Kyungmin Park <kyungmin.park@samsung.com> Cc: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'tools/usb')
-rw-r--r--tools/usb/testusb.c427
1 files changed, 427 insertions, 0 deletions
diff --git a/tools/usb/testusb.c b/tools/usb/testusb.c
new file mode 100644
index 000000000000..1f372983be6d
--- /dev/null
+++ b/tools/usb/testusb.c
@@ -0,0 +1,427 @@
1/* $(CROSS_COMPILE)cc -Wall -g -lpthread -o testusb testusb.c */
2
3/*
4 * Copyright (c) 2002 by David Brownell
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <ftw.h>
24#include <stdlib.h>
25#include <pthread.h>
26#include <unistd.h>
27#include <errno.h>
28
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <fcntl.h>
32
33#include <sys/ioctl.h>
34#include <linux/usbdevice_fs.h>
35
36/*-------------------------------------------------------------------------*/
37
38#define TEST_CASES 30
39
40// FIXME make these public somewhere; usbdevfs.h?
41
42struct usbtest_param {
43 // inputs
44 unsigned test_num; /* 0..(TEST_CASES-1) */
45 unsigned iterations;
46 unsigned length;
47 unsigned vary;
48 unsigned sglen;
49
50 // outputs
51 struct timeval duration;
52};
53#define USBTEST_REQUEST _IOWR('U', 100, struct usbtest_param)
54
55/*-------------------------------------------------------------------------*/
56
57/* #include <linux/usb_ch9.h> */
58
59struct usb_device_descriptor {
60 __u8 bLength;
61 __u8 bDescriptorType;
62 __u16 bcdUSB;
63 __u8 bDeviceClass;
64 __u8 bDeviceSubClass;
65 __u8 bDeviceProtocol;
66 __u8 bMaxPacketSize0;
67 __u16 idVendor;
68 __u16 idProduct;
69 __u16 bcdDevice;
70 __u8 iManufacturer;
71 __u8 iProduct;
72 __u8 iSerialNumber;
73 __u8 bNumConfigurations;
74} __attribute__ ((packed));
75
76enum usb_device_speed {
77 USB_SPEED_UNKNOWN = 0, /* enumerating */
78 USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */
79 USB_SPEED_HIGH /* usb 2.0 */
80};
81
82/*-------------------------------------------------------------------------*/
83
84static char *speed (enum usb_device_speed s)
85{
86 switch (s) {
87 case USB_SPEED_UNKNOWN: return "unknown";
88 case USB_SPEED_LOW: return "low";
89 case USB_SPEED_FULL: return "full";
90 case USB_SPEED_HIGH: return "high";
91 default: return "??";
92 }
93}
94
95struct testdev {
96 struct testdev *next;
97 char *name;
98 pthread_t thread;
99 enum usb_device_speed speed;
100 unsigned ifnum : 8;
101 unsigned forever : 1;
102 int test;
103
104 struct usbtest_param param;
105};
106static struct testdev *testdevs;
107
108static int is_testdev (struct usb_device_descriptor *dev)
109{
110 /* FX2 with (tweaked) bulksrc firmware */
111 if (dev->idVendor == 0x0547 && dev->idProduct == 0x1002)
112 return 1;
113
114 /*----------------------------------------------------*/
115
116 /* devices that start up using the EZ-USB default device and
117 * which we can use after loading simple firmware. hotplug
118 * can fxload it, and then run this test driver.
119 *
120 * we return false positives in two cases:
121 * - the device has a "real" driver (maybe usb-serial) that
122 * renumerates. the device should vanish quickly.
123 * - the device doesn't have the test firmware installed.
124 */
125
126 /* generic EZ-USB FX controller */
127 if (dev->idVendor == 0x0547 && dev->idProduct == 0x2235)
128 return 1;
129
130 /* generic EZ-USB FX2 controller */
131 if (dev->idVendor == 0x04b4 && dev->idProduct == 0x8613)
132 return 1;
133
134 /* CY3671 development board with EZ-USB FX */
135 if (dev->idVendor == 0x0547 && dev->idProduct == 0x0080)
136 return 1;
137
138 /* Keyspan 19Qi uses an21xx (original EZ-USB) */
139 if (dev->idVendor == 0x06cd && dev->idProduct == 0x010b)
140 return 1;
141
142 /*----------------------------------------------------*/
143
144 /* "gadget zero", Linux-USB test software */
145 if (dev->idVendor == 0x0525 && dev->idProduct == 0xa4a0)
146 return 1;
147
148 /* user mode subset of that */
149 if (dev->idVendor == 0x0525 && dev->idProduct == 0xa4a4)
150 return 1;
151
152 /* iso version of usermode code */
153 if (dev->idVendor == 0x0525 && dev->idProduct == 0xa4a3)
154 return 1;
155
156 /* some GPL'd test firmware uses these IDs */
157
158 if (dev->idVendor == 0xfff0 && dev->idProduct == 0xfff0)
159 return 1;
160
161 /*----------------------------------------------------*/
162
163 /* iBOT2 high speed webcam */
164 if (dev->idVendor == 0x0b62 && dev->idProduct == 0x0059)
165 return 1;
166
167 return 0;
168}
169
170static int find_testdev (const char *name, const struct stat *sb, int flag)
171{
172 int fd;
173 struct usb_device_descriptor dev;
174
175 if (flag != FTW_F)
176 return 0;
177 /* ignore /proc/bus/usb/{devices,drivers} */
178 if (strrchr (name, '/')[1] == 'd')
179 return 0;
180
181 if ((fd = open (name, O_RDONLY)) < 0) {
182 perror ("can't open dev file r/o");
183 return 0;
184 }
185 if (read (fd, &dev, sizeof dev) != sizeof dev)
186 fputs ("short devfile read!\n", stderr);
187 else if (is_testdev (&dev)) {
188 struct testdev *entry;
189
190 if ((entry = calloc (1, sizeof *entry)) == 0) {
191 fputs ("no mem!\n", stderr);
192 goto done;
193 }
194 entry->name = strdup (name);
195 if (!entry->name) {
196 free (entry);
197 goto done;
198 }
199
200 // FIXME better to look at each interface and ask if it's
201 // bound to