blob: 1c78e747f72b3ce63b99dabc1ccd7a2e3af5cf1b [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001#include <linux/kernel.h>
2#include <linux/errno.h>
3#include <linux/init.h>
4#include <linux/slab.h>
5#include <linux/mm.h>
6#include <linux/module.h>
7#include <linux/moduleparam.h>
David Hardeman378f0582005-09-17 17:55:31 +10008#include <linux/scatterlist.h>
Matthias Kaehlcke1cfab022007-12-13 16:15:33 -08009#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070010
11#include <linux/usb.h>
12
13
14/*-------------------------------------------------------------------------*/
15
Alan Sternd0b46522013-01-30 16:38:11 -050016static int override_alt = -1;
17module_param_named(alt, override_alt, int, 0644);
18MODULE_PARM_DESC(alt, ">= 0 to override altsetting selection");
19
20/*-------------------------------------------------------------------------*/
21
Martin Fuzzeyfabbf212010-10-01 00:20:42 +020022/* FIXME make these public somewhere; usbdevfs.h? */
Linus Torvalds1da177e2005-04-16 15:20:36 -070023struct usbtest_param {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +020024 /* inputs */
Linus Torvalds1da177e2005-04-16 15:20:36 -070025 unsigned test_num; /* 0..(TEST_CASES-1) */
26 unsigned iterations;
27 unsigned length;
28 unsigned vary;
29 unsigned sglen;
30
Martin Fuzzeyfabbf212010-10-01 00:20:42 +020031 /* outputs */
Linus Torvalds1da177e2005-04-16 15:20:36 -070032 struct timeval duration;
33};
34#define USBTEST_REQUEST _IOWR('U', 100, struct usbtest_param)
35
36/*-------------------------------------------------------------------------*/
37
38#define GENERIC /* let probe() bind using module params */
39
40/* Some devices that can be used for testing will have "real" drivers.
41 * Entries for those need to be enabled here by hand, after disabling
42 * that "real" driver.
43 */
44//#define IBOT2 /* grab iBOT2 webcams */
45//#define KEYSPAN_19Qi /* grab un-renumerated serial adapter */
46
47/*-------------------------------------------------------------------------*/
48
49struct usbtest_info {
50 const char *name;
51 u8 ep_in; /* bulk/intr source */
52 u8 ep_out; /* bulk/intr sink */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +020053 unsigned autoconf:1;
54 unsigned ctrl_out:1;
55 unsigned iso:1; /* try iso in/out */
Linus Torvalds1da177e2005-04-16 15:20:36 -070056 int alt;
57};
58
59/* this is accessed only through usbfs ioctl calls.
60 * one ioctl to issue a test ... one lock per device.
61 * tests create other threads if they need them.
62 * urbs and buffers are allocated dynamically,
63 * and data generated deterministically.
64 */
65struct usbtest_dev {
66 struct usb_interface *intf;
67 struct usbtest_info *info;
68 int in_pipe;
69 int out_pipe;
70 int in_iso_pipe;
71 int out_iso_pipe;
72 struct usb_endpoint_descriptor *iso_in, *iso_out;
Matthias Kaehlcke1cfab022007-12-13 16:15:33 -080073 struct mutex lock;
Linus Torvalds1da177e2005-04-16 15:20:36 -070074
75#define TBUF_SIZE 256
76 u8 *buf;
77};
78
Martin Fuzzeyfabbf212010-10-01 00:20:42 +020079static struct usb_device *testdev_to_usbdev(struct usbtest_dev *test)
Linus Torvalds1da177e2005-04-16 15:20:36 -070080{
Martin Fuzzeyfabbf212010-10-01 00:20:42 +020081 return interface_to_usbdev(test->intf);
Linus Torvalds1da177e2005-04-16 15:20:36 -070082}
83
84/* set up all urbs so they can be used with either bulk or interrupt */
85#define INTERRUPT_RATE 1 /* msec/transfer */
86
David Brownell28ffd792008-04-25 18:51:10 -070087#define ERROR(tdev, fmt, args...) \
88 dev_err(&(tdev)->intf->dev , fmt , ## args)
Arjan van de Venb6c63932008-07-25 01:45:52 -070089#define WARNING(tdev, fmt, args...) \
David Brownell28ffd792008-04-25 18:51:10 -070090 dev_warn(&(tdev)->intf->dev , fmt , ## args)
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
Martin Fuzzey084fb202011-01-16 19:17:11 +010092#define GUARD_BYTE 0xA5
93
Linus Torvalds1da177e2005-04-16 15:20:36 -070094/*-------------------------------------------------------------------------*/
95
96static int
Martin Fuzzeyfabbf212010-10-01 00:20:42 +020097get_endpoints(struct usbtest_dev *dev, struct usb_interface *intf)
Linus Torvalds1da177e2005-04-16 15:20:36 -070098{
99 int tmp;
100 struct usb_host_interface *alt;
101 struct usb_host_endpoint *in, *out;
102 struct usb_host_endpoint *iso_in, *iso_out;
103 struct usb_device *udev;
104
105 for (tmp = 0; tmp < intf->num_altsetting; tmp++) {
106 unsigned ep;
107
108 in = out = NULL;
109 iso_in = iso_out = NULL;
110 alt = intf->altsetting + tmp;
111
Alan Sternd0b46522013-01-30 16:38:11 -0500112 if (override_alt >= 0 &&
113 override_alt != alt->desc.bAlternateSetting)
114 continue;
115
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 /* take the first altsetting with in-bulk + out-bulk;
Justin P. Mattock70f23fd2011-05-10 10:16:21 +0200117 * ignore other endpoints and altsettings.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118 */
119 for (ep = 0; ep < alt->desc.bNumEndpoints; ep++) {
120 struct usb_host_endpoint *e;
121
122 e = alt->endpoint + ep;
Huang Rui9a37a502013-09-24 00:03:43 +0800123 switch (usb_endpoint_type(&e->desc)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 case USB_ENDPOINT_XFER_BULK:
125 break;
126 case USB_ENDPOINT_XFER_ISOC:
127 if (dev->info->iso)
128 goto try_iso;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200129 /* FALLTHROUGH */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130 default:
131 continue;
132 }
Luiz Fernando N. Capitulino4d823dd2006-10-26 13:03:02 -0300133 if (usb_endpoint_dir_in(&e->desc)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134 if (!in)
135 in = e;
136 } else {
137 if (!out)
138 out = e;
139 }
140 continue;
141try_iso:
Luiz Fernando N. Capitulino4d823dd2006-10-26 13:03:02 -0300142 if (usb_endpoint_dir_in(&e->desc)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143 if (!iso_in)
144 iso_in = e;
145 } else {
146 if (!iso_out)
147 iso_out = e;
148 }
149 }
Ming Lei951fd8e2010-08-02 22:09:17 +0800150 if ((in && out) || iso_in || iso_out)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151 goto found;
152 }
153 return -EINVAL;
154
155found:
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200156 udev = testdev_to_usbdev(dev);
Alan Sternd0b46522013-01-30 16:38:11 -0500157 dev->info->alt = alt->desc.bAlternateSetting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158 if (alt->desc.bAlternateSetting != 0) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200159 tmp = usb_set_interface(udev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160 alt->desc.bInterfaceNumber,
161 alt->desc.bAlternateSetting);
162 if (tmp < 0)
163 return tmp;
164 }
165
166 if (in) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200167 dev->in_pipe = usb_rcvbulkpipe(udev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168 in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200169 dev->out_pipe = usb_sndbulkpipe(udev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
171 }
172 if (iso_in) {
173 dev->iso_in = &iso_in->desc;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200174 dev->in_iso_pipe = usb_rcvisocpipe(udev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175 iso_in->desc.bEndpointAddress
176 & USB_ENDPOINT_NUMBER_MASK);
Ming Lei951fd8e2010-08-02 22:09:17 +0800177 }
178
179 if (iso_out) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180 dev->iso_out = &iso_out->desc;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200181 dev->out_iso_pipe = usb_sndisocpipe(udev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 iso_out->desc.bEndpointAddress
183 & USB_ENDPOINT_NUMBER_MASK);
184 }
185 return 0;
186}
187
188/*-------------------------------------------------------------------------*/
189
190/* Support for testing basic non-queued I/O streams.
191 *
192 * These just package urbs as requests that can be easily canceled.
193 * Each urb's data buffer is dynamically allocated; callers can fill
194 * them with non-zero test data (or test for it) when appropriate.
195 */
196
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200197static void simple_callback(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198{
Ming Leicdc97792008-02-24 18:41:47 +0800199 complete(urb->context);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200}
201
Martin Fuzzey084fb202011-01-16 19:17:11 +0100202static struct urb *usbtest_alloc_urb(
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203 struct usb_device *udev,
204 int pipe,
Martin Fuzzey084fb202011-01-16 19:17:11 +0100205 unsigned long bytes,
206 unsigned transfer_flags,
207 unsigned offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208{
209 struct urb *urb;
210
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200211 urb = usb_alloc_urb(0, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212 if (!urb)
213 return urb;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200214 usb_fill_bulk_urb(urb, udev, pipe, NULL, bytes, simple_callback, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215 urb->interval = (udev->speed == USB_SPEED_HIGH)
216 ? (INTERRUPT_RATE << 3)
217 : INTERRUPT_RATE;
Martin Fuzzey084fb202011-01-16 19:17:11 +0100218 urb->transfer_flags = transfer_flags;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200219 if (usb_pipein(pipe))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220 urb->transfer_flags |= URB_SHORT_NOT_OK;
Martin Fuzzey084fb202011-01-16 19:17:11 +0100221
222 if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
223 urb->transfer_buffer = usb_alloc_coherent(udev, bytes + offset,
224 GFP_KERNEL, &urb->transfer_dma);
225 else
226 urb->transfer_buffer = kmalloc(bytes + offset, GFP_KERNEL);
227
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228 if (!urb->transfer_buffer) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200229 usb_free_urb(urb);
Martin Fuzzey084fb202011-01-16 19:17:11 +0100230 return NULL;
231 }
232
233 /* To test unaligned transfers add an offset and fill the
234 unused memory with a guard value */
235 if (offset) {
236 memset(urb->transfer_buffer, GUARD_BYTE, offset);
237 urb->transfer_buffer += offset;
238 if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
239 urb->transfer_dma += offset;
240 }
241
242 /* For inbound transfers use guard byte so that test fails if
243 data not correctly copied */
244 memset(urb->transfer_buffer,
245 usb_pipein(urb->pipe) ? GUARD_BYTE : 0,
246 bytes);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247 return urb;
248}
249
Martin Fuzzey084fb202011-01-16 19:17:11 +0100250static struct urb *simple_alloc_urb(
251 struct usb_device *udev,
252 int pipe,
253 unsigned long bytes)
254{
255 return usbtest_alloc_urb(udev, pipe, bytes, URB_NO_TRANSFER_DMA_MAP, 0);
256}
257
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200258static unsigned pattern;
Vikram Pandita7f4e9852009-11-09 21:24:32 -0600259static unsigned mod_pattern;
260module_param_named(pattern, mod_pattern, uint, S_IRUGO | S_IWUSR);
261MODULE_PARM_DESC(mod_pattern, "i/o pattern (0 == zeroes)");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200263static inline void simple_fill_buf(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264{
265 unsigned i;
266 u8 *buf = urb->transfer_buffer;
267 unsigned len = urb->transfer_buffer_length;
268
269 switch (pattern) {
270 default:
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200271 /* FALLTHROUGH */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272 case 0:
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200273 memset(buf, 0, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274 break;
275 case 1: /* mod63 */
276 for (i = 0; i < len; i++)
277 *buf++ = (u8) (i % 63);
278 break;
279 }
280}
281
Greg Dietsche304b0b52011-05-08 22:51:43 -0500282static inline unsigned long buffer_offset(void *buf)
Martin Fuzzey084fb202011-01-16 19:17:11 +0100283{
Greg Dietsche304b0b52011-05-08 22:51:43 -0500284 return (unsigned long)buf & (ARCH_KMALLOC_MINALIGN - 1);
Martin Fuzzey084fb202011-01-16 19:17:11 +0100285}
286
287static int check_guard_bytes(struct usbtest_dev *tdev, struct urb *urb)
288{
289 u8 *buf = urb->transfer_buffer;
290 u8 *guard = buf - buffer_offset(buf);
291 unsigned i;
292
293 for (i = 0; guard < buf; i++, guard++) {
294 if (*guard != GUARD_BYTE) {
295 ERROR(tdev, "guard byte[%d] %d (not %d)\n",
296 i, *guard, GUARD_BYTE);
297 return -EINVAL;
298 }
299 }
300 return 0;
301}
302
303static int simple_check_buf(struct usbtest_dev *tdev, struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304{
305 unsigned i;
306 u8 expected;
307 u8 *buf = urb->transfer_buffer;
308 unsigned len = urb->actual_length;
309
Martin Fuzzey084fb202011-01-16 19:17:11 +0100310 int ret = check_guard_bytes(tdev, urb);
311 if (ret)
312 return ret;
313
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314 for (i = 0; i < len; i++, buf++) {
315 switch (pattern) {
316 /* all-zeroes has no synchronization issues */
317 case 0:
318 expected = 0;
319 break;
320 /* mod63 stays in sync with short-terminated transfers,
321 * or otherwise when host and gadget agree on how large
322 * each usb transfer request should be. resync is done
323 * with set_interface or set_config.
324 */
325 case 1: /* mod63 */
326 expected = i % 63;
327 break;
328 /* always fail unsupported patterns */
329 default:
330 expected = !*buf;
331 break;
332 }
333 if (*buf == expected)
334 continue;
David Brownell28ffd792008-04-25 18:51:10 -0700335 ERROR(tdev, "buf[%d] = %d (not %d)\n", i, *buf, expected);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 return -EINVAL;
337 }
338 return 0;
339}
340
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200341static void simple_free_urb(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342{
Greg Dietsche304b0b52011-05-08 22:51:43 -0500343 unsigned long offset = buffer_offset(urb->transfer_buffer);
Martin Fuzzey084fb202011-01-16 19:17:11 +0100344
345 if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
346 usb_free_coherent(
347 urb->dev,
348 urb->transfer_buffer_length + offset,
349 urb->transfer_buffer - offset,
350 urb->transfer_dma - offset);
351 else
352 kfree(urb->transfer_buffer - offset);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200353 usb_free_urb(urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354}
355
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200356static int simple_io(
David Brownell28ffd792008-04-25 18:51:10 -0700357 struct usbtest_dev *tdev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358 struct urb *urb,
359 int iterations,
360 int vary,
361 int expected,
362 const char *label
363)
364{
365 struct usb_device *udev = urb->dev;
366 int max = urb->transfer_buffer_length;
367 struct completion completion;
368 int retval = 0;
369
370 urb->context = &completion;
371 while (retval == 0 && iterations-- > 0) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200372 init_completion(&completion);
Sebastian Andrzej Siewior7c79d092011-08-23 10:44:54 +0200373 if (usb_pipeout(urb->pipe)) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200374 simple_fill_buf(urb);
Sebastian Andrzej Siewior7c79d092011-08-23 10:44:54 +0200375 urb->transfer_flags |= URB_ZERO_PACKET;
376 }
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200377 retval = usb_submit_urb(urb, GFP_KERNEL);
378 if (retval != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 break;
380
381 /* NOTE: no timeouts; can't be broken out of by interrupt */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200382 wait_for_completion(&completion);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 retval = urb->status;
384 urb->dev = udev;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200385 if (retval == 0 && usb_pipein(urb->pipe))
David Brownell28ffd792008-04-25 18:51:10 -0700386 retval = simple_check_buf(tdev, urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387
388 if (vary) {
389 int len = urb->transfer_buffer_length;
390
391 len += vary;
392 len %= max;
393 if (len == 0)
394 len = (vary < max) ? vary : max;
395 urb->transfer_buffer_length = len;
396 }
397
398 /* FIXME if endpoint halted, clear halt (and log) */
399 }
400 urb->transfer_buffer_length = max;
401
402 if (expected != retval)
David Brownell28ffd792008-04-25 18:51:10 -0700403 dev_err(&udev->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404 "%s failed, iterations left %d, status %d (not %d)\n",
405 label, iterations, retval, expected);
406 return retval;
407}
408
409
410/*-------------------------------------------------------------------------*/
411
412/* We use scatterlist primitives to test queued I/O.
413 * Yes, this also tests the scatterlist primitives.
414 */
415
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200416static void free_sglist(struct scatterlist *sg, int nents)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417{
418 unsigned i;
David Brownell28ffd792008-04-25 18:51:10 -0700419
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 if (!sg)
421 return;
422 for (i = 0; i < nents; i++) {
Jens Axboe45711f12007-10-22 21:19:53 +0200423 if (!sg_page(&sg[i]))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424 continue;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200425 kfree(sg_virt(&sg[i]));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426 }
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200427 kfree(sg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428}
429
430static struct scatterlist *
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200431alloc_sglist(int nents, int max, int vary)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432{
433 struct scatterlist *sg;
434 unsigned i;
435 unsigned size = max;
436
Dan Carpenter564e6982012-11-17 18:06:11 +0300437 if (max == 0)
438 return NULL;
439
Huang Ruif55055b2013-10-21 23:15:30 +0800440 sg = kmalloc_array(nents, sizeof(*sg), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441 if (!sg)
442 return NULL;
Alan Stern4756feb2008-03-27 10:15:22 -0400443 sg_init_table(sg, nents);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444
445 for (i = 0; i < nents; i++) {
446 char *buf;
David Brownell8b524902006-04-02 10:20:15 -0800447 unsigned j;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200449 buf = kzalloc(size, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450 if (!buf) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200451 free_sglist(sg, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 return NULL;
453 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454
455 /* kmalloc pages are always physically contiguous! */
Alan Stern4756feb2008-03-27 10:15:22 -0400456 sg_set_buf(&sg[i], buf, size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700457
David Brownell8b524902006-04-02 10:20:15 -0800458 switch (pattern) {
459 case 0:
460 /* already zeroed */
461 break;
462 case 1:
463 for (j = 0; j < size; j++)
464 *buf++ = (u8) (j % 63);
465 break;
466 }
467
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468 if (vary) {
469 size += vary;
470 size %= max;
471 if (size == 0)
472 size = (vary < max) ? vary : max;
473 }
474 }
475
476 return sg;
477}
478
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200479static int perform_sglist(
David Brownell28ffd792008-04-25 18:51:10 -0700480 struct usbtest_dev *tdev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481 unsigned iterations,
482 int pipe,
483 struct usb_sg_request *req,
484 struct scatterlist *sg,
485 int nents
486)
487{
David Brownell28ffd792008-04-25 18:51:10 -0700488 struct usb_device *udev = testdev_to_usbdev(tdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489 int retval = 0;
490
491 while (retval == 0 && iterations-- > 0) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200492 retval = usb_sg_init(req, udev, pipe,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493 (udev->speed == USB_SPEED_HIGH)
494 ? (INTERRUPT_RATE << 3)
495 : INTERRUPT_RATE,
Christoph Lametere94b1762006-12-06 20:33:17 -0800496 sg, nents, 0, GFP_KERNEL);
David Brownell28ffd792008-04-25 18:51:10 -0700497
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498 if (retval)
499 break;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200500 usb_sg_wait(req);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501 retval = req->status;
502
David Brownell8b524902006-04-02 10:20:15 -0800503 /* FIXME check resulting data pattern */
504
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 /* FIXME if endpoint halted, clear halt (and log) */
506 }
507
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200508 /* FIXME for unlink or fault handling tests, don't report
509 * failure if retval is as we expected ...
510 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 if (retval)
David Brownell28ffd792008-04-25 18:51:10 -0700512 ERROR(tdev, "perform_sglist failed, "
513 "iterations left %d, status %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514 iterations, retval);
515 return retval;
516}
517
518
519/*-------------------------------------------------------------------------*/
520
521/* unqueued control message testing
522 *
523 * there's a nice set of device functional requirements in chapter 9 of the
524 * usb 2.0 spec, which we can apply to ANY device, even ones that don't use
525 * special test firmware.
526 *
527 * we know the device is configured (or suspended) by the time it's visible
528 * through usbfs. we can't change that, so we won't test enumeration (which
529 * worked 'well enough' to get here, this time), power management (ditto),
530 * or remote wakeup (which needs human interaction).
531 */
532
533static unsigned realworld = 1;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200534module_param(realworld, uint, 0);
535MODULE_PARM_DESC(realworld, "clear to demand stricter spec compliance");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200537static int get_altsetting(struct usbtest_dev *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538{
539 struct usb_interface *iface = dev->intf;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200540 struct usb_device *udev = interface_to_usbdev(iface);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 int retval;
542
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200543 retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544 USB_REQ_GET_INTERFACE, USB_DIR_IN|USB_RECIP_INTERFACE,
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200545 0, iface->altsetting[0].desc.bInterfaceNumber,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546 dev->buf, 1, USB_CTRL_GET_TIMEOUT);
547 switch (retval) {
548 case 1:
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200549 return dev->buf[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550 case 0:
551 retval = -ERANGE;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200552 /* FALLTHROUGH */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553 default:
554 return retval;
555 }
556}
557
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200558static int set_altsetting(struct usbtest_dev *dev, int alternate)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559{
560 struct usb_interface *iface = dev->intf;
561 struct usb_device *udev;
562
563 if (alternate < 0 || alternate >= 256)
564 return -EINVAL;
565
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200566 udev = interface_to_usbdev(iface);
567 return usb_set_interface(udev,
568 iface->altsetting[0].desc.bInterfaceNumber,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 alternate);
570}
571
David Brownell28ffd792008-04-25 18:51:10 -0700572static int is_good_config(struct usbtest_dev *tdev, int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573{
574 struct usb_config_descriptor *config;
David Brownell28ffd792008-04-25 18:51:10 -0700575
Huang Ruif55055b2013-10-21 23:15:30 +0800576 if (len < sizeof(*config))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577 return 0;
David Brownell28ffd792008-04-25 18:51:10 -0700578 config = (struct usb_config_descriptor *) tdev->buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579
580 switch (config->bDescriptorType) {
581 case USB_DT_CONFIG:
582 case USB_DT_OTHER_SPEED_CONFIG:
583 if (config->bLength != 9) {
David Brownell28ffd792008-04-25 18:51:10 -0700584 ERROR(tdev, "bogus config descriptor length\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 return 0;
586 }
587 /* this bit 'must be 1' but often isn't */
588 if (!realworld && !(config->bmAttributes & 0x80)) {
David Brownell28ffd792008-04-25 18:51:10 -0700589 ERROR(tdev, "high bit of config attributes not set\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590 return 0;
591 }
592 if (config->bmAttributes & 0x1f) { /* reserved == 0 */
David Brownell28ffd792008-04-25 18:51:10 -0700593 ERROR(tdev, "reserved config bits set\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594 return 0;
595 }
596 break;
597 default:
598 return 0;
599 }
600
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200601 if (le16_to_cpu(config->wTotalLength) == len) /* read it all */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602 return 1;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200603 if (le16_to_cpu(config->wTotalLength) >= TBUF_SIZE) /* max partial read */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604 return 1;
David Brownell28ffd792008-04-25 18:51:10 -0700605 ERROR(tdev, "bogus config descriptor read size\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606 return 0;
607}
608
Huang Rui82f92672013-10-30 11:27:38 +0800609static int is_good_ext(struct usbtest_dev *tdev, u8 *buf)
610{
611 struct usb_ext_cap_descriptor *ext;
612 u32 attr;
613
614 ext = (struct usb_ext_cap_descriptor *) buf;
615
616 if (ext->bLength != USB_DT_USB_EXT_CAP_SIZE) {
617 ERROR(tdev, "bogus usb 2.0 extension descriptor length\n");
618 return 0;
619 }
620
621 attr = le32_to_cpu(ext->bmAttributes);
622 /* bits[1:4] is used and others are reserved */
623 if (attr & ~0x1e) { /* reserved == 0 */
624 ERROR(tdev, "reserved bits set\n");
625 return 0;
626 }
627
628 return 1;
629}
630
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631/* sanity test for standard requests working with usb_control_mesg() and some
632 * of the utility functions which use it.
633 *
634 * this doesn't test how endpoint halts behave or data toggles get set, since
635 * we won't do I/O to bulk/interrupt endpoints here (which is how to change
636 * halt or toggle). toggle testing is impractical without support from hcds.
637 *
638 * this avoids failing devices linux would normally work with, by not testing
639 * config/altsetting operations for devices that only support their defaults.
640 * such devices rarely support those needless operations.
641 *
642 * NOTE that since this is a sanity test, it's not examining boundary cases
643 * to see if usbcore, hcd, and device all behave right. such testing would
644 * involve varied read sizes and other operation sequences.
645 */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200646static int ch9_postconfig(struct usbtest_dev *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647{
648 struct usb_interface *iface = dev->intf;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200649 struct usb_device *udev = interface_to_usbdev(iface);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650 int i, alt, retval;
651
652 /* [9.2.3] if there's more than one altsetting, we need to be able to
653 * set and get each one. mostly trusts the descriptors from usbcore.
654 */
655 for (i = 0; i < iface->num_altsetting; i++) {
656
657 /* 9.2.3 constrains the range here */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200658 alt = iface->altsetting[i].desc.bAlternateSetting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700659 if (alt < 0 || alt >= iface->num_altsetting) {
David Brownell28ffd792008-04-25 18:51:10 -0700660 dev_err(&iface->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661 "invalid alt [%d].bAltSetting = %d\n",
662 i, alt);
663 }
664
665 /* [real world] get/set unimplemented if there's only one */
666 if (realworld && iface->num_altsetting == 1)
667 continue;
668
669 /* [9.4.10] set_interface */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200670 retval = set_altsetting(dev, alt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671 if (retval) {
David Brownell28ffd792008-04-25 18:51:10 -0700672 dev_err(&iface->dev, "can't set_interface = %d, %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 alt, retval);
674 return retval;
675 }
676
677 /* [9.4.4] get_interface always works */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200678 retval = get_altsetting(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 if (retval != alt) {
David Brownell28ffd792008-04-25 18:51:10 -0700680 dev_err(&iface->dev, "get alt should be %d, was %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 alt, retval);
682 return (retval < 0) ? retval : -EDOM;
683 }
684
685 }
686
687 /* [real world] get_config unimplemented if there's only one */
688 if (!realworld || udev->descriptor.bNumConfigurations != 1) {
689 int expected = udev->actconfig->desc.bConfigurationValue;
690
691 /* [9.4.2] get_configuration always works
692 * ... although some cheap devices (like one TI Hub I've got)
693 * won't return config descriptors except before set_config.
694 */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200695 retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 USB_REQ_GET_CONFIGURATION,
697 USB_DIR_IN | USB_RECIP_DEVICE,
698 0, 0, dev->buf, 1, USB_CTRL_GET_TIMEOUT);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200699 if (retval != 1 || dev->buf[0] != expected) {
David Brownell28ffd792008-04-25 18:51:10 -0700700 dev_err(&iface->dev, "get config --> %d %d (1 %d)\n",
David Brownellff7c79e2005-04-22 13:17:00 -0700701 retval, dev->buf[0], expected);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702 return (retval < 0) ? retval : -EDOM;
703 }
704 }
705
706 /* there's always [9.4.3] a device descriptor [9.6.1] */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200707 retval = usb_get_descriptor(udev, USB_DT_DEVICE, 0,
Huang Ruif55055b2013-10-21 23:15:30 +0800708 dev->buf, sizeof(udev->descriptor));
709 if (retval != sizeof(udev->descriptor)) {
David Brownell28ffd792008-04-25 18:51:10 -0700710 dev_err(&iface->dev, "dev descriptor --> %d\n", retval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 return (retval < 0) ? retval : -EDOM;
712 }
713
Huang Rui9d3bd762013-10-28 23:31:32 +0800714 /*
715 * there's always [9.4.3] a bos device descriptor [9.6.2] in USB
716 * 3.0 spec
717 */
718 if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0300) {
Huang Rui82f92672013-10-30 11:27:38 +0800719 struct usb_bos_descriptor *bos = NULL;
720 struct usb_dev_cap_header *header = NULL;
721 unsigned total, num, length;
722 u8 *buf;
723
Huang Rui9d3bd762013-10-28 23:31:32 +0800724 retval = usb_get_descriptor(udev, USB_DT_BOS, 0, dev->buf,
725 sizeof(*udev->bos->desc));
726 if (retval != sizeof(*udev->bos->desc)) {
727 dev_err(&iface->dev, "bos descriptor --> %d\n", retval);
728 return (retval < 0) ? retval : -EDOM;
729 }
Huang Rui82f92672013-10-30 11:27:38 +0800730
731 bos = (struct usb_bos_descriptor *)dev->buf;
732 total = le16_to_cpu(bos->wTotalLength);
733 num = bos->bNumDeviceCaps;
734
735 if (total > TBUF_SIZE)
736 total = TBUF_SIZE;
737
738 /*
739 * get generic device-level capability descriptors [9.6.2]
740 * in USB 3.0 spec
741 */
742 retval = usb_get_descriptor(udev, USB_DT_BOS, 0, dev->buf,
743 total);
744 if (retval != total) {
745 dev_err(&iface->dev, "bos descriptor set --> %d\n",
746 retval);
747 return (retval < 0) ? retval : -EDOM;
748 }
749
750 length = sizeof(*udev->bos->desc);
751 buf = dev->buf;
752 for (i = 0; i < num; i++) {
753 buf += length;
754 if (buf + sizeof(struct usb_dev_cap_header) >
755 dev->buf + total)
756 break;
757
758 header = (struct usb_dev_cap_header *)buf;
759 length = header->bLength;
760
761 if (header->bDescriptorType !=
762 USB_DT_DEVICE_CAPABILITY) {
763 dev_warn(&udev->dev, "not device capability descriptor, skip\n");
764 continue;
765 }
766
767 switch (header->bDevCapabilityType) {
768 case USB_CAP_TYPE_EXT:
769 if (buf + USB_DT_USB_EXT_CAP_SIZE >
770 dev->buf + total ||
771 !is_good_ext(dev, buf)) {
772 dev_err(&iface->dev, "bogus usb 2.0 extension descriptor\n");
773 return -EDOM;
774 }
775 break;
776 default:
777 break;
778 }
779 }
Huang Rui9d3bd762013-10-28 23:31:32 +0800780 }
781
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 /* there's always [9.4.3] at least one config descriptor [9.6.3] */
783 for (i = 0; i < udev->descriptor.bNumConfigurations; i++) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200784 retval = usb_get_descriptor(udev, USB_DT_CONFIG, i,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785 dev->buf, TBUF_SIZE);
David Brownell28ffd792008-04-25 18:51:10 -0700786 if (!is_good_config(dev, retval)) {
787 dev_err(&iface->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 "config [%d] descriptor --> %d\n",
789 i, retval);
790 return (retval < 0) ? retval : -EDOM;
791 }
792
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200793 /* FIXME cross-checking udev->config[i] to make sure usbcore
794 * parsed it right (etc) would be good testing paranoia
795 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 }
797
798 /* and sometimes [9.2.6.6] speed dependent descriptors */
799 if (le16_to_cpu(udev->descriptor.bcdUSB) == 0x0200) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200800 struct usb_qualifier_descriptor *d = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801
802 /* device qualifier [9.6.2] */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200803 retval = usb_get_descriptor(udev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804 USB_DT_DEVICE_QUALIFIER, 0, dev->buf,
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200805 sizeof(struct usb_qualifier_descriptor));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806 if (retval == -EPIPE) {
807 if (udev->speed == USB_SPEED_HIGH) {
David Brownell28ffd792008-04-25 18:51:10 -0700808 dev_err(&iface->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809 "hs dev qualifier --> %d\n",
810 retval);
811 return (retval < 0) ? retval : -EDOM;
812 }
813 /* usb2.0 but not high-speed capable; fine */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200814 } else if (retval != sizeof(struct usb_qualifier_descriptor)) {
David Brownell28ffd792008-04-25 18:51:10 -0700815 dev_err(&iface->dev, "dev qualifier --> %d\n", retval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816 return (retval < 0) ? retval : -EDOM;
817 } else
818 d = (struct usb_qualifier_descriptor *) dev->buf;
819
820 /* might not have [9.6.2] any other-speed configs [9.6.4] */
821 if (d) {
822 unsigned max = d->bNumConfigurations;
823 for (i = 0; i < max; i++) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200824 retval = usb_get_descriptor(udev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825 USB_DT_OTHER_SPEED_CONFIG, i,
826 dev->buf, TBUF_SIZE);
David Brownell28ffd792008-04-25 18:51:10 -0700827 if (!is_good_config(dev, retval)) {
828 dev_err(&iface->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829 "other speed config --> %d\n",
830 retval);
831 return (retval < 0) ? retval : -EDOM;
832 }
833 }
834 }
835 }
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200836 /* FIXME fetch strings from at least the device descriptor */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837
838 /* [9.4.5] get_status always works */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200839 retval = usb_get_status(udev, USB_RECIP_DEVICE, 0, dev->buf);
Alan Stern15b73362013-07-30 15:35:40 -0400840 if (retval) {
David Brownell28ffd792008-04-25 18:51:10 -0700841 dev_err(&iface->dev, "get dev status --> %d\n", retval);
Alan Stern15b73362013-07-30 15:35:40 -0400842 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843 }
844
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200845 /* FIXME configuration.bmAttributes says if we could try to set/clear
846 * the device's remote wakeup feature ... if we can, test that here
847 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200849 retval = usb_get_status(udev, USB_RECIP_INTERFACE,
850 iface->altsetting[0].desc.bInterfaceNumber, dev->buf);
Alan Stern15b73362013-07-30 15:35:40 -0400851 if (retval) {
David Brownell28ffd792008-04-25 18:51:10 -0700852 dev_err(&iface->dev, "get interface status --> %d\n", retval);
Alan Stern15b73362013-07-30 15:35:40 -0400853 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854 }
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200855 /* FIXME get status for each endpoint in the interface */
David Brownell28ffd792008-04-25 18:51:10 -0700856
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 return 0;
858}
859
860/*-------------------------------------------------------------------------*/
861
862/* use ch9 requests to test whether:
863 * (a) queues work for control, keeping N subtests queued and
864 * active (auto-resubmit) for M loops through the queue.
865 * (b) protocol stalls (control-only) will autorecover.
866 * it's not like bulk/intr; no halt clearing.
867 * (c) short control reads are reported and handled.
868 * (d) queues are always processed in-order
869 */
870
871struct ctrl_ctx {
872 spinlock_t lock;
873 struct usbtest_dev *dev;
874 struct completion complete;
875 unsigned count;
876 unsigned pending;
877 int status;
878 struct urb **urb;
879 struct usbtest_param *param;
880 int last;
881};
882
883#define NUM_SUBCASES 15 /* how many test subcases here? */
884
885struct subcase {
886 struct usb_ctrlrequest setup;
887 int number;
888 int expected;
889};
890
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200891static void ctrl_complete(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892{
893 struct ctrl_ctx *ctx = urb->context;
894 struct usb_ctrlrequest *reqp;
895 struct subcase *subcase;
896 int status = urb->status;
897
898 reqp = (struct usb_ctrlrequest *)urb->setup_packet;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200899 subcase = container_of(reqp, struct subcase, setup);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200901 spin_lock(&ctx->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902 ctx->count--;
903 ctx->pending--;
904
905 /* queue must transfer and complete in fifo order, unless
906 * usb_unlink_urb() is used to unlink something not at the
907 * physical queue head (not tested).
908 */
909 if (subcase->number > 0) {
910 if ((subcase->number - ctx->last) != 1) {
David Brownell28ffd792008-04-25 18:51:10 -0700911 ERROR(ctx->dev,
912 "subcase %d completed out of order, last %d\n",
913 subcase->number, ctx->last);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914 status = -EDOM;
915 ctx->last = subcase->number;
916 goto error;
917 }
918 }
919 ctx->last = subcase->number;
920
921 /* succeed or fault in only one way? */
922 if (status == subcase->expected)
923 status = 0;
924
925 /* async unlink for cleanup? */
926 else if (status != -ECONNRESET) {
927
928 /* some faults are allowed, not required */
929 if (subcase->expected > 0 && (
Greg Kroah-Hartman59d99782007-07-18 10:58:02 -0700930 ((status == -subcase->expected /* happened */
931 || status == 0)))) /* didn't */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932 status = 0;
933 /* sometimes more than one fault is allowed */
934 else if (subcase->number == 12 && status == -EPIPE)
935 status = 0;
936 else
David Brownell28ffd792008-04-25 18:51:10 -0700937 ERROR(ctx->dev, "subtest %d error, status %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938 subcase->number, status);
939 }
940
941 /* unexpected status codes mean errors; ideally, in hardware */
942 if (status) {
943error:
944 if (ctx->status == 0) {
945 int i;
946
947 ctx->status = status;
David Brownell28ffd792008-04-25 18:51:10 -0700948 ERROR(ctx->dev, "control queue %02x.%02x, err %d, "
949 "%d left, subcase %d, len %d/%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950 reqp->bRequestType, reqp->bRequest,
David Brownell28ffd792008-04-25 18:51:10 -0700951 status, ctx->count, subcase->number,
952 urb->actual_length,
953 urb->transfer_buffer_length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954
955 /* FIXME this "unlink everything" exit route should
956 * be a separate test case.
957 */
958
959 /* unlink whatever's still pending */
960 for (i = 1; i < ctx->param->sglen; i++) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200961 struct urb *u = ctx->urb[
962 (i + subcase->number)
963 % ctx->param->sglen];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700964
965 if (u == urb || !u->dev)
966 continue;
Franck Bui-Huucaa2a122006-05-15 19:23:53 +0200967 spin_unlock(&ctx->lock);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200968 status = usb_unlink_urb(u);
Franck Bui-Huucaa2a122006-05-15 19:23:53 +0200969 spin_lock(&ctx->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970 switch (status) {
971 case -EINPROGRESS:
972 case -EBUSY:
973 case -EIDRM:
974 continue;
975 default:
David Brownell28ffd792008-04-25 18:51:10 -0700976 ERROR(ctx->dev, "urb unlink --> %d\n",
977 status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978 }
979 }
980 status = ctx->status;
981 }
982 }
983
984 /* resubmit if we need to, else mark this as done */
985 if ((status == 0) && (ctx->pending < ctx->count)) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200986 status = usb_submit_urb(urb, GFP_ATOMIC);
987 if (status != 0) {
David Brownell28ffd792008-04-25 18:51:10 -0700988 ERROR(ctx->dev,
989 "can't resubmit ctrl %02x.%02x, err %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990 reqp->bRequestType, reqp->bRequest, status);
991 urb->dev = NULL;
992 } else
993 ctx->pending++;
994 } else
995 urb->dev = NULL;
David Brownell28ffd792008-04-25 18:51:10 -0700996
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997 /* signal completion when nothing's queued */
998 if (ctx->pending == 0)
Martin Fuzzeyfabbf212010-10-01 00:20:42 +0200999 complete(&ctx->complete);
1000 spin_unlock(&ctx->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001}
1002
1003static int
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001004test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005{
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001006 struct usb_device *udev = testdev_to_usbdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007 struct urb **urb;
1008 struct ctrl_ctx context;
1009 int i;
1010
Xi Wange65cdfa2012-04-09 15:48:55 -04001011 if (param->sglen == 0 || param->iterations > UINT_MAX / param->sglen)
1012 return -EOPNOTSUPP;
1013
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001014 spin_lock_init(&context.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015 context.dev = dev;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001016 init_completion(&context.complete);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017 context.count = param->sglen * param->iterations;
1018 context.pending = 0;
1019 context.status = -ENOMEM;
1020 context.param = param;
1021 context.last = -1;
1022
1023 /* allocate and init the urbs we'll queue.
1024 * as with bulk/intr sglists, sglen is the queue depth; it also
1025 * controls which subtests run (more tests than sglen) or rerun.
1026 */
Christoph Lametere94b1762006-12-06 20:33:17 -08001027 urb = kcalloc(param->sglen, sizeof(struct urb *), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 if (!urb)
1029 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030 for (i = 0; i < param->sglen; i++) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001031 int pipe = usb_rcvctrlpipe(udev, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 unsigned len;
1033 struct urb *u;
1034 struct usb_ctrlrequest req;
1035 struct subcase *reqp;
Marcin Slusarz6def7552008-05-12 20:17:25 +02001036
1037 /* sign of this variable means:
1038 * -: tested code must return this (negative) error code
1039 * +: tested code may return this (negative too) error code
1040 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 int expected = 0;
1042
1043 /* requests here are mostly expected to succeed on any
1044 * device, but some are chosen to trigger protocol stalls
1045 * or short reads.
1046 */
Huang Ruif55055b2013-10-21 23:15:30 +08001047 memset(&req, 0, sizeof(req));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048 req.bRequest = USB_REQ_GET_DESCRIPTOR;
1049 req.bRequestType = USB_DIR_IN|USB_RECIP_DEVICE;
1050
1051 switch (i % NUM_SUBCASES) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001052 case 0: /* get device descriptor */
1053 req.wValue = cpu_to_le16(USB_DT_DEVICE << 8);
1054 len = sizeof(struct usb_device_descriptor);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055 break;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001056 case 1: /* get first config descriptor (only) */
1057 req.wValue = cpu_to_le16((USB_DT_CONFIG << 8) | 0);
1058 len = sizeof(struct usb_config_descriptor);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059 break;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001060 case 2: /* get altsetting (OFTEN STALLS) */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061 req.bRequest = USB_REQ_GET_INTERFACE;
1062 req.bRequestType = USB_DIR_IN|USB_RECIP_INTERFACE;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001063 /* index = 0 means first interface */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064 len = 1;
1065 expected = EPIPE;
1066 break;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001067 case 3: /* get interface status */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068 req.bRequest = USB_REQ_GET_STATUS;
1069 req.bRequestType = USB_DIR_IN|USB_RECIP_INTERFACE;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001070 /* interface 0 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071 len = 2;
1072 break;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001073 case 4: /* get device status */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074 req.bRequest = USB_REQ_GET_STATUS;
1075 req.bRequestType = USB_DIR_IN|USB_RECIP_DEVICE;
1076 len = 2;
1077 break;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001078 case 5: /* get device qualifier (MAY STALL) */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079 req.wValue = cpu_to_le16 (USB_DT_DEVICE_QUALIFIER << 8);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001080 len = sizeof(struct usb_qualifier_descriptor);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081 if (udev->speed != USB_SPEED_HIGH)
1082 expected = EPIPE;
1083 break;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001084 case 6: /* get first config descriptor, plus interface */
1085 req.wValue = cpu_to_le16((USB_DT_CONFIG << 8) | 0);
1086 len = sizeof(struct usb_config_descriptor);
1087 len += sizeof(struct usb_interface_descriptor);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088 break;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001089 case 7: /* get interface descriptor (ALWAYS STALLS) */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090 req.wValue = cpu_to_le16 (USB_DT_INTERFACE << 8);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001091 /* interface == 0 */
1092 len = sizeof(struct usb_interface_descriptor);
David Brownell28ffd792008-04-25 18:51:10 -07001093 expected = -EPIPE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094 break;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001095 /* NOTE: two consecutive stalls in the queue here.
1096 * that tests fault recovery a bit more aggressively. */
1097 case 8: /* clear endpoint halt (MAY STALL) */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098 req.bRequest = USB_REQ_CLEAR_FEATURE;
1099 req.bRequestType = USB_RECIP_ENDPOINT;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001100 /* wValue 0 == ep halt */
1101 /* wIndex 0 == ep0 (shouldn't halt!) */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102 len = 0;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001103 pipe = usb_sndctrlpipe(udev, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104 expected = EPIPE;
1105 break;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001106 case 9: /* get endpoint status */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107 req.bRequest = USB_REQ_GET_STATUS;
1108 req.bRequestType = USB_DIR_IN|USB_RECIP_ENDPOINT;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001109 /* endpoint 0 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110 len = 2;
1111 break;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001112 case 10: /* trigger short read (EREMOTEIO) */
1113 req.wValue = cpu_to_le16((USB_DT_CONFIG << 8) | 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 len = 1024;
1115 expected = -EREMOTEIO;
1116 break;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001117 /* NOTE: two consecutive _different_ faults in the queue. */
1118 case 11: /* get endpoint descriptor (ALWAYS STALLS) */
1119 req.wValue = cpu_to_le16(USB_DT_ENDPOINT << 8);
1120 /* endpoint == 0 */
1121 len = sizeof(struct usb_interface_descriptor);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122 expected = EPIPE;
1123 break;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001124 /* NOTE: sometimes even a third fault in the queue! */
1125 case 12: /* get string 0 descriptor (MAY STALL) */
1126 req.wValue = cpu_to_le16(USB_DT_STRING << 8);
1127 /* string == 0, for language IDs */
1128 len = sizeof(struct usb_interface_descriptor);
1129 /* may succeed when > 4 languages */
1130 expected = EREMOTEIO; /* or EPIPE, if no strings */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131 break;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001132 case 13: /* short read, resembling case 10 */
1133 req.wValue = cpu_to_le16((USB_DT_CONFIG << 8) | 0);
1134 /* last data packet "should" be DATA1, not DATA0 */
Paul Zimmerman6a23ccd2012-04-16 14:19:07 -07001135 if (udev->speed == USB_SPEED_SUPER)
1136 len = 1024 - 512;
1137 else
1138 len = 1024 - udev->descriptor.bMaxPacketSize0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139 expected = -EREMOTEIO;
1140 break;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001141 case 14: /* short read; try to fill the last packet */
1142 req.wValue = cpu_to_le16((USB_DT_DEVICE << 8) | 0);
David Brownell28ffd792008-04-25 18:51:10 -07001143 /* device descriptor size == 18 bytes */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144 len = udev->descriptor.bMaxPacketSize0;
Sebastian Andrzej Siewior67e7d642011-04-14 16:17:21 +02001145 if (udev->speed == USB_SPEED_SUPER)
1146 len = 512;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001147 switch (len) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001148 case 8:
1149 len = 24;
1150 break;
1151 case 16:
1152 len = 32;
1153 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001154 }
1155 expected = -EREMOTEIO;
1156 break;
1157 default:
David Brownell28ffd792008-04-25 18:51:10 -07001158 ERROR(dev, "bogus number of ctrl queue testcases!\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001159 context.status = -EINVAL;
1160 goto cleanup;
1161 }
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001162 req.wLength = cpu_to_le16(len);
1163 urb[i] = u = simple_alloc_urb(udev, pipe, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 if (!u)
1165 goto cleanup;
1166
Huang Ruif55055b2013-10-21 23:15:30 +08001167 reqp = kmalloc(sizeof(*reqp), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168 if (!reqp)
1169 goto cleanup;
1170 reqp->setup = req;
1171 reqp->number = i % NUM_SUBCASES;
1172 reqp->expected = expected;
1173 u->setup_packet = (char *) &reqp->setup;
1174
1175 u->context = &context;
1176 u->complete = ctrl_complete;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177 }
1178
1179 /* queue the urbs */
1180 context.urb = urb;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001181 spin_lock_irq(&context.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182 for (i = 0; i < param->sglen; i++) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001183 context.status = usb_submit_urb(urb[i], GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184 if (context.status != 0) {
David Brownell28ffd792008-04-25 18:51:10 -07001185 ERROR(dev, "can't submit urb[%d], status %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186 i, context.status);
1187 context.count = context.pending;
1188 break;
1189 }
1190 context.pending++;
1191 }
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001192 spin_unlock_irq(&context.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193
1194 /* FIXME set timer and time out; provide a disconnect hook */
1195
1196 /* wait for the last one to complete */
1197 if (context.pending > 0)
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001198 wait_for_completion(&context.complete);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199
1200cleanup:
1201 for (i = 0; i < param->sglen; i++) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001202 if (!urb[i])
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203 continue;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001204 urb[i]->dev = udev;
Alan Stern0ede76f2010-03-05 15:10:17 -05001205 kfree(urb[i]->setup_packet);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001206 simple_free_urb(urb[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207 }
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001208 kfree(urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 return context.status;
1210}
1211#undef NUM_SUBCASES
1212
1213
1214/*-------------------------------------------------------------------------*/
1215
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001216static void unlink1_callback(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217{
1218 int status = urb->status;
1219
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001220 /* we "know" -EPIPE (stall) never happens */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 if (!status)
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001222 status = usb_submit_urb(urb, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223 if (status) {
1224 urb->status = status;
Ming Leicdc97792008-02-24 18:41:47 +08001225 complete(urb->context);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226 }
1227}
1228
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001229static int unlink1(struct usbtest_dev *dev, int pipe, int size, int async)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230{
1231 struct urb *urb;
1232 struct completion completion;
1233 int retval = 0;
1234
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001235 init_completion(&completion);
1236 urb = simple_alloc_urb(testdev_to_usbdev(dev), pipe, size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237 if (!urb)
1238 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239 urb->context = &completion;
1240 urb->complete = unlink1_callback;
1241
1242 /* keep the endpoint busy. there are lots of hc/hcd-internal
1243 * states, and testing should get to all of them over time.
1244 *
1245 * FIXME want additional tests for when endpoint is STALLing
1246 * due to errors, or is just NAKing requests.
1247 */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001248 retval = usb_submit_urb(urb, GFP_KERNEL);
1249 if (retval != 0) {
David Brownell28ffd792008-04-25 18:51:10 -07001250 dev_err(&dev->intf->dev, "submit fail %d\n", retval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251 return retval;
1252 }
1253
1254 /* unlinking that should always work. variable delay tests more
1255 * hcd states and code paths, even with little other system load.
1256 */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001257 msleep(jiffies % (2 * INTERRUPT_RATE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001258 if (async) {
Martin Fuzzey3b6c0232009-06-04 23:20:38 +02001259 while (!completion_done(&completion)) {
1260 retval = usb_unlink_urb(urb);
1261
1262 switch (retval) {
1263 case -EBUSY:
1264 case -EIDRM:
1265 /* we can't unlink urbs while they're completing
1266 * or if they've completed, and we haven't
1267 * resubmitted. "normal" drivers would prevent
1268 * resubmission, but since we're testing unlink
1269 * paths, we can't.
1270 */
1271 ERROR(dev, "unlink retry\n");
1272 continue;
1273 case 0:
1274 case -EINPROGRESS:
1275 break;
1276
1277 default:
1278 dev_err(&dev->intf->dev,
1279 "unlink fail %d\n", retval);
1280 return retval;
1281 }
1282
1283 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284 }
1285 } else
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001286 usb_kill_urb(urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001287
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001288 wait_for_completion(&completion);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001289 retval = urb->status;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001290 simple_free_urb(urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001291
1292 if (async)
1293 return (retval == -ECONNRESET) ? 0 : retval - 1000;
1294 else
1295 return (retval == -ENOENT || retval == -EPERM) ?
1296 0 : retval - 2000;
1297}
1298
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001299static int unlink_simple(struct usbtest_dev *dev, int pipe, int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001300{
1301 int retval = 0;
1302
1303 /* test sync and async paths */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001304 retval = unlink1(dev, pipe, len, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001305 if (!retval)
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001306 retval = unlink1(dev, pipe, len, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307 return retval;
1308}
1309
1310/*-------------------------------------------------------------------------*/
1311
Alan Stern869410f2011-04-14 11:21:04 -04001312struct queued_ctx {
1313 struct completion complete;
1314 atomic_t pending;
1315 unsigned num;
1316 int status;
1317 struct urb **urbs;
1318};
1319
1320static void unlink_queued_callback(struct urb *urb)
1321{
1322 int status = urb->status;
1323 struct queued_ctx *ctx = urb->context;
1324
1325 if (ctx->status)
1326 goto done;
1327 if (urb == ctx->urbs[ctx->num - 4] || urb == ctx->urbs[ctx->num - 2]) {
1328 if (status == -ECONNRESET)
1329 goto done;
1330 /* What error should we report if the URB completed normally? */
1331 }
1332 if (status != 0)
1333 ctx->status = status;
1334
1335 done:
1336 if (atomic_dec_and_test(&ctx->pending))
1337 complete(&ctx->complete);
1338}
1339
1340static int unlink_queued(struct usbtest_dev *dev, int pipe, unsigned num,
1341 unsigned size)
1342{
1343 struct queued_ctx ctx;
1344 struct usb_device *udev = testdev_to_usbdev(dev);
1345 void *buf;
1346 dma_addr_t buf_dma;
1347 int i;
1348 int retval = -ENOMEM;
1349
1350 init_completion(&ctx.complete);
1351 atomic_set(&ctx.pending, 1); /* One more than the actual value */
1352 ctx.num = num;
1353 ctx.status = 0;
1354
1355 buf = usb_alloc_coherent(udev, size, GFP_KERNEL, &buf_dma);
1356 if (!buf)
1357 return retval;
1358 memset(buf, 0, size);
1359
1360 /* Allocate and init the urbs we'll queue */
1361 ctx.urbs = kcalloc(num, sizeof(struct urb *), GFP_KERNEL);
1362 if (!ctx.urbs)
1363 goto free_buf;
1364 for (i = 0; i < num; i++) {
1365 ctx.urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
1366 if (!ctx.urbs[i])
1367 goto free_urbs;
1368 usb_fill_bulk_urb(ctx.urbs[i], udev, pipe, buf, size,
1369 unlink_queued_callback, &ctx);
1370 ctx.urbs[i]->transfer_dma = buf_dma;
1371 ctx.urbs[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
1372 }
1373
1374 /* Submit all the URBs and then unlink URBs num - 4 and num - 2. */
1375 for (i = 0; i < num; i++) {
1376 atomic_inc(&ctx.pending);
1377 retval = usb_submit_urb(ctx.urbs[i], GFP_KERNEL);
1378 if (retval != 0) {
1379 dev_err(&dev->intf->dev, "submit urbs[%d] fail %d\n",
1380 i, retval);
1381 atomic_dec(&ctx.pending);
1382 ctx.status = retval;
1383 break;
1384 }
1385 }
1386 if (i == num) {
1387 usb_unlink_urb(ctx.urbs[num - 4]);
1388 usb_unlink_urb(ctx.urbs[num - 2]);
1389 } else {
1390 while (--i >= 0)
1391 usb_unlink_urb(ctx.urbs[i]);
1392 }
1393
1394 if (atomic_dec_and_test(&ctx.pending)) /* The extra count */
1395 complete(&ctx.complete);
1396 wait_for_completion(&ctx.complete);
1397 retval = ctx.status;
1398
1399 free_urbs:
1400 for (i = 0; i < num; i++)
1401 usb_free_urb(ctx.urbs[i]);
1402 kfree(ctx.urbs);
1403 free_buf:
1404 usb_free_coherent(udev, size, buf, buf_dma);
1405 return retval;
1406}
1407
1408/*-------------------------------------------------------------------------*/
1409
David Brownell28ffd792008-04-25 18:51:10 -07001410static int verify_not_halted(struct usbtest_dev *tdev, int ep, struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411{
1412 int retval;
1413 u16 status;
1414
1415 /* shouldn't look or act halted */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001416 retval = usb_get_status(urb->dev, USB_RECIP_ENDPOINT, ep, &status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417 if (retval < 0) {
David Brownell28ffd792008-04-25 18:51:10 -07001418 ERROR(tdev, "ep %02x couldn't get no-halt status, %d\n",
1419 ep, retval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420 return retval;
1421 }
1422 if (status != 0) {
David Brownell28ffd792008-04-25 18:51:10 -07001423 ERROR(tdev, "ep %02x bogus status: %04x != 0\n", ep, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424 return -EINVAL;
1425 }
David Brownell28ffd792008-04-25 18:51:10 -07001426 retval = simple_io(tdev, urb, 1, 0, 0, __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001427 if (retval != 0)
1428 return -EINVAL;
1429 return 0;
1430}
1431
David Brownell28ffd792008-04-25 18:51:10 -07001432static int verify_halted(struct usbtest_dev *tdev, int ep, struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001433{
1434 int retval;
1435 u16 status;
1436
1437 /* should look and act halted */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001438 retval = usb_get_status(urb->dev, USB_RECIP_ENDPOINT, ep, &status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001439 if (retval < 0) {
David Brownell28ffd792008-04-25 18:51:10 -07001440 ERROR(tdev, "ep %02x couldn't get halt status, %d\n",
1441 ep, retval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442 return retval;
1443 }
1444 if (status != 1) {
David Brownell28ffd792008-04-25 18:51:10 -07001445 ERROR(tdev, "ep %02x bogus status: %04x != 1\n", ep, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446 return -EINVAL;
1447 }
David Brownell28ffd792008-04-25 18:51:10 -07001448 retval = simple_io(tdev, urb, 1, 0, -EPIPE, __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001449 if (retval != -EPIPE)
1450 return -EINVAL;
David Brownell28ffd792008-04-25 18:51:10 -07001451 retval = simple_io(tdev, urb, 1, 0, -EPIPE, "verify_still_halted");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452 if (retval != -EPIPE)
1453 return -EINVAL;
1454 return 0;
1455}
1456
David Brownell28ffd792008-04-25 18:51:10 -07001457static int test_halt(struct usbtest_dev *tdev, int ep, struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001458{
1459 int retval;
1460
1461 /* shouldn't look or act halted now */
David Brownell28ffd792008-04-25 18:51:10 -07001462 retval = verify_not_halted(tdev, ep, urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463 if (retval < 0)
1464 return retval;
1465
1466 /* set halt (protocol test only), verify it worked */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001467 retval = usb_control_msg(urb->dev, usb_sndctrlpipe(urb->dev, 0),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468 USB_REQ_SET_FEATURE, USB_RECIP_ENDPOINT,
1469 USB_ENDPOINT_HALT, ep,
1470 NULL, 0, USB_CTRL_SET_TIMEOUT);
1471 if (retval < 0) {
David Brownell28ffd792008-04-25 18:51:10 -07001472 ERROR(tdev, "ep %02x couldn't set halt, %d\n", ep, retval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473 return retval;
1474 }
David Brownell28ffd792008-04-25 18:51:10 -07001475 retval = verify_halted(tdev, ep, urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001476 if (retval < 0)
1477 return retval;
1478
1479 /* clear halt (tests API + protocol), verify it worked */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001480 retval = usb_clear_halt(urb->dev, urb->pipe);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481 if (retval < 0) {
David Brownell28ffd792008-04-25 18:51:10 -07001482 ERROR(tdev, "ep %02x couldn't clear halt, %d\n", ep, retval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001483 return retval;
1484 }
David Brownell28ffd792008-04-25 18:51:10 -07001485 retval = verify_not_halted(tdev, ep, urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486 if (retval < 0)
1487 return retval;
1488
1489 /* NOTE: could also verify SET_INTERFACE clear halts ... */
1490
1491 return 0;
1492}
1493
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001494static int halt_simple(struct usbtest_dev *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495{
Paul Zimmerman6a23ccd2012-04-16 14:19:07 -07001496 int ep;
1497 int retval = 0;
1498 struct urb *urb;
1499 struct usb_device *udev = testdev_to_usbdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500
Paul Zimmerman6a23ccd2012-04-16 14:19:07 -07001501 if (udev->speed == USB_SPEED_SUPER)
1502 urb = simple_alloc_urb(udev, 0, 1024);
1503 else
1504 urb = simple_alloc_urb(udev, 0, 512);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505 if (urb == NULL)
1506 return -ENOMEM;
1507
1508 if (dev->in_pipe) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001509 ep = usb_pipeendpoint(dev->in_pipe) | USB_DIR_IN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510 urb->pipe = dev->in_pipe;
David Brownell28ffd792008-04-25 18:51:10 -07001511 retval = test_halt(dev, ep, urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512 if (retval < 0)
1513 goto done;
1514 }
1515
1516 if (dev->out_pipe) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001517 ep = usb_pipeendpoint(dev->out_pipe);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518 urb->pipe = dev->out_pipe;
David Brownell28ffd792008-04-25 18:51:10 -07001519 retval = test_halt(dev, ep, urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520 }
1521done:
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001522 simple_free_urb(urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 return retval;
1524}
1525
1526/*-------------------------------------------------------------------------*/
1527
1528/* Control OUT tests use the vendor control requests from Intel's
1529 * USB 2.0 compliance test device: write a buffer, read it back.
1530 *
1531 * Intel's spec only _requires_ that it work for one packet, which
1532 * is pretty weak. Some HCDs place limits here; most devices will
1533 * need to be able to handle more than one OUT data packet. We'll
1534 * try whatever we're told to try.
1535 */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001536static int ctrl_out(struct usbtest_dev *dev,
Martin Fuzzey084fb202011-01-16 19:17:11 +01001537 unsigned count, unsigned length, unsigned vary, unsigned offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538{
Orjan Fribergf54fa842006-08-08 23:31:40 -07001539 unsigned i, j, len;
1540 int retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541 u8 *buf;
1542 char *what = "?";
1543 struct usb_device *udev;
Orjan Fribergf54fa842006-08-08 23:31:40 -07001544
David Brownellff7c79e2005-04-22 13:17:00 -07001545 if (length < 1 || length > 0xffff || vary >= length)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546 return -EINVAL;
1547
Martin Fuzzey084fb202011-01-16 19:17:11 +01001548 buf = kmalloc(length + offset, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549 if (!buf)
1550 return -ENOMEM;
1551
Martin Fuzzey084fb202011-01-16 19:17:11 +01001552 buf += offset;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001553 udev = testdev_to_usbdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554 len = length;
1555 retval = 0;
1556
1557 /* NOTE: hardware might well act differently if we pushed it
1558 * with lots back-to-back queued requests.
1559 */
1560 for (i = 0; i < count; i++) {
1561 /* write patterned data */
1562 for (j = 0; j < len; j++)
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001563 buf[j] = i + j;
1564 retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565 0x5b, USB_DIR_OUT|USB_TYPE_VENDOR,
1566 0, 0, buf, len, USB_CTRL_SET_TIMEOUT);
1567 if (retval != len) {
1568 what = "write";
David Brownellff7c79e2005-04-22 13:17:00 -07001569 if (retval >= 0) {
David Brownell28ffd792008-04-25 18:51:10 -07001570 ERROR(dev, "ctrl_out, wlen %d (expected %d)\n",
David Brownellff7c79e2005-04-22 13:17:00 -07001571 retval, len);
1572 retval = -EBADMSG;
1573 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 break;
1575 }
1576
1577 /* read it back -- assuming nothing intervened!! */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001578 retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579 0x5c, USB_DIR_IN|USB_TYPE_VENDOR,
1580 0, 0, buf, len, USB_CTRL_GET_TIMEOUT);
1581 if (retval != len) {
1582 what = "read";
David Brownellff7c79e2005-04-22 13:17:00 -07001583 if (retval >= 0) {
David Brownell28ffd792008-04-25 18:51:10 -07001584 ERROR(dev, "ctrl_out, rlen %d (expected %d)\n",
David Brownellff7c79e2005-04-22 13:17:00 -07001585 retval, len);
1586 retval = -EBADMSG;
1587 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001588 break;
1589 }
1590
1591 /* fail if we can't verify */
1592 for (j = 0; j < len; j++) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001593 if (buf[j] != (u8) (i + j)) {
David Brownell28ffd792008-04-25 18:51:10 -07001594 ERROR(dev, "ctrl_out, byte %d is %d not %d\n",
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001595 j, buf[j], (u8) i + j);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596 retval = -EBADMSG;
1597 break;
1598 }
1599 }
1600 if (retval < 0) {
1601 what = "verify";
1602 break;
1603 }
1604
1605 len += vary;
David Brownellff7c79e2005-04-22 13:17:00 -07001606
1607 /* [real world] the "zero bytes IN" case isn't really used.
Joe Perchesdc0d5c12007-12-17 11:40:18 -08001608 * hardware can easily trip up in this weird case, since its
David Brownellff7c79e2005-04-22 13:17:00 -07001609 * status stage is IN, not OUT like other ep0in transfers.
1610 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 if (len > length)
David Brownellff7c79e2005-04-22 13:17:00 -07001612 len = realworld ? 1 : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613 }
1614
1615 if (retval < 0)
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001616 ERROR(dev, "ctrl_out %s failed, code %d, count %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617 what, retval, i);
1618
Martin Fuzzey084fb202011-01-16 19:17:11 +01001619 kfree(buf - offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620 return retval;
1621}
1622
1623/*-------------------------------------------------------------------------*/
1624
1625/* ISO tests ... mimics common usage
1626 * - buffer length is split into N packets (mostly maxpacket sized)
1627 * - multi-buffers according to sglen
1628 */
1629
1630struct iso_context {
1631 unsigned count;
1632 unsigned pending;
1633 spinlock_t lock;
1634 struct completion done;
Alan Stern9da21502006-05-22 16:47:13 -04001635 int submit_error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636 unsigned long errors;
Alan Stern9da21502006-05-22 16:47:13 -04001637 unsigned long packet_count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638 struct usbtest_dev *dev;
1639};
1640
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001641static void iso_callback(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642{
1643 struct iso_context *ctx = urb->context;
1644
1645 spin_lock(&ctx->lock);
1646 ctx->count--;
1647
Alan Stern9da21502006-05-22 16:47:13 -04001648 ctx->packet_count += urb->number_of_packets;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649 if (urb->error_count > 0)
1650 ctx->errors += urb->error_count;
Alan Stern9da21502006-05-22 16:47:13 -04001651 else if (urb->status != 0)
1652 ctx->errors += urb->number_of_packets;
Martin Fuzzey40aed522010-10-01 00:20:48 +02001653 else if (urb->actual_length != urb->transfer_buffer_length)
1654 ctx->errors++;
Martin Fuzzey084fb202011-01-16 19:17:11 +01001655 else if (check_guard_bytes(ctx->dev, urb) != 0)
1656 ctx->errors++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657
Alan Stern9da21502006-05-22 16:47:13 -04001658 if (urb->status == 0 && ctx->count > (ctx->pending - 1)
1659 && !ctx->submit_error) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001660 int status = usb_submit_urb(urb, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661 switch (status) {
1662 case 0:
1663 goto done;
1664 default:
David Brownell28ffd792008-04-25 18:51:10 -07001665 dev_err(&ctx->dev->intf->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666 "iso resubmit err %d\n",
1667 status);
1668 /* FALLTHROUGH */
1669 case -ENODEV: /* disconnected */
Alan Stern9da21502006-05-22 16:47:13 -04001670 case -ESHUTDOWN: /* endpoint disabled */
1671 ctx->submit_error = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672 break;
1673 }
1674 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675
1676 ctx->pending--;
1677 if (ctx->pending == 0) {
1678 if (ctx->errors)
David Brownell28ffd792008-04-25 18:51:10 -07001679 dev_err(&ctx->dev->intf->dev,
Alan Stern9da21502006-05-22 16:47:13 -04001680 "iso test, %lu errors out of %lu\n",
1681 ctx->errors, ctx->packet_count);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001682 complete(&ctx->done);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 }
1684done:
1685 spin_unlock(&ctx->lock);
1686}
1687
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001688static struct urb *iso_alloc_urb(
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689 struct usb_device *udev,
1690 int pipe,
1691 struct usb_endpoint_descriptor *desc,
Martin Fuzzey084fb202011-01-16 19:17:11 +01001692 long bytes,
1693 unsigned offset
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694)
1695{
1696 struct urb *urb;
1697 unsigned i, maxp, packets;
1698
1699 if (bytes < 0 || !desc)
1700 return NULL;
Kuninori Morimoto29cc8892011-08-23 03:12:03 -07001701 maxp = 0x7ff & usb_endpoint_maxp(desc);
1702 maxp *= 1 + (0x3 & (usb_endpoint_maxp(desc) >> 11));
Julia Lawalldfa5ec72008-03-04 15:25:11 -08001703 packets = DIV_ROUND_UP(bytes, maxp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001705 urb = usb_alloc_urb(packets, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706 if (!urb)
1707 return urb;
1708 urb->dev = udev;
1709 urb->pipe = pipe;
1710
1711 urb->number_of_packets = packets;
1712 urb->transfer_buffer_length = bytes;
Martin Fuzzey084fb202011-01-16 19:17:11 +01001713 urb->transfer_buffer = usb_alloc_coherent(udev, bytes + offset,
1714 GFP_KERNEL,
1715 &urb->transfer_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 if (!urb->transfer_buffer) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001717 usb_free_urb(urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 return NULL;
1719 }
Martin Fuzzey084fb202011-01-16 19:17:11 +01001720 if (offset) {
1721 memset(urb->transfer_buffer, GUARD_BYTE, offset);
1722 urb->transfer_buffer += offset;
1723 urb->transfer_dma += offset;
1724 }
1725 /* For inbound transfers use guard byte so that test fails if
1726 data not correctly copied */
1727 memset(urb->transfer_buffer,
1728 usb_pipein(urb->pipe) ? GUARD_BYTE : 0,
1729 bytes);
1730
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 for (i = 0; i < packets; i++) {
1732 /* here, only the last packet will be short */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001733 urb->iso_frame_desc[i].length = min((unsigned) bytes, maxp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734 bytes -= urb->iso_frame_desc[i].length;
1735
1736 urb->iso_frame_desc[i].offset = maxp * i;
1737 }
1738
1739 urb->complete = iso_callback;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001740 /* urb->context = SET BY CALLER */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 urb->interval = 1 << (desc->bInterval - 1);
1742 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
1743 return urb;
1744}
1745
1746static int
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001747test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param,
Martin Fuzzey084fb202011-01-16 19:17:11 +01001748 int pipe, struct usb_endpoint_descriptor *desc, unsigned offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749{
1750 struct iso_context context;
1751 struct usb_device *udev;
1752 unsigned i;
1753 unsigned long packets = 0;
Alan Stern9da21502006-05-22 16:47:13 -04001754 int status = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 struct urb *urbs[10]; /* FIXME no limit */
1756
1757 if (param->sglen > 10)
1758 return -EDOM;
1759
Huang Ruif55055b2013-10-21 23:15:30 +08001760 memset(&context, 0, sizeof(context));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761 context.count = param->iterations * param->sglen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762 context.dev = dev;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001763 init_completion(&context.done);
1764 spin_lock_init(&context.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001765
Huang Ruif55055b2013-10-21 23:15:30 +08001766 memset(urbs, 0, sizeof(urbs));
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001767 udev = testdev_to_usbdev(dev);
David Brownell28ffd792008-04-25 18:51:10 -07001768 dev_info(&dev->intf->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769 "... iso period %d %sframes, wMaxPacket %04x\n",
1770 1 << (desc->bInterval - 1),
1771 (udev->speed == USB_SPEED_HIGH) ? "micro" : "",
Kuninori Morimoto29cc8892011-08-23 03:12:03 -07001772 usb_endpoint_maxp(desc));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773
1774 for (i = 0; i < param->sglen; i++) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001775 urbs[i] = iso_alloc_urb(udev, pipe, desc,
Martin Fuzzey084fb202011-01-16 19:17:11 +01001776 param->length, offset);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001777 if (!urbs[i]) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778 status = -ENOMEM;
1779 goto fail;
1780 }
1781 packets += urbs[i]->number_of_packets;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001782 urbs[i]->context = &context;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783 }
1784 packets *= param->iterations;
David Brownell28ffd792008-04-25 18:51:10 -07001785 dev_info(&dev->intf->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786 "... total %lu msec (%lu packets)\n",
1787 (packets * (1 << (desc->bInterval - 1)))
1788 / ((udev->speed == USB_SPEED_HIGH) ? 8 : 1),
1789 packets);
1790
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001791 spin_lock_irq(&context.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 for (i = 0; i < param->sglen; i++) {
Alan Stern9da21502006-05-22 16:47:13 -04001793 ++context.pending;
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001794 status = usb_submit_urb(urbs[i], GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795 if (status < 0) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001796 ERROR(dev, "submit iso[%d], error %d\n", i, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797 if (i == 0) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001798 spin_unlock_irq(&context.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799 goto fail;
1800 }
1801
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001802 simple_free_urb(urbs[i]);
Ming Leie10e1be2010-08-02 22:09:01 +08001803 urbs[i] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804 context.pending--;
Alan Stern9da21502006-05-22 16:47:13 -04001805 context.submit_error = 1;
1806 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 }
1808 }
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001809 spin_unlock_irq(&context.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001811 wait_for_completion(&context.done);
Alan Stern9da21502006-05-22 16:47:13 -04001812
Ming Leie10e1be2010-08-02 22:09:01 +08001813 for (i = 0; i < param->sglen; i++) {
1814 if (urbs[i])
1815 simple_free_urb(urbs[i]);
1816 }
Alan Stern9da21502006-05-22 16:47:13 -04001817 /*
1818 * Isochronous transfers are expected to fail sometimes. As an
1819 * arbitrary limit, we will report an error if any submissions
1820 * fail or if the transfer failure rate is > 10%.
1821 */
1822 if (status != 0)
1823 ;
1824 else if (context.submit_error)
1825 status = -EACCES;
1826 else if (context.errors > context.packet_count / 10)
1827 status = -EIO;
1828 return status;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829
1830fail:
1831 for (i = 0; i < param->sglen; i++) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001832 if (urbs[i])
1833 simple_free_urb(urbs[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834 }
1835 return status;
1836}
1837
Martin Fuzzey084fb202011-01-16 19:17:11 +01001838static int test_unaligned_bulk(
1839 struct usbtest_dev *tdev,
1840 int pipe,
1841 unsigned length,
1842 int iterations,
1843 unsigned transfer_flags,
1844 const char *label)
1845{
1846 int retval;
1847 struct urb *urb = usbtest_alloc_urb(
1848 testdev_to_usbdev(tdev), pipe, length, transfer_flags, 1);
1849
1850 if (!urb)
1851 return -ENOMEM;
1852
1853 retval = simple_io(tdev, urb, iterations, 0, 0, label);
1854 simple_free_urb(urb);
1855 return retval;
1856}
1857
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858/*-------------------------------------------------------------------------*/
1859
1860/* We only have this one interface to user space, through usbfs.
1861 * User mode code can scan usbfs to find N different devices (maybe on
1862 * different busses) to use when testing, and allocate one thread per
1863 * test. So discovery is simplified, and we have no device naming issues.
1864 *
1865 * Don't use these only as stress/load tests. Use them along with with
1866 * other USB bus activity: plugging, unplugging, mousing, mp3 playback,
1867 * video capture, and so on. Run different tests at different times, in
1868 * different sequences. Nothing here should interact with other devices,
1869 * except indirectly by consuming USB bandwidth and CPU resources for test
1870 * threads and request completion. But the only way to know that for sure
1871 * is to test when HC queues are in use by many devices.
David Brownell28ffd792008-04-25 18:51:10 -07001872 *
1873 * WARNING: Because usbfs grabs udev->dev.sem before calling this ioctl(),
1874 * it locks out usbcore in certain code paths. Notably, if you disconnect
1875 * the device-under-test, khubd will wait block forever waiting for the
1876 * ioctl to complete ... so that usb_disconnect() can abort the pending
1877 * urbs and then call usbtest_disconnect(). To abort a test, you're best
1878 * off just killing the userspace task and waiting for it to exit.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879 */
1880
1881static int
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001882usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001883{
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001884 struct usbtest_dev *dev = usb_get_intfdata(intf);
1885 struct usb_device *udev = testdev_to_usbdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886 struct usbtest_param *param = buf;
1887 int retval = -EOPNOTSUPP;
1888 struct urb *urb;
1889 struct scatterlist *sg;
1890 struct usb_sg_request req;
1891 struct timeval start;
1892 unsigned i;
1893
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001894 /* FIXME USBDEVFS_CONNECTINFO doesn't say how fast the device is. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895
Vikram Pandita7f4e9852009-11-09 21:24:32 -06001896 pattern = mod_pattern;
1897
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898 if (code != USBTEST_REQUEST)
1899 return -EOPNOTSUPP;
1900
roel kluin8aafdf62008-10-21 00:36:44 -04001901 if (param->iterations <= 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902 return -EINVAL;
1903
Matthias Kaehlcke1cfab022007-12-13 16:15:33 -08001904 if (mutex_lock_interruptible(&dev->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905 return -ERESTARTSYS;
1906
Alan Stern70a1c9e2008-03-06 17:00:58 -05001907 /* FIXME: What if a system sleep starts while a test is running? */
David Brownellff7c79e2005-04-22 13:17:00 -07001908
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909 /* some devices, like ez-usb default devices, need a non-default
1910 * altsetting to have any active endpoints. some tests change
1911 * altsettings; force a default so most tests don't need to check.
1912 */
1913 if (dev->info->alt >= 0) {
David Brownell28ffd792008-04-25 18:51:10 -07001914 int res;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915
1916 if (intf->altsetting->desc.bInterfaceNumber) {
Matthias Kaehlcke1cfab022007-12-13 16:15:33 -08001917 mutex_unlock(&dev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918 return -ENODEV;
1919 }
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001920 res = set_altsetting(dev, dev->info->alt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921 if (res) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001922 dev_err(&intf->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923 "set altsetting to %d failed, %d\n",
1924 dev->info->alt, res);
Matthias Kaehlcke1cfab022007-12-13 16:15:33 -08001925 mutex_unlock(&dev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926 return res;
1927 }
1928 }
1929
1930 /*
1931 * Just a bunch of test cases that every HCD is expected to handle.
1932 *
1933 * Some may need specific firmware, though it'd be good to have
1934 * one firmware image to handle all the test cases.
1935 *
1936 * FIXME add more tests! cancel requests, verify the data, control
1937 * queueing, concurrent read+write threads, and so on.
1938 */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001939 do_gettimeofday(&start);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940 switch (param->test_num) {
1941
1942 case 0:
David Brownell28ffd792008-04-25 18:51:10 -07001943 dev_info(&intf->dev, "TEST 0: NOP\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944 retval = 0;
1945 break;
1946
1947 /* Simple non-queued bulk I/O tests */
1948 case 1:
1949 if (dev->out_pipe == 0)
1950 break;
David Brownell28ffd792008-04-25 18:51:10 -07001951 dev_info(&intf->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001952 "TEST 1: write %d bytes %u times\n",
1953 param->length, param->iterations);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001954 urb = simple_alloc_urb(udev, dev->out_pipe, param->length);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001955 if (!urb) {
1956 retval = -ENOMEM;
1957 break;
1958 }
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001959 /* FIRMWARE: bulk sink (maybe accepts short writes) */
David Brownell28ffd792008-04-25 18:51:10 -07001960 retval = simple_io(dev, urb, param->iterations, 0, 0, "test1");
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001961 simple_free_urb(urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001962 break;
1963 case 2:
1964 if (dev->in_pipe == 0)
1965 break;
David Brownell28ffd792008-04-25 18:51:10 -07001966 dev_info(&intf->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001967 "TEST 2: read %d bytes %u times\n",
1968 param->length, param->iterations);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001969 urb = simple_alloc_urb(udev, dev->in_pipe, param->length);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001970 if (!urb) {
1971 retval = -ENOMEM;
1972 break;
1973 }
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001974 /* FIRMWARE: bulk source (maybe generates short writes) */
David Brownell28ffd792008-04-25 18:51:10 -07001975 retval = simple_io(dev, urb, param->iterations, 0, 0, "test2");
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001976 simple_free_urb(urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977 break;
1978 case 3:
1979 if (dev->out_pipe == 0 || param->vary == 0)
1980 break;
David Brownell28ffd792008-04-25 18:51:10 -07001981 dev_info(&intf->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001982 "TEST 3: write/%d 0..%d bytes %u times\n",
1983 param->vary, param->length, param->iterations);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001984 urb = simple_alloc_urb(udev, dev->out_pipe, param->length);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001985 if (!urb) {
1986 retval = -ENOMEM;
1987 break;
1988 }
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001989 /* FIRMWARE: bulk sink (maybe accepts short writes) */
David Brownell28ffd792008-04-25 18:51:10 -07001990 retval = simple_io(dev, urb, param->iterations, param->vary,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001991 0, "test3");
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02001992 simple_free_urb(urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001993 break;
1994 case 4:
1995 if (dev->in_pipe == 0 || param->vary == 0)
1996 break;
David Brownell28ffd792008-04-25 18:51:10 -07001997 dev_info(&intf->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001998 "TEST 4: read/%d 0..%d bytes %u times\n",
1999 param->vary, param->length, param->iterations);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002000 urb = simple_alloc_urb(udev, dev->in_pipe, param->length);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002001 if (!urb) {
2002 retval = -ENOMEM;
2003 break;
2004 }
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002005 /* FIRMWARE: bulk source (maybe generates short writes) */
David Brownell28ffd792008-04-25 18:51:10 -07002006 retval = simple_io(dev, urb, param->iterations, param->vary,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002007 0, "test4");
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002008 simple_free_urb(urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002009 break;
2010
2011 /* Queued bulk I/O tests */
2012 case 5:
2013 if (dev->out_pipe == 0 || param->sglen == 0)
2014 break;
David Brownell28ffd792008-04-25 18:51:10 -07002015 dev_info(&intf->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002016 "TEST 5: write %d sglists %d entries of %d bytes\n",
2017 param->iterations,
2018 param->sglen, param->length);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002019 sg = alloc_sglist(param->sglen, param->length, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020 if (!sg) {
2021 retval = -ENOMEM;
2022 break;
2023 }
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002024 /* FIRMWARE: bulk sink (maybe accepts short writes) */
David Brownell28ffd792008-04-25 18:51:10 -07002025 retval = perform_sglist(dev, param->iterations, dev->out_pipe,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002026 &req, sg, param->sglen);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002027 free_sglist(sg, param->sglen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002028 break;
2029
2030 case 6:
2031 if (dev->in_pipe == 0 || param->sglen == 0)
2032 break;
David Brownell28ffd792008-04-25 18:51:10 -07002033 dev_info(&intf->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002034 "TEST 6: read %d sglists %d entries of %d bytes\n",
2035 param->iterations,
2036 param->sglen, param->length);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002037 sg = alloc_sglist(param->sglen, param->length, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002038 if (!sg) {
2039 retval = -ENOMEM;
2040 break;
2041 }
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002042 /* FIRMWARE: bulk source (maybe generates short writes) */
David Brownell28ffd792008-04-25 18:51:10 -07002043 retval = perform_sglist(dev, param->iterations, dev->in_pipe,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002044 &req, sg, param->sglen);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002045 free_sglist(sg, param->sglen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002046 break;
2047 case 7:
2048 if (dev->out_pipe == 0 || param->sglen == 0 || param->vary == 0)
2049 break;
David Brownell28ffd792008-04-25 18:51:10 -07002050 dev_info(&intf->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002051 "TEST 7: write/%d %d sglists %d entries 0..%d bytes\n",
2052 param->vary, param->iterations,
2053 param->sglen, param->length);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002054 sg = alloc_sglist(param->sglen, param->length, param->vary);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002055 if (!sg) {
2056 retval = -ENOMEM;
2057 break;
2058 }
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002059 /* FIRMWARE: bulk sink (maybe accepts short writes) */
David Brownell28ffd792008-04-25 18:51:10 -07002060 retval = perform_sglist(dev, param->iterations, dev->out_pipe,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002061 &req, sg, param->sglen);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002062 free_sglist(sg, param->sglen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002063 break;
2064 case 8:
2065 if (dev->in_pipe == 0 || param->sglen == 0 || param->vary == 0)
2066 break;
David Brownell28ffd792008-04-25 18:51:10 -07002067 dev_info(&intf->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002068 "TEST 8: read/%d %d sglists %d entries 0..%d bytes\n",
2069 param->vary, param->iterations,
2070 param->sglen, param->length);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002071 sg = alloc_sglist(param->sglen, param->length, param->vary);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002072 if (!sg) {
2073 retval = -ENOMEM;
2074 break;
2075 }
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002076 /* FIRMWARE: bulk source (maybe generates short writes) */
David Brownell28ffd792008-04-25 18:51:10 -07002077 retval = perform_sglist(dev, param->iterations, dev->in_pipe,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002078 &req, sg, param->sglen);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002079 free_sglist(sg, param->sglen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002080 break;
2081
2082 /* non-queued sanity tests for control (chapter 9 subset) */
2083 case 9:
2084 retval = 0;
David Brownell28ffd792008-04-25 18:51:10 -07002085 dev_info(&intf->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086 "TEST 9: ch9 (subset) control tests, %d times\n",
2087 param->iterations);
2088 for (i = param->iterations; retval == 0 && i--; /* NOP */)
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002089 retval = ch9_postconfig(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002090 if (retval)
David Brownell28ffd792008-04-25 18:51:10 -07002091 dev_err(&intf->dev, "ch9 subset failed, "
2092 "iterations left %d\n", i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002093 break;
2094
2095 /* queued control messaging */
2096 case 10:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097 retval = 0;
David Brownell28ffd792008-04-25 18:51:10 -07002098 dev_info(&intf->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002099 "TEST 10: queue %d control calls, %d times\n",
2100 param->sglen,
2101 param->iterations);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002102 retval = test_ctrl_queue(dev, param);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002103 break;
2104
2105 /* simple non-queued unlinks (ring with one urb) */
2106 case 11:
2107 if (dev->in_pipe == 0 || !param->length)
2108 break;
2109 retval = 0;
David Brownell28ffd792008-04-25 18:51:10 -07002110 dev_info(&intf->dev, "TEST 11: unlink %d reads of %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002111 param->iterations, param->length);
2112 for (i = param->iterations; retval == 0 && i--; /* NOP */)
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002113 retval = unlink_simple(dev, dev->in_pipe,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002114 param->length);
2115 if (retval)
David Brownell28ffd792008-04-25 18:51:10 -07002116 dev_err(&intf->dev, "unlink reads failed %d, "
Linus Torvalds1da177e2005-04-16 15:20:36 -07002117 "iterations left %d\n", retval, i);
2118 break;
2119 case 12:
2120 if (dev->out_pipe == 0 || !param->length)
2121 break;
2122 retval = 0;
David Brownell28ffd792008-04-25 18:51:10 -07002123 dev_info(&intf->dev, "TEST 12: unlink %d writes of %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124 param->iterations, param->length);
2125 for (i = param->iterations; retval == 0 && i--; /* NOP */)
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002126 retval = unlink_simple(dev, dev->out_pipe,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002127 param->length);
2128 if (retval)
David Brownell28ffd792008-04-25 18:51:10 -07002129 dev_err(&intf->dev, "unlink writes failed %d, "
Linus Torvalds1da177e2005-04-16 15:20:36 -07002130 "iterations left %d\n", retval, i);
2131 break;
2132
2133 /* ep halt tests */
2134 case 13:
2135 if (dev->out_pipe == 0 && dev->in_pipe == 0)
2136 break;
2137 retval = 0;
David Brownell28ffd792008-04-25 18:51:10 -07002138 dev_info(&intf->dev, "TEST 13: set/clear %d halts\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002139 param->iterations);
2140 for (i = param->iterations; retval == 0 && i--; /* NOP */)
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002141 retval = halt_simple(dev);
David Brownell28ffd792008-04-25 18:51:10 -07002142
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143 if (retval)
David Brownell28ffd792008-04-25 18:51:10 -07002144 ERROR(dev, "halts failed, iterations left %d\n", i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002145 break;
2146
2147 /* control write tests */
2148 case 14:
2149 if (!dev->info->ctrl_out)
2150 break;
David Brownell28ffd792008-04-25 18:51:10 -07002151 dev_info(&intf->dev, "TEST 14: %d ep0out, %d..%d vary %d\n",
David Brownellff7c79e2005-04-22 13:17:00 -07002152 param->iterations,
2153 realworld ? 1 : 0, param->length,
2154 param->vary);
David Brownell28ffd792008-04-25 18:51:10 -07002155 retval = ctrl_out(dev, param->iterations,
Martin Fuzzey084fb202011-01-16 19:17:11 +01002156 param->length, param->vary, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002157 break;
2158
2159 /* iso write tests */
2160 case 15:
2161 if (dev->out_iso_pipe == 0 || param->sglen == 0)
2162 break;
David Brownell28ffd792008-04-25 18:51:10 -07002163 dev_info(&intf->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002164 "TEST 15: write %d iso, %d entries of %d bytes\n",
2165 param->iterations,
2166 param->sglen, param->length);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002167 /* FIRMWARE: iso sink */
2168 retval = test_iso_queue(dev, param,
Martin Fuzzey084fb202011-01-16 19:17:11 +01002169 dev->out_iso_pipe, dev->iso_out, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002170 break;
2171
2172 /* iso read tests */
2173 case 16:
2174 if (dev->in_iso_pipe == 0 || param->sglen == 0)
2175 break;
David Brownell28ffd792008-04-25 18:51:10 -07002176 dev_info(&intf->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002177 "TEST 16: read %d iso, %d entries of %d bytes\n",
2178 param->iterations,
2179 param->sglen, param->length);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002180 /* FIRMWARE: iso source */
2181 retval = test_iso_queue(dev, param,
Martin Fuzzey084fb202011-01-16 19:17:11 +01002182 dev->in_iso_pipe, dev->iso_in, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002183 break;
2184
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002185 /* FIXME scatterlist cancel (needs helper thread) */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002186
Martin Fuzzey084fb202011-01-16 19:17:11 +01002187 /* Tests for bulk I/O using DMA mapping by core and odd address */
2188 case 17:
2189 if (dev->out_pipe == 0)
2190 break;
2191 dev_info(&intf->dev,
2192 "TEST 17: write odd addr %d bytes %u times core map\n",
2193 param->length, param->iterations);
2194
2195 retval = test_unaligned_bulk(
2196 dev, dev->out_pipe,
2197 param->length, param->iterations,
2198 0, "test17");
2199 break;
2200
2201 case 18:
2202 if (dev->in_pipe == 0)
2203 break;
2204 dev_info(&intf->dev,
2205 "TEST 18: read odd addr %d bytes %u times core map\n",
2206 param->length, param->iterations);
2207
2208 retval = test_unaligned_bulk(
2209 dev, dev->in_pipe,
2210 param->length, param->iterations,
2211 0, "test18");
2212 break;
2213
2214 /* Tests for bulk I/O using premapped coherent buffer and odd address */
2215 case 19:
2216 if (dev->out_pipe == 0)
2217 break;
2218 dev_info(&intf->dev,
2219 "TEST 19: write odd addr %d bytes %u times premapped\n",
2220 param->length, param->iterations);
2221
2222 retval = test_unaligned_bulk(
2223 dev, dev->out_pipe,
2224 param->length, param->iterations,
2225 URB_NO_TRANSFER_DMA_MAP, "test19");
2226 break;
2227
2228 case 20:
2229 if (dev->in_pipe == 0)
2230 break;
2231 dev_info(&intf->dev,
2232 "TEST 20: read odd addr %d bytes %u times premapped\n",
2233 param->length, param->iterations);
2234
2235 retval = test_unaligned_bulk(
2236 dev, dev->in_pipe,
2237 param->length, param->iterations,
2238 URB_NO_TRANSFER_DMA_MAP, "test20");
2239 break;
2240
2241 /* control write tests with unaligned buffer */
2242 case 21:
2243 if (!dev->info->ctrl_out)
2244 break;
2245 dev_info(&intf->dev,
2246 "TEST 21: %d ep0out odd addr, %d..%d vary %d\n",
2247 param->iterations,
2248 realworld ? 1 : 0, param->length,
2249 param->vary);
2250 retval = ctrl_out(dev, param->iterations,
2251 param->length, param->vary, 1);
2252 break;
2253
2254 /* unaligned iso tests */
2255 case 22:
2256 if (dev->out_iso_pipe == 0 || param->sglen == 0)
2257 break;
2258 dev_info(&intf->dev,
2259 "TEST 22: write %d iso odd, %d entries of %d bytes\n",
2260 param->iterations,
2261 param->sglen, param->length);
2262 retval = test_iso_queue(dev, param,
2263 dev->out_iso_pipe, dev->iso_out, 1);
2264 break;
2265
2266 case 23:
2267 if (dev->in_iso_pipe == 0 || param->sglen == 0)
2268 break;
2269 dev_info(&intf->dev,
2270 "TEST 23: read %d iso odd, %d entries of %d bytes\n",
2271 param->iterations,
2272 param->sglen, param->length);
2273 retval = test_iso_queue(dev, param,
2274 dev->in_iso_pipe, dev->iso_in, 1);
2275 break;
2276
Alan Stern869410f2011-04-14 11:21:04 -04002277 /* unlink URBs from a bulk-OUT queue */
2278 case 24:
2279 if (dev->out_pipe == 0 || !param->length || param->sglen < 4)
2280 break;
2281 retval = 0;
Alan Stern2cb50002013-01-02 13:58:18 -05002282 dev_info(&intf->dev, "TEST 24: unlink from %d queues of "
Alan Stern869410f2011-04-14 11:21:04 -04002283 "%d %d-byte writes\n",
2284 param->iterations, param->sglen, param->length);
2285 for (i = param->iterations; retval == 0 && i > 0; --i) {
2286 retval = unlink_queued(dev, dev->out_pipe,
2287 param->sglen, param->length);
2288 if (retval) {
2289 dev_err(&intf->dev,
2290 "unlink queued writes failed %d, "
2291 "iterations left %d\n", retval, i);
2292 break;
2293 }
2294 }
2295 break;
2296
Linus Torvalds1da177e2005-04-16 15:20:36 -07002297 }
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002298 do_gettimeofday(&param->duration);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002299 param->duration.tv_sec -= start.tv_sec;
2300 param->duration.tv_usec -= start.tv_usec;
2301 if (param->duration.tv_usec < 0) {
2302 param->duration.tv_usec += 1000 * 1000;
2303 param->duration.tv_sec -= 1;
2304 }
Matthias Kaehlcke1cfab022007-12-13 16:15:33 -08002305 mutex_unlock(&dev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002306 return retval;
2307}
2308
2309/*-------------------------------------------------------------------------*/
2310
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002311static unsigned force_interrupt;
2312module_param(force_interrupt, uint, 0);
2313MODULE_PARM_DESC(force_interrupt, "0 = test default; else interrupt");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002314
2315#ifdef GENERIC
2316static unsigned short vendor;
2317module_param(vendor, ushort, 0);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002318MODULE_PARM_DESC(vendor, "vendor code (from usb-if)");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319
2320static unsigned short product;
2321module_param(product, ushort, 0);
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002322MODULE_PARM_DESC(product, "product code (from vendor)");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323#endif
2324
2325static int
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002326usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002327{
2328 struct usb_device *udev;
2329 struct usbtest_dev *dev;
2330 struct usbtest_info *info;
2331 char *rtest, *wtest;
2332 char *irtest, *iwtest;
2333
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002334 udev = interface_to_usbdev(intf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002335
2336#ifdef GENERIC
2337 /* specify devices by module parameters? */
2338 if (id->match_flags == 0) {
2339 /* vendor match required, product match optional */
2340 if (!vendor || le16_to_cpu(udev->descriptor.idVendor) != (u16)vendor)
2341 return -ENODEV;
2342 if (product && le16_to_cpu(udev->descriptor.idProduct) != (u16)product)
2343 return -ENODEV;
David Brownell28ffd792008-04-25 18:51:10 -07002344 dev_info(&intf->dev, "matched module params, "
2345 "vend=0x%04x prod=0x%04x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002346 le16_to_cpu(udev->descriptor.idVendor),
2347 le16_to_cpu(udev->descriptor.idProduct));
2348 }
2349#endif
2350
Christoph Lametere94b1762006-12-06 20:33:17 -08002351 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002352 if (!dev)
2353 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002354 info = (struct usbtest_info *) id->driver_info;
2355 dev->info = info;
Matthias Kaehlcke1cfab022007-12-13 16:15:33 -08002356 mutex_init(&dev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002357
2358 dev->intf = intf;
2359
2360 /* cacheline-aligned scratch for i/o */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002361 dev->buf = kmalloc(TBUF_SIZE, GFP_KERNEL);
2362 if (dev->buf == NULL) {
2363 kfree(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002364 return -ENOMEM;
2365 }
2366
2367 /* NOTE this doesn't yet test the handful of difference that are
2368 * visible with high speed interrupts: bigger maxpacket (1K) and
2369 * "high bandwidth" modes (up to 3 packets/uframe).
2370 */
2371 rtest = wtest = "";
2372 irtest = iwtest = "";
2373 if (force_interrupt || udev->speed == USB_SPEED_LOW) {
2374 if (info->ep_in) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002375 dev->in_pipe = usb_rcvintpipe(udev, info->ep_in);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002376 rtest = " intr-in";
2377 }
2378 if (info->ep_out) {
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002379 dev->out_pipe = usb_sndintpipe(udev, info->ep_out);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002380 wtest = " intr-out";
2381 }
2382 } else {
Alan Sternd0b46522013-01-30 16:38:11 -05002383 if (override_alt >= 0 || info->autoconf) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002384 int status;
2385
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002386 status = get_endpoints(dev, intf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002387 if (status < 0) {
Arjan van de Venb6c63932008-07-25 01:45:52 -07002388 WARNING(dev, "couldn't get endpoints, %d\n",
David Brownell28ffd792008-04-25 18:51:10 -07002389 status);
Julia Lawallf4a728d2012-03-25 21:08:32 +02002390 kfree(dev->buf);
2391 kfree(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002392 return status;
2393 }
2394 /* may find bulk or ISO pipes */
2395 } else {
2396 if (info->ep_in)
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002397 dev->in_pipe = usb_rcvbulkpipe(udev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002398 info->ep_in);
2399 if (info->ep_out)
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002400 dev->out_pipe = usb_sndbulkpipe(udev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401 info->ep_out);
2402 }
2403 if (dev->in_pipe)
2404 rtest = " bulk-in";
2405 if (dev->out_pipe)
2406 wtest = " bulk-out";
2407 if (dev->in_iso_pipe)
2408 irtest = " iso-in";
2409 if (dev->out_iso_pipe)
2410 iwtest = " iso-out";
2411 }
2412
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002413 usb_set_intfdata(intf, dev);
2414 dev_info(&intf->dev, "%s\n", info->name);
Michal Nazarewicze538dfd2011-08-30 17:11:19 +02002415 dev_info(&intf->dev, "%s {control%s%s%s%s%s} tests%s\n",
2416 usb_speed_string(udev->speed),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002417 info->ctrl_out ? " in/out" : "",
2418 rtest, wtest,
2419 irtest, iwtest,
2420 info->alt >= 0 ? " (+alt)" : "");
2421 return 0;
2422}
2423
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002424static int usbtest_suspend(struct usb_interface *intf, pm_message_t message)
David Brownellff7c79e2005-04-22 13:17:00 -07002425{
David Brownellff7c79e2005-04-22 13:17:00 -07002426 return 0;
2427}
2428
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002429static int usbtest_resume(struct usb_interface *intf)
David Brownellff7c79e2005-04-22 13:17:00 -07002430{
David Brownellff7c79e2005-04-22 13:17:00 -07002431 return 0;
2432}
2433
2434
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002435static void usbtest_disconnect(struct usb_interface *intf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002436{
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002437 struct usbtest_dev *dev = usb_get_intfdata(intf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002438
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002439 usb_set_intfdata(intf, NULL);
2440 dev_dbg(&intf->dev, "disconnect\n");
2441 kfree(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002442}
2443
2444/* Basic testing only needs a device that can source or sink bulk traffic.
2445 * Any device can test control transfers (default with GENERIC binding).
2446 *
2447 * Several entries work with the default EP0 implementation that's built
2448 * into EZ-USB chips. There's a default vendor ID which can be overridden
2449 * by (very) small config EEPROMS, but otherwise all these devices act
2450 * identically until firmware is loaded: only EP0 works. It turns out
2451 * to be easy to make other endpoints work, without modifying that EP0
2452 * behavior. For now, we expect that kind of firmware.
2453 */
2454
2455/* an21xx or fx versions of ez-usb */
2456static struct usbtest_info ez1_info = {
2457 .name = "EZ-USB device",
2458 .ep_in = 2,
2459 .ep_out = 2,
2460 .alt = 1,
2461};
2462
2463/* fx2 version of ez-usb */
2464static struct usbtest_info ez2_info = {
2465 .name = "FX2 device",
2466 .ep_in = 6,
2467 .ep_out = 2,
2468 .alt = 1,
2469};
2470
2471/* ezusb family device with dedicated usb test firmware,
2472 */
2473static struct usbtest_info fw_info = {
2474 .name = "usb test device",
2475 .ep_in = 2,
2476 .ep_out = 2,
2477 .alt = 1,
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002478 .autoconf = 1, /* iso and ctrl_out need autoconf */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002479 .ctrl_out = 1,
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002480 .iso = 1, /* iso_ep's are #8 in/out */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002481};
2482
2483/* peripheral running Linux and 'zero.c' test firmware, or
2484 * its user-mode cousin. different versions of this use
2485 * different hardware with the same vendor/product codes.
2486 * host side MUST rely on the endpoint descriptors.
2487 */
2488static struct usbtest_info gz_info = {
2489 .name = "Linux gadget zero",
2490 .autoconf = 1,
2491 .ctrl_out = 1,
Boyan Nedeltchev4b85c622012-11-12 13:06:06 +02002492 .iso = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002493 .alt = 0,
2494};
2495
2496static struct usbtest_info um_info = {
2497 .name = "Linux user mode test driver",
2498 .autoconf = 1,
2499 .alt = -1,
2500};
2501
2502static struct usbtest_info um2_info = {
2503 .name = "Linux user mode ISO test driver",
2504 .autoconf = 1,
2505 .iso = 1,
2506 .alt = -1,
2507};
2508
2509#ifdef IBOT2
2510/* this is a nice source of high speed bulk data;
2511 * uses an FX2, with firmware provided in the device
2512 */
2513static struct usbtest_info ibot2_info = {
2514 .name = "iBOT2 webcam",
2515 .ep_in = 2,
2516 .alt = -1,
2517};
2518#endif
2519
2520#ifdef GENERIC
2521/* we can use any device to test control traffic */
2522static struct usbtest_info generic_info = {
2523 .name = "Generic USB device",
2524 .alt = -1,
2525};
2526#endif
2527
Linus Torvalds1da177e2005-04-16 15:20:36 -07002528
Németh Márton33b9e162010-01-10 15:34:45 +01002529static const struct usb_device_id id_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002530
Linus Torvalds1da177e2005-04-16 15:20:36 -07002531 /*-------------------------------------------------------------*/
2532
2533 /* EZ-USB devices which download firmware to replace (or in our
2534 * case augment) the default device implementation.
2535 */
2536
2537 /* generic EZ-USB FX controller */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002538 { USB_DEVICE(0x0547, 0x2235),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002539 .driver_info = (unsigned long) &ez1_info,
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002540 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07002541
2542 /* CY3671 development board with EZ-USB FX */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002543 { USB_DEVICE(0x0547, 0x0080),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002544 .driver_info = (unsigned long) &ez1_info,
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002545 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07002546
2547 /* generic EZ-USB FX2 controller (or development board) */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002548 { USB_DEVICE(0x04b4, 0x8613),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002549 .driver_info = (unsigned long) &ez2_info,
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002550 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551
2552 /* re-enumerated usb test device firmware */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002553 { USB_DEVICE(0xfff0, 0xfff0),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002554 .driver_info = (unsigned long) &fw_info,
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002555 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07002556
2557 /* "Gadget Zero" firmware runs under Linux */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002558 { USB_DEVICE(0x0525, 0xa4a0),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002559 .driver_info = (unsigned long) &gz_info,
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002560 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07002561
2562 /* so does a user-mode variant */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002563 { USB_DEVICE(0x0525, 0xa4a4),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564 .driver_info = (unsigned long) &um_info,
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002565 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07002566
2567 /* ... and a user-mode variant that talks iso */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002568 { USB_DEVICE(0x0525, 0xa4a3),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002569 .driver_info = (unsigned long) &um2_info,
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002570 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07002571
2572#ifdef KEYSPAN_19Qi
2573 /* Keyspan 19qi uses an21xx (original EZ-USB) */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002574 /* this does not coexist with the real Keyspan 19qi driver! */
2575 { USB_DEVICE(0x06cd, 0x010b),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002576 .driver_info = (unsigned long) &ez1_info,
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002577 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07002578#endif
2579
2580 /*-------------------------------------------------------------*/
2581
2582#ifdef IBOT2
2583 /* iBOT2 makes a nice source of high speed bulk-in data */
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002584 /* this does not coexist with a real iBOT2 driver! */
2585 { USB_DEVICE(0x0b62, 0x0059),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002586 .driver_info = (unsigned long) &ibot2_info,
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002587 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07002588#endif
2589
2590 /*-------------------------------------------------------------*/
2591
2592#ifdef GENERIC
2593 /* module params can specify devices to use for control tests */
2594 { .driver_info = (unsigned long) &generic_info, },
2595#endif
2596
2597 /*-------------------------------------------------------------*/
2598
2599 { }
2600};
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002601MODULE_DEVICE_TABLE(usb, id_table);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002602
2603static struct usb_driver usbtest_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604 .name = "usbtest",
2605 .id_table = id_table,
2606 .probe = usbtest_probe,
Andi Kleenc532b292010-06-01 23:04:41 +02002607 .unlocked_ioctl = usbtest_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002608 .disconnect = usbtest_disconnect,
David Brownellff7c79e2005-04-22 13:17:00 -07002609 .suspend = usbtest_suspend,
2610 .resume = usbtest_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002611};
2612
2613/*-------------------------------------------------------------------------*/
2614
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002615static int __init usbtest_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002616{
2617#ifdef GENERIC
2618 if (vendor)
David Brownell28ffd792008-04-25 18:51:10 -07002619 pr_debug("params: vend=0x%04x prod=0x%04x\n", vendor, product);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002620#endif
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002621 return usb_register(&usbtest_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002622}
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002623module_init(usbtest_init);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002624
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002625static void __exit usbtest_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002626{
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002627 usb_deregister(&usbtest_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002628}
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002629module_exit(usbtest_exit);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002630
Martin Fuzzeyfabbf212010-10-01 00:20:42 +02002631MODULE_DESCRIPTION("USB Core/HCD Testing Driver");
2632MODULE_LICENSE("GPL");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002633