42 #include <sys/types.h>
46 #include <sys/ioctl.h>
47 #include <linux/usbdevice_fs.h>
66 #define USBTEST_REQUEST _IOWR('U', 100, struct usbtest_param)
72 #define USB_DT_DEVICE 0x01
73 #define USB_DT_INTERFACE 0x04
75 #define USB_CLASS_PER_INTERFACE 0
76 #define USB_CLASS_VENDOR_SPEC 0xff
124 default:
return "??";
139 static struct testdev *testdevs;
141 static int testdev_ffs_ifnum(FILE *
fd)
149 if (fread(
u.buf, 1, 1, fd) != 1)
151 if (fread(
u.buf + 1, (
unsigned char)
u.buf[0] - 1, 1, fd) != 1)
154 if (
u.intf.bLength ==
sizeof u.intf
156 &&
u.intf.bNumEndpoints == 2
158 &&
u.intf.bInterfaceSubClass == 0
159 &&
u.intf.bInterfaceProtocol == 0)
160 return (
unsigned char)
u.intf.bInterfaceNumber;
164 static int testdev_ifnum(FILE *fd)
168 if (fread(&
dev,
sizeof dev, 1, fd) != 1)
175 if (
dev.idVendor == 0x0547 &&
dev.idProduct == 0x1002)
191 if (
dev.idVendor == 0x0547 &&
dev.idProduct == 0x2235)
195 if (
dev.idVendor == 0x04b4 &&
dev.idProduct == 0x8613)
199 if (
dev.idVendor == 0x0547 &&
dev.idProduct == 0x0080)
203 if (
dev.idVendor == 0x06cd &&
dev.idProduct == 0x010b)
209 if (
dev.idVendor == 0x0525 &&
dev.idProduct == 0xa4a0)
213 if (
dev.idVendor == 0x0525 &&
dev.idProduct == 0xa4a4)
214 return testdev_ffs_ifnum(fd);
218 if (
dev.idVendor == 0x0525 &&
dev.idProduct == 0xa4a3)
223 if (
dev.idVendor == 0xfff0 &&
dev.idProduct == 0xfff0)
229 if (
dev.idVendor == 0x0b62 &&
dev.idProduct == 0x0059)
238 if (
dev.idVendor == 0x0525 &&
dev.idProduct == 0xa4ac
241 return testdev_ffs_ifnum(fd);
246 static int find_testdev(
const char *
name,
const struct stat *
sb,
int flag)
257 fd = fopen(name,
"rb");
263 ifnum = testdev_ifnum(fd);
268 entry = calloc(1,
sizeof *entry);
272 entry->
name = strdup(name);
285 fprintf(stderr,
"%s speed\t%s\t%u\n",
288 entry->
next = testdevs;
294 usbdev_ioctl (
int fd,
int ifno,
unsigned request,
void *
param)
300 wrapper.data =
param;
305 static void *handle_testdev (
void *
arg)
312 perror (
"can't open dev file r/w");
318 if (dev->
test != -1 && dev->
test != i)
322 status = usbdev_ioctl (fd, dev->
ifnum,
334 if (strerror_r (errno, buf,
sizeof buf)) {
335 snprintf (buf,
sizeof buf,
"error %d", err);
338 printf (
"%s test %d --> %d (%s)\n",
339 dev->
name, i, errno, buf);
341 printf (
"%s test %d, %4d.%.06d secs\n", dev->
name, i,
342 (
int) dev->
param.duration.tv_sec,
343 (
int) dev->
param.duration.tv_usec);
354 static const char *usbfs_dir_find(
void)
356 static char udev_usb_path[] =
"/dev/bus/usb";
358 if (
access(udev_usb_path, F_OK) == 0)
359 return udev_usb_path;
364 static int parse_num(
unsigned *num,
const char *
str)
370 val = strtoul(str, &end, 0);
371 if (errno || *end || val >
UINT_MAX)
383 const char *usbfs_dir =
NULL;
384 int all = 0,
forever = 0, not = 0;
403 device = getenv (
"DEVICE");
405 while ((c = getopt (argc, argv,
"D:aA:c:g:hlns:t:v:")) !=
EOF)
422 if (parse_num(¶m.
sglen, optarg))
432 if (parse_num(¶m.
length, optarg))
436 test = atoi (optarg);
441 if (parse_num(¶m.
vary, optarg))
449 "usage: %s [options]\n"
451 "\t-D dev only test specific device\n"
453 "\t-a test all recognized devices\n"
454 "\t-l loop forever(for stress test)\n"
455 "\t-t testnum only run specified case\n"
456 "\t-n no test running, show devices to be tested\n"
458 "\t-c iterations default 1000\n"
459 "\t-s packetsize default 512\n"
460 "\t-g sglen default 32\n"
461 "\t-v vary default 512\n",
467 if (!all && !device) {
468 fprintf (stderr,
"must specify '-a' or '-D dev', "
469 "or DEVICE=/dev/bus/usb/BBB/DDD in env\n");
475 usbfs_dir = usbfs_dir_find();
477 fputs (
"usbfs files are missing\n", stderr);
483 if (ftw (usbfs_dir, find_testdev, 3) != 0) {
484 fputs (
"ftw failed; is usbfs missing?\n", stderr);
489 if (!testdevs && !device) {
490 fputs (
"no test devices recognized\n", stderr);
495 if (testdevs && testdevs->
next == 0 && !device)
496 device = testdevs->
name;
497 for (entry = testdevs;
entry; entry = entry->
next) {
507 return handle_testdev (entry) !=
entry;
509 status = pthread_create (&entry->
thread, 0, handle_testdev, entry);
511 perror (
"pthread_create");
519 fprintf (stderr,
"%s: %s may see only control tests\n",
522 memset (&dev, 0,
sizeof dev);
527 return handle_testdev (&dev) != &
dev;
531 for (entry = testdevs;
entry; entry = entry->
next) {
534 if (pthread_join (entry->
thread, &retval))
535 perror (
"pthread_join");