diff options
author | Pantelis Antoniou <panto@antoniou-consulting.com> | 2012-11-30 08:01:09 +0000 |
---|---|---|
committer | Tom Rini <trini@ti.com> | 2013-02-15 14:25:53 -0500 |
commit | c3aa9815e7f40a01994b3681741ce72599d73ab6 (patch) | |
tree | c86423a306bb41197183ba5a6541b9446255b496 /drivers | |
parent | c8adc11eb9dc4b294379642a6b0308312ff4bec8 (diff) |
dfu: Send correct DFU response from composite_setup
DFU is a bit peculiar. It needs to hook to composite setup and
return it's function descriptor.
So when get-descriptor request comes with a type of DFU_DT_FUNC
we iterate over the configs, and functions, and when we find
the DFU function we call the setup method which is prepared
to return the appropriate function descriptor.
Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/gadget/composite.c | 27 | ||||
-rw-r--r-- | drivers/usb/gadget/ep0.c | 1 | ||||
-rw-r--r-- | drivers/usb/gadget/f_dfu.c | 6 |
3 files changed, 32 insertions, 2 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index ebb5131a9cb..64964360c7f 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -773,6 +773,33 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) if (value >= 0) value = min(w_length, (u16) value); break; + +#ifdef CONFIG_DFU_FUNCTION + /* DFU is mighty weird */ + case DFU_DT_FUNC: + w_value &= 0xff; + list_for_each_entry(c, &cdev->configs, list) { + if (w_value != 0) { + w_value--; + continue; + } + + list_for_each_entry(f, &c->functions, list) { + + /* DFU function only */ + if (strcmp(f->name, "dfu") != 0) + continue; + + value = f->setup(f, ctrl); + goto dfu_func_done; + } + } +dfu_func_done: + if (value >= 0) + value = min(w_length, (u16) value); + break; +#endif + default: goto unknown; } diff --git a/drivers/usb/gadget/ep0.c b/drivers/usb/gadget/ep0.c index aa8f91600d7..971d846ff6e 100644 --- a/drivers/usb/gadget/ep0.c +++ b/drivers/usb/gadget/ep0.c @@ -221,6 +221,7 @@ static int ep0_get_descriptor (struct usb_device_instance *device, break; case USB_DESCRIPTOR_TYPE_CONFIGURATION: + case USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION: { struct usb_configuration_descriptor *configuration_descriptor; diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c index 10547e3279b..6494f5e6e38 100644 --- a/drivers/usb/gadget/f_dfu.c +++ b/drivers/usb/gadget/f_dfu.c @@ -534,8 +534,10 @@ dfu_handle(struct usb_function *f, const struct usb_ctrlrequest *ctrl) value = min(len, (u16) sizeof(dfu_func)); memcpy(req->buf, &dfu_func, value); } - } else /* DFU specific request */ - value = dfu_state[f_dfu->dfu_state] (f_dfu, ctrl, gadget, req); + return value; + } + + value = dfu_state[f_dfu->dfu_state] (f_dfu, ctrl, gadget, req); if (value >= 0) { req->length = value; |