Message ID | 1481217049-7333-1-git-send-email-patrick.delaunay73@gmail.com |
---|---|
State | Accepted |
Commit | 8987012fe5a8bc226d1b3f5187c152b8d85a2dcd |
Delegated to: | Ćukasz Majewski |
Headers | show |
On 12/08/2016 06:10 PM, Patrick Delaunay wrote: > From: Patrick Delaunay <patrick.delaunay@st.com> > > The "DFU descriptor set" must contain the "DFU functional descriptor" > but it is missing today in U-Boot code > (cf: DFU spec 1.1, chapter 4.2 DFU Mode Descriptor Set) > This patch only allocate buffer and copy DFU functional descriptor > after interfaces. > > > Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com> > Signed-off-by: Patrick Delaunay <patrick.delaunay73@gmail.com> +CC Lukasz > --- > in DFU spec 1.1 : > > 4.2 DFU Mode Descriptor Set > After the host and device agree to perform DFU > operations, the host re-enumerates the device. > It is at this time that the device exports > the DFU descriptor set, which contains: > - A DFU device descriptor > - A single configuration descriptor > - A single interface descriptor (including descriptors > for alternate settings, if present) > - A single functional descriptor > > But after test and code-review the functional descriptor > is missing in U-Boot in response to USB_DT_CONFIG. > > This descriptor is provided only when it is specifically > requested (see dfu_handle function for USB_TYPE_STANDARD request > USB_REQ_GET_DESCRIPTOR for DFU_DT_FUNC). > > cf composite.c:config_desc() > descriptor is provided in f->descriptors or f->hs_descriptors > set to f_dfu->function in f_dfu.c, in to_dfu_mode() > and f_dfu->function is initialized in dfu_prepare_function() > only with interfaces > but not with DFU functional descriptor ! > > This patch only allocate buffer and copy DFU functional descriptor > after interfaces descriptor and tested with Linux command "lsusb -v" > > => "Device Firmware Upgrade Interface Descriptor" > is now present as expected > > Device Descriptor: > bLength 18 > bDescriptorType 1 > Configuration Descriptor: > bLength 9 > bDescriptorType 2 > wTotalLength 36 > bNumInterfaces 1 > bConfigurationValue 1 > iConfiguration 2 USB download gadget > bmAttributes 0xc0 > Self Powered > MaxPower 2mA > ..... > Interface Descriptor: > .... > Device Firmware Upgrade Interface Descriptor: > bLength 9 > bDescriptorType 33 > bmAttributes 15 > Will Detach > Manifestation Tolerant > Upload Supported > Download Supported > wDetachTimeout 0 milliseconds > wTransferSize 4096 bytes > bcdDFUVersion 1.10 > Device Qualifier (for other device speed): > bLength 10 > bDescriptorType 6 > bcdUSB 2.00 > bDeviceClass 0 (Defined at Interface level) > bDeviceSubClass 0 > bDeviceProtocol 0 > bMaxPacketSize0 64 > bNumConfigurations 1 > Device Status: 0x0001 > Self Powered > > > drivers/usb/gadget/f_dfu.c | 10 +++++++++- > 1 file changed, 9 insertions(+), 1 deletion(-) > > diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c > index 8e7c981..73b32f8 100644 > --- a/drivers/usb/gadget/f_dfu.c > +++ b/drivers/usb/gadget/f_dfu.c > @@ -654,7 +654,7 @@ static int dfu_prepare_function(struct f_dfu *f_dfu, int n) > struct usb_interface_descriptor *d; > int i = 0; > > - f_dfu->function = calloc(sizeof(struct usb_descriptor_header *), n + 1); > + f_dfu->function = calloc(sizeof(struct usb_descriptor_header *), n + 2); > if (!f_dfu->function) > goto enomem; > > @@ -673,6 +673,14 @@ static int dfu_prepare_function(struct f_dfu *f_dfu, int n) > > f_dfu->function[i] = (struct usb_descriptor_header *)d; > } > + > + /* add DFU Functional Descriptor */ > + f_dfu->function[i] = calloc(sizeof(dfu_func), 1); > + if (!f_dfu->function[i]) > + goto enomem; > + memcpy(f_dfu->function[i], &dfu_func, sizeof(dfu_func)); > + > + i++; > f_dfu->function[i] = NULL; > > return 0; >
diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c index 8e7c981..73b32f8 100644 --- a/drivers/usb/gadget/f_dfu.c +++ b/drivers/usb/gadget/f_dfu.c @@ -654,7 +654,7 @@ static int dfu_prepare_function(struct f_dfu *f_dfu, int n) struct usb_interface_descriptor *d; int i = 0; - f_dfu->function = calloc(sizeof(struct usb_descriptor_header *), n + 1); + f_dfu->function = calloc(sizeof(struct usb_descriptor_header *), n + 2); if (!f_dfu->function) goto enomem; @@ -673,6 +673,14 @@ static int dfu_prepare_function(struct f_dfu *f_dfu, int n) f_dfu->function[i] = (struct usb_descriptor_header *)d; } + + /* add DFU Functional Descriptor */ + f_dfu->function[i] = calloc(sizeof(dfu_func), 1); + if (!f_dfu->function[i]) + goto enomem; + memcpy(f_dfu->function[i], &dfu_func, sizeof(dfu_func)); + + i++; f_dfu->function[i] = NULL; return 0;