Add linux-next specific files for 20110831
[linux-2.6/next.git] / drivers / usb / gadget / f_sourcesink.c
blob96c512f4694c4c7419eb9ce9d3fcfe86ddf19755
1 /*
2 * f_sourcesink.c - USB peripheral source/sink configuration driver
4 * Copyright (C) 2003-2008 David Brownell
5 * Copyright (C) 2008 by Nokia Corporation
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /* #define VERBOSE_DEBUG */
24 #include <linux/slab.h>
25 #include <linux/kernel.h>
26 #include <linux/device.h>
27 #include <linux/module.h>
29 #include "g_zero.h"
30 #include "gadget_chips.h"
34 * SOURCE/SINK FUNCTION ... a primary testing vehicle for USB peripheral
35 * controller drivers.
37 * This just sinks bulk packets OUT to the peripheral and sources them IN
38 * to the host, optionally with specific data patterns for integrity tests.
39 * As such it supports basic functionality and load tests.
41 * In terms of control messaging, this supports all the standard requests
42 * plus two that support control-OUT tests. If the optional "autoresume"
43 * mode is enabled, it provides good functional coverage for the "USBCV"
44 * test harness from USB-IF.
46 * Note that because this doesn't queue more than one request at a time,
47 * some other function must be used to test queueing logic. The network
48 * link (g_ether) is the best overall option for that, since its TX and RX
49 * queues are relatively independent, will receive a range of packet sizes,
50 * and can often be made to run out completely. Those issues are important
51 * when stress testing peripheral controller drivers.
54 * This is currently packaged as a configuration driver, which can't be
55 * combined with other functions to make composite devices. However, it
56 * can be combined with other independent configurations.
58 struct f_sourcesink {
59 struct usb_function function;
61 struct usb_ep *in_ep;
62 struct usb_ep *out_ep;
65 static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
67 return container_of(f, struct f_sourcesink, function);
70 static unsigned pattern;
71 module_param(pattern, uint, 0);
72 MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63 ");
74 /*-------------------------------------------------------------------------*/
76 static struct usb_interface_descriptor source_sink_intf = {
77 .bLength = sizeof source_sink_intf,
78 .bDescriptorType = USB_DT_INTERFACE,
80 .bNumEndpoints = 2,
81 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
82 /* .iInterface = DYNAMIC */
85 /* full speed support: */
87 static struct usb_endpoint_descriptor fs_source_desc = {
88 .bLength = USB_DT_ENDPOINT_SIZE,
89 .bDescriptorType = USB_DT_ENDPOINT,
91 .bEndpointAddress = USB_DIR_IN,
92 .bmAttributes = USB_ENDPOINT_XFER_BULK,
95 static struct usb_endpoint_descriptor fs_sink_desc = {
96 .bLength = USB_DT_ENDPOINT_SIZE,
97 .bDescriptorType = USB_DT_ENDPOINT,
99 .bEndpointAddress = USB_DIR_OUT,
100 .bmAttributes = USB_ENDPOINT_XFER_BULK,
103 static struct usb_descriptor_header *fs_source_sink_descs[] = {
104 (struct usb_descriptor_header *) &source_sink_intf,
105 (struct usb_descriptor_header *) &fs_sink_desc,
106 (struct usb_descriptor_header *) &fs_source_desc,
107 NULL,
110 /* high speed support: */
112 static struct usb_endpoint_descriptor hs_source_desc = {
113 .bLength = USB_DT_ENDPOINT_SIZE,
114 .bDescriptorType = USB_DT_ENDPOINT,
116 .bmAttributes = USB_ENDPOINT_XFER_BULK,
117 .wMaxPacketSize = cpu_to_le16(512),
120 static struct usb_endpoint_descriptor hs_sink_desc = {
121 .bLength = USB_DT_ENDPOINT_SIZE,
122 .bDescriptorType = USB_DT_ENDPOINT,
124 .bmAttributes = USB_ENDPOINT_XFER_BULK,
125 .wMaxPacketSize = cpu_to_le16(512),
128 static struct usb_descriptor_header *hs_source_sink_descs[] = {
129 (struct usb_descriptor_header *) &source_sink_intf,
130 (struct usb_descriptor_header *) &hs_source_desc,
131 (struct usb_descriptor_header *) &hs_sink_desc,
132 NULL,
135 /* super speed support: */
137 static struct usb_endpoint_descriptor ss_source_desc = {
138 .bLength = USB_DT_ENDPOINT_SIZE,
139 .bDescriptorType = USB_DT_ENDPOINT,
141 .bmAttributes = USB_ENDPOINT_XFER_BULK,
142 .wMaxPacketSize = cpu_to_le16(1024),
145 struct usb_ss_ep_comp_descriptor ss_source_comp_desc = {
146 .bLength = USB_DT_SS_EP_COMP_SIZE,
147 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
148 .bMaxBurst = 0,
149 .bmAttributes = 0,
150 .wBytesPerInterval = 0,
153 static struct usb_endpoint_descriptor ss_sink_desc = {
154 .bLength = USB_DT_ENDPOINT_SIZE,
155 .bDescriptorType = USB_DT_ENDPOINT,
157 .bmAttributes = USB_ENDPOINT_XFER_BULK,
158 .wMaxPacketSize = cpu_to_le16(1024),
161 struct usb_ss_ep_comp_descriptor ss_sink_comp_desc = {
162 .bLength = USB_DT_SS_EP_COMP_SIZE,
163 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
164 .bMaxBurst = 0,
165 .bmAttributes = 0,
166 .wBytesPerInterval = 0,
169 static struct usb_descriptor_header *ss_source_sink_descs[] = {
170 (struct usb_descriptor_header *) &source_sink_intf,
171 (struct usb_descriptor_header *) &ss_source_desc,
172 (struct usb_descriptor_header *) &ss_source_comp_desc,
173 (struct usb_descriptor_header *) &ss_sink_desc,
174 (struct usb_descriptor_header *) &ss_sink_comp_desc,
175 NULL,
178 /* function-specific strings: */
180 static struct usb_string strings_sourcesink[] = {
181 [0].s = "source and sink data",
182 { } /* end of list */
185 static struct usb_gadget_strings stringtab_sourcesink = {
186 .language = 0x0409, /* en-us */
187 .strings = strings_sourcesink,
190 static struct usb_gadget_strings *sourcesink_strings[] = {
191 &stringtab_sourcesink,
192 NULL,
195 /*-------------------------------------------------------------------------*/
197 static int __init
198 sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
200 struct usb_composite_dev *cdev = c->cdev;
201 struct f_sourcesink *ss = func_to_ss(f);
202 int id;
204 /* allocate interface ID(s) */
205 id = usb_interface_id(c, f);
206 if (id < 0)
207 return id;
208 source_sink_intf.bInterfaceNumber = id;
210 /* allocate endpoints */
211 ss->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_source_desc);
212 if (!ss->in_ep) {
213 autoconf_fail:
214 ERROR(cdev, "%s: can't autoconfigure on %s\n",
215 f->name, cdev->gadget->name);
216 return -ENODEV;
218 ss->in_ep->driver_data = cdev; /* claim */
220 ss->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_sink_desc);
221 if (!ss->out_ep)
222 goto autoconf_fail;
223 ss->out_ep->driver_data = cdev; /* claim */
225 /* support high speed hardware */
226 if (gadget_is_dualspeed(c->cdev->gadget)) {
227 hs_source_desc.bEndpointAddress =
228 fs_source_desc.bEndpointAddress;
229 hs_sink_desc.bEndpointAddress =
230 fs_sink_desc.bEndpointAddress;
231 f->hs_descriptors = hs_source_sink_descs;
234 /* support super speed hardware */
235 if (gadget_is_superspeed(c->cdev->gadget)) {
236 ss_source_desc.bEndpointAddress =
237 fs_source_desc.bEndpointAddress;
238 ss_sink_desc.bEndpointAddress =
239 fs_sink_desc.bEndpointAddress;
240 f->ss_descriptors = ss_source_sink_descs;
243 DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
244 (gadget_is_superspeed(c->cdev->gadget) ? "super" :
245 (gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full")),
246 f->name, ss->in_ep->name, ss->out_ep->name);
247 return 0;
250 static void
251 sourcesink_unbind(struct usb_configuration *c, struct usb_function *f)
253 kfree(func_to_ss(f));
256 /* optionally require specific source/sink data patterns */
257 static int check_read_data(struct f_sourcesink *ss, struct usb_request *req)
259 unsigned i;
260 u8 *buf = req->buf;
261 struct usb_composite_dev *cdev = ss->function.config->cdev;
263 for (i = 0; i < req->actual; i++, buf++) {
264 switch (pattern) {
266 /* all-zeroes has no synchronization issues */
267 case 0:
268 if (*buf == 0)
269 continue;
270 break;
272 /* "mod63" stays in sync with short-terminated transfers,
273 * OR otherwise when host and gadget agree on how large
274 * each usb transfer request should be. Resync is done
275 * with set_interface or set_config. (We *WANT* it to
276 * get quickly out of sync if controllers or their drivers
277 * stutter for any reason, including buffer duplcation...)
279 case 1:
280 if (*buf == (u8)(i % 63))
281 continue;
282 break;
284 ERROR(cdev, "bad OUT byte, buf[%d] = %d\n", i, *buf);
285 usb_ep_set_halt(ss->out_ep);
286 return -EINVAL;
288 return 0;
291 static void reinit_write_data(struct usb_ep *ep, struct usb_request *req)
293 unsigned i;
294 u8 *buf = req->buf;
296 switch (pattern) {
297 case 0:
298 memset(req->buf, 0, req->length);
299 break;
300 case 1:
301 for (i = 0; i < req->length; i++)
302 *buf++ = (u8) (i % 63);
303 break;
307 static void source_sink_complete(struct usb_ep *ep, struct usb_request *req)
309 struct f_sourcesink *ss = ep->driver_data;
310 struct usb_composite_dev *cdev = ss->function.config->cdev;
311 int status = req->status;
313 switch (status) {
315 case 0: /* normal completion? */
316 if (ep == ss->out_ep) {
317 check_read_data(ss, req);
318 memset(req->buf, 0x55, req->length);
319 } else
320 reinit_write_data(ep, req);
321 break;
323 /* this endpoint is normally active while we're configured */
324 case -ECONNABORTED: /* hardware forced ep reset */
325 case -ECONNRESET: /* request dequeued */
326 case -ESHUTDOWN: /* disconnect from host */
327 VDBG(cdev, "%s gone (%d), %d/%d\n", ep->name, status,
328 req->actual, req->length);
329 if (ep == ss->out_ep)
330 check_read_data(ss, req);
331 free_ep_req(ep, req);
332 return;
334 case -EOVERFLOW: /* buffer overrun on read means that
335 * we didn't provide a big enough
336 * buffer.
338 default:
339 #if 1
340 DBG(cdev, "%s complete --> %d, %d/%d\n", ep->name,
341 status, req->actual, req->length);
342 #endif
343 case -EREMOTEIO: /* short read */
344 break;
347 status = usb_ep_queue(ep, req, GFP_ATOMIC);
348 if (status) {
349 ERROR(cdev, "kill %s: resubmit %d bytes --> %d\n",
350 ep->name, req->length, status);
351 usb_ep_set_halt(ep);
352 /* FIXME recover later ... somehow */
356 static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in)
358 struct usb_ep *ep;
359 struct usb_request *req;
360 int status;
362 ep = is_in ? ss->in_ep : ss->out_ep;
363 req = alloc_ep_req(ep);
364 if (!req)
365 return -ENOMEM;
367 req->complete = source_sink_complete;
368 if (is_in)
369 reinit_write_data(ep, req);
370 else
371 memset(req->buf, 0x55, req->length);
373 status = usb_ep_queue(ep, req, GFP_ATOMIC);
374 if (status) {
375 struct usb_composite_dev *cdev;
377 cdev = ss->function.config->cdev;
378 ERROR(cdev, "start %s %s --> %d\n",
379 is_in ? "IN" : "OUT",
380 ep->name, status);
381 free_ep_req(ep, req);
384 return status;
387 static void disable_source_sink(struct f_sourcesink *ss)
389 struct usb_composite_dev *cdev;
391 cdev = ss->function.config->cdev;
392 disable_endpoints(cdev, ss->in_ep, ss->out_ep);
393 VDBG(cdev, "%s disabled\n", ss->function.name);
396 static int
397 enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss)
399 int result = 0;
400 struct usb_ep *ep;
402 /* one endpoint writes (sources) zeroes IN (to the host) */
403 ep = ss->in_ep;
404 result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
405 if (result)
406 return result;
407 result = usb_ep_enable(ep);
408 if (result < 0)
409 return result;
410 ep->driver_data = ss;
412 result = source_sink_start_ep(ss, true);
413 if (result < 0) {
414 fail:
415 ep = ss->in_ep;
416 usb_ep_disable(ep);
417 ep->driver_data = NULL;
418 return result;
421 /* one endpoint reads (sinks) anything OUT (from the host) */
422 ep = ss->out_ep;
423 result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
424 if (result)
425 goto fail;
426 result = usb_ep_enable(ep);
427 if (result < 0)
428 goto fail;
429 ep->driver_data = ss;
431 result = source_sink_start_ep(ss, false);
432 if (result < 0) {
433 usb_ep_disable(ep);
434 ep->driver_data = NULL;
435 goto fail;
438 DBG(cdev, "%s enabled\n", ss->function.name);
439 return result;
442 static int sourcesink_set_alt(struct usb_function *f,
443 unsigned intf, unsigned alt)
445 struct f_sourcesink *ss = func_to_ss(f);
446 struct usb_composite_dev *cdev = f->config->cdev;
448 /* we know alt is zero */
449 if (ss->in_ep->driver_data)
450 disable_source_sink(ss);
451 return enable_source_sink(cdev, ss);
454 static void sourcesink_disable(struct usb_function *f)
456 struct f_sourcesink *ss = func_to_ss(f);
458 disable_source_sink(ss);
461 /*-------------------------------------------------------------------------*/
463 static int __init sourcesink_bind_config(struct usb_configuration *c)
465 struct f_sourcesink *ss;
466 int status;
468 ss = kzalloc(sizeof *ss, GFP_KERNEL);
469 if (!ss)
470 return -ENOMEM;
472 ss->function.name = "source/sink";
473 ss->function.descriptors = fs_source_sink_descs;
474 ss->function.bind = sourcesink_bind;
475 ss->function.unbind = sourcesink_unbind;
476 ss->function.set_alt = sourcesink_set_alt;
477 ss->function.disable = sourcesink_disable;
479 status = usb_add_function(c, &ss->function);
480 if (status)
481 kfree(ss);
482 return status;
485 static int sourcesink_setup(struct usb_configuration *c,
486 const struct usb_ctrlrequest *ctrl)
488 struct usb_request *req = c->cdev->req;
489 int value = -EOPNOTSUPP;
490 u16 w_index = le16_to_cpu(ctrl->wIndex);
491 u16 w_value = le16_to_cpu(ctrl->wValue);
492 u16 w_length = le16_to_cpu(ctrl->wLength);
494 req->length = USB_BUFSIZ;
496 /* composite driver infrastructure handles everything except
497 * the two control test requests.
499 switch (ctrl->bRequest) {
502 * These are the same vendor-specific requests supported by
503 * Intel's USB 2.0 compliance test devices. We exceed that
504 * device spec by allowing multiple-packet requests.
506 * NOTE: the Control-OUT data stays in req->buf ... better
507 * would be copying it into a scratch buffer, so that other
508 * requests may safely intervene.
510 case 0x5b: /* control WRITE test -- fill the buffer */
511 if (ctrl->bRequestType != (USB_DIR_OUT|USB_TYPE_VENDOR))
512 goto unknown;
513 if (w_value || w_index)
514 break;
515 /* just read that many bytes into the buffer */
516 if (w_length > req->length)
517 break;
518 value = w_length;
519 break;
520 case 0x5c: /* control READ test -- return the buffer */
521 if (ctrl->bRequestType != (USB_DIR_IN|USB_TYPE_VENDOR))
522 goto unknown;
523 if (w_value || w_index)
524 break;
525 /* expect those bytes are still in the buffer; send back */
526 if (w_length > req->length)
527 break;
528 value = w_length;
529 break;
531 default:
532 unknown:
533 VDBG(c->cdev,
534 "unknown control req%02x.%02x v%04x i%04x l%d\n",
535 ctrl->bRequestType, ctrl->bRequest,
536 w_value, w_index, w_length);
539 /* respond with data transfer or status phase? */
540 if (value >= 0) {
541 VDBG(c->cdev, "source/sink req%02x.%02x v%04x i%04x l%d\n",
542 ctrl->bRequestType, ctrl->bRequest,
543 w_value, w_index, w_length);
544 req->zero = 0;
545 req->length = value;
546 value = usb_ep_queue(c->cdev->gadget->ep0, req, GFP_ATOMIC);
547 if (value < 0)
548 ERROR(c->cdev, "source/sinkc response, err %d\n",
549 value);
552 /* device either stalls (value < 0) or reports success */
553 return value;
556 static struct usb_configuration sourcesink_driver = {
557 .label = "source/sink",
558 .strings = sourcesink_strings,
559 .setup = sourcesink_setup,
560 .bConfigurationValue = 3,
561 .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
562 /* .iConfiguration = DYNAMIC */
566 * sourcesink_add - add a source/sink testing configuration to a device
567 * @cdev: the device to support the configuration
569 int __init sourcesink_add(struct usb_composite_dev *cdev, bool autoresume)
571 int id;
573 /* allocate string ID(s) */
574 id = usb_string_id(cdev);
575 if (id < 0)
576 return id;
577 strings_sourcesink[0].id = id;
579 source_sink_intf.iInterface = id;
580 sourcesink_driver.iConfiguration = id;
582 /* support autoresume for remote wakeup testing */
583 if (autoresume)
584 sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
586 /* support OTG systems */
587 if (gadget_is_otg(cdev->gadget)) {
588 sourcesink_driver.descriptors = otg_desc;
589 sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
592 return usb_add_config(cdev, &sourcesink_driver, sourcesink_bind_config);