]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/core/config.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[linux-2.6-omap-h63xx.git] / drivers / usb / core / config.c
index cb69aa1e02e8762913e1d68901fb64495b68d8d0..568244c99bdc0f5d7b0e03d2177d1153e9d49d49 100644 (file)
@@ -145,6 +145,23 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
                        endpoint->desc.wMaxPacketSize = cpu_to_le16(8);
        }
 
+       /*
+        * Some buggy high speed devices have bulk endpoints using
+        * maxpacket sizes other than 512.  High speed HCDs may not
+        * be able to handle that particular bug, so let's warn...
+        */
+       if (to_usb_device(ddev)->speed == USB_SPEED_HIGH
+                       && usb_endpoint_xfer_bulk(d)) {
+               unsigned maxp;
+
+               maxp = le16_to_cpu(endpoint->desc.wMaxPacketSize) & 0x07ff;
+               if (maxp != 512)
+                       dev_warn(ddev, "config %d interface %d altsetting %d "
+                               "bulk endpoint 0x%X has invalid maxpacket %d\n",
+                               cfgno, inum, asnum, d->bEndpointAddress,
+                               maxp);
+       }
+
        /* Skip over any Class Specific or Vendor Specific descriptors;
         * find the next endpoint or interface descriptor */
        endpoint->extra = buffer;
@@ -238,7 +255,7 @@ static int usb_parse_interface(struct device *ddev, int cfgno,
 
        /* Allocate space for the right(?) number of endpoints */
        num_ep = num_ep_orig = alt->desc.bNumEndpoints;
-       alt->desc.bNumEndpoints = 0;            // Use as a counter
+       alt->desc.bNumEndpoints = 0;            /* Use as a counter */
        if (num_ep > USB_MAXENDPOINTS) {
                dev_warn(ddev, "too many endpoints for config %d interface %d "
                    "altsetting %d: %d, using maximum allowed: %d\n",
@@ -246,7 +263,8 @@ static int usb_parse_interface(struct device *ddev, int cfgno,
                num_ep = USB_MAXENDPOINTS;
        }
 
-       if (num_ep > 0) {       /* Can't allocate 0 bytes */
+       if (num_ep > 0) {
+               /* Can't allocate 0 bytes */
                len = sizeof(struct usb_host_endpoint) * num_ep;
                alt->endpoint = kzalloc(len, GFP_KERNEL);
                if (!alt->endpoint)
@@ -475,8 +493,9 @@ static int usb_parse_configuration(struct device *ddev, int cfgidx,
        return 0;
 }
 
-// hub-only!! ... and only exported for reset/reinit path.
-// otherwise used internally on disconnect/destroy path
+/* 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;
@@ -498,7 +517,7 @@ void usb_destroy_configuration(struct usb_device *dev)
                kfree(cf->string);
                for (i = 0; i < cf->desc.bNumInterfaces; i++) {
                        if (cf->intf_cache[i])
-                               kref_put(&cf->intf_cache[i]->ref, 
+                               kref_put(&cf->intf_cache[i]->ref,
                                          usb_release_interface_cache);
                }
        }
@@ -507,18 +526,30 @@ void usb_destroy_configuration(struct usb_device *dev)
 }
 
 
-// hub-only!! ... and only in reset path, or usb_new_device()
-// (used by real hubs and virtual root hubs)
+/*
+ * Get the USB config descriptors, cache and parse'em
+ *
+ * hub-only!! ... and only in reset path, or usb_new_device()
+ * (used by real hubs and virtual root hubs)
+ *
+ * NOTE: if this is a WUSB device and is not authorized, we skip the
+ *       whole thing. A non-authorized USB device has no
+ *       configurations.
+ */
 int usb_get_configuration(struct usb_device *dev)
 {
        struct device *ddev = &dev->dev;
        int ncfg = dev->descriptor.bNumConfigurations;
-       int result = -ENOMEM;
+       int result = 0;
        unsigned int cfgno, length;
        unsigned char *buffer;
        unsigned char *bigbuffer;
-       struct usb_config_descriptor *desc;
+       struct usb_config_descriptor *desc;
 
+       cfgno = 0;
+       if (dev->authorized == 0)       /* Not really an error */
+               goto out_not_authorized;
+       result = -ENOMEM;
        if (ncfg > USB_MAXCONFIG) {
                dev_warn(ddev, "too many configurations: %d, "
                    "using maximum allowed: %d\n", ncfg, USB_MAXCONFIG);
@@ -545,14 +576,15 @@ int usb_get_configuration(struct usb_device *dev)
                goto err2;
        desc = (struct usb_config_descriptor *)buffer;
 
-       for (cfgno = 0; cfgno < ncfg; cfgno++) {
+       result = 0;
+       for (; cfgno < ncfg; cfgno++) {
                /* We grab just the first descriptor so we know how long
                 * the whole configuration is */
                result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno,
                    buffer, USB_DT_CONFIG_SIZE);
                if (result < 0) {
                        dev_err(ddev, "unable to read config index %d "
-                           "descriptor/%s\n", cfgno, "start");
+                           "descriptor/%s: %d\n", cfgno, "start", result);
                        dev_err(ddev, "chopping to %d config(s)\n", cfgno);
                        dev->descriptor.bNumConfigurations = cfgno;
                        break;
@@ -599,6 +631,7 @@ int usb_get_configuration(struct usb_device *dev)
 
 err:
        kfree(buffer);
+out_not_authorized:
        dev->descriptor.bNumConfigurations = cfgno;
 err2:
        if (result == -ENOMEM)