15 #include <linux/slab.h>
16 #include <linux/kernel.h>
17 #include <linux/device.h>
18 #include <linux/module.h>
68 static unsigned isoc_interval = 4;
72 static unsigned isoc_maxpacket = 1024;
76 static unsigned isoc_mult;
80 static unsigned isoc_maxburst;
90 .bAlternateSetting = 0,
100 .bAlternateSetting = 1,
149 #define FS_ALT_IFC_1_OFFSET 3
198 #define HS_ALT_IFC_1_OFFSET 3
222 .wBytesPerInterval = 0,
239 .wBytesPerInterval = 0,
285 #define SS_ALT_IFC_1_OFFSET 5
299 static struct usb_string strings_sourcesink[] = {
300 [0].s =
"source and sink data",
306 .strings = strings_sourcesink,
310 &stringtab_sourcesink,
334 ERROR(cdev,
"%s: can't autoconfigure on %s\n",
346 if (isoc_interval < 1)
348 if (isoc_interval > 16)
352 if (isoc_maxburst > 15)
357 1023 : isoc_maxpacket;
358 fs_iso_source_desc.
bInterval = isoc_interval;
360 1023 : isoc_maxpacket;
361 fs_iso_sink_desc.
bInterval = isoc_interval;
386 if (isoc_maxpacket > 1024)
387 isoc_maxpacket = 1024;
390 if (gadget_is_dualspeed(c->
cdev->gadget)) {
403 hs_iso_source_desc.
bInterval = isoc_interval;
409 hs_iso_sink_desc.
bInterval = isoc_interval;
417 if (gadget_is_superspeed(c->
cdev->gadget)) {
429 ss_iso_source_desc.
bInterval = isoc_interval;
431 ss_iso_source_comp_desc.
bMaxBurst = isoc_maxburst;
433 isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
438 ss_iso_sink_desc.
bInterval = isoc_interval;
440 ss_iso_sink_comp_desc.
bMaxBurst = isoc_maxburst;
442 isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
449 DBG(cdev,
"%s speed %s: IN/%s, OUT/%s, ISO-IN/%s, ISO-OUT/%s\n",
450 (gadget_is_superspeed(c->
cdev->gadget) ?
"super" :
451 (gadget_is_dualspeed(c->
cdev->gadget) ?
"dual" :
"full")),
461 kfree(func_to_ss(f));
474 for (i = 0; i < req->
actual; i++, buf++) {
491 if (*buf == (
u8)(i % 63))
495 ERROR(cdev,
"bad OUT byte, buf[%d] = %d\n", i, *buf);
496 usb_ep_set_halt(ss->
out_ep);
512 for (i = 0; i < req->
length; i++)
513 *buf++ = (
u8) (i % 63);
536 check_read_data(ss, req);
540 reinit_write_data(ep, req);
547 VDBG(cdev,
"%s gone (%d), %d/%d\n", ep->
name, status,
550 check_read_data(ss, req);
560 DBG(cdev,
"%s complete --> %d, %d/%d\n", ep->
name,
569 ERROR(cdev,
"kill %s: resubmit %d bytes --> %d\n",
576 static int source_sink_start_ep(
struct f_sourcesink *ss,
bool is_in,
577 bool is_iso,
int speed)
583 for (i = 0; i < 8; i++) {
587 size = isoc_maxpacket * (isoc_mult + 1) *
591 size = isoc_maxpacket * (isoc_mult + 1);
594 size = isoc_maxpacket > 1023 ?
595 1023 : isoc_maxpacket;
608 req->
complete = source_sink_complete;
610 reinit_write_data(ep, req);
619 ERROR(cdev,
"start %s%s %s --> %d\n",
620 is_iso ?
"ISO-" :
"", is_in ?
"IN" :
"OUT",
632 static void disable_source_sink(
struct f_sourcesink *ss)
647 int speed = cdev->
gadget->speed;
655 result = usb_ep_enable(ep);
660 result = source_sink_start_ep(ss,
true,
false, speed);
674 result = usb_ep_enable(ep);
679 result = source_sink_start_ep(ss,
false,
false, speed);
697 result = usb_ep_enable(ep);
702 result = source_sink_start_ep(ss,
true,
true, speed);
720 result = usb_ep_enable(ep);
725 result = source_sink_start_ep(ss,
false,
true, speed);
735 DBG(cdev,
"%s enabled, alt intf %d\n", ss->
function.name, alt);
740 unsigned intf,
unsigned alt)
745 if (ss->
in_ep->driver_data)
746 disable_source_sink(ss);
747 return enable_source_sink(cdev, ss, alt);
750 static int sourcesink_get_alt(
struct usb_function *f,
unsigned intf)
761 disable_source_sink(ss);
776 ss->
function.descriptors = fs_source_sink_descs;
777 ss->
function.bind = sourcesink_bind;
778 ss->
function.unbind = sourcesink_unbind;
779 ss->
function.set_alt = sourcesink_set_alt;
780 ss->
function.get_alt = sourcesink_get_alt;
781 ss->
function.disable = sourcesink_disable;
817 if (w_value || w_index)
820 if (w_length > req->
length)
827 if (w_value || w_index)
830 if (w_length > req->
length)
838 "unknown control req%02x.%02x v%04x i%04x l%d\n",
840 w_value, w_index, w_length);
845 VDBG(c->
cdev,
"source/sink req%02x.%02x v%04x i%04x l%d\n",
847 w_value, w_index, w_length);
852 ERROR(c->
cdev,
"source/sink response, err %d\n",
861 .label =
"source/sink",
862 .strings = sourcesink_strings,
863 .setup = sourcesink_setup,
864 .bConfigurationValue = 3,
881 strings_sourcesink[0].
id =
id;
892 if (gadget_is_otg(cdev->
gadget)) {
897 return usb_add_config(cdev, &sourcesink_driver, sourcesink_bind_config);