[U-Boot] [PATCH] usb: gadget: dfu: add functional descriptor in descriptor set

Marek Vasut marex at denx.de
Thu Dec 8 18:26:10 CET 2016


On 12/08/2016 06:10 PM, Patrick Delaunay wrote:
> From: Patrick Delaunay <patrick.delaunay at 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 at st.com>
> Signed-off-by: Patrick Delaunay <patrick.delaunay73 at 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;
> 


-- 
Best regards,
Marek Vasut


More information about the U-Boot mailing list