summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrzej Pietrasiewicz <andrzej.p@samsung.com>2013-11-07 08:41:25 +0100
committerFelipe Balbi <balbi@ti.com>2013-11-26 20:40:44 +0100
commita01091e5ce866562ea2638a80f2241d8d6bde164 (patch)
tree1221e6dac8732d6b02a51baffbad4e6557cec768
parentusb: musb: dsps: polling ID pin status only in otg mode (diff)
downloadlinux-a01091e5ce866562ea2638a80f2241d8d6bde164.tar.xz
linux-a01091e5ce866562ea2638a80f2241d8d6bde164.zip
usb: gadget: composite: redirect setup requests
If there are setup requests not directed to an endpont or an interface, current config's setup() has been attempted so far. This patch, in case the above fails, adds code which tries the setup() of configuration's function if there is only one function in the configuration. This behavior is required to provide equivalent of gadget zero with configfs. The gadget zero has a "config driver" for sourcesink, but all it does is delegating the request to the function proper. So when the equivalent gadget is set up with configfs it needs to handle requests directed to "config driver", but with configfs it is not possible to specify "config drivers". Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Acked-by: Michal Nazarewicz <mina86@mina86.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r--drivers/usb/gadget/composite.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 3e7ae707f691..611fe89c3a8b 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1451,8 +1451,22 @@ unknown:
struct usb_configuration *c;
c = cdev->config;
- if (c && c->setup)
+ if (!c)
+ goto done;
+
+ /* try current config's setup */
+ if (c->setup) {
value = c->setup(c, ctrl);
+ goto done;
+ }
+
+ /* try the only function in the current config */
+ if (!list_is_singular(&c->functions))
+ goto done;
+ f = list_first_entry(&c->functions, struct usb_function,
+ list);
+ if (f->setup)
+ value = f->setup(f, ctrl);
}
goto done;