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"
27 * SOURCE/SINK FUNCTION ... a primary testing vehicle for USB peripheral
30 * This just sinks bulk packets OUT to the peripheral and sources them IN
31 * to the host, optionally with specific data patterns for integrity tests.
32 * As such it supports basic functionality and load tests.
34 * In terms of control messaging, this supports all the standard requests
35 * plus two that support control-OUT tests. If the optional "autoresume"
36 * mode is enabled, it provides good functional coverage for the "USBCV"
37 * test harness from USB-IF.
39 * Note that because this doesn't queue more than one request at a time,
40 * some other function must be used to test queueing logic. The network
41 * link (g_ether) is the best overall option for that, since its TX and RX
42 * queues are relatively independent, will receive a range of packet sizes,
43 * and can often be made to run out completely. Those issues are important
44 * when stress testing peripheral controller drivers.
47 * This is currently packaged as a configuration driver, which can't be
48 * combined with other functions to make composite devices. However, it
49 * can be combined with other independent configurations.
52 struct usb_function function
;
55 struct usb_ep
*out_ep
;
56 struct usb_ep
*iso_in_ep
;
57 struct usb_ep
*iso_out_ep
;
61 static inline struct f_sourcesink
*func_to_ss(struct usb_function
*f
)
63 return container_of(f
, struct f_sourcesink
, function
);
66 static unsigned pattern
;
67 static unsigned isoc_interval
;
68 static unsigned isoc_maxpacket
;
69 static unsigned isoc_mult
;
70 static unsigned isoc_maxburst
;
71 static unsigned buflen
;
73 /*-------------------------------------------------------------------------*/
75 static struct usb_interface_descriptor source_sink_intf_alt0
= {
76 .bLength
= USB_DT_INTERFACE_SIZE
,
77 .bDescriptorType
= USB_DT_INTERFACE
,
79 .bAlternateSetting
= 0,
81 .bInterfaceClass
= USB_CLASS_VENDOR_SPEC
,
82 /* .iInterface = DYNAMIC */
85 static struct usb_interface_descriptor source_sink_intf_alt1
= {
86 .bLength
= USB_DT_INTERFACE_SIZE
,
87 .bDescriptorType
= USB_DT_INTERFACE
,
89 .bAlternateSetting
= 1,
91 .bInterfaceClass
= USB_CLASS_VENDOR_SPEC
,
92 /* .iInterface = DYNAMIC */
95 /* full speed support: */
97 static struct usb_endpoint_descriptor fs_source_desc
= {
98 .bLength
= USB_DT_ENDPOINT_SIZE
,
99 .bDescriptorType
= USB_DT_ENDPOINT
,
101 .bEndpointAddress
= USB_DIR_IN
,
102 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
105 static struct usb_endpoint_descriptor fs_sink_desc
= {
106 .bLength
= USB_DT_ENDPOINT_SIZE
,
107 .bDescriptorType
= USB_DT_ENDPOINT
,
109 .bEndpointAddress
= USB_DIR_OUT
,
110 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
113 static struct usb_endpoint_descriptor fs_iso_source_desc
= {
114 .bLength
= USB_DT_ENDPOINT_SIZE
,
115 .bDescriptorType
= USB_DT_ENDPOINT
,
117 .bEndpointAddress
= USB_DIR_IN
,
118 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
,
119 .wMaxPacketSize
= cpu_to_le16(1023),
123 static struct usb_endpoint_descriptor fs_iso_sink_desc
= {
124 .bLength
= USB_DT_ENDPOINT_SIZE
,
125 .bDescriptorType
= USB_DT_ENDPOINT
,
127 .bEndpointAddress
= USB_DIR_OUT
,
128 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
,
129 .wMaxPacketSize
= cpu_to_le16(1023),
133 static struct usb_descriptor_header
*fs_source_sink_descs
[] = {
134 (struct usb_descriptor_header
*) &source_sink_intf_alt0
,
135 (struct usb_descriptor_header
*) &fs_sink_desc
,
136 (struct usb_descriptor_header
*) &fs_source_desc
,
137 (struct usb_descriptor_header
*) &source_sink_intf_alt1
,
138 #define FS_ALT_IFC_1_OFFSET 3
139 (struct usb_descriptor_header
*) &fs_sink_desc
,
140 (struct usb_descriptor_header
*) &fs_source_desc
,
141 (struct usb_descriptor_header
*) &fs_iso_sink_desc
,
142 (struct usb_descriptor_header
*) &fs_iso_source_desc
,
146 /* high speed support: */
148 static struct usb_endpoint_descriptor hs_source_desc
= {
149 .bLength
= USB_DT_ENDPOINT_SIZE
,
150 .bDescriptorType
= USB_DT_ENDPOINT
,
152 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
153 .wMaxPacketSize
= cpu_to_le16(512),
156 static struct usb_endpoint_descriptor hs_sink_desc
= {
157 .bLength
= USB_DT_ENDPOINT_SIZE
,
158 .bDescriptorType
= USB_DT_ENDPOINT
,
160 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
161 .wMaxPacketSize
= cpu_to_le16(512),
164 static struct usb_endpoint_descriptor hs_iso_source_desc
= {
165 .bLength
= USB_DT_ENDPOINT_SIZE
,
166 .bDescriptorType
= USB_DT_ENDPOINT
,
168 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
,
169 .wMaxPacketSize
= cpu_to_le16(1024),
173 static struct usb_endpoint_descriptor hs_iso_sink_desc
= {
174 .bLength
= USB_DT_ENDPOINT_SIZE
,
175 .bDescriptorType
= USB_DT_ENDPOINT
,
177 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
,
178 .wMaxPacketSize
= cpu_to_le16(1024),
182 static struct usb_descriptor_header
*hs_source_sink_descs
[] = {
183 (struct usb_descriptor_header
*) &source_sink_intf_alt0
,
184 (struct usb_descriptor_header
*) &hs_source_desc
,
185 (struct usb_descriptor_header
*) &hs_sink_desc
,
186 (struct usb_descriptor_header
*) &source_sink_intf_alt1
,
187 #define HS_ALT_IFC_1_OFFSET 3
188 (struct usb_descriptor_header
*) &hs_source_desc
,
189 (struct usb_descriptor_header
*) &hs_sink_desc
,
190 (struct usb_descriptor_header
*) &hs_iso_source_desc
,
191 (struct usb_descriptor_header
*) &hs_iso_sink_desc
,
195 /* super speed support: */
197 static struct usb_endpoint_descriptor ss_source_desc
= {
198 .bLength
= USB_DT_ENDPOINT_SIZE
,
199 .bDescriptorType
= USB_DT_ENDPOINT
,
201 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
202 .wMaxPacketSize
= cpu_to_le16(1024),
205 static struct usb_ss_ep_comp_descriptor ss_source_comp_desc
= {
206 .bLength
= USB_DT_SS_EP_COMP_SIZE
,
207 .bDescriptorType
= USB_DT_SS_ENDPOINT_COMP
,
211 .wBytesPerInterval
= 0,
214 static struct usb_endpoint_descriptor ss_sink_desc
= {
215 .bLength
= USB_DT_ENDPOINT_SIZE
,
216 .bDescriptorType
= USB_DT_ENDPOINT
,
218 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
219 .wMaxPacketSize
= cpu_to_le16(1024),
222 static struct usb_ss_ep_comp_descriptor ss_sink_comp_desc
= {
223 .bLength
= USB_DT_SS_EP_COMP_SIZE
,
224 .bDescriptorType
= USB_DT_SS_ENDPOINT_COMP
,
228 .wBytesPerInterval
= 0,
231 static struct usb_endpoint_descriptor ss_iso_source_desc
= {
232 .bLength
= USB_DT_ENDPOINT_SIZE
,
233 .bDescriptorType
= USB_DT_ENDPOINT
,
235 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
,
236 .wMaxPacketSize
= cpu_to_le16(1024),
240 static struct usb_ss_ep_comp_descriptor ss_iso_source_comp_desc
= {
241 .bLength
= USB_DT_SS_EP_COMP_SIZE
,
242 .bDescriptorType
= USB_DT_SS_ENDPOINT_COMP
,
246 .wBytesPerInterval
= cpu_to_le16(1024),
249 static struct usb_endpoint_descriptor ss_iso_sink_desc
= {
250 .bLength
= USB_DT_ENDPOINT_SIZE
,
251 .bDescriptorType
= USB_DT_ENDPOINT
,
253 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
,
254 .wMaxPacketSize
= cpu_to_le16(1024),
258 static struct usb_ss_ep_comp_descriptor ss_iso_sink_comp_desc
= {
259 .bLength
= USB_DT_SS_EP_COMP_SIZE
,
260 .bDescriptorType
= USB_DT_SS_ENDPOINT_COMP
,
264 .wBytesPerInterval
= cpu_to_le16(1024),
267 static struct usb_descriptor_header
*ss_source_sink_descs
[] = {
268 (struct usb_descriptor_header
*) &source_sink_intf_alt0
,
269 (struct usb_descriptor_header
*) &ss_source_desc
,
270 (struct usb_descriptor_header
*) &ss_source_comp_desc
,
271 (struct usb_descriptor_header
*) &ss_sink_desc
,
272 (struct usb_descriptor_header
*) &ss_sink_comp_desc
,
273 (struct usb_descriptor_header
*) &source_sink_intf_alt1
,
274 #define SS_ALT_IFC_1_OFFSET 5
275 (struct usb_descriptor_header
*) &ss_source_desc
,
276 (struct usb_descriptor_header
*) &ss_source_comp_desc
,
277 (struct usb_descriptor_header
*) &ss_sink_desc
,
278 (struct usb_descriptor_header
*) &ss_sink_comp_desc
,
279 (struct usb_descriptor_header
*) &ss_iso_source_desc
,
280 (struct usb_descriptor_header
*) &ss_iso_source_comp_desc
,
281 (struct usb_descriptor_header
*) &ss_iso_sink_desc
,
282 (struct usb_descriptor_header
*) &ss_iso_sink_comp_desc
,
286 /* function-specific strings: */
288 static struct usb_string strings_sourcesink
[] = {
289 [0].s
= "source and sink data",
290 { } /* end of list */
293 static struct usb_gadget_strings stringtab_sourcesink
= {
294 .language
= 0x0409, /* en-us */
295 .strings
= strings_sourcesink
,
298 static struct usb_gadget_strings
*sourcesink_strings
[] = {
299 &stringtab_sourcesink
,
303 /*-------------------------------------------------------------------------*/
305 static inline struct usb_request
*ss_alloc_ep_req(struct usb_ep
*ep
, int len
)
307 return alloc_ep_req(ep
, len
, buflen
);
310 void free_ep_req(struct usb_ep
*ep
, struct usb_request
*req
)
313 usb_ep_free_request(ep
, req
);
316 static void disable_ep(struct usb_composite_dev
*cdev
, struct usb_ep
*ep
)
320 if (ep
->driver_data
) {
321 value
= usb_ep_disable(ep
);
323 DBG(cdev
, "disable %s --> %d\n",
325 ep
->driver_data
= NULL
;
329 void disable_endpoints(struct usb_composite_dev
*cdev
,
330 struct usb_ep
*in
, struct usb_ep
*out
,
331 struct usb_ep
*iso_in
, struct usb_ep
*iso_out
)
333 disable_ep(cdev
, in
);
334 disable_ep(cdev
, out
);
336 disable_ep(cdev
, iso_in
);
338 disable_ep(cdev
, iso_out
);
342 sourcesink_bind(struct usb_configuration
*c
, struct usb_function
*f
)
344 struct usb_composite_dev
*cdev
= c
->cdev
;
345 struct f_sourcesink
*ss
= func_to_ss(f
);
349 /* allocate interface ID(s) */
350 id
= usb_interface_id(c
, f
);
353 source_sink_intf_alt0
.bInterfaceNumber
= id
;
354 source_sink_intf_alt1
.bInterfaceNumber
= id
;
356 /* allocate bulk endpoints */
357 ss
->in_ep
= usb_ep_autoconfig(cdev
->gadget
, &fs_source_desc
);
360 ERROR(cdev
, "%s: can't autoconfigure on %s\n",
361 f
->name
, cdev
->gadget
->name
);
364 ss
->in_ep
->driver_data
= cdev
; /* claim */
366 ss
->out_ep
= usb_ep_autoconfig(cdev
->gadget
, &fs_sink_desc
);
369 ss
->out_ep
->driver_data
= cdev
; /* claim */
371 /* sanity check the isoc module parameters */
372 if (isoc_interval
< 1)
374 if (isoc_interval
> 16)
378 if (isoc_maxburst
> 15)
381 /* fill in the FS isoc descriptors from the module parameters */
382 fs_iso_source_desc
.wMaxPacketSize
= isoc_maxpacket
> 1023 ?
383 1023 : isoc_maxpacket
;
384 fs_iso_source_desc
.bInterval
= isoc_interval
;
385 fs_iso_sink_desc
.wMaxPacketSize
= isoc_maxpacket
> 1023 ?
386 1023 : isoc_maxpacket
;
387 fs_iso_sink_desc
.bInterval
= isoc_interval
;
389 /* allocate iso endpoints */
390 ss
->iso_in_ep
= usb_ep_autoconfig(cdev
->gadget
, &fs_iso_source_desc
);
393 ss
->iso_in_ep
->driver_data
= cdev
; /* claim */
395 ss
->iso_out_ep
= usb_ep_autoconfig(cdev
->gadget
, &fs_iso_sink_desc
);
396 if (ss
->iso_out_ep
) {
397 ss
->iso_out_ep
->driver_data
= cdev
; /* claim */
399 ss
->iso_in_ep
->driver_data
= NULL
;
400 ss
->iso_in_ep
= NULL
;
403 * We still want to work even if the UDC doesn't have isoc
404 * endpoints, so null out the alt interface that contains
407 fs_source_sink_descs
[FS_ALT_IFC_1_OFFSET
] = NULL
;
408 hs_source_sink_descs
[HS_ALT_IFC_1_OFFSET
] = NULL
;
409 ss_source_sink_descs
[SS_ALT_IFC_1_OFFSET
] = NULL
;
412 if (isoc_maxpacket
> 1024)
413 isoc_maxpacket
= 1024;
415 /* support high speed hardware */
416 hs_source_desc
.bEndpointAddress
= fs_source_desc
.bEndpointAddress
;
417 hs_sink_desc
.bEndpointAddress
= fs_sink_desc
.bEndpointAddress
;
420 * Fill in the HS isoc descriptors from the module parameters.
421 * We assume that the user knows what they are doing and won't
422 * give parameters that their UDC doesn't support.
424 hs_iso_source_desc
.wMaxPacketSize
= isoc_maxpacket
;
425 hs_iso_source_desc
.wMaxPacketSize
|= isoc_mult
<< 11;
426 hs_iso_source_desc
.bInterval
= isoc_interval
;
427 hs_iso_source_desc
.bEndpointAddress
=
428 fs_iso_source_desc
.bEndpointAddress
;
430 hs_iso_sink_desc
.wMaxPacketSize
= isoc_maxpacket
;
431 hs_iso_sink_desc
.wMaxPacketSize
|= isoc_mult
<< 11;
432 hs_iso_sink_desc
.bInterval
= isoc_interval
;
433 hs_iso_sink_desc
.bEndpointAddress
= fs_iso_sink_desc
.bEndpointAddress
;
435 /* support super speed hardware */
436 ss_source_desc
.bEndpointAddress
=
437 fs_source_desc
.bEndpointAddress
;
438 ss_sink_desc
.bEndpointAddress
=
439 fs_sink_desc
.bEndpointAddress
;
442 * Fill in the SS isoc descriptors from the module parameters.
443 * We assume that the user knows what they are doing and won't
444 * give parameters that their UDC doesn't support.
446 ss_iso_source_desc
.wMaxPacketSize
= isoc_maxpacket
;
447 ss_iso_source_desc
.bInterval
= isoc_interval
;
448 ss_iso_source_comp_desc
.bmAttributes
= isoc_mult
;
449 ss_iso_source_comp_desc
.bMaxBurst
= isoc_maxburst
;
450 ss_iso_source_comp_desc
.wBytesPerInterval
=
451 isoc_maxpacket
* (isoc_mult
+ 1) * (isoc_maxburst
+ 1);
452 ss_iso_source_desc
.bEndpointAddress
=
453 fs_iso_source_desc
.bEndpointAddress
;
455 ss_iso_sink_desc
.wMaxPacketSize
= isoc_maxpacket
;
456 ss_iso_sink_desc
.bInterval
= isoc_interval
;
457 ss_iso_sink_comp_desc
.bmAttributes
= isoc_mult
;
458 ss_iso_sink_comp_desc
.bMaxBurst
= isoc_maxburst
;
459 ss_iso_sink_comp_desc
.wBytesPerInterval
=
460 isoc_maxpacket
* (isoc_mult
+ 1) * (isoc_maxburst
+ 1);
461 ss_iso_sink_desc
.bEndpointAddress
= fs_iso_sink_desc
.bEndpointAddress
;
463 ret
= usb_assign_descriptors(f
, fs_source_sink_descs
,
464 hs_source_sink_descs
, ss_source_sink_descs
);
468 DBG(cdev
, "%s speed %s: IN/%s, OUT/%s, ISO-IN/%s, ISO-OUT/%s\n",
469 (gadget_is_superspeed(c
->cdev
->gadget
) ? "super" :
470 (gadget_is_dualspeed(c
->cdev
->gadget
) ? "dual" : "full")),
471 f
->name
, ss
->in_ep
->name
, ss
->out_ep
->name
,
472 ss
->iso_in_ep
? ss
->iso_in_ep
->name
: "<none>",
473 ss
->iso_out_ep
? ss
->iso_out_ep
->name
: "<none>");
478 sourcesink_free_func(struct usb_function
*f
)
480 struct f_ss_opts
*opts
;
482 opts
= container_of(f
->fi
, struct f_ss_opts
, func_inst
);
484 mutex_lock(&opts
->lock
);
486 mutex_unlock(&opts
->lock
);
488 usb_free_all_descriptors(f
);
489 kfree(func_to_ss(f
));
492 /* optionally require specific source/sink data patterns */
493 static int check_read_data(struct f_sourcesink
*ss
, struct usb_request
*req
)
497 struct usb_composite_dev
*cdev
= ss
->function
.config
->cdev
;
502 for (i
= 0; i
< req
->actual
; i
++, buf
++) {
505 /* all-zeroes has no synchronization issues */
511 /* "mod63" stays in sync with short-terminated transfers,
512 * OR otherwise when host and gadget agree on how large
513 * each usb transfer request should be. Resync is done
514 * with set_interface or set_config. (We *WANT* it to
515 * get quickly out of sync if controllers or their drivers
516 * stutter for any reason, including buffer duplication...)
519 if (*buf
== (u8
)(i
% 63))
523 ERROR(cdev
, "bad OUT byte, buf[%d] = %d\n", i
, *buf
);
524 usb_ep_set_halt(ss
->out_ep
);
530 static void reinit_write_data(struct usb_ep
*ep
, struct usb_request
*req
)
537 memset(req
->buf
, 0, req
->length
);
540 for (i
= 0; i
< req
->length
; i
++)
541 *buf
++ = (u8
) (i
% 63);
548 static void source_sink_complete(struct usb_ep
*ep
, struct usb_request
*req
)
550 struct usb_composite_dev
*cdev
;
551 struct f_sourcesink
*ss
= ep
->driver_data
;
552 int status
= req
->status
;
554 /* driver_data will be null if ep has been disabled */
558 cdev
= ss
->function
.config
->cdev
;
562 case 0: /* normal completion? */
563 if (ep
== ss
->out_ep
) {
564 check_read_data(ss
, req
);
566 memset(req
->buf
, 0x55, req
->length
);
570 /* this endpoint is normally active while we're configured */
571 case -ECONNABORTED
: /* hardware forced ep reset */
572 case -ECONNRESET
: /* request dequeued */
573 case -ESHUTDOWN
: /* disconnect from host */
574 VDBG(cdev
, "%s gone (%d), %d/%d\n", ep
->name
, status
,
575 req
->actual
, req
->length
);
576 if (ep
== ss
->out_ep
)
577 check_read_data(ss
, req
);
578 free_ep_req(ep
, req
);
581 case -EOVERFLOW
: /* buffer overrun on read means that
582 * we didn't provide a big enough
587 DBG(cdev
, "%s complete --> %d, %d/%d\n", ep
->name
,
588 status
, req
->actual
, req
->length
);
590 case -EREMOTEIO
: /* short read */
594 status
= usb_ep_queue(ep
, req
, GFP_ATOMIC
);
596 ERROR(cdev
, "kill %s: resubmit %d bytes --> %d\n",
597 ep
->name
, req
->length
, status
);
599 /* FIXME recover later ... somehow */
603 static int source_sink_start_ep(struct f_sourcesink
*ss
, bool is_in
,
604 bool is_iso
, int speed
)
607 struct usb_request
*req
;
610 for (i
= 0; i
< 8; i
++) {
613 case USB_SPEED_SUPER
:
614 size
= isoc_maxpacket
* (isoc_mult
+ 1) *
618 size
= isoc_maxpacket
* (isoc_mult
+ 1);
621 size
= isoc_maxpacket
> 1023 ?
622 1023 : isoc_maxpacket
;
625 ep
= is_in
? ss
->iso_in_ep
: ss
->iso_out_ep
;
626 req
= ss_alloc_ep_req(ep
, size
);
628 ep
= is_in
? ss
->in_ep
: ss
->out_ep
;
629 req
= ss_alloc_ep_req(ep
, 0);
635 req
->complete
= source_sink_complete
;
637 reinit_write_data(ep
, req
);
638 else if (pattern
!= 2)
639 memset(req
->buf
, 0x55, req
->length
);
641 status
= usb_ep_queue(ep
, req
, GFP_ATOMIC
);
643 struct usb_composite_dev
*cdev
;
645 cdev
= ss
->function
.config
->cdev
;
646 ERROR(cdev
, "start %s%s %s --> %d\n",
647 is_iso
? "ISO-" : "", is_in
? "IN" : "OUT",
649 free_ep_req(ep
, req
);
659 static void disable_source_sink(struct f_sourcesink
*ss
)
661 struct usb_composite_dev
*cdev
;
663 cdev
= ss
->function
.config
->cdev
;
664 disable_endpoints(cdev
, ss
->in_ep
, ss
->out_ep
, ss
->iso_in_ep
,
666 VDBG(cdev
, "%s disabled\n", ss
->function
.name
);
670 enable_source_sink(struct usb_composite_dev
*cdev
, struct f_sourcesink
*ss
,
674 int speed
= cdev
->gadget
->speed
;
677 /* one bulk endpoint writes (sources) zeroes IN (to the host) */
679 result
= config_ep_by_speed(cdev
->gadget
, &(ss
->function
), ep
);
682 result
= usb_ep_enable(ep
);
685 ep
->driver_data
= ss
;
687 result
= source_sink_start_ep(ss
, true, false, speed
);
692 ep
->driver_data
= NULL
;
696 /* one bulk endpoint reads (sinks) anything OUT (from the host) */
698 result
= config_ep_by_speed(cdev
->gadget
, &(ss
->function
), ep
);
701 result
= usb_ep_enable(ep
);
704 ep
->driver_data
= ss
;
706 result
= source_sink_start_ep(ss
, false, false, speed
);
711 ep
->driver_data
= NULL
;
718 /* one iso endpoint writes (sources) zeroes IN (to the host) */
721 result
= config_ep_by_speed(cdev
->gadget
, &(ss
->function
), ep
);
724 result
= usb_ep_enable(ep
);
727 ep
->driver_data
= ss
;
729 result
= source_sink_start_ep(ss
, true, true, speed
);
735 ep
->driver_data
= NULL
;
741 /* one iso endpoint reads (sinks) anything OUT (from the host) */
744 result
= config_ep_by_speed(cdev
->gadget
, &(ss
->function
), ep
);
747 result
= usb_ep_enable(ep
);
750 ep
->driver_data
= ss
;
752 result
= source_sink_start_ep(ss
, false, true, speed
);
755 ep
->driver_data
= NULL
;
762 DBG(cdev
, "%s enabled, alt intf %d\n", ss
->function
.name
, alt
);
766 static int sourcesink_set_alt(struct usb_function
*f
,
767 unsigned intf
, unsigned alt
)
769 struct f_sourcesink
*ss
= func_to_ss(f
);
770 struct usb_composite_dev
*cdev
= f
->config
->cdev
;
772 if (ss
->in_ep
->driver_data
)
773 disable_source_sink(ss
);
774 return enable_source_sink(cdev
, ss
, alt
);
777 static int sourcesink_get_alt(struct usb_function
*f
, unsigned intf
)
779 struct f_sourcesink
*ss
= func_to_ss(f
);
784 static void sourcesink_disable(struct usb_function
*f
)
786 struct f_sourcesink
*ss
= func_to_ss(f
);
788 disable_source_sink(ss
);
791 /*-------------------------------------------------------------------------*/
793 static int sourcesink_setup(struct usb_function
*f
,
794 const struct usb_ctrlrequest
*ctrl
)
796 struct usb_configuration
*c
= f
->config
;
797 struct usb_request
*req
= c
->cdev
->req
;
798 int value
= -EOPNOTSUPP
;
799 u16 w_index
= le16_to_cpu(ctrl
->wIndex
);
800 u16 w_value
= le16_to_cpu(ctrl
->wValue
);
801 u16 w_length
= le16_to_cpu(ctrl
->wLength
);
803 req
->length
= USB_COMP_EP0_BUFSIZ
;
805 /* composite driver infrastructure handles everything except
806 * the two control test requests.
808 switch (ctrl
->bRequest
) {
811 * These are the same vendor-specific requests supported by
812 * Intel's USB 2.0 compliance test devices. We exceed that
813 * device spec by allowing multiple-packet requests.
815 * NOTE: the Control-OUT data stays in req->buf ... better
816 * would be copying it into a scratch buffer, so that other
817 * requests may safely intervene.
819 case 0x5b: /* control WRITE test -- fill the buffer */
820 if (ctrl
->bRequestType
!= (USB_DIR_OUT
|USB_TYPE_VENDOR
))
822 if (w_value
|| w_index
)
824 /* just read that many bytes into the buffer */
825 if (w_length
> req
->length
)
829 case 0x5c: /* control READ test -- return the buffer */
830 if (ctrl
->bRequestType
!= (USB_DIR_IN
|USB_TYPE_VENDOR
))
832 if (w_value
|| w_index
)
834 /* expect those bytes are still in the buffer; send back */
835 if (w_length
> req
->length
)
843 "unknown control req%02x.%02x v%04x i%04x l%d\n",
844 ctrl
->bRequestType
, ctrl
->bRequest
,
845 w_value
, w_index
, w_length
);
848 /* respond with data transfer or status phase? */
850 VDBG(c
->cdev
, "source/sink req%02x.%02x v%04x i%04x l%d\n",
851 ctrl
->bRequestType
, ctrl
->bRequest
,
852 w_value
, w_index
, w_length
);
855 value
= usb_ep_queue(c
->cdev
->gadget
->ep0
, req
, GFP_ATOMIC
);
857 ERROR(c
->cdev
, "source/sink response, err %d\n",
861 /* device either stalls (value < 0) or reports success */
865 static struct usb_function
*source_sink_alloc_func(
866 struct usb_function_instance
*fi
)
868 struct f_sourcesink
*ss
;
869 struct f_ss_opts
*ss_opts
;
871 ss
= kzalloc(sizeof(*ss
), GFP_KERNEL
);
875 ss_opts
= container_of(fi
, struct f_ss_opts
, func_inst
);
877 mutex_lock(&ss_opts
->lock
);
879 mutex_unlock(&ss_opts
->lock
);
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 inline struct f_ss_opts
*to_f_ss_opts(struct config_item
*item
)
903 return container_of(to_config_group(item
), struct f_ss_opts
,
907 CONFIGFS_ATTR_STRUCT(f_ss_opts
);
908 CONFIGFS_ATTR_OPS(f_ss_opts
);
910 static void ss_attr_release(struct config_item
*item
)
912 struct f_ss_opts
*ss_opts
= to_f_ss_opts(item
);
914 usb_put_function_instance(&ss_opts
->func_inst
);
917 static struct configfs_item_operations ss_item_ops
= {
918 .release
= ss_attr_release
,
919 .show_attribute
= f_ss_opts_attr_show
,
920 .store_attribute
= f_ss_opts_attr_store
,
923 static ssize_t
f_ss_opts_pattern_show(struct f_ss_opts
*opts
, char *page
)
927 mutex_lock(&opts
->lock
);
928 result
= sprintf(page
, "%u", opts
->pattern
);
929 mutex_unlock(&opts
->lock
);
934 static ssize_t
f_ss_opts_pattern_store(struct f_ss_opts
*opts
,
935 const char *page
, size_t len
)
940 mutex_lock(&opts
->lock
);
946 ret
= kstrtou8(page
, 0, &num
);
950 if (num
!= 0 && num
!= 1 && num
!= 2) {
958 mutex_unlock(&opts
->lock
);
962 static struct f_ss_opts_attribute f_ss_opts_pattern
=
963 __CONFIGFS_ATTR(pattern
, S_IRUGO
| S_IWUSR
,
964 f_ss_opts_pattern_show
,
965 f_ss_opts_pattern_store
);
967 static ssize_t
f_ss_opts_isoc_interval_show(struct f_ss_opts
*opts
, char *page
)
971 mutex_lock(&opts
->lock
);
972 result
= sprintf(page
, "%u", opts
->isoc_interval
);
973 mutex_unlock(&opts
->lock
);
978 static ssize_t
f_ss_opts_isoc_interval_store(struct f_ss_opts
*opts
,
979 const char *page
, size_t len
)
984 mutex_lock(&opts
->lock
);
990 ret
= kstrtou8(page
, 0, &num
);
999 opts
->isoc_interval
= num
;
1002 mutex_unlock(&opts
->lock
);
1006 static struct f_ss_opts_attribute f_ss_opts_isoc_interval
=
1007 __CONFIGFS_ATTR(isoc_interval
, S_IRUGO
| S_IWUSR
,
1008 f_ss_opts_isoc_interval_show
,
1009 f_ss_opts_isoc_interval_store
);
1011 static ssize_t
f_ss_opts_isoc_maxpacket_show(struct f_ss_opts
*opts
, char *page
)
1015 mutex_lock(&opts
->lock
);
1016 result
= sprintf(page
, "%u", opts
->isoc_maxpacket
);
1017 mutex_unlock(&opts
->lock
);
1022 static ssize_t
f_ss_opts_isoc_maxpacket_store(struct f_ss_opts
*opts
,
1023 const char *page
, size_t len
)
1028 mutex_lock(&opts
->lock
);
1034 ret
= kstrtou16(page
, 0, &num
);
1043 opts
->isoc_maxpacket
= num
;
1046 mutex_unlock(&opts
->lock
);
1050 static struct f_ss_opts_attribute f_ss_opts_isoc_maxpacket
=
1051 __CONFIGFS_ATTR(isoc_maxpacket
, S_IRUGO
| S_IWUSR
,
1052 f_ss_opts_isoc_maxpacket_show
,
1053 f_ss_opts_isoc_maxpacket_store
);
1055 static ssize_t
f_ss_opts_isoc_mult_show(struct f_ss_opts
*opts
, char *page
)
1059 mutex_lock(&opts
->lock
);
1060 result
= sprintf(page
, "%u", opts
->isoc_mult
);
1061 mutex_unlock(&opts
->lock
);
1066 static ssize_t
f_ss_opts_isoc_mult_store(struct f_ss_opts
*opts
,
1067 const char *page
, size_t len
)
1072 mutex_lock(&opts
->lock
);
1078 ret
= kstrtou8(page
, 0, &num
);
1087 opts
->isoc_mult
= num
;
1090 mutex_unlock(&opts
->lock
);
1094 static struct f_ss_opts_attribute f_ss_opts_isoc_mult
=
1095 __CONFIGFS_ATTR(isoc_mult
, S_IRUGO
| S_IWUSR
,
1096 f_ss_opts_isoc_mult_show
,
1097 f_ss_opts_isoc_mult_store
);
1099 static ssize_t
f_ss_opts_isoc_maxburst_show(struct f_ss_opts
*opts
, char *page
)
1103 mutex_lock(&opts
->lock
);
1104 result
= sprintf(page
, "%u", opts
->isoc_maxburst
);
1105 mutex_unlock(&opts
->lock
);
1110 static ssize_t
f_ss_opts_isoc_maxburst_store(struct f_ss_opts
*opts
,
1111 const char *page
, size_t len
)
1116 mutex_lock(&opts
->lock
);
1122 ret
= kstrtou8(page
, 0, &num
);
1131 opts
->isoc_maxburst
= num
;
1134 mutex_unlock(&opts
->lock
);
1138 static struct f_ss_opts_attribute f_ss_opts_isoc_maxburst
=
1139 __CONFIGFS_ATTR(isoc_maxburst
, S_IRUGO
| S_IWUSR
,
1140 f_ss_opts_isoc_maxburst_show
,
1141 f_ss_opts_isoc_maxburst_store
);
1143 static ssize_t
f_ss_opts_bulk_buflen_show(struct f_ss_opts
*opts
, char *page
)
1147 mutex_lock(&opts
->lock
);
1148 result
= sprintf(page
, "%u", opts
->bulk_buflen
);
1149 mutex_unlock(&opts
->lock
);
1154 static ssize_t
f_ss_opts_bulk_buflen_store(struct f_ss_opts
*opts
,
1155 const char *page
, size_t len
)
1160 mutex_lock(&opts
->lock
);
1166 ret
= kstrtou32(page
, 0, &num
);
1170 opts
->bulk_buflen
= num
;
1173 mutex_unlock(&opts
->lock
);
1177 static struct f_ss_opts_attribute f_ss_opts_bulk_buflen
=
1178 __CONFIGFS_ATTR(buflen
, S_IRUGO
| S_IWUSR
,
1179 f_ss_opts_bulk_buflen_show
,
1180 f_ss_opts_bulk_buflen_store
);
1182 static struct configfs_attribute
*ss_attrs
[] = {
1183 &f_ss_opts_pattern
.attr
,
1184 &f_ss_opts_isoc_interval
.attr
,
1185 &f_ss_opts_isoc_maxpacket
.attr
,
1186 &f_ss_opts_isoc_mult
.attr
,
1187 &f_ss_opts_isoc_maxburst
.attr
,
1188 &f_ss_opts_bulk_buflen
.attr
,
1192 static struct config_item_type ss_func_type
= {
1193 .ct_item_ops
= &ss_item_ops
,
1194 .ct_attrs
= ss_attrs
,
1195 .ct_owner
= THIS_MODULE
,
1198 static void source_sink_free_instance(struct usb_function_instance
*fi
)
1200 struct f_ss_opts
*ss_opts
;
1202 ss_opts
= container_of(fi
, struct f_ss_opts
, func_inst
);
1206 static struct usb_function_instance
*source_sink_alloc_inst(void)
1208 struct f_ss_opts
*ss_opts
;
1210 ss_opts
= kzalloc(sizeof(*ss_opts
), GFP_KERNEL
);
1212 return ERR_PTR(-ENOMEM
);
1213 mutex_init(&ss_opts
->lock
);
1214 ss_opts
->func_inst
.free_func_inst
= source_sink_free_instance
;
1215 ss_opts
->isoc_interval
= GZERO_ISOC_INTERVAL
;
1216 ss_opts
->isoc_maxpacket
= GZERO_ISOC_MAXPACKET
;
1217 ss_opts
->bulk_buflen
= GZERO_BULK_BUFLEN
;
1219 config_group_init_type_name(&ss_opts
->func_inst
.group
, "",
1222 return &ss_opts
->func_inst
;
1224 DECLARE_USB_FUNCTION(SourceSink
, source_sink_alloc_inst
,
1225 source_sink_alloc_func
);
1227 static int __init
sslb_modinit(void)
1231 ret
= usb_function_register(&SourceSinkusb_func
);
1236 usb_function_unregister(&SourceSinkusb_func
);
1239 static void __exit
sslb_modexit(void)
1241 usb_function_unregister(&SourceSinkusb_func
);
1244 module_init(sslb_modinit
);
1245 module_exit(sslb_modexit
);
1247 MODULE_LICENSE("GPL");