summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorPantelis Antoniou <panto@antoniou-consulting.com>2012-11-30 08:01:09 +0000
committerTom Rini <trini@ti.com>2013-02-15 14:25:53 -0500
commitc3aa9815e7f40a01994b3681741ce72599d73ab6 (patch)
treec86423a306bb41197183ba5a6541b9446255b496 /drivers
parentc8adc11eb9dc4b294379642a6b0308312ff4bec8 (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.c27
-rw-r--r--drivers/usb/gadget/ep0.c1
-rw-r--r--drivers/usb/gadget/f_dfu.c6
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;