patch-2.4.0-test7 linux/drivers/usb/usb.c
Next file: linux/drivers/usb/usbkbd.c
Previous file: linux/drivers/usb/usb-uhci.c
Back to the patch index
Back to the overall index
- Lines: 76
- Date:
Tue Aug 22 09:06:31 2000
- Orig file:
v2.4.0-test6/linux/drivers/usb/usb.c
- Orig date:
Wed Aug 9 19:19:51 2000
diff -u --recursive --new-file v2.4.0-test6/linux/drivers/usb/usb.c linux/drivers/usb/usb.c
@@ -1222,9 +1222,7 @@
int usb_parse_configuration(struct usb_device *dev, struct usb_config_descriptor *config, char *buffer)
{
- int i;
- int retval;
- int size;
+ int i, retval, size;
struct usb_descriptor_header *header;
memcpy(config, buffer, USB_DT_CONFIG_SIZE);
@@ -1252,19 +1250,54 @@
size -= config->bLength;
for (i = 0; i < config->bNumInterfaces; i++) {
- header = (struct usb_descriptor_header *)buffer;
- if ((header->bLength > size) || (header->bLength <= 2)) {
- err("ran out of descriptors parsing");
- return -1;
- }
-
- if (header->bDescriptorType != USB_DT_INTERFACE) {
- warn("unexpected descriptor 0x%X",
- header->bDescriptorType);
+ int numskipped, len;
+ char *begin;
+
+ /* Skip over the rest of the Class Specific or Vendor */
+ /* Specific descriptors */
+ begin = buffer;
+ numskipped = 0;
+ while (size >= sizeof(struct usb_descriptor_header)) {
+ header = (struct usb_descriptor_header *)buffer;
+
+ if ((header->bLength > size) || (header->bLength < 2)) {
+ err("invalid descriptor length of %d", header->bLength);
+ return -1;
+ }
+
+ /* If we find another descriptor which is at or below */
+ /* us in the descriptor heirarchy then we're done */
+ if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
+ (header->bDescriptorType == USB_DT_INTERFACE) ||
+ (header->bDescriptorType == USB_DT_CONFIG) ||
+ (header->bDescriptorType == USB_DT_DEVICE))
+ break;
+
+ dbg("skipping descriptor 0x%X", header->bDescriptorType);
+ numskipped++;
buffer += header->bLength;
size -= header->bLength;
- continue;
+ }
+ if (numskipped)
+ dbg("skipped %d class/vendor specific endpoint descriptors", numskipped);
+
+ /* Copy any unknown descriptors into a storage area for */
+ /* drivers to later parse */
+ len = (int)(buffer - begin);
+ if (!len) {
+ config->extra = NULL;
+ config->extralen = 0;
+ } else {
+ config->extra = kmalloc(len, GFP_KERNEL);
+ if (!config->extra) {
+ err("couldn't allocate memory for config extra descriptors");
+ config->extralen = 0;
+ return -1;
+ }
+
+ memcpy(config->extra, begin, len);
+ config->extralen = len;
}
retval = usb_parse_interface(dev, config->interface + i, buffer, size);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)