]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/usb/gadget/function/f_sourcesink.c
usb: dwc2: refactor common low-level hw code to platform.c
[mirror_ubuntu-bionic-kernel.git] / drivers / usb / gadget / function / f_sourcesink.c
CommitLineData
a400cadc
DB
1/*
2 * f_sourcesink.c - USB peripheral source/sink configuration driver
3 *
4 * Copyright (C) 2003-2008 David Brownell
5 * Copyright (C) 2008 by Nokia Corporation
6 *
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.
a400cadc
DB
11 */
12
13/* #define VERBOSE_DEBUG */
14
5a0e3ad6 15#include <linux/slab.h>
a400cadc 16#include <linux/kernel.h>
a400cadc 17#include <linux/device.h>
6eb0de82 18#include <linux/module.h>
cf9a08ae
SAS
19#include <linux/usb/composite.h>
20#include <linux/err.h>
a400cadc
DB
21
22#include "g_zero.h"
1efd54ea 23#include "u_f.h"
a400cadc 24
a400cadc
DB
25/*
26 * SOURCE/SINK FUNCTION ... a primary testing vehicle for USB peripheral
27 * controller drivers.
28 *
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.
32 *
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.
37 *
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.
a400cadc
DB
44 */
45struct f_sourcesink {
46 struct usb_function function;
47
48 struct usb_ep *in_ep;
49 struct usb_ep *out_ep;
b4036ccd
PZ
50 struct usb_ep *iso_in_ep;
51 struct usb_ep *iso_out_ep;
52 int cur_alt;
a400cadc
DB
53};
54
55static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
56{
57 return container_of(f, struct f_sourcesink, function);
58}
59
a400cadc 60static unsigned pattern;
cf9a08ae
SAS
61static unsigned isoc_interval;
62static unsigned isoc_maxpacket;
b4036ccd 63static unsigned isoc_mult;
b4036ccd 64static unsigned isoc_maxburst;
cf9a08ae 65static unsigned buflen;
a400cadc
DB
66
67/*-------------------------------------------------------------------------*/
68
b4036ccd
PZ
69static struct usb_interface_descriptor source_sink_intf_alt0 = {
70 .bLength = USB_DT_INTERFACE_SIZE,
a400cadc
DB
71 .bDescriptorType = USB_DT_INTERFACE,
72
b4036ccd 73 .bAlternateSetting = 0,
a400cadc
DB
74 .bNumEndpoints = 2,
75 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
b4036ccd
PZ
76 /* .iInterface = DYNAMIC */
77};
78
79static struct usb_interface_descriptor source_sink_intf_alt1 = {
80 .bLength = USB_DT_INTERFACE_SIZE,
81 .bDescriptorType = USB_DT_INTERFACE,
82
83 .bAlternateSetting = 1,
84 .bNumEndpoints = 4,
85 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
86 /* .iInterface = DYNAMIC */
a400cadc
DB
87};
88
89/* full speed support: */
90
91static struct usb_endpoint_descriptor fs_source_desc = {
92 .bLength = USB_DT_ENDPOINT_SIZE,
93 .bDescriptorType = USB_DT_ENDPOINT,
94
95 .bEndpointAddress = USB_DIR_IN,
96 .bmAttributes = USB_ENDPOINT_XFER_BULK,
97};
98
99static struct usb_endpoint_descriptor fs_sink_desc = {
100 .bLength = USB_DT_ENDPOINT_SIZE,
101 .bDescriptorType = USB_DT_ENDPOINT,
102
103 .bEndpointAddress = USB_DIR_OUT,
104 .bmAttributes = USB_ENDPOINT_XFER_BULK,
105};
106
b4036ccd
PZ
107static struct usb_endpoint_descriptor fs_iso_source_desc = {
108 .bLength = USB_DT_ENDPOINT_SIZE,
109 .bDescriptorType = USB_DT_ENDPOINT,
110
111 .bEndpointAddress = USB_DIR_IN,
112 .bmAttributes = USB_ENDPOINT_XFER_ISOC,
113 .wMaxPacketSize = cpu_to_le16(1023),
114 .bInterval = 4,
115};
116
117static struct usb_endpoint_descriptor fs_iso_sink_desc = {
118 .bLength = USB_DT_ENDPOINT_SIZE,
119 .bDescriptorType = USB_DT_ENDPOINT,
120
121 .bEndpointAddress = USB_DIR_OUT,
122 .bmAttributes = USB_ENDPOINT_XFER_ISOC,
123 .wMaxPacketSize = cpu_to_le16(1023),
124 .bInterval = 4,
125};
126
a400cadc 127static struct usb_descriptor_header *fs_source_sink_descs[] = {
b4036ccd 128 (struct usb_descriptor_header *) &source_sink_intf_alt0,
a400cadc
DB
129 (struct usb_descriptor_header *) &fs_sink_desc,
130 (struct usb_descriptor_header *) &fs_source_desc,
b4036ccd
PZ
131 (struct usb_descriptor_header *) &source_sink_intf_alt1,
132#define FS_ALT_IFC_1_OFFSET 3
133 (struct usb_descriptor_header *) &fs_sink_desc,
134 (struct usb_descriptor_header *) &fs_source_desc,
135 (struct usb_descriptor_header *) &fs_iso_sink_desc,
136 (struct usb_descriptor_header *) &fs_iso_source_desc,
a400cadc
DB
137 NULL,
138};
139
140/* high speed support: */
141
142static struct usb_endpoint_descriptor hs_source_desc = {
143 .bLength = USB_DT_ENDPOINT_SIZE,
144 .bDescriptorType = USB_DT_ENDPOINT,
145
146 .bmAttributes = USB_ENDPOINT_XFER_BULK,
551509d2 147 .wMaxPacketSize = cpu_to_le16(512),
a400cadc
DB
148};
149
150static struct usb_endpoint_descriptor hs_sink_desc = {
151 .bLength = USB_DT_ENDPOINT_SIZE,
152 .bDescriptorType = USB_DT_ENDPOINT,
153
154 .bmAttributes = USB_ENDPOINT_XFER_BULK,
551509d2 155 .wMaxPacketSize = cpu_to_le16(512),
a400cadc
DB
156};
157
b4036ccd
PZ
158static struct usb_endpoint_descriptor hs_iso_source_desc = {
159 .bLength = USB_DT_ENDPOINT_SIZE,
160 .bDescriptorType = USB_DT_ENDPOINT,
161
162 .bmAttributes = USB_ENDPOINT_XFER_ISOC,
163 .wMaxPacketSize = cpu_to_le16(1024),
164 .bInterval = 4,
165};
166
167static struct usb_endpoint_descriptor hs_iso_sink_desc = {
168 .bLength = USB_DT_ENDPOINT_SIZE,
169 .bDescriptorType = USB_DT_ENDPOINT,
170
171 .bmAttributes = USB_ENDPOINT_XFER_ISOC,
172 .wMaxPacketSize = cpu_to_le16(1024),
173 .bInterval = 4,
174};
175
a400cadc 176static struct usb_descriptor_header *hs_source_sink_descs[] = {
b4036ccd 177 (struct usb_descriptor_header *) &source_sink_intf_alt0,
a400cadc
DB
178 (struct usb_descriptor_header *) &hs_source_desc,
179 (struct usb_descriptor_header *) &hs_sink_desc,
b4036ccd
PZ
180 (struct usb_descriptor_header *) &source_sink_intf_alt1,
181#define HS_ALT_IFC_1_OFFSET 3
182 (struct usb_descriptor_header *) &hs_source_desc,
183 (struct usb_descriptor_header *) &hs_sink_desc,
184 (struct usb_descriptor_header *) &hs_iso_source_desc,
185 (struct usb_descriptor_header *) &hs_iso_sink_desc,
a400cadc
DB
186 NULL,
187};
188
57c97c02
AB
189/* super speed support: */
190
191static struct usb_endpoint_descriptor ss_source_desc = {
192 .bLength = USB_DT_ENDPOINT_SIZE,
193 .bDescriptorType = USB_DT_ENDPOINT,
194
195 .bmAttributes = USB_ENDPOINT_XFER_BULK,
196 .wMaxPacketSize = cpu_to_le16(1024),
197};
198
4a5ee77c 199static struct usb_ss_ep_comp_descriptor ss_source_comp_desc = {
57c97c02
AB
200 .bLength = USB_DT_SS_EP_COMP_SIZE,
201 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
b4036ccd 202
57c97c02
AB
203 .bMaxBurst = 0,
204 .bmAttributes = 0,
205 .wBytesPerInterval = 0,
206};
207
208static struct usb_endpoint_descriptor ss_sink_desc = {
209 .bLength = USB_DT_ENDPOINT_SIZE,
210 .bDescriptorType = USB_DT_ENDPOINT,
211
212 .bmAttributes = USB_ENDPOINT_XFER_BULK,
213 .wMaxPacketSize = cpu_to_le16(1024),
214};
215
4a5ee77c 216static struct usb_ss_ep_comp_descriptor ss_sink_comp_desc = {
57c97c02
AB
217 .bLength = USB_DT_SS_EP_COMP_SIZE,
218 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
b4036ccd 219
57c97c02
AB
220 .bMaxBurst = 0,
221 .bmAttributes = 0,
222 .wBytesPerInterval = 0,
223};
224
b4036ccd
PZ
225static struct usb_endpoint_descriptor ss_iso_source_desc = {
226 .bLength = USB_DT_ENDPOINT_SIZE,
227 .bDescriptorType = USB_DT_ENDPOINT,
228
229 .bmAttributes = USB_ENDPOINT_XFER_ISOC,
230 .wMaxPacketSize = cpu_to_le16(1024),
231 .bInterval = 4,
232};
233
4a5ee77c 234static struct usb_ss_ep_comp_descriptor ss_iso_source_comp_desc = {
b4036ccd
PZ
235 .bLength = USB_DT_SS_EP_COMP_SIZE,
236 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
237
238 .bMaxBurst = 0,
239 .bmAttributes = 0,
240 .wBytesPerInterval = cpu_to_le16(1024),
241};
242
243static struct usb_endpoint_descriptor ss_iso_sink_desc = {
244 .bLength = USB_DT_ENDPOINT_SIZE,
245 .bDescriptorType = USB_DT_ENDPOINT,
246
247 .bmAttributes = USB_ENDPOINT_XFER_ISOC,
248 .wMaxPacketSize = cpu_to_le16(1024),
249 .bInterval = 4,
250};
251
4a5ee77c 252static struct usb_ss_ep_comp_descriptor ss_iso_sink_comp_desc = {
b4036ccd
PZ
253 .bLength = USB_DT_SS_EP_COMP_SIZE,
254 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
255
256 .bMaxBurst = 0,
257 .bmAttributes = 0,
258 .wBytesPerInterval = cpu_to_le16(1024),
259};
260
57c97c02 261static struct usb_descriptor_header *ss_source_sink_descs[] = {
b4036ccd 262 (struct usb_descriptor_header *) &source_sink_intf_alt0,
57c97c02
AB
263 (struct usb_descriptor_header *) &ss_source_desc,
264 (struct usb_descriptor_header *) &ss_source_comp_desc,
265 (struct usb_descriptor_header *) &ss_sink_desc,
266 (struct usb_descriptor_header *) &ss_sink_comp_desc,
b4036ccd
PZ
267 (struct usb_descriptor_header *) &source_sink_intf_alt1,
268#define SS_ALT_IFC_1_OFFSET 5
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 *) &ss_iso_source_desc,
274 (struct usb_descriptor_header *) &ss_iso_source_comp_desc,
275 (struct usb_descriptor_header *) &ss_iso_sink_desc,
276 (struct usb_descriptor_header *) &ss_iso_sink_comp_desc,
57c97c02
AB
277 NULL,
278};
279
a400cadc
DB
280/* function-specific strings: */
281
282static struct usb_string strings_sourcesink[] = {
283 [0].s = "source and sink data",
284 { } /* end of list */
285};
286
287static struct usb_gadget_strings stringtab_sourcesink = {
288 .language = 0x0409, /* en-us */
289 .strings = strings_sourcesink,
290};
291
292static struct usb_gadget_strings *sourcesink_strings[] = {
293 &stringtab_sourcesink,
294 NULL,
295};
296
297/*-------------------------------------------------------------------------*/
298
1efd54ea 299static inline struct usb_request *ss_alloc_ep_req(struct usb_ep *ep, int len)
cf9a08ae 300{
1efd54ea 301 return alloc_ep_req(ep, len, buflen);
cf9a08ae
SAS
302}
303
304void free_ep_req(struct usb_ep *ep, struct usb_request *req)
305{
306 kfree(req->buf);
307 usb_ep_free_request(ep, req);
308}
309
310static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep)
311{
312 int value;
313
dbd2badf
RB
314 value = usb_ep_disable(ep);
315 if (value < 0)
316 DBG(cdev, "disable %s --> %d\n", ep->name, value);
cf9a08ae
SAS
317}
318
319void disable_endpoints(struct usb_composite_dev *cdev,
320 struct usb_ep *in, struct usb_ep *out,
2c247804 321 struct usb_ep *iso_in, struct usb_ep *iso_out)
cf9a08ae
SAS
322{
323 disable_ep(cdev, in);
324 disable_ep(cdev, out);
325 if (iso_in)
326 disable_ep(cdev, iso_in);
327 if (iso_out)
328 disable_ep(cdev, iso_out);
329}
330
331static int
a400cadc
DB
332sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
333{
334 struct usb_composite_dev *cdev = c->cdev;
335 struct f_sourcesink *ss = func_to_ss(f);
336 int id;
10287bae 337 int ret;
a400cadc
DB
338
339 /* allocate interface ID(s) */
340 id = usb_interface_id(c, f);
341 if (id < 0)
342 return id;
b4036ccd
PZ
343 source_sink_intf_alt0.bInterfaceNumber = id;
344 source_sink_intf_alt1.bInterfaceNumber = id;
a400cadc 345
b4036ccd 346 /* allocate bulk endpoints */
a400cadc
DB
347 ss->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_source_desc);
348 if (!ss->in_ep) {
349autoconf_fail:
350 ERROR(cdev, "%s: can't autoconfigure on %s\n",
351 f->name, cdev->gadget->name);
352 return -ENODEV;
353 }
a400cadc
DB
354
355 ss->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_sink_desc);
356 if (!ss->out_ep)
357 goto autoconf_fail;
a400cadc 358
b4036ccd
PZ
359 /* sanity check the isoc module parameters */
360 if (isoc_interval < 1)
361 isoc_interval = 1;
362 if (isoc_interval > 16)
363 isoc_interval = 16;
364 if (isoc_mult > 2)
365 isoc_mult = 2;
366 if (isoc_maxburst > 15)
367 isoc_maxburst = 15;
368
369 /* fill in the FS isoc descriptors from the module parameters */
370 fs_iso_source_desc.wMaxPacketSize = isoc_maxpacket > 1023 ?
371 1023 : isoc_maxpacket;
372 fs_iso_source_desc.bInterval = isoc_interval;
373 fs_iso_sink_desc.wMaxPacketSize = isoc_maxpacket > 1023 ?
374 1023 : isoc_maxpacket;
375 fs_iso_sink_desc.bInterval = isoc_interval;
376
377 /* allocate iso endpoints */
378 ss->iso_in_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_source_desc);
379 if (!ss->iso_in_ep)
380 goto no_iso;
b4036ccd
PZ
381
382 ss->iso_out_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_sink_desc);
dbd2badf
RB
383 if (!ss->iso_out_ep) {
384 usb_ep_autoconfig_release(ss->iso_in_ep);
b4036ccd
PZ
385 ss->iso_in_ep = NULL;
386no_iso:
387 /*
388 * We still want to work even if the UDC doesn't have isoc
389 * endpoints, so null out the alt interface that contains
390 * them and continue.
391 */
392 fs_source_sink_descs[FS_ALT_IFC_1_OFFSET] = NULL;
393 hs_source_sink_descs[HS_ALT_IFC_1_OFFSET] = NULL;
394 ss_source_sink_descs[SS_ALT_IFC_1_OFFSET] = NULL;
395 }
396
397 if (isoc_maxpacket > 1024)
398 isoc_maxpacket = 1024;
399
a400cadc 400 /* support high speed hardware */
10287bae
SAS
401 hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress;
402 hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress;
403
404 /*
2c247804
FB
405 * Fill in the HS isoc descriptors from the module parameters.
406 * We assume that the user knows what they are doing and won't
407 * give parameters that their UDC doesn't support.
10287bae
SAS
408 */
409 hs_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
410 hs_iso_source_desc.wMaxPacketSize |= isoc_mult << 11;
411 hs_iso_source_desc.bInterval = isoc_interval;
412 hs_iso_source_desc.bEndpointAddress =
413 fs_iso_source_desc.bEndpointAddress;
414
415 hs_iso_sink_desc.wMaxPacketSize = isoc_maxpacket;
416 hs_iso_sink_desc.wMaxPacketSize |= isoc_mult << 11;
417 hs_iso_sink_desc.bInterval = isoc_interval;
418 hs_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
a400cadc 419
57c97c02 420 /* support super speed hardware */
10287bae
SAS
421 ss_source_desc.bEndpointAddress =
422 fs_source_desc.bEndpointAddress;
423 ss_sink_desc.bEndpointAddress =
424 fs_sink_desc.bEndpointAddress;
425
426 /*
2c247804
FB
427 * Fill in the SS isoc descriptors from the module parameters.
428 * We assume that the user knows what they are doing and won't
429 * give parameters that their UDC doesn't support.
10287bae
SAS
430 */
431 ss_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
432 ss_iso_source_desc.bInterval = isoc_interval;
433 ss_iso_source_comp_desc.bmAttributes = isoc_mult;
434 ss_iso_source_comp_desc.bMaxBurst = isoc_maxburst;
435 ss_iso_source_comp_desc.wBytesPerInterval =
436 isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
437 ss_iso_source_desc.bEndpointAddress =
438 fs_iso_source_desc.bEndpointAddress;
439
440 ss_iso_sink_desc.wMaxPacketSize = isoc_maxpacket;
441 ss_iso_sink_desc.bInterval = isoc_interval;
442 ss_iso_sink_comp_desc.bmAttributes = isoc_mult;
443 ss_iso_sink_comp_desc.bMaxBurst = isoc_maxburst;
444 ss_iso_sink_comp_desc.wBytesPerInterval =
445 isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
446 ss_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
447
448 ret = usb_assign_descriptors(f, fs_source_sink_descs,
449 hs_source_sink_descs, ss_source_sink_descs);
450 if (ret)
451 return ret;
57c97c02 452
2c247804 453 DBG(cdev, "%s speed %s: IN/%s, OUT/%s, ISO-IN/%s, ISO-OUT/%s\n",
57c97c02
AB
454 (gadget_is_superspeed(c->cdev->gadget) ? "super" :
455 (gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full")),
b4036ccd
PZ
456 f->name, ss->in_ep->name, ss->out_ep->name,
457 ss->iso_in_ep ? ss->iso_in_ep->name : "<none>",
2c247804 458 ss->iso_out_ep ? ss->iso_out_ep->name : "<none>");
a400cadc
DB
459 return 0;
460}
461
462static void
cf9a08ae 463sourcesink_free_func(struct usb_function *f)
a400cadc 464{
25d80151
AP
465 struct f_ss_opts *opts;
466
467 opts = container_of(f->fi, struct f_ss_opts, func_inst);
468
469 mutex_lock(&opts->lock);
470 opts->refcnt--;
471 mutex_unlock(&opts->lock);
472
10287bae 473 usb_free_all_descriptors(f);
a400cadc
DB
474 kfree(func_to_ss(f));
475}
476
477/* optionally require specific source/sink data patterns */
478static int check_read_data(struct f_sourcesink *ss, struct usb_request *req)
479{
480 unsigned i;
481 u8 *buf = req->buf;
482 struct usb_composite_dev *cdev = ss->function.config->cdev;
04683909 483 int max_packet_size = le16_to_cpu(ss->out_ep->desc->wMaxPacketSize);
a400cadc 484
b4036ccd
PZ
485 if (pattern == 2)
486 return 0;
487
a400cadc
DB
488 for (i = 0; i < req->actual; i++, buf++) {
489 switch (pattern) {
490
491 /* all-zeroes has no synchronization issues */
492 case 0:
493 if (*buf == 0)
494 continue;
495 break;
496
497 /* "mod63" stays in sync with short-terminated transfers,
498 * OR otherwise when host and gadget agree on how large
499 * each usb transfer request should be. Resync is done
500 * with set_interface or set_config. (We *WANT* it to
501 * get quickly out of sync if controllers or their drivers
b4036ccd 502 * stutter for any reason, including buffer duplication...)
a400cadc
DB
503 */
504 case 1:
04683909 505 if (*buf == (u8)((i % max_packet_size) % 63))
a400cadc
DB
506 continue;
507 break;
508 }
509 ERROR(cdev, "bad OUT byte, buf[%d] = %d\n", i, *buf);
510 usb_ep_set_halt(ss->out_ep);
511 return -EINVAL;
512 }
513 return 0;
514}
515
516static void reinit_write_data(struct usb_ep *ep, struct usb_request *req)
517{
518 unsigned i;
519 u8 *buf = req->buf;
04683909 520 int max_packet_size = le16_to_cpu(ep->desc->wMaxPacketSize);
a400cadc
DB
521
522 switch (pattern) {
523 case 0:
524 memset(req->buf, 0, req->length);
525 break;
526 case 1:
527 for (i = 0; i < req->length; i++)
04683909 528 *buf++ = (u8) ((i % max_packet_size) % 63);
a400cadc 529 break;
b4036ccd
PZ
530 case 2:
531 break;
a400cadc
DB
532 }
533}
534
535static void source_sink_complete(struct usb_ep *ep, struct usb_request *req)
536{
b4036ccd
PZ
537 struct usb_composite_dev *cdev;
538 struct f_sourcesink *ss = ep->driver_data;
539 int status = req->status;
540
541 /* driver_data will be null if ep has been disabled */
542 if (!ss)
543 return;
544
545 cdev = ss->function.config->cdev;
a400cadc
DB
546
547 switch (status) {
548
549 case 0: /* normal completion? */
550 if (ep == ss->out_ep) {
551 check_read_data(ss, req);
b4036ccd
PZ
552 if (pattern != 2)
553 memset(req->buf, 0x55, req->length);
32c9cf22 554 }
a400cadc
DB
555 break;
556
557 /* this endpoint is normally active while we're configured */
558 case -ECONNABORTED: /* hardware forced ep reset */
559 case -ECONNRESET: /* request dequeued */
560 case -ESHUTDOWN: /* disconnect from host */
561 VDBG(cdev, "%s gone (%d), %d/%d\n", ep->name, status,
562 req->actual, req->length);
563 if (ep == ss->out_ep)
564 check_read_data(ss, req);
565 free_ep_req(ep, req);
566 return;
567
568 case -EOVERFLOW: /* buffer overrun on read means that
569 * we didn't provide a big enough
570 * buffer.
571 */
572 default:
573#if 1
574 DBG(cdev, "%s complete --> %d, %d/%d\n", ep->name,
575 status, req->actual, req->length);
576#endif
577 case -EREMOTEIO: /* short read */
578 break;
579 }
580
581 status = usb_ep_queue(ep, req, GFP_ATOMIC);
582 if (status) {
583 ERROR(cdev, "kill %s: resubmit %d bytes --> %d\n",
584 ep->name, req->length, status);
585 usb_ep_set_halt(ep);
586 /* FIXME recover later ... somehow */
587 }
588}
589
b4036ccd 590static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
2c247804 591 bool is_iso, int speed)
a400cadc
DB
592{
593 struct usb_ep *ep;
594 struct usb_request *req;
b4036ccd
PZ
595 int i, size, status;
596
597 for (i = 0; i < 8; i++) {
2c247804 598 if (is_iso) {
b4036ccd
PZ
599 switch (speed) {
600 case USB_SPEED_SUPER:
601 size = isoc_maxpacket * (isoc_mult + 1) *
602 (isoc_maxburst + 1);
603 break;
604 case USB_SPEED_HIGH:
605 size = isoc_maxpacket * (isoc_mult + 1);
606 break;
607 default:
608 size = isoc_maxpacket > 1023 ?
609 1023 : isoc_maxpacket;
610 break;
611 }
612 ep = is_in ? ss->iso_in_ep : ss->iso_out_ep;
1efd54ea 613 req = ss_alloc_ep_req(ep, size);
2c247804 614 } else {
b4036ccd 615 ep = is_in ? ss->in_ep : ss->out_ep;
1efd54ea 616 req = ss_alloc_ep_req(ep, 0);
b4036ccd 617 }
a400cadc 618
b4036ccd
PZ
619 if (!req)
620 return -ENOMEM;
a400cadc 621
b4036ccd
PZ
622 req->complete = source_sink_complete;
623 if (is_in)
624 reinit_write_data(ep, req);
625 else if (pattern != 2)
626 memset(req->buf, 0x55, req->length);
a400cadc 627
b4036ccd
PZ
628 status = usb_ep_queue(ep, req, GFP_ATOMIC);
629 if (status) {
630 struct usb_composite_dev *cdev;
a400cadc 631
b4036ccd
PZ
632 cdev = ss->function.config->cdev;
633 ERROR(cdev, "start %s%s %s --> %d\n",
2c247804
FB
634 is_iso ? "ISO-" : "", is_in ? "IN" : "OUT",
635 ep->name, status);
b4036ccd
PZ
636 free_ep_req(ep, req);
637 }
638
2c247804 639 if (!is_iso)
b4036ccd 640 break;
a400cadc
DB
641 }
642
643 return status;
644}
645
646static void disable_source_sink(struct f_sourcesink *ss)
647{
648 struct usb_composite_dev *cdev;
649
650 cdev = ss->function.config->cdev;
b4036ccd 651 disable_endpoints(cdev, ss->in_ep, ss->out_ep, ss->iso_in_ep,
2c247804 652 ss->iso_out_ep);
a400cadc
DB
653 VDBG(cdev, "%s disabled\n", ss->function.name);
654}
655
656static int
b4036ccd
PZ
657enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss,
658 int alt)
a400cadc
DB
659{
660 int result = 0;
b4036ccd 661 int speed = cdev->gadget->speed;
a400cadc
DB
662 struct usb_ep *ep;
663
b4036ccd 664 /* one bulk endpoint writes (sources) zeroes IN (to the host) */
a400cadc 665 ep = ss->in_ep;
ea2a1df7
TB
666 result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
667 if (result)
668 return result;
72c973dd 669 result = usb_ep_enable(ep);
a400cadc
DB
670 if (result < 0)
671 return result;
672 ep->driver_data = ss;
673
2c247804 674 result = source_sink_start_ep(ss, true, false, speed);
a400cadc
DB
675 if (result < 0) {
676fail:
677 ep = ss->in_ep;
678 usb_ep_disable(ep);
a400cadc
DB
679 return result;
680 }
681
b4036ccd 682 /* one bulk endpoint reads (sinks) anything OUT (from the host) */
a400cadc 683 ep = ss->out_ep;
ea2a1df7
TB
684 result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
685 if (result)
686 goto fail;
72c973dd 687 result = usb_ep_enable(ep);
a400cadc
DB
688 if (result < 0)
689 goto fail;
690 ep->driver_data = ss;
691
2c247804 692 result = source_sink_start_ep(ss, false, false, speed);
a400cadc 693 if (result < 0) {
b4036ccd
PZ
694fail2:
695 ep = ss->out_ep;
a400cadc 696 usb_ep_disable(ep);
a400cadc
DB
697 goto fail;
698 }
699
b4036ccd
PZ
700 if (alt == 0)
701 goto out;
702
703 /* one iso endpoint writes (sources) zeroes IN (to the host) */
704 ep = ss->iso_in_ep;
705 if (ep) {
706 result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
707 if (result)
708 goto fail2;
709 result = usb_ep_enable(ep);
710 if (result < 0)
711 goto fail2;
712 ep->driver_data = ss;
713
2c247804 714 result = source_sink_start_ep(ss, true, true, speed);
b4036ccd
PZ
715 if (result < 0) {
716fail3:
717 ep = ss->iso_in_ep;
dbd2badf 718 if (ep)
b4036ccd 719 usb_ep_disable(ep);
b4036ccd
PZ
720 goto fail2;
721 }
722 }
723
724 /* one iso endpoint reads (sinks) anything OUT (from the host) */
725 ep = ss->iso_out_ep;
726 if (ep) {
727 result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
728 if (result)
729 goto fail3;
730 result = usb_ep_enable(ep);
731 if (result < 0)
732 goto fail3;
733 ep->driver_data = ss;
734
2c247804 735 result = source_sink_start_ep(ss, false, true, speed);
b4036ccd
PZ
736 if (result < 0) {
737 usb_ep_disable(ep);
b4036ccd
PZ
738 goto fail3;
739 }
740 }
741out:
742 ss->cur_alt = alt;
743
744 DBG(cdev, "%s enabled, alt intf %d\n", ss->function.name, alt);
a400cadc
DB
745 return result;
746}
747
748static int sourcesink_set_alt(struct usb_function *f,
749 unsigned intf, unsigned alt)
750{
b4036ccd
PZ
751 struct f_sourcesink *ss = func_to_ss(f);
752 struct usb_composite_dev *cdev = f->config->cdev;
a400cadc 753
dbd2badf 754 disable_source_sink(ss);
b4036ccd
PZ
755 return enable_source_sink(cdev, ss, alt);
756}
757
758static int sourcesink_get_alt(struct usb_function *f, unsigned intf)
759{
760 struct f_sourcesink *ss = func_to_ss(f);
761
762 return ss->cur_alt;
a400cadc
DB
763}
764
765static void sourcesink_disable(struct usb_function *f)
766{
767 struct f_sourcesink *ss = func_to_ss(f);
768
769 disable_source_sink(ss);
770}
771
a400cadc 772/*-------------------------------------------------------------------------*/
cf9a08ae 773
544aca39 774static int sourcesink_setup(struct usb_function *f,
a400cadc
DB
775 const struct usb_ctrlrequest *ctrl)
776{
544aca39 777 struct usb_configuration *c = f->config;
a400cadc
DB
778 struct usb_request *req = c->cdev->req;
779 int value = -EOPNOTSUPP;
780 u16 w_index = le16_to_cpu(ctrl->wIndex);
781 u16 w_value = le16_to_cpu(ctrl->wValue);
782 u16 w_length = le16_to_cpu(ctrl->wLength);
783
e13f17ff 784 req->length = USB_COMP_EP0_BUFSIZ;
5030ec73 785
a400cadc
DB
786 /* composite driver infrastructure handles everything except
787 * the two control test requests.
788 */
789 switch (ctrl->bRequest) {
790
791 /*
792 * These are the same vendor-specific requests supported by
793 * Intel's USB 2.0 compliance test devices. We exceed that
794 * device spec by allowing multiple-packet requests.
795 *
796 * NOTE: the Control-OUT data stays in req->buf ... better
797 * would be copying it into a scratch buffer, so that other
798 * requests may safely intervene.
799 */
800 case 0x5b: /* control WRITE test -- fill the buffer */
801 if (ctrl->bRequestType != (USB_DIR_OUT|USB_TYPE_VENDOR))
802 goto unknown;
803 if (w_value || w_index)
804 break;
805 /* just read that many bytes into the buffer */
806 if (w_length > req->length)
807 break;
808 value = w_length;
809 break;
810 case 0x5c: /* control READ test -- return the buffer */
811 if (ctrl->bRequestType != (USB_DIR_IN|USB_TYPE_VENDOR))
812 goto unknown;
813 if (w_value || w_index)
814 break;
815 /* expect those bytes are still in the buffer; send back */
816 if (w_length > req->length)
817 break;
818 value = w_length;
819 break;
820
821 default:
822unknown:
823 VDBG(c->cdev,
824 "unknown control req%02x.%02x v%04x i%04x l%d\n",
825 ctrl->bRequestType, ctrl->bRequest,
826 w_value, w_index, w_length);
827 }
828
829 /* respond with data transfer or status phase? */
830 if (value >= 0) {
831 VDBG(c->cdev, "source/sink req%02x.%02x v%04x i%04x l%d\n",
832 ctrl->bRequestType, ctrl->bRequest,
833 w_value, w_index, w_length);
834 req->zero = 0;
835 req->length = value;
836 value = usb_ep_queue(c->cdev->gadget->ep0, req, GFP_ATOMIC);
837 if (value < 0)
b4036ccd 838 ERROR(c->cdev, "source/sink response, err %d\n",
a400cadc
DB
839 value);
840 }
841
842 /* device either stalls (value < 0) or reports success */
843 return value;
844}
845
cf9a08ae
SAS
846static struct usb_function *source_sink_alloc_func(
847 struct usb_function_instance *fi)
544aca39 848{
cf9a08ae
SAS
849 struct f_sourcesink *ss;
850 struct f_ss_opts *ss_opts;
544aca39
SAS
851
852 ss = kzalloc(sizeof(*ss), GFP_KERNEL);
853 if (!ss)
cf9a08ae 854 return NULL;
544aca39 855
cf9a08ae 856 ss_opts = container_of(fi, struct f_ss_opts, func_inst);
25d80151
AP
857
858 mutex_lock(&ss_opts->lock);
859 ss_opts->refcnt++;
860 mutex_unlock(&ss_opts->lock);
861
cf9a08ae
SAS
862 pattern = ss_opts->pattern;
863 isoc_interval = ss_opts->isoc_interval;
864 isoc_maxpacket = ss_opts->isoc_maxpacket;
865 isoc_mult = ss_opts->isoc_mult;
866 isoc_maxburst = ss_opts->isoc_maxburst;
867 buflen = ss_opts->bulk_buflen;
544aca39
SAS
868
869 ss->function.name = "source/sink";
870 ss->function.bind = sourcesink_bind;
544aca39
SAS
871 ss->function.set_alt = sourcesink_set_alt;
872 ss->function.get_alt = sourcesink_get_alt;
873 ss->function.disable = sourcesink_disable;
874 ss->function.setup = sourcesink_setup;
cf9a08ae 875 ss->function.strings = sourcesink_strings;
544aca39 876
cf9a08ae
SAS
877 ss->function.free_func = sourcesink_free_func;
878
879 return &ss->function;
544aca39
SAS
880}
881
25d80151
AP
882static inline struct f_ss_opts *to_f_ss_opts(struct config_item *item)
883{
884 return container_of(to_config_group(item), struct f_ss_opts,
885 func_inst.group);
886}
887
888CONFIGFS_ATTR_STRUCT(f_ss_opts);
889CONFIGFS_ATTR_OPS(f_ss_opts);
890
891static void ss_attr_release(struct config_item *item)
892{
893 struct f_ss_opts *ss_opts = to_f_ss_opts(item);
894
895 usb_put_function_instance(&ss_opts->func_inst);
896}
897
898static struct configfs_item_operations ss_item_ops = {
899 .release = ss_attr_release,
900 .show_attribute = f_ss_opts_attr_show,
901 .store_attribute = f_ss_opts_attr_store,
902};
903
904static ssize_t f_ss_opts_pattern_show(struct f_ss_opts *opts, char *page)
905{
906 int result;
907
908 mutex_lock(&opts->lock);
fa50bff6 909 result = sprintf(page, "%u\n", opts->pattern);
25d80151
AP
910 mutex_unlock(&opts->lock);
911
912 return result;
913}
914
915static ssize_t f_ss_opts_pattern_store(struct f_ss_opts *opts,
916 const char *page, size_t len)
917{
918 int ret;
919 u8 num;
920
921 mutex_lock(&opts->lock);
922 if (opts->refcnt) {
923 ret = -EBUSY;
924 goto end;
925 }
926
927 ret = kstrtou8(page, 0, &num);
928 if (ret)
929 goto end;
930
931 if (num != 0 && num != 1 && num != 2) {
932 ret = -EINVAL;
933 goto end;
934 }
935
936 opts->pattern = num;
937 ret = len;
938end:
939 mutex_unlock(&opts->lock);
940 return ret;
941}
942
943static struct f_ss_opts_attribute f_ss_opts_pattern =
944 __CONFIGFS_ATTR(pattern, S_IRUGO | S_IWUSR,
945 f_ss_opts_pattern_show,
946 f_ss_opts_pattern_store);
947
948static ssize_t f_ss_opts_isoc_interval_show(struct f_ss_opts *opts, char *page)
949{
950 int result;
951
952 mutex_lock(&opts->lock);
fa50bff6 953 result = sprintf(page, "%u\n", opts->isoc_interval);
25d80151
AP
954 mutex_unlock(&opts->lock);
955
956 return result;
957}
958
959static ssize_t f_ss_opts_isoc_interval_store(struct f_ss_opts *opts,
960 const char *page, size_t len)
961{
962 int ret;
963 u8 num;
964
965 mutex_lock(&opts->lock);
966 if (opts->refcnt) {
967 ret = -EBUSY;
968 goto end;
969 }
970
971 ret = kstrtou8(page, 0, &num);
972 if (ret)
973 goto end;
974
975 if (num > 16) {
976 ret = -EINVAL;
977 goto end;
978 }
979
980 opts->isoc_interval = num;
981 ret = len;
982end:
983 mutex_unlock(&opts->lock);
984 return ret;
985}
986
987static struct f_ss_opts_attribute f_ss_opts_isoc_interval =
988 __CONFIGFS_ATTR(isoc_interval, S_IRUGO | S_IWUSR,
989 f_ss_opts_isoc_interval_show,
990 f_ss_opts_isoc_interval_store);
991
992static ssize_t f_ss_opts_isoc_maxpacket_show(struct f_ss_opts *opts, char *page)
993{
994 int result;
995
996 mutex_lock(&opts->lock);
fa50bff6 997 result = sprintf(page, "%u\n", opts->isoc_maxpacket);
25d80151
AP
998 mutex_unlock(&opts->lock);
999
1000 return result;
1001}
1002
1003static ssize_t f_ss_opts_isoc_maxpacket_store(struct f_ss_opts *opts,
1004 const char *page, size_t len)
1005{
1006 int ret;
1007 u16 num;
1008
1009 mutex_lock(&opts->lock);
1010 if (opts->refcnt) {
1011 ret = -EBUSY;
1012 goto end;
1013 }
1014
1015 ret = kstrtou16(page, 0, &num);
1016 if (ret)
1017 goto end;
1018
1019 if (num > 1024) {
1020 ret = -EINVAL;
1021 goto end;
1022 }
1023
1024 opts->isoc_maxpacket = num;
1025 ret = len;
1026end:
1027 mutex_unlock(&opts->lock);
1028 return ret;
1029}
1030
1031static struct f_ss_opts_attribute f_ss_opts_isoc_maxpacket =
1032 __CONFIGFS_ATTR(isoc_maxpacket, S_IRUGO | S_IWUSR,
1033 f_ss_opts_isoc_maxpacket_show,
1034 f_ss_opts_isoc_maxpacket_store);
1035
1036static ssize_t f_ss_opts_isoc_mult_show(struct f_ss_opts *opts, char *page)
1037{
1038 int result;
1039
1040 mutex_lock(&opts->lock);
fa50bff6 1041 result = sprintf(page, "%u\n", opts->isoc_mult);
25d80151
AP
1042 mutex_unlock(&opts->lock);
1043
1044 return result;
1045}
1046
1047static ssize_t f_ss_opts_isoc_mult_store(struct f_ss_opts *opts,
1048 const char *page, size_t len)
1049{
1050 int ret;
1051 u8 num;
1052
1053 mutex_lock(&opts->lock);
1054 if (opts->refcnt) {
1055 ret = -EBUSY;
1056 goto end;
1057 }
1058
1059 ret = kstrtou8(page, 0, &num);
1060 if (ret)
1061 goto end;
1062
1063 if (num > 2) {
1064 ret = -EINVAL;
1065 goto end;
1066 }
1067
1068 opts->isoc_mult = num;
1069 ret = len;
1070end:
1071 mutex_unlock(&opts->lock);
1072 return ret;
1073}
1074
1075static struct f_ss_opts_attribute f_ss_opts_isoc_mult =
1076 __CONFIGFS_ATTR(isoc_mult, S_IRUGO | S_IWUSR,
1077 f_ss_opts_isoc_mult_show,
1078 f_ss_opts_isoc_mult_store);
1079
1080static ssize_t f_ss_opts_isoc_maxburst_show(struct f_ss_opts *opts, char *page)
1081{
1082 int result;
1083
1084 mutex_lock(&opts->lock);
fa50bff6 1085 result = sprintf(page, "%u\n", opts->isoc_maxburst);
25d80151
AP
1086 mutex_unlock(&opts->lock);
1087
1088 return result;
1089}
1090
1091static ssize_t f_ss_opts_isoc_maxburst_store(struct f_ss_opts *opts,
1092 const char *page, size_t len)
1093{
1094 int ret;
1095 u8 num;
1096
1097 mutex_lock(&opts->lock);
1098 if (opts->refcnt) {
1099 ret = -EBUSY;
1100 goto end;
1101 }
1102
1103 ret = kstrtou8(page, 0, &num);
1104 if (ret)
1105 goto end;
1106
1107 if (num > 15) {
1108 ret = -EINVAL;
1109 goto end;
1110 }
1111
1112 opts->isoc_maxburst = num;
1113 ret = len;
1114end:
1115 mutex_unlock(&opts->lock);
1116 return ret;
1117}
1118
1119static struct f_ss_opts_attribute f_ss_opts_isoc_maxburst =
1120 __CONFIGFS_ATTR(isoc_maxburst, S_IRUGO | S_IWUSR,
1121 f_ss_opts_isoc_maxburst_show,
1122 f_ss_opts_isoc_maxburst_store);
1123
1124static ssize_t f_ss_opts_bulk_buflen_show(struct f_ss_opts *opts, char *page)
1125{
1126 int result;
1127
1128 mutex_lock(&opts->lock);
fa50bff6 1129 result = sprintf(page, "%u\n", opts->bulk_buflen);
25d80151
AP
1130 mutex_unlock(&opts->lock);
1131
1132 return result;
1133}
1134
1135static ssize_t f_ss_opts_bulk_buflen_store(struct f_ss_opts *opts,
1136 const char *page, size_t len)
1137{
1138 int ret;
1139 u32 num;
1140
1141 mutex_lock(&opts->lock);
1142 if (opts->refcnt) {
1143 ret = -EBUSY;
1144 goto end;
1145 }
1146
1147 ret = kstrtou32(page, 0, &num);
1148 if (ret)
1149 goto end;
1150
1151 opts->bulk_buflen = num;
1152 ret = len;
1153end:
1154 mutex_unlock(&opts->lock);
1155 return ret;
1156}
1157
1158static struct f_ss_opts_attribute f_ss_opts_bulk_buflen =
1159 __CONFIGFS_ATTR(buflen, S_IRUGO | S_IWUSR,
1160 f_ss_opts_bulk_buflen_show,
1161 f_ss_opts_bulk_buflen_store);
1162
1163static struct configfs_attribute *ss_attrs[] = {
1164 &f_ss_opts_pattern.attr,
1165 &f_ss_opts_isoc_interval.attr,
1166 &f_ss_opts_isoc_maxpacket.attr,
1167 &f_ss_opts_isoc_mult.attr,
1168 &f_ss_opts_isoc_maxburst.attr,
1169 &f_ss_opts_bulk_buflen.attr,
1170 NULL,
1171};
1172
1173static struct config_item_type ss_func_type = {
1174 .ct_item_ops = &ss_item_ops,
1175 .ct_attrs = ss_attrs,
1176 .ct_owner = THIS_MODULE,
1177};
1178
9890e330 1179static void source_sink_free_instance(struct usb_function_instance *fi)
544aca39 1180{
cf9a08ae
SAS
1181 struct f_ss_opts *ss_opts;
1182
1183 ss_opts = container_of(fi, struct f_ss_opts, func_inst);
1184 kfree(ss_opts);
544aca39 1185}
cf9a08ae
SAS
1186
1187static struct usb_function_instance *source_sink_alloc_inst(void)
1188{
1189 struct f_ss_opts *ss_opts;
1190
1191 ss_opts = kzalloc(sizeof(*ss_opts), GFP_KERNEL);
1192 if (!ss_opts)
1193 return ERR_PTR(-ENOMEM);
25d80151 1194 mutex_init(&ss_opts->lock);
9890e330 1195 ss_opts->func_inst.free_func_inst = source_sink_free_instance;
25d80151
AP
1196 ss_opts->isoc_interval = GZERO_ISOC_INTERVAL;
1197 ss_opts->isoc_maxpacket = GZERO_ISOC_MAXPACKET;
1198 ss_opts->bulk_buflen = GZERO_BULK_BUFLEN;
1199
1200 config_group_init_type_name(&ss_opts->func_inst.group, "",
1201 &ss_func_type);
1202
cf9a08ae
SAS
1203 return &ss_opts->func_inst;
1204}
1205DECLARE_USB_FUNCTION(SourceSink, source_sink_alloc_inst,
1206 source_sink_alloc_func);
1207
1208static int __init sslb_modinit(void)
1209{
1210 int ret;
1211
1212 ret = usb_function_register(&SourceSinkusb_func);
1213 if (ret)
1214 return ret;
1215 ret = lb_modinit();
1216 if (ret)
1217 usb_function_unregister(&SourceSinkusb_func);
1218 return ret;
1219}
1220static void __exit sslb_modexit(void)
1221{
1222 usb_function_unregister(&SourceSinkusb_func);
1223 lb_modexit();
1224}
1225module_init(sslb_modinit);
1226module_exit(sslb_modexit);
1227
1228MODULE_LICENSE("GPL");