Skip to content
Snippets Groups Projects
Commit c75f57fb authored by Stefan Brüns's avatar Stefan Brüns Committed by Marek Vasut
Browse files

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: default avatarStefan Brüns <stefan.bruens@rwth-aachen.de>
Reviewed-by: default avatarMarek Vasut <marex@denx.de>
Reviewed-by: default avatarSimon Glass <sjg@chromium.org>
parent 78680314
No related branches found
No related tags found
No related merge requests found
...@@ -566,13 +566,12 @@ static int usb_get_descriptor(struct usb_device *dev, unsigned char type, ...@@ -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, int usb_get_configuration_len(struct usb_device *dev, int cfgno)
unsigned char *buffer, int cfgno)
{ {
int result; int result;
unsigned int length; ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, 9);
struct usb_config_descriptor *config; struct usb_config_descriptor *config;
config = (struct usb_config_descriptor *)&buffer[0]; config = (struct usb_config_descriptor *)&buffer[0];
...@@ -586,17 +585,23 @@ int usb_get_configuration_no(struct usb_device *dev, ...@@ -586,17 +585,23 @@ int usb_get_configuration_no(struct usb_device *dev,
"(expected %i, got %i)\n", 9, result); "(expected %i, got %i)\n", 9, result);
return -EIO; 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", * gets configuration cfgno and store it in the buffer
__func__, length); */
return -EIO; 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); result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, length);
debug("get_conf_no %d Result %d, wLength %d\n", cfgno, result, length); debug("get_conf_no %d Result %d, wLength %d\n", cfgno, result,
config->wTotalLength = length; /* validated, with CPU byte order */ le16_to_cpu(config->wTotalLength));
config->wTotalLength = result; /* validated, with CPU byte order */
return result; return result;
} }
...@@ -1070,7 +1075,7 @@ static int usb_prepare_device(struct usb_device *dev, int addr, bool do_read, ...@@ -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) int usb_select_config(struct usb_device *dev)
{ {
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ); unsigned char *tmpbuf = 0;
int err; int err;
err = get_descriptor_len(dev, USB_DT_DEVICE_SIZE, USB_DT_DEVICE_SIZE); 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) ...@@ -1084,14 +1089,23 @@ int usb_select_config(struct usb_device *dev)
le16_to_cpus(&dev->descriptor.bcdDevice); le16_to_cpus(&dev->descriptor.bcdDevice);
/* only support for one config for now */ /* 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) { if (err < 0) {
printf("usb_new_device: Cannot read configuration, " \ printf("usb_new_device: Cannot read configuration, " \
"skipping device %04x:%04x\n", "skipping device %04x:%04x\n",
dev->descriptor.idVendor, dev->descriptor.idProduct); dev->descriptor.idVendor, dev->descriptor.idProduct);
free(tmpbuf);
return err; return err;
} }
usb_parse_config(dev, tmpbuf, 0); usb_parse_config(dev, tmpbuf, 0);
free(tmpbuf);
usb_set_maxpacket(dev); usb_set_maxpacket(dev);
/* /*
* we set the default configuration here * we set the default configuration here
......
...@@ -266,8 +266,9 @@ int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe, ...@@ -266,8 +266,9 @@ int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe,
void *buffer, int transfer_len, int interval); void *buffer, int transfer_len, int interval);
int usb_disable_asynch(int disable); int usb_disable_asynch(int disable);
int usb_maxpacket(struct usb_device *dev, unsigned long pipe); int usb_maxpacket(struct usb_device *dev, unsigned long pipe);
int usb_get_configuration_no(struct usb_device *dev, unsigned char *buffer, int usb_get_configuration_no(struct usb_device *dev, int cfgno,
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, int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type,
unsigned char id, void *buf, int size); unsigned char id, void *buf, int size);
int usb_get_class_descriptor(struct usb_device *dev, int ifnum, int usb_get_class_descriptor(struct usb_device *dev, int ifnum,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment