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.
13 /* #define VERBOSE_DEBUG */
15 #include <linux/slab.h>
16 #include <linux/kernel.h>
17 #include <linux/device.h>
18 #include <linux/module.h>
19 #include <linux/usb/composite.h>
20 #include <linux/err.h>
23 #include "gadget_chips.h"
26 * SOURCE/SINK FUNCTION ... a primary testing vehicle for USB peripheral
29 * This just sinks bulk packets OUT to the peripheral and sources them IN
30 * to the host, optionally with specific data patterns for integrity tests.
31 * As such it supports basic functionality and load tests.
33 * In terms of control messaging, this supports all the standard requests
34 * plus two that support control-OUT tests. If the optional "autoresume"
35 * mode is enabled, it provides good functional coverage for the "USBCV"
36 * test harness from USB-IF.
38 * Note that because this doesn't queue more than one request at a time,
39 * some other function must be used to test queueing logic. The network
40 * link (g_ether) is the best overall option for that, since its TX and RX
41 * queues are relatively independent, will receive a range of packet sizes,
42 * and can often be made to run out completely. Those issues are important
43 * when stress testing peripheral controller drivers.
46 * This is currently packaged as a configuration driver, which can't be
47 * combined with other functions to make composite devices. However, it
48 * can be combined with other independent configurations.
51 struct usb_function function
;
54 struct usb_ep
*out_ep
;
55 struct usb_ep
*iso_in_ep
;
56 struct usb_ep
*iso_out_ep
;
60 static inline struct f_sourcesink
*func_to_ss(struct usb_function
*f
)
62 return container_of(f
, struct f_sourcesink
, function
);
65 static unsigned pattern
;
66 static unsigned isoc_interval
;
67 static unsigned isoc_maxpacket
;
68 static unsigned isoc_mult
;
69 static unsigned isoc_maxburst
;
70 static unsigned buflen
;
72 /*-------------------------------------------------------------------------*/
74 static struct usb_interface_descriptor source_sink_intf_alt0
= {
75 .bLength
= USB_DT_INTERFACE_SIZE
,
76 .bDescriptorType
= USB_DT_INTERFACE
,
78 .bAlternateSetting
= 0,
80 .bInterfaceClass
= USB_CLASS_VENDOR_SPEC
,
81 /* .iInterface = DYNAMIC */
84 static struct usb_interface_descriptor source_sink_intf_alt1
= {
85 .bLength
= USB_DT_INTERFACE_SIZE
,
86 .bDescriptorType
= USB_DT_INTERFACE
,
88 .bAlternateSetting
= 1,
90 .bInterfaceClass
= USB_CLASS_VENDOR_SPEC
,
91 /* .iInterface = DYNAMIC */
94 /* full speed support: */
96 static struct usb_endpoint_descriptor fs_source_desc
= {
97 .bLength
= USB_DT_ENDPOINT_SIZE
,
98 .bDescriptorType
= USB_DT_ENDPOINT
,
100 .bEndpointAddress
= USB_DIR_IN
,
101 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
104 static struct usb_endpoint_descriptor fs_sink_desc
= {
105 .bLength
= USB_DT_ENDPOINT_SIZE
,
106 .bDescriptorType
= USB_DT_ENDPOINT
,
108 .bEndpointAddress
= USB_DIR_OUT
,
109 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
112 static struct usb_endpoint_descriptor fs_iso_source_desc
= {
113 .bLength
= USB_DT_ENDPOINT_SIZE
,
114 .bDescriptorType
= USB_DT_ENDPOINT
,
116 .bEndpointAddress
= USB_DIR_IN
,
117 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
,
118 .wMaxPacketSize
= cpu_to_le16(1023),
122 static struct usb_endpoint_descriptor fs_iso_sink_desc
= {
123 .bLength
= USB_DT_ENDPOINT_SIZE
,
124 .bDescriptorType
= USB_DT_ENDPOINT
,
126 .bEndpointAddress
= USB_DIR_OUT
,
127 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
,
128 .wMaxPacketSize
= cpu_to_le16(1023),
132 static struct usb_descriptor_header
*fs_source_sink_descs
[] = {
133 (struct usb_descriptor_header
*) &source_sink_intf_alt0
,
134 (struct usb_descriptor_header
*) &fs_sink_desc
,
135 (struct usb_descriptor_header
*) &fs_source_desc
,
136 (struct usb_descriptor_header
*) &source_sink_intf_alt1
,
137 #define FS_ALT_IFC_1_OFFSET 3
138 (struct usb_descriptor_header
*) &fs_sink_desc
,
139 (struct usb_descriptor_header
*) &fs_source_desc
,
140 (struct usb_descriptor_header
*) &fs_iso_sink_desc
,
141 (struct usb_descriptor_header
*) &fs_iso_source_desc
,
145 /* high speed support: */
147 static struct usb_endpoint_descriptor hs_source_desc
= {
148 .bLength
= USB_DT_ENDPOINT_SIZE
,
149 .bDescriptorType
= USB_DT_ENDPOINT
,
151 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
152 .wMaxPacketSize
= cpu_to_le16(512),
155 static struct usb_endpoint_descriptor hs_sink_desc
= {
156 .bLength
= USB_DT_ENDPOINT_SIZE
,
157 .bDescriptorType
= USB_DT_ENDPOINT
,
159 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
160 .wMaxPacketSize
= cpu_to_le16(512),
163 static struct usb_endpoint_descriptor hs_iso_source_desc
= {
164 .bLength
= USB_DT_ENDPOINT_SIZE
,
165 .bDescriptorType
= USB_DT_ENDPOINT
,
167 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
,
168 .wMaxPacketSize
= cpu_to_le16(1024),
172 static struct usb_endpoint_descriptor hs_iso_sink_desc
= {
173 .bLength
= USB_DT_ENDPOINT_SIZE
,
174 .bDescriptorType
= USB_DT_ENDPOINT
,
176 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
,
177 .wMaxPacketSize
= cpu_to_le16(1024),
181 static struct usb_descriptor_header
*hs_source_sink_descs
[] = {
182 (struct usb_descriptor_header
*) &source_sink_intf_alt0
,
183 (struct usb_descriptor_header
*) &hs_source_desc
,
184 (struct usb_descriptor_header
*) &hs_sink_desc
,
185 (struct usb_descriptor_header
*) &source_sink_intf_alt1
,
186 #define HS_ALT_IFC_1_OFFSET 3
187 (struct usb_descriptor_header
*) &hs_source_desc
,
188 (struct usb_descriptor_header
*) &hs_sink_desc
,
189 (struct usb_descriptor_header
*) &hs_iso_source_desc
,
190 (struct usb_descriptor_header
*) &hs_iso_sink_desc
,
194 /* super speed support: */
196 static struct usb_endpoint_descriptor ss_source_desc
= {
197 .bLength
= USB_DT_ENDPOINT_SIZE
,
198 .bDescriptorType
= USB_DT_ENDPOINT
,
200 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
201 .wMaxPacketSize
= cpu_to_le16(1024),
204 struct usb_ss_ep_comp_descriptor ss_source_comp_desc
= {
205 .bLength
= USB_DT_SS_EP_COMP_SIZE
,
206 .bDescriptorType
= USB_DT_SS_ENDPOINT_COMP
,
210 .wBytesPerInterval
= 0,
213 static struct usb_endpoint_descriptor ss_sink_desc
= {
214 .bLength
= USB_DT_ENDPOINT_SIZE
,
215 .bDescriptorType
= USB_DT_ENDPOINT
,
217 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
218 .wMaxPacketSize
= cpu_to_le16(1024),
221 struct usb_ss_ep_comp_descriptor ss_sink_comp_desc
= {
222 .bLength
= USB_DT_SS_EP_COMP_SIZE
,
223 .bDescriptorType
= USB_DT_SS_ENDPOINT_COMP
,
227 .wBytesPerInterval
= 0,
230 static struct usb_endpoint_descriptor ss_iso_source_desc
= {
231 .bLength
= USB_DT_ENDPOINT_SIZE
,
232 .bDescriptorType
= USB_DT_ENDPOINT
,
234 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
,
235 .wMaxPacketSize
= cpu_to_le16(1024),
239 struct usb_ss_ep_comp_descriptor ss_iso_source_comp_desc
= {
240 .bLength
= USB_DT_SS_EP_COMP_SIZE
,
241 .bDescriptorType
= USB_DT_SS_ENDPOINT_COMP
,
245 .wBytesPerInterval
= cpu_to_le16(1024),
248 static struct usb_endpoint_descriptor ss_iso_sink_desc
= {
249 .bLength
= USB_DT_ENDPOINT_SIZE
,
250 .bDescriptorType
= USB_DT_ENDPOINT
,
252 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
,
253 .wMaxPacketSize
= cpu_to_le16(1024),
257 struct usb_ss_ep_comp_descriptor ss_iso_sink_comp_desc
= {
258 .bLength
= USB_DT_SS_EP_COMP_SIZE
,
259 .bDescriptorType
= USB_DT_SS_ENDPOINT_COMP
,
263 .wBytesPerInterval
= cpu_to_le16(1024),
266 static struct usb_descriptor_header
*ss_source_sink_descs
[] = {
267 (struct usb_descriptor_header
*) &source_sink_intf_alt0
,
268 (struct usb_descriptor_header
*) &ss_source_desc
,
269 (struct usb_descriptor_header
*) &ss_source_comp_desc
,
270 (struct usb_descriptor_header
*) &ss_sink_desc
,
271 (struct usb_descriptor_header
*) &ss_sink_comp_desc
,
272 (struct usb_descriptor_header
*) &source_sink_intf_alt1
,
273 #define SS_ALT_IFC_1_OFFSET 5
274 (struct usb_descriptor_header
*) &ss_source_desc
,
275 (struct usb_descriptor_header
*) &ss_source_comp_desc
,
276 (struct usb_descriptor_header
*) &ss_sink_desc
,
277 (struct usb_descriptor_header
*) &ss_sink_comp_desc
,
278 (struct usb_descriptor_header
*) &ss_iso_source_desc
,
279 (struct usb_descriptor_header
*) &ss_iso_source_comp_desc
,
280 (struct usb_descriptor_header
*) &ss_iso_sink_desc
,
281 (struct usb_descriptor_header
*) &ss_iso_sink_comp_desc
,
285 /* function-specific strings: */
287 static struct usb_string strings_sourcesink
[] = {
288 [0].s
= "source and sink data",
289 { } /* end of list */
292 static struct usb_gadget_strings stringtab_sourcesink
= {
293 .language
= 0x0409, /* en-us */
294 .strings
= strings_sourcesink
,
297 static struct usb_gadget_strings
*sourcesink_strings
[] = {
298 &stringtab_sourcesink
,
302 /*-------------------------------------------------------------------------*/
304 struct usb_request
*alloc_ep_req(struct usb_ep
*ep
, int len
)
306 struct usb_request
*req
;
308 req
= usb_ep_alloc_request(ep
, GFP_ATOMIC
);
313 req
->length
= buflen
;
314 req
->buf
= kmalloc(req
->length
, GFP_ATOMIC
);
316 usb_ep_free_request(ep
, req
);
323 void free_ep_req(struct usb_ep
*ep
, struct usb_request
*req
)
326 usb_ep_free_request(ep
, req
);
329 static void disable_ep(struct usb_composite_dev
*cdev
, struct usb_ep
*ep
)
333 if (ep
->driver_data
) {
334 value
= usb_ep_disable(ep
);
336 DBG(cdev
, "disable %s --> %d\n",
338 ep
->driver_data
= NULL
;
342 void disable_endpoints(struct usb_composite_dev
*cdev
,
343 struct usb_ep
*in
, struct usb_ep
*out
,
344 struct usb_ep
*iso_in
, struct usb_ep
*iso_out
)
346 disable_ep(cdev
, in
);
347 disable_ep(cdev
, out
);
349 disable_ep(cdev
, iso_in
);
351 disable_ep(cdev
, iso_out
);
355 sourcesink_bind(struct usb_configuration
*c
, struct usb_function
*f
)
357 struct usb_composite_dev
*cdev
= c
->cdev
;
358 struct f_sourcesink
*ss
= func_to_ss(f
);
362 /* allocate interface ID(s) */
363 id
= usb_interface_id(c
, f
);
366 source_sink_intf_alt0
.bInterfaceNumber
= id
;
367 source_sink_intf_alt1
.bInterfaceNumber
= id
;
369 /* allocate bulk endpoints */
370 ss
->in_ep
= usb_ep_autoconfig(cdev
->gadget
, &fs_source_desc
);
373 ERROR(cdev
, "%s: can't autoconfigure on %s\n",
374 f
->name
, cdev
->gadget
->name
);
377 ss
->in_ep
->driver_data
= cdev
; /* claim */
379 ss
->out_ep
= usb_ep_autoconfig(cdev
->gadget
, &fs_sink_desc
);
382 ss
->out_ep
->driver_data
= cdev
; /* claim */
384 /* sanity check the isoc module parameters */
385 if (isoc_interval
< 1)
387 if (isoc_interval
> 16)
391 if (isoc_maxburst
> 15)
394 /* fill in the FS isoc descriptors from the module parameters */
395 fs_iso_source_desc
.wMaxPacketSize
= isoc_maxpacket
> 1023 ?
396 1023 : isoc_maxpacket
;
397 fs_iso_source_desc
.bInterval
= isoc_interval
;
398 fs_iso_sink_desc
.wMaxPacketSize
= isoc_maxpacket
> 1023 ?
399 1023 : isoc_maxpacket
;
400 fs_iso_sink_desc
.bInterval
= isoc_interval
;
402 /* allocate iso endpoints */
403 ss
->iso_in_ep
= usb_ep_autoconfig(cdev
->gadget
, &fs_iso_source_desc
);
406 ss
->iso_in_ep
->driver_data
= cdev
; /* claim */
408 ss
->iso_out_ep
= usb_ep_autoconfig(cdev
->gadget
, &fs_iso_sink_desc
);
409 if (ss
->iso_out_ep
) {
410 ss
->iso_out_ep
->driver_data
= cdev
; /* claim */
412 ss
->iso_in_ep
->driver_data
= NULL
;
413 ss
->iso_in_ep
= NULL
;
416 * We still want to work even if the UDC doesn't have isoc
417 * endpoints, so null out the alt interface that contains
420 fs_source_sink_descs
[FS_ALT_IFC_1_OFFSET
] = NULL
;
421 hs_source_sink_descs
[HS_ALT_IFC_1_OFFSET
] = NULL
;
422 ss_source_sink_descs
[SS_ALT_IFC_1_OFFSET
] = NULL
;
425 if (isoc_maxpacket
> 1024)
426 isoc_maxpacket
= 1024;
428 /* support high speed hardware */
429 hs_source_desc
.bEndpointAddress
= fs_source_desc
.bEndpointAddress
;
430 hs_sink_desc
.bEndpointAddress
= fs_sink_desc
.bEndpointAddress
;
433 * Fill in the HS isoc descriptors from the module parameters.
434 * We assume that the user knows what they are doing and won't
435 * give parameters that their UDC doesn't support.
437 hs_iso_source_desc
.wMaxPacketSize
= isoc_maxpacket
;
438 hs_iso_source_desc
.wMaxPacketSize
|= isoc_mult
<< 11;
439 hs_iso_source_desc
.bInterval
= isoc_interval
;
440 hs_iso_source_desc
.bEndpointAddress
=
441 fs_iso_source_desc
.bEndpointAddress
;
443 hs_iso_sink_desc
.wMaxPacketSize
= isoc_maxpacket
;
444 hs_iso_sink_desc
.wMaxPacketSize
|= isoc_mult
<< 11;
445 hs_iso_sink_desc
.bInterval
= isoc_interval
;
446 hs_iso_sink_desc
.bEndpointAddress
= fs_iso_sink_desc
.bEndpointAddress
;
448 /* support super speed hardware */
449 ss_source_desc
.bEndpointAddress
=
450 fs_source_desc
.bEndpointAddress
;
451 ss_sink_desc
.bEndpointAddress
=
452 fs_sink_desc
.bEndpointAddress
;
455 * Fill in the SS isoc descriptors from the module parameters.
456 * We assume that the user knows what they are doing and won't
457 * give parameters that their UDC doesn't support.
459 ss_iso_source_desc
.wMaxPacketSize
= isoc_maxpacket
;
460 ss_iso_source_desc
.bInterval
= isoc_interval
;
461 ss_iso_source_comp_desc
.bmAttributes
= isoc_mult
;
462 ss_iso_source_comp_desc
.bMaxBurst
= isoc_maxburst
;
463 ss_iso_source_comp_desc
.wBytesPerInterval
=
464 isoc_maxpacket
* (isoc_mult
+ 1) * (isoc_maxburst
+ 1);
465 ss_iso_source_desc
.bEndpointAddress
=
466 fs_iso_source_desc
.bEndpointAddress
;
468 ss_iso_sink_desc
.wMaxPacketSize
= isoc_maxpacket
;
469 ss_iso_sink_desc
.bInterval
= isoc_interval
;
470 ss_iso_sink_comp_desc
.bmAttributes
= isoc_mult
;
471 ss_iso_sink_comp_desc
.bMaxBurst
= isoc_maxburst
;
472 ss_iso_sink_comp_desc
.wBytesPerInterval
=
473 isoc_maxpacket
* (isoc_mult
+ 1) * (isoc_maxburst
+ 1);
474 ss_iso_sink_desc
.bEndpointAddress
= fs_iso_sink_desc
.bEndpointAddress
;
476 ret
= usb_assign_descriptors(f
, fs_source_sink_descs
,
477 hs_source_sink_descs
, ss_source_sink_descs
);
481 DBG(cdev
, "%s speed %s: IN/%s, OUT/%s, ISO-IN/%s, ISO-OUT/%s\n",
482 (gadget_is_superspeed(c
->cdev
->gadget
) ? "super" :
483 (gadget_is_dualspeed(c
->cdev
->gadget
) ? "dual" : "full")),
484 f
->name
, ss
->in_ep
->name
, ss
->out_ep
->name
,
485 ss
->iso_in_ep
? ss
->iso_in_ep
->name
: "<none>",
486 ss
->iso_out_ep
? ss
->iso_out_ep
->name
: "<none>");
491 sourcesink_free_func(struct usb_function
*f
)
493 usb_free_all_descriptors(f
);
494 kfree(func_to_ss(f
));
497 /* optionally require specific source/sink data patterns */
498 static int check_read_data(struct f_sourcesink
*ss
, struct usb_request
*req
)
502 struct usb_composite_dev
*cdev
= ss
->function
.config
->cdev
;
507 for (i
= 0; i
< req
->actual
; i
++, buf
++) {
510 /* all-zeroes has no synchronization issues */
516 /* "mod63" stays in sync with short-terminated transfers,
517 * OR otherwise when host and gadget agree on how large
518 * each usb transfer request should be. Resync is done
519 * with set_interface or set_config. (We *WANT* it to
520 * get quickly out of sync if controllers or their drivers
521 * stutter for any reason, including buffer duplication...)
524 if (*buf
== (u8
)(i
% 63))
528 ERROR(cdev
, "bad OUT byte, buf[%d] = %d\n", i
, *buf
);
529 usb_ep_set_halt(ss
->out_ep
);
535 static void reinit_write_data(struct usb_ep
*ep
, struct usb_request
*req
)
542 memset(req
->buf
, 0, req
->length
);
545 for (i
= 0; i
< req
->length
; i
++)
546 *buf
++ = (u8
) (i
% 63);
553 static void source_sink_complete(struct usb_ep
*ep
, struct usb_request
*req
)
555 struct usb_composite_dev
*cdev
;
556 struct f_sourcesink
*ss
= ep
->driver_data
;
557 int status
= req
->status
;
559 /* driver_data will be null if ep has been disabled */
563 cdev
= ss
->function
.config
->cdev
;
567 case 0: /* normal completion? */
568 if (ep
== ss
->out_ep
) {
569 check_read_data(ss
, req
);
571 memset(req
->buf
, 0x55, req
->length
);
575 /* this endpoint is normally active while we're configured */
576 case -ECONNABORTED
: /* hardware forced ep reset */
577 case -ECONNRESET
: /* request dequeued */
578 case -ESHUTDOWN
: /* disconnect from host */
579 VDBG(cdev
, "%s gone (%d), %d/%d\n", ep
->name
, status
,
580 req
->actual
, req
->length
);
581 if (ep
== ss
->out_ep
)
582 check_read_data(ss
, req
);
583 free_ep_req(ep
, req
);
586 case -EOVERFLOW
: /* buffer overrun on read means that
587 * we didn't provide a big enough
592 DBG(cdev
, "%s complete --> %d, %d/%d\n", ep
->name
,
593 status
, req
->actual
, req
->length
);
595 case -EREMOTEIO
: /* short read */
599 status
= usb_ep_queue(ep
, req
, GFP_ATOMIC
);
601 ERROR(cdev
, "kill %s: resubmit %d bytes --> %d\n",
602 ep
->name
, req
->length
, status
);
604 /* FIXME recover later ... somehow */
608 static int source_sink_start_ep(struct f_sourcesink
*ss
, bool is_in
,
609 bool is_iso
, int speed
)
612 struct usb_request
*req
;
615 for (i
= 0; i
< 8; i
++) {
618 case USB_SPEED_SUPER
:
619 size
= isoc_maxpacket
* (isoc_mult
+ 1) *
623 size
= isoc_maxpacket
* (isoc_mult
+ 1);
626 size
= isoc_maxpacket
> 1023 ?
627 1023 : isoc_maxpacket
;
630 ep
= is_in
? ss
->iso_in_ep
: ss
->iso_out_ep
;
631 req
= alloc_ep_req(ep
, size
);
633 ep
= is_in
? ss
->in_ep
: ss
->out_ep
;
634 req
= alloc_ep_req(ep
, 0);
640 req
->complete
= source_sink_complete
;
642 reinit_write_data(ep
, req
);
643 else if (pattern
!= 2)
644 memset(req
->buf
, 0x55, req
->length
);
646 status
= usb_ep_queue(ep
, req
, GFP_ATOMIC
);
648 struct usb_composite_dev
*cdev
;
650 cdev
= ss
->function
.config
->cdev
;
651 ERROR(cdev
, "start %s%s %s --> %d\n",
652 is_iso
? "ISO-" : "", is_in
? "IN" : "OUT",
654 free_ep_req(ep
, req
);
664 static void disable_source_sink(struct f_sourcesink
*ss
)
666 struct usb_composite_dev
*cdev
;
668 cdev
= ss
->function
.config
->cdev
;
669 disable_endpoints(cdev
, ss
->in_ep
, ss
->out_ep
, ss
->iso_in_ep
,
671 VDBG(cdev
, "%s disabled\n", ss
->function
.name
);
675 enable_source_sink(struct usb_composite_dev
*cdev
, struct f_sourcesink
*ss
,
679 int speed
= cdev
->gadget
->speed
;
682 /* one bulk endpoint writes (sources) zeroes IN (to the host) */
684 result
= config_ep_by_speed(cdev
->gadget
, &(ss
->function
), ep
);
687 result
= usb_ep_enable(ep
);
690 ep
->driver_data
= ss
;
692 result
= source_sink_start_ep(ss
, true, false, speed
);
697 ep
->driver_data
= NULL
;
701 /* one bulk endpoint reads (sinks) anything OUT (from the host) */
703 result
= config_ep_by_speed(cdev
->gadget
, &(ss
->function
), ep
);
706 result
= usb_ep_enable(ep
);
709 ep
->driver_data
= ss
;
711 result
= source_sink_start_ep(ss
, false, false, speed
);
716 ep
->driver_data
= NULL
;
723 /* one iso endpoint writes (sources) zeroes IN (to the host) */
726 result
= config_ep_by_speed(cdev
->gadget
, &(ss
->function
), ep
);
729 result
= usb_ep_enable(ep
);
732 ep
->driver_data
= ss
;
734 result
= source_sink_start_ep(ss
, true, true, speed
);
740 ep
->driver_data
= NULL
;
746 /* one iso endpoint reads (sinks) anything OUT (from the host) */
749 result
= config_ep_by_speed(cdev
->gadget
, &(ss
->function
), ep
);
752 result
= usb_ep_enable(ep
);
755 ep
->driver_data
= ss
;
757 result
= source_sink_start_ep(ss
, false, true, speed
);
760 ep
->driver_data
= NULL
;
767 DBG(cdev
, "%s enabled, alt intf %d\n", ss
->function
.name
, alt
);
771 static int sourcesink_set_alt(struct usb_function
*f
,
772 unsigned intf
, unsigned alt
)
774 struct f_sourcesink
*ss
= func_to_ss(f
);
775 struct usb_composite_dev
*cdev
= f
->config
->cdev
;
777 if (ss
->in_ep
->driver_data
)
778 disable_source_sink(ss
);
779 return enable_source_sink(cdev
, ss
, alt
);
782 static int sourcesink_get_alt(struct usb_function
*f
, unsigned intf
)
784 struct f_sourcesink
*ss
= func_to_ss(f
);
789 static void sourcesink_disable(struct usb_function
*f
)
791 struct f_sourcesink
*ss
= func_to_ss(f
);
793 disable_source_sink(ss
);
796 /*-------------------------------------------------------------------------*/
798 static int sourcesink_setup(struct usb_function
*f
,
799 const struct usb_ctrlrequest
*ctrl
)
801 struct usb_configuration
*c
= f
->config
;
802 struct usb_request
*req
= c
->cdev
->req
;
803 int value
= -EOPNOTSUPP
;
804 u16 w_index
= le16_to_cpu(ctrl
->wIndex
);
805 u16 w_value
= le16_to_cpu(ctrl
->wValue
);
806 u16 w_length
= le16_to_cpu(ctrl
->wLength
);
808 req
->length
= USB_COMP_EP0_BUFSIZ
;
810 /* composite driver infrastructure handles everything except
811 * the two control test requests.
813 switch (ctrl
->bRequest
) {
816 * These are the same vendor-specific requests supported by
817 * Intel's USB 2.0 compliance test devices. We exceed that
818 * device spec by allowing multiple-packet requests.
820 * NOTE: the Control-OUT data stays in req->buf ... better
821 * would be copying it into a scratch buffer, so that other
822 * requests may safely intervene.
824 case 0x5b: /* control WRITE test -- fill the buffer */
825 if (ctrl
->bRequestType
!= (USB_DIR_OUT
|USB_TYPE_VENDOR
))
827 if (w_value
|| w_index
)
829 /* just read that many bytes into the buffer */
830 if (w_length
> req
->length
)
834 case 0x5c: /* control READ test -- return the buffer */
835 if (ctrl
->bRequestType
!= (USB_DIR_IN
|USB_TYPE_VENDOR
))
837 if (w_value
|| w_index
)
839 /* expect those bytes are still in the buffer; send back */
840 if (w_length
> req
->length
)
848 "unknown control req%02x.%02x v%04x i%04x l%d\n",
849 ctrl
->bRequestType
, ctrl
->bRequest
,
850 w_value
, w_index
, w_length
);
853 /* respond with data transfer or status phase? */
855 VDBG(c
->cdev
, "source/sink req%02x.%02x v%04x i%04x l%d\n",
856 ctrl
->bRequestType
, ctrl
->bRequest
,
857 w_value
, w_index
, w_length
);
860 value
= usb_ep_queue(c
->cdev
->gadget
->ep0
, req
, GFP_ATOMIC
);
862 ERROR(c
->cdev
, "source/sink response, err %d\n",
866 /* device either stalls (value < 0) or reports success */
870 static struct usb_function
*source_sink_alloc_func(
871 struct usb_function_instance
*fi
)
873 struct f_sourcesink
*ss
;
874 struct f_ss_opts
*ss_opts
;
876 ss
= kzalloc(sizeof(*ss
), GFP_KERNEL
);
880 ss_opts
= container_of(fi
, struct f_ss_opts
, func_inst
);
881 pattern
= ss_opts
->pattern
;
882 isoc_interval
= ss_opts
->isoc_interval
;
883 isoc_maxpacket
= ss_opts
->isoc_maxpacket
;
884 isoc_mult
= ss_opts
->isoc_mult
;
885 isoc_maxburst
= ss_opts
->isoc_maxburst
;
886 buflen
= ss_opts
->bulk_buflen
;
888 ss
->function
.name
= "source/sink";
889 ss
->function
.bind
= sourcesink_bind
;
890 ss
->function
.set_alt
= sourcesink_set_alt
;
891 ss
->function
.get_alt
= sourcesink_get_alt
;
892 ss
->function
.disable
= sourcesink_disable
;
893 ss
->function
.setup
= sourcesink_setup
;
894 ss
->function
.strings
= sourcesink_strings
;
896 ss
->function
.free_func
= sourcesink_free_func
;
898 return &ss
->function
;
901 static void acm_free_instance(struct usb_function_instance
*fi
)
903 struct f_ss_opts
*ss_opts
;
905 ss_opts
= container_of(fi
, struct f_ss_opts
, func_inst
);
909 static struct usb_function_instance
*source_sink_alloc_inst(void)
911 struct f_ss_opts
*ss_opts
;
913 ss_opts
= kzalloc(sizeof(*ss_opts
), GFP_KERNEL
);
915 return ERR_PTR(-ENOMEM
);
916 ss_opts
->func_inst
.free_func_inst
= acm_free_instance
;
917 return &ss_opts
->func_inst
;
919 DECLARE_USB_FUNCTION(SourceSink
, source_sink_alloc_inst
,
920 source_sink_alloc_func
);
922 static int __init
sslb_modinit(void)
926 ret
= usb_function_register(&SourceSinkusb_func
);
931 usb_function_unregister(&SourceSinkusb_func
);
934 static void __exit
sslb_modexit(void)
936 usb_function_unregister(&SourceSinkusb_func
);
939 module_init(sslb_modinit
);
940 module_exit(sslb_modexit
);
942 MODULE_LICENSE("GPL");