# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#                  ChangeSet    1.613   -> 1.614  
#       drivers/usb/core/usb.c  1.62    -> 1.63   
#       drivers/usb/core/Makefile       1.6     -> 1.7    
#                      (new)            -> 1.2     drivers/usb/core/config.c
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/05/30      [EMAIL PROTECTED] 1.614
# USB: Move configuration parsing code from usb.c to config.c
# --------------------------------------------
#
diff -Nru a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
--- a/drivers/usb/core/Makefile Fri May 31 16:47:03 2002
+++ b/drivers/usb/core/Makefile Fri May 31 16:47:03 2002
@@ -2,9 +2,10 @@
 # Makefile for USB Core files and filesystem
 #
 
-export-objs    := usb.o hcd.o urb.o message.o 
+export-objs    := usb.o hcd.o urb.o message.o config.o
 
-usbcore-objs   := usb.o usb-debug.o hub.o hcd.o urb.o message.o 
+usbcore-objs   := usb.o usb-debug.o hub.o hcd.o urb.o message.o \
+                       config.o
 
 ifeq ($(CONFIG_USB_DEVICEFS),y)
        usbcore-objs    += devio.o inode.o drivers.o devices.o
diff -Nru a/drivers/usb/core/config.c b/drivers/usb/core/config.c
--- /dev/null   Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/core/config.c Fri May 31 16:47:03 2002
@@ -0,0 +1,494 @@
+#include <linux/usb.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <asm/byteorder.h>
+
+static int usb_parse_endpoint(struct usb_endpoint_descriptor *endpoint, unsigned char 
+*buffer, int size)
+{
+       struct usb_descriptor_header *header;
+       unsigned char *begin;
+       int parsed = 0, len, numskipped;
+
+       header = (struct usb_descriptor_header *)buffer;
+
+       /* Everything should be fine being passed into here, but we sanity */
+       /*  check JIC */
+       if (header->bLength > size) {
+               err("ran out of descriptors parsing");
+               return -1;
+       }
+               
+       if (header->bDescriptorType != USB_DT_ENDPOINT) {
+               warn("unexpected descriptor 0x%X, expecting endpoint descriptor, type 
+0x%X",
+                       endpoint->bDescriptorType, USB_DT_ENDPOINT);
+               return parsed;
+       }
+
+       if (header->bLength == USB_DT_ENDPOINT_AUDIO_SIZE)
+               memcpy(endpoint, buffer, USB_DT_ENDPOINT_AUDIO_SIZE);
+       else
+               memcpy(endpoint, buffer, USB_DT_ENDPOINT_SIZE);
+       
+       le16_to_cpus(&endpoint->wMaxPacketSize);
+
+       buffer += header->bLength;
+       size -= header->bLength;
+       parsed += header->bLength;
+
+       /* 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 < 2) {
+                       err("invalid descriptor length of %d", header->bLength);
+                       return -1;
+               }
+
+               /* If we find another "proper" descriptor 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;
+               parsed += header->bLength;
+       }
+       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) {
+               endpoint->extra = NULL;
+               endpoint->extralen = 0;
+               return parsed;
+       }
+
+       endpoint->extra = kmalloc(len, GFP_KERNEL);
+
+       if (!endpoint->extra) {
+               err("couldn't allocate memory for endpoint extra descriptors");
+               endpoint->extralen = 0;
+               return parsed;
+       }
+
+       memcpy(endpoint->extra, begin, len);
+       endpoint->extralen = len;
+
+       return parsed;
+}
+
+static int usb_parse_interface(struct usb_interface *interface, unsigned char 
+*buffer, int size)
+{
+       int i, len, numskipped, retval, parsed = 0;
+       struct usb_descriptor_header *header;
+       struct usb_interface_descriptor *ifp;
+       unsigned char *begin;
+
+       interface->act_altsetting = 0;
+       interface->num_altsetting = 0;
+       interface->max_altsetting = USB_ALTSETTINGALLOC;
+
+       interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * 
+interface->max_altsetting, GFP_KERNEL);
+       
+       if (!interface->altsetting) {
+               err("couldn't kmalloc interface->altsetting");
+               return -1;
+       }
+
+       while (size > 0) {
+               if (interface->num_altsetting >= interface->max_altsetting) {
+                       void *ptr;
+                       int oldmas;
+
+                       oldmas = interface->max_altsetting;
+                       interface->max_altsetting += USB_ALTSETTINGALLOC;
+                       if (interface->max_altsetting > USB_MAXALTSETTING) {
+                               warn("too many alternate settings (max %d)",
+                                       USB_MAXALTSETTING);
+                               return -1;
+                       }
+
+                       ptr = interface->altsetting;
+                       interface->altsetting = kmalloc(sizeof(struct 
+usb_interface_descriptor) * interface->max_altsetting, GFP_KERNEL);
+                       if (!interface->altsetting) {
+                               err("couldn't kmalloc interface->altsetting");
+                               interface->altsetting = ptr;
+                               return -1;
+                       }
+                       memcpy(interface->altsetting, ptr, sizeof(struct 
+usb_interface_descriptor) * oldmas);
+
+                       kfree(ptr);
+               }
+
+               ifp = interface->altsetting + interface->num_altsetting;
+               ifp->endpoint = NULL;
+               ifp->extra = NULL;
+               ifp->extralen = 0;
+               interface->num_altsetting++;
+
+               memcpy(ifp, buffer, USB_DT_INTERFACE_SIZE);
+
+               /* Skip over the interface */
+               buffer += ifp->bLength;
+               parsed += ifp->bLength;
+               size -= ifp->bLength;
+
+               begin = buffer;
+               numskipped = 0;
+
+               /* Skip over any interface, class or vendor descriptors */
+               while (size >= sizeof(struct usb_descriptor_header)) {
+                       header = (struct usb_descriptor_header *)buffer;
+
+                       if (header->bLength < 2) {
+                               err("invalid descriptor length of %d", 
+header->bLength);
+                               return -1;
+                       }
+
+                       /* If we find another "proper" descriptor then we're done  */
+                       if ((header->bDescriptorType == USB_DT_INTERFACE) ||
+                           (header->bDescriptorType == USB_DT_ENDPOINT) ||
+                           (header->bDescriptorType == USB_DT_CONFIG) ||
+                           (header->bDescriptorType == USB_DT_DEVICE))
+                               break;
+
+                       numskipped++;
+
+                       buffer += header->bLength;
+                       parsed += header->bLength;
+                       size -= header->bLength;
+               }
+
+               if (numskipped)
+                       dbg("skipped %d class/vendor specific interface descriptors", 
+numskipped);
+
+               /* Copy any unknown descriptors into a storage area for */
+               /*  drivers to later parse */
+               len = (int)(buffer - begin);
+               if (len) {
+                       ifp->extra = kmalloc(len, GFP_KERNEL);
+
+                       if (!ifp->extra) {
+                               err("couldn't allocate memory for interface extra 
+descriptors");
+                               ifp->extralen = 0;
+                               return -1;
+                       }
+                       memcpy(ifp->extra, begin, len);
+                       ifp->extralen = len;
+               }
+
+               /* Did we hit an unexpected descriptor? */
+               header = (struct usb_descriptor_header *)buffer;
+               if ((size >= sizeof(struct usb_descriptor_header)) &&
+                   ((header->bDescriptorType == USB_DT_CONFIG) ||
+                    (header->bDescriptorType == USB_DT_DEVICE)))
+                       return parsed;
+
+               if (ifp->bNumEndpoints > USB_MAXENDPOINTS) {
+                       warn("too many endpoints");
+                       return -1;
+               }
+
+               ifp->endpoint = (struct usb_endpoint_descriptor *)
+                       kmalloc(ifp->bNumEndpoints *
+                       sizeof(struct usb_endpoint_descriptor), GFP_KERNEL);
+               if (!ifp->endpoint) {
+                       err("out of memory");
+                       return -1;      
+               }
+
+               memset(ifp->endpoint, 0, ifp->bNumEndpoints *
+                       sizeof(struct usb_endpoint_descriptor));
+       
+               for (i = 0; i < ifp->bNumEndpoints; i++) {
+                       header = (struct usb_descriptor_header *)buffer;
+
+                       if (header->bLength > size) {
+                               err("ran out of descriptors parsing");
+                               return -1;
+                       }
+               
+                       retval = usb_parse_endpoint(ifp->endpoint + i, buffer, size);
+                       if (retval < 0)
+                               return retval;
+
+                       buffer += retval;
+                       parsed += retval;
+                       size -= retval;
+               }
+
+               /* We check to see if it's an alternate to this one */
+               ifp = (struct usb_interface_descriptor *)buffer;
+               if (size < USB_DT_INTERFACE_SIZE ||
+                   ifp->bDescriptorType != USB_DT_INTERFACE ||
+                   !ifp->bAlternateSetting)
+                       return parsed;
+       }
+
+       return parsed;
+}
+
+int usb_parse_configuration(struct usb_config_descriptor *config, char *buffer)
+{
+       int i, retval, size;
+       struct usb_descriptor_header *header;
+
+       memcpy(config, buffer, USB_DT_CONFIG_SIZE);
+       le16_to_cpus(&config->wTotalLength);
+       size = config->wTotalLength;
+
+       if (config->bNumInterfaces > USB_MAXINTERFACES) {
+               warn("too many interfaces");
+               return -1;
+       }
+
+       config->interface = (struct usb_interface *)
+               kmalloc(config->bNumInterfaces *
+               sizeof(struct usb_interface), GFP_KERNEL);
+       dbg("kmalloc IF %p, numif %i", config->interface, config->bNumInterfaces);
+       if (!config->interface) {
+               err("out of memory");
+               return -1;      
+       }
+
+       memset(config->interface, 0,
+              config->bNumInterfaces * sizeof(struct usb_interface));
+
+       buffer += config->bLength;
+       size -= config->bLength;
+       
+       config->extra = NULL;
+       config->extralen = 0;
+
+       for (i = 0; i < config->bNumInterfaces; i++) {
+               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 "proper" descriptor 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;
+               }
+               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) {
+                       if (config->extralen) {
+                               warn("extra config descriptor");
+                       } 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(config->interface + i, buffer, size);
+               if (retval < 0)
+                       return retval;
+
+               buffer += retval;
+               size -= retval;
+       }
+
+       return size;
+}
+
+// hub-only!! ... and only exported for reset/reinit path.
+// otherwise used internally on disconnect/destroy path
+void usb_destroy_configuration(struct usb_device *dev)
+{
+       int c, i, j, k;
+       
+       if (!dev->config)
+               return;
+
+       if (dev->rawdescriptors) {
+               for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
+                       kfree(dev->rawdescriptors[i]);
+
+               kfree(dev->rawdescriptors);
+       }
+
+       for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
+               struct usb_config_descriptor *cf = &dev->config[c];
+
+               if (!cf->interface)
+                       break;
+
+               for (i = 0; i < cf->bNumInterfaces; i++) {
+                       struct usb_interface *ifp =
+                               &cf->interface[i];
+                               
+                       if (!ifp->altsetting)
+                               break;
+
+                       for (j = 0; j < ifp->num_altsetting; j++) {
+                               struct usb_interface_descriptor *as =
+                                       &ifp->altsetting[j];
+                                       
+                               if(as->extra) {
+                                       kfree(as->extra);
+                               }
+
+                               if (!as->endpoint)
+                                       break;
+                                       
+                               for(k = 0; k < as->bNumEndpoints; k++) {
+                                       if(as->endpoint[k].extra) {
+                                               kfree(as->endpoint[k].extra);
+                                       }
+                               }       
+                               kfree(as->endpoint);
+                       }
+
+                       kfree(ifp->altsetting);
+               }
+               kfree(cf->interface);
+       }
+       kfree(dev->config);
+}
+
+
+// hub-only!! ... and only in reset path, or usb_new_device()
+// (used by real hubs and virtual root hubs)
+int usb_get_configuration(struct usb_device *dev)
+{
+       int result;
+       unsigned int cfgno, length;
+       unsigned char *buffer;
+       unsigned char *bigbuffer;
+       struct usb_config_descriptor *desc;
+
+       if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG) {
+               warn("too many configurations");
+               return -EINVAL;
+       }
+
+       if (dev->descriptor.bNumConfigurations < 1) {
+               warn("not enough configurations");
+               return -EINVAL;
+       }
+
+       dev->config = (struct usb_config_descriptor *)
+               kmalloc(dev->descriptor.bNumConfigurations *
+               sizeof(struct usb_config_descriptor), GFP_KERNEL);
+       if (!dev->config) {
+               err("out of memory");
+               return -ENOMEM; 
+       }
+       memset(dev->config, 0, dev->descriptor.bNumConfigurations *
+               sizeof(struct usb_config_descriptor));
+
+       dev->rawdescriptors = (char **)kmalloc(sizeof(char *) *
+               dev->descriptor.bNumConfigurations, GFP_KERNEL);
+       if (!dev->rawdescriptors) {
+               err("out of memory");
+               return -ENOMEM;
+       }
+
+       buffer = kmalloc(8, GFP_KERNEL);
+       if (!buffer) {
+               err("unable to allocate memory for configuration descriptors");
+               return -ENOMEM;
+       }
+       desc = (struct usb_config_descriptor *)buffer;
+
+       for (cfgno = 0; cfgno < dev->descriptor.bNumConfigurations; cfgno++) {
+               /* We grab the first 8 bytes so we know how long the whole */
+               /*  configuration is */
+               result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8);
+               if (result < 8) {
+                       if (result < 0)
+                               err("unable to get descriptor");
+                       else {
+                               err("config descriptor too short (expected %i, got 
+%i)", 8, result);
+                               result = -EINVAL;
+                       }
+                       goto err;
+               }
+
+               /* Get the full buffer */
+               length = le16_to_cpu(desc->wTotalLength);
+
+               bigbuffer = kmalloc(length, GFP_KERNEL);
+               if (!bigbuffer) {
+                       err("unable to allocate memory for configuration descriptors");
+                       result = -ENOMEM;
+                       goto err;
+               }
+
+               /* Now that we know the length, get the whole thing */
+               result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, 
+length);
+               if (result < 0) {
+                       err("couldn't get all of config descriptors");
+                       kfree(bigbuffer);
+                       goto err;
+               }       
+       
+               if (result < length) {
+                       err("config descriptor too short (expected %i, got %i)", 
+length, result);
+                       result = -EINVAL;
+                       kfree(bigbuffer);
+                       goto err;
+               }
+
+               dev->rawdescriptors[cfgno] = bigbuffer;
+
+               result = usb_parse_configuration(&dev->config[cfgno], bigbuffer);
+               if (result > 0)
+                       dbg("descriptor data left");
+               else if (result < 0) {
+                       result = -EINVAL;
+                       goto err;
+               }
+       }
+
+       kfree(buffer);
+       return 0;
+err:
+       kfree(buffer);
+       dev->descriptor.bNumConfigurations = cfgno;
+       return result;
+}
+
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c    Fri May 31 16:47:03 2002
+++ b/drivers/usb/core/usb.c    Fri May 31 16:47:03 2002
@@ -33,7 +33,6 @@
 #include <linux/devfs_fs_kernel.h>
 #include <linux/spinlock.h>
 #include <linux/errno.h>
-#include <asm/byteorder.h>
 
 #ifdef CONFIG_USB_DEBUG
        #define DEBUG
@@ -1035,390 +1034,6 @@
 
 /*-------------------------------------------------------------------*/
 
-static int usb_parse_endpoint(struct usb_endpoint_descriptor *endpoint, unsigned char 
*buffer, int size)
-{
-       struct usb_descriptor_header *header;
-       unsigned char *begin;
-       int parsed = 0, len, numskipped;
-
-       header = (struct usb_descriptor_header *)buffer;
-
-       /* Everything should be fine being passed into here, but we sanity */
-       /*  check JIC */
-       if (header->bLength > size) {
-               err("ran out of descriptors parsing");
-               return -1;
-       }
-               
-       if (header->bDescriptorType != USB_DT_ENDPOINT) {
-               warn("unexpected descriptor 0x%X, expecting endpoint descriptor, type 
0x%X",
-                       endpoint->bDescriptorType, USB_DT_ENDPOINT);
-               return parsed;
-       }
-
-       if (header->bLength == USB_DT_ENDPOINT_AUDIO_SIZE)
-               memcpy(endpoint, buffer, USB_DT_ENDPOINT_AUDIO_SIZE);
-       else
-               memcpy(endpoint, buffer, USB_DT_ENDPOINT_SIZE);
-       
-       le16_to_cpus(&endpoint->wMaxPacketSize);
-
-       buffer += header->bLength;
-       size -= header->bLength;
-       parsed += header->bLength;
-
-       /* 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 < 2) {
-                       err("invalid descriptor length of %d", header->bLength);
-                       return -1;
-               }
-
-               /* If we find another "proper" descriptor 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;
-               parsed += header->bLength;
-       }
-       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) {
-               endpoint->extra = NULL;
-               endpoint->extralen = 0;
-               return parsed;
-       }
-
-       endpoint->extra = kmalloc(len, GFP_KERNEL);
-
-       if (!endpoint->extra) {
-               err("couldn't allocate memory for endpoint extra descriptors");
-               endpoint->extralen = 0;
-               return parsed;
-       }
-
-       memcpy(endpoint->extra, begin, len);
-       endpoint->extralen = len;
-
-       return parsed;
-}
-
-static int usb_parse_interface(struct usb_interface *interface, unsigned char 
*buffer, int size)
-{
-       int i, len, numskipped, retval, parsed = 0;
-       struct usb_descriptor_header *header;
-       struct usb_interface_descriptor *ifp;
-       unsigned char *begin;
-
-       interface->act_altsetting = 0;
-       interface->num_altsetting = 0;
-       interface->max_altsetting = USB_ALTSETTINGALLOC;
-
-       interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * 
interface->max_altsetting, GFP_KERNEL);
-       
-       if (!interface->altsetting) {
-               err("couldn't kmalloc interface->altsetting");
-               return -1;
-       }
-
-       while (size > 0) {
-               if (interface->num_altsetting >= interface->max_altsetting) {
-                       void *ptr;
-                       int oldmas;
-
-                       oldmas = interface->max_altsetting;
-                       interface->max_altsetting += USB_ALTSETTINGALLOC;
-                       if (interface->max_altsetting > USB_MAXALTSETTING) {
-                               warn("too many alternate settings (max %d)",
-                                       USB_MAXALTSETTING);
-                               return -1;
-                       }
-
-                       ptr = interface->altsetting;
-                       interface->altsetting = kmalloc(sizeof(struct 
usb_interface_descriptor) * interface->max_altsetting, GFP_KERNEL);
-                       if (!interface->altsetting) {
-                               err("couldn't kmalloc interface->altsetting");
-                               interface->altsetting = ptr;
-                               return -1;
-                       }
-                       memcpy(interface->altsetting, ptr, sizeof(struct 
usb_interface_descriptor) * oldmas);
-
-                       kfree(ptr);
-               }
-
-               ifp = interface->altsetting + interface->num_altsetting;
-               ifp->endpoint = NULL;
-               ifp->extra = NULL;
-               ifp->extralen = 0;
-               interface->num_altsetting++;
-
-               memcpy(ifp, buffer, USB_DT_INTERFACE_SIZE);
-
-               /* Skip over the interface */
-               buffer += ifp->bLength;
-               parsed += ifp->bLength;
-               size -= ifp->bLength;
-
-               begin = buffer;
-               numskipped = 0;
-
-               /* Skip over any interface, class or vendor descriptors */
-               while (size >= sizeof(struct usb_descriptor_header)) {
-                       header = (struct usb_descriptor_header *)buffer;
-
-                       if (header->bLength < 2) {
-                               err("invalid descriptor length of %d", 
header->bLength);
-                               return -1;
-                       }
-
-                       /* If we find another "proper" descriptor then we're done  */
-                       if ((header->bDescriptorType == USB_DT_INTERFACE) ||
-                           (header->bDescriptorType == USB_DT_ENDPOINT) ||
-                           (header->bDescriptorType == USB_DT_CONFIG) ||
-                           (header->bDescriptorType == USB_DT_DEVICE))
-                               break;
-
-                       numskipped++;
-
-                       buffer += header->bLength;
-                       parsed += header->bLength;
-                       size -= header->bLength;
-               }
-
-               if (numskipped)
-                       dbg("skipped %d class/vendor specific interface descriptors", 
numskipped);
-
-               /* Copy any unknown descriptors into a storage area for */
-               /*  drivers to later parse */
-               len = (int)(buffer - begin);
-               if (len) {
-                       ifp->extra = kmalloc(len, GFP_KERNEL);
-
-                       if (!ifp->extra) {
-                               err("couldn't allocate memory for interface extra 
descriptors");
-                               ifp->extralen = 0;
-                               return -1;
-                       }
-                       memcpy(ifp->extra, begin, len);
-                       ifp->extralen = len;
-               }
-
-               /* Did we hit an unexpected descriptor? */
-               header = (struct usb_descriptor_header *)buffer;
-               if ((size >= sizeof(struct usb_descriptor_header)) &&
-                   ((header->bDescriptorType == USB_DT_CONFIG) ||
-                    (header->bDescriptorType == USB_DT_DEVICE)))
-                       return parsed;
-
-               if (ifp->bNumEndpoints > USB_MAXENDPOINTS) {
-                       warn("too many endpoints");
-                       return -1;
-               }
-
-               ifp->endpoint = (struct usb_endpoint_descriptor *)
-                       kmalloc(ifp->bNumEndpoints *
-                       sizeof(struct usb_endpoint_descriptor), GFP_KERNEL);
-               if (!ifp->endpoint) {
-                       err("out of memory");
-                       return -1;      
-               }
-
-               memset(ifp->endpoint, 0, ifp->bNumEndpoints *
-                       sizeof(struct usb_endpoint_descriptor));
-       
-               for (i = 0; i < ifp->bNumEndpoints; i++) {
-                       header = (struct usb_descriptor_header *)buffer;
-
-                       if (header->bLength > size) {
-                               err("ran out of descriptors parsing");
-                               return -1;
-                       }
-               
-                       retval = usb_parse_endpoint(ifp->endpoint + i, buffer, size);
-                       if (retval < 0)
-                               return retval;
-
-                       buffer += retval;
-                       parsed += retval;
-                       size -= retval;
-               }
-
-               /* We check to see if it's an alternate to this one */
-               ifp = (struct usb_interface_descriptor *)buffer;
-               if (size < USB_DT_INTERFACE_SIZE ||
-                   ifp->bDescriptorType != USB_DT_INTERFACE ||
-                   !ifp->bAlternateSetting)
-                       return parsed;
-       }
-
-       return parsed;
-}
-
-int usb_parse_configuration(struct usb_config_descriptor *config, char *buffer)
-{
-       int i, retval, size;
-       struct usb_descriptor_header *header;
-
-       memcpy(config, buffer, USB_DT_CONFIG_SIZE);
-       le16_to_cpus(&config->wTotalLength);
-       size = config->wTotalLength;
-
-       if (config->bNumInterfaces > USB_MAXINTERFACES) {
-               warn("too many interfaces");
-               return -1;
-       }
-
-       config->interface = (struct usb_interface *)
-               kmalloc(config->bNumInterfaces *
-               sizeof(struct usb_interface), GFP_KERNEL);
-       dbg("kmalloc IF %p, numif %i", config->interface, config->bNumInterfaces);
-       if (!config->interface) {
-               err("out of memory");
-               return -1;      
-       }
-
-       memset(config->interface, 0,
-              config->bNumInterfaces * sizeof(struct usb_interface));
-
-       buffer += config->bLength;
-       size -= config->bLength;
-       
-       config->extra = NULL;
-       config->extralen = 0;
-
-       for (i = 0; i < config->bNumInterfaces; i++) {
-               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 "proper" descriptor 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;
-               }
-               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) {
-                       if (config->extralen) {
-                               warn("extra config descriptor");
-                       } 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(config->interface + i, buffer, size);
-               if (retval < 0)
-                       return retval;
-
-               buffer += retval;
-               size -= retval;
-       }
-
-       return size;
-}
-
-// hub-only!! ... and only exported for reset/reinit path.
-// otherwise used internally on disconnect/destroy path
-void usb_destroy_configuration(struct usb_device *dev)
-{
-       int c, i, j, k;
-       
-       if (!dev->config)
-               return;
-
-       if (dev->rawdescriptors) {
-               for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
-                       kfree(dev->rawdescriptors[i]);
-
-               kfree(dev->rawdescriptors);
-       }
-
-       for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
-               struct usb_config_descriptor *cf = &dev->config[c];
-
-               if (!cf->interface)
-                       break;
-
-               for (i = 0; i < cf->bNumInterfaces; i++) {
-                       struct usb_interface *ifp =
-                               &cf->interface[i];
-                               
-                       if (!ifp->altsetting)
-                               break;
-
-                       for (j = 0; j < ifp->num_altsetting; j++) {
-                               struct usb_interface_descriptor *as =
-                                       &ifp->altsetting[j];
-                                       
-                               if(as->extra) {
-                                       kfree(as->extra);
-                               }
-
-                               if (!as->endpoint)
-                                       break;
-                                       
-                               for(k = 0; k < as->bNumEndpoints; k++) {
-                                       if(as->endpoint[k].extra) {
-                                               kfree(as->endpoint[k].extra);
-                                       }
-                               }       
-                               kfree(as->endpoint);
-                       }
-
-                       kfree(ifp->altsetting);
-               }
-               kfree(cf->interface);
-       }
-       kfree(dev->config);
-}
 
 /* for returning string descriptors in UTF-16LE */
 static int ascii2utf (char *ascii, __u8 *utf, int utfmax)
@@ -1618,108 +1233,6 @@
                0, dev->devnum, 0, NULL, 0, HZ * USB_CTRL_GET_TIMEOUT);
 }
 
-
-// hub-only!! ... and only in reset path, or usb_new_device()
-// (used by real hubs and virtual root hubs)
-int usb_get_configuration(struct usb_device *dev)
-{
-       int result;
-       unsigned int cfgno, length;
-       unsigned char *buffer;
-       unsigned char *bigbuffer;
-       struct usb_config_descriptor *desc;
-
-       if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG) {
-               warn("too many configurations");
-               return -EINVAL;
-       }
-
-       if (dev->descriptor.bNumConfigurations < 1) {
-               warn("not enough configurations");
-               return -EINVAL;
-       }
-
-       dev->config = (struct usb_config_descriptor *)
-               kmalloc(dev->descriptor.bNumConfigurations *
-               sizeof(struct usb_config_descriptor), GFP_KERNEL);
-       if (!dev->config) {
-               err("out of memory");
-               return -ENOMEM; 
-       }
-       memset(dev->config, 0, dev->descriptor.bNumConfigurations *
-               sizeof(struct usb_config_descriptor));
-
-       dev->rawdescriptors = (char **)kmalloc(sizeof(char *) *
-               dev->descriptor.bNumConfigurations, GFP_KERNEL);
-       if (!dev->rawdescriptors) {
-               err("out of memory");
-               return -ENOMEM;
-       }
-
-       buffer = kmalloc(8, GFP_KERNEL);
-       if (!buffer) {
-               err("unable to allocate memory for configuration descriptors");
-               return -ENOMEM;
-       }
-       desc = (struct usb_config_descriptor *)buffer;
-
-       for (cfgno = 0; cfgno < dev->descriptor.bNumConfigurations; cfgno++) {
-               /* We grab the first 8 bytes so we know how long the whole */
-               /*  configuration is */
-               result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8);
-               if (result < 8) {
-                       if (result < 0)
-                               err("unable to get descriptor");
-                       else {
-                               err("config descriptor too short (expected %i, got 
%i)", 8, result);
-                               result = -EINVAL;
-                       }
-                       goto err;
-               }
-
-               /* Get the full buffer */
-               length = le16_to_cpu(desc->wTotalLength);
-
-               bigbuffer = kmalloc(length, GFP_KERNEL);
-               if (!bigbuffer) {
-                       err("unable to allocate memory for configuration descriptors");
-                       result = -ENOMEM;
-                       goto err;
-               }
-
-               /* Now that we know the length, get the whole thing */
-               result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, 
length);
-               if (result < 0) {
-                       err("couldn't get all of config descriptors");
-                       kfree(bigbuffer);
-                       goto err;
-               }       
-       
-               if (result < length) {
-                       err("config descriptor too short (expected %i, got %i)", 
length, result);
-                       result = -EINVAL;
-                       kfree(bigbuffer);
-                       goto err;
-               }
-
-               dev->rawdescriptors[cfgno] = bigbuffer;
-
-               result = usb_parse_configuration(&dev->config[cfgno], bigbuffer);
-               if (result > 0)
-                       dbg("descriptor data left");
-               else if (result < 0) {
-                       result = -EINVAL;
-                       goto err;
-               }
-       }
-
-       kfree(buffer);
-       return 0;
-err:
-       kfree(buffer);
-       dev->descriptor.bNumConfigurations = cfgno;
-       return result;
-}
 
 /*
  * By the time we get here, the device has gotten a new device ID

_______________________________________________________________

Don't miss the 2002 Sprint PCS Application Developer's Conference
August 25-28 in Las Vegas -- http://devcon.sprintpcs.com/adp/index.cfm

_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to