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

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 --- 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;

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;
participants (2)
-
Marek Vasut
-
Patrick Delaunay