15 #include <linux/slab.h>
16 #include <linux/kernel.h>
17 #include <linux/device.h>
47 static unsigned qlen = 32;
54 .bLength =
sizeof loopback_intf,
127 .wBytesPerInterval = 0,
143 .wBytesPerInterval = 0,
157 static struct usb_string strings_loopback[] = {
158 [0].s =
"loop input to output",
164 .strings = strings_loopback,
192 ERROR(cdev,
"%s: can't autoconfigure on %s\n",
204 if (gadget_is_dualspeed(c->
cdev->gadget)) {
213 if (gadget_is_superspeed(c->
cdev->gadget)) {
221 DBG(cdev,
"%s speed %s: IN/%s, OUT/%s\n",
222 (gadget_is_superspeed(c->
cdev->gadget) ?
"super" :
223 (gadget_is_dualspeed(c->
cdev->gadget) ?
"dual" :
"full")),
231 kfree(func_to_loop(f));
252 ERROR(cdev,
"can't loop %s to %s: %d\n",
267 ERROR(cdev,
"%s loop complete --> %d, %d/%d\n", ep->
name,
284 static void disable_loopback(
struct f_loopback *loop)
306 result = usb_ep_enable(ep);
317 result = usb_ep_enable(ep);
331 for (i = 0; i < qlen && result == 0; i++) {
337 ERROR(cdev,
"%s queue req --> %d\n",
352 unsigned intf,
unsigned alt)
358 if (loop->
in_ep->driver_data)
359 disable_loopback(loop);
360 return enable_loopback(cdev, loop);
367 disable_loopback(loop);
382 loop->
function.descriptors = fs_loopback_descs;
383 loop->
function.bind = loopback_bind;
384 loop->
function.unbind = loopback_unbind;
385 loop->
function.set_alt = loopback_set_alt;
386 loop->
function.disable = loopback_disable;
396 .strings = loopback_strings,
397 .bConfigurationValue = 2,
414 strings_loopback[0].
id =
id;
424 if (gadget_is_otg(cdev->
gadget)) {
429 return usb_add_config(cdev, &loopback_driver, loopback_bind_config);