usb: Alloc buffer for USB descriptor dynamically
PATCH v2 1/1 usb: Alloc buffer for USB descriptor dynamically
The configuration descriptor includes all interface, endpoint and auxiliary descriptors (e.g. report, union) so 512 bytes may not be enough.
Signed-off-by Stefan Br?ns <[email protected]>
Reviewed-by Marek Vasut <[email protected]>
Reviewed-by Simon Glass <[email protected]>
---
v2: add missing free() in error path
common/usb.c | 42 ++++++++++++++++++++++++++++-------------- include/usb.h | 5 +++-- 2 files changed, 31 insertions(+), 16 deletions(-)
common/usb.c +28 -14
@@ -566,13 +566,12 @@ static int usb_get_descriptor(struct usb_device *dev, unsigned char type, }/********************************************************************** -* gets configuration cfgno and store it in the buffer +* gets len of configuration cfgno */ -int usb_get_configuration_no (struct usb_device *dev, -unsigned char *buffer,int cfgno) +int usb_get_configuration_len (struct usb_device *dev,int cfgno) {int result; -unsigned int length; + ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, 9);struct usb_config_descriptor *config; config = (struct usb_config_descriptor *)&buffer[0 ];
@@ -586,17 +585,23 @@ int usb_get_configuration_no(struct usb_device *dev, "(expected %i, got %i)\n", 9, result);return -EIO ; } - length =le16_to_cpu (config->wTotalLength); +return le16_to_cpu (config->wTotalLength); +} -if (length >USB_BUFSIZ ) { -printf ("%s: failed to get descriptor - too long: %d\n" , - __func__, length); -return -EIO ; - } +/********************************************************************** +* gets configuration cfgno and store it in the buffer +*/ +int usb_get_configuration_no (struct usb_device *dev,int cfgno, +unsigned char *buffer,int length) +{ +int result; +struct usb_config_descriptor *config; + config = (struct usb_config_descriptor *)&buffer[0 ]; result =usb_get_descriptor (dev,USB_DT_CONFIG , cfgno, buffer, length); -debug ("get_conf_no %d Result %d, wLength %d\n" , cfgno, result, length); - config->wTotalLength = length;/* validated, with CPU byte order */ +debug ("get_conf_no %d Result %d, wLength %d\n" , cfgno, result, +le16_to_cpu (config->wTotalLength)); + config->wTotalLength = result;/* validated, with CPU byte order */ return result; }
@@ -1070,7 +1075,7 @@ static int usb_prepare_device(struct usb_device *dev, int addr, bool do_read,int usb_select_config (struct usb_device *dev) { - ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ); +unsigned char *tmpbuf =0 ;int err; err =get_descriptor_len (dev,USB_DT_DEVICE_SIZE ,USB_DT_DEVICE_SIZE );
@@ -1084,14 +1089,23 @@ int usb_select_config(struct usb_device *dev)le16_to_cpus (&dev->descriptor.bcdDevice);/* only support for one config for now */ - err =usb_get_configuration_no (dev, tmpbuf,0 ); + err =usb_get_configuration_len (dev,0 ); +if (err >=0 ) { + tmpbuf = (unsigned char *)malloc_cache_aligned (err); +if (!tmpbuf) + err = -ENOMEM ; +else + err =usb_get_configuration_no (dev,0 , tmpbuf, err); + }if (err <0 ) {printf ("usb_new_device: Cannot read configuration, " \"skipping device %04x:%04x\n" , dev->descriptor.idVendor, dev->descriptor.idProduct); +free (tmpbuf);return err; }usb_parse_config (dev, tmpbuf,0 ); +free (tmpbuf);usb_set_maxpacket (dev);/* * we set the default configuration here
include/usb.h +3 -2
@@ -266,8 +266,9 @@ int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int transfer_len, int interval);int usb_disable_asynch (int disable);int usb_maxpacket (struct usb_device *dev,unsigned long pipe); -int usb_get_configuration_no (struct usb_device *dev,unsigned char *buffer, -int cfgno); +int usb_get_configuration_no (struct usb_device *dev,int cfgno, +unsigned char *buffer,int length); +int usb_get_configuration_len (struct usb_device *dev,int cfgno);int usb_get_report (struct usb_device *dev,int ifnum,unsigned char type,unsigned char id,void *buf,int size); int usb_get_class_descriptor(struct usb_device *dev, int ifnum,
Signature · 1 line
2.1.4
Marek Vasut
AppliedPATCH v2 1/1 usb: Alloc buffer for USB descriptor dynamically
Quoted 6 lines · Stefan Br?ns
The configuration descriptor includes all interface, endpoint and auxiliary descriptors (e.g. report, union) so 512 bytes may not be enough.
Signed-off-by Stefan Br?ns <[email protected]>Reviewed-by Marek Vasut <[email protected]>Reviewed-by Simon Glass <[email protected]>
Applied, thanks.
Best regards,
Marek Vasut