From f7b4162eb1bddfa3008e65d4d3ed29d117dc1eb8 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 1 Mar 2013 15:30:18 +0100 Subject: [PATCH] usb:composite:fix Provide function data when addressing device with only one interface This commit fixes problems with some non-standard requests send with device address instead of interface address (bmRequestType.Receipent field). This happens with dfu-util (debian version: 0.5), which address non standard requests (like w_value=0x21 and bRequest=GET_DESCRIPTOR) to device. Without this fix, the above request is STALLED, and hence causes dfu-util to assume some standard configuration (packet size = 1024B instead of 4096B) In turn it displays following errors: Error obtaining DFU functional descriptor Warning: Assuming DFU version 1.0 Warning: Transfer size can not be detected ... Warning: Trying default transfer size 1024 This fix allows passing non-standard request to function setup code, where it shall be handled. Tested at: Trats (exynos4210) Tested with:DFU and UMS gadgets Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park --- drivers/usb/gadget/composite.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index ebb5131a9c..2c5600ed52 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -859,6 +859,25 @@ unknown: if (&f->list == &cdev->config->functions) f = NULL; break; + /* + * dfu-util (version 0.5) sets bmRequestType.Receipent = Device + * for non-standard request (w_value = 0x21, + * bRequest = GET_DESCRIPTOR in this case). + * When only one interface is registered (as it is done now), + * then this request shall be handled as it was requested for + * interface. + * + * In the below code it is checked if only one interface is + * present and proper function for it is extracted. Due to that + * function's setup (f->setup) is called to handle this + * special non-standard request. + */ + case USB_RECIP_DEVICE: + debug("cdev->config->next_interface_id: %d intf: %d\n", + cdev->config->next_interface_id, intf); + if (cdev->config->next_interface_id == 1) + f = cdev->config->interface[intf]; + break; } if (f && f->setup) -- 2.30.2