Hi, this is the first time I post to this list, so please excuse any 
mistake...

Until kernel 2.6.3 there was a patch that permitted to use some USB
whose first interface number is 1 instead of 0. But with kernel 2.6.5
the patch didn't work anymore. So I "ported" the patch in the new kernel.

Disclaimer:
I never coded anything in the kernel and I've never seen any USB
specification, but now my usb mouse works ;), I hope someone
could say if I did the right things...

I'm not subscribed to the list so please CC me: papik (at) ticino (dot) com

-Papik


Here is the patch:
--- linux-2.6.5/drivers/usb/core/config.c       2004-04-16 15:29:58.000000000 +0200
+++ edited/drivers/usb/core/config.c    2004-05-10 00:37:50.205602696 +0200
@@ -87,11 +87,11 @@
        kfree(intf);
 }
 
-static int usb_parse_interface(struct usb_host_config *config, unsigned char *buffer, 
int size)
+static int usb_parse_interface(struct usb_host_config *config, unsigned char *buffer, 
int size, int inums[])
 {
        unsigned char *buffer0 = buffer;
        struct usb_interface_descriptor *d;
-       int inum, asnum;
+       int inum, intfindx, asnum;
        struct usb_interface *interface;
        struct usb_host_interface *ifp;
        int len, numskipped;
@@ -107,7 +107,14 @@
        }
 
        inum = d->bInterfaceNumber;
-       if (inum >= config->desc.bNumInterfaces) {
+
+       /* find in inums the index of inum */
+       for (intfindx=0; intfindx < config->desc.bNumInterfaces; ++intfindx)
+       {
+               if (inums[intfindx] == inum)
+                       break;
+       }
+       if (intfindx >= config->desc.bNumInterfaces) {
 
                /* Skip to the next interface descriptor */
                buffer += d->bLength;
@@ -123,7 +130,7 @@
                return buffer - buffer0;
        }
 
-       interface = config->interface[inum];
+       interface = config->interface[intfindx];
        asnum = d->bAlternateSetting;
        if (asnum >= interface->num_altsetting) {
                warn("invalid alternate setting %d for interface %d",
@@ -199,7 +206,8 @@
 int usb_parse_configuration(struct usb_host_config *config, char *buffer, int size)
 {
        int nintf, nintf_orig;
-       int i, j;
+       int i, j, n;
+       int inum, inums[USB_MAXINTERFACES];
        struct usb_interface *interface;
        char *buffer2;
        int size2;
@@ -223,6 +231,7 @@
                config->desc.bNumInterfaces = nintf = USB_MAXINTERFACES;
        }
 
+       /* Alloc  and clear memory for interfaces */
        for (i = 0; i < nintf; ++i) {
                interface = config->interface[i] =
                    kmalloc(sizeof(struct usb_interface), GFP_KERNEL);
@@ -238,6 +247,7 @@
         * number of altsettings for each interface */
        buffer2 = buffer;
        size2 = size;
+       i = 0; /* Interface number counter */
        j = 0;
        while (size2 >= sizeof(struct usb_descriptor_header)) {
                header = (struct usb_descriptor_header *) buffer2;
@@ -254,14 +264,26 @@
                                return -EINVAL;
                        }
                        d = (struct usb_interface_descriptor *) header;
-                       i = d->bInterfaceNumber;
-                       if (i >= nintf_orig) {
-                               warn("invalid interface number (%d/%d)",
-                                   i, nintf_orig);
+                       inum = d->bInterfaceNumber;
+                       /* Interface already encountered ? */
+                       for (n = i-1; n >=0; --n)
+                               if (inums[n] == inum)
+                                       break;
+                       if (n < 0)
+                       {
+                               n = i;
+                               inums[n]=inum;
+                               ++i;
+                       }
+                       if (n >= nintf_orig) {
+                               warn("too many interfaces(%d/%d)",
+                                   n, nintf_orig);
                                return -EINVAL;
                        }
-                       if (i < nintf)
-                               ++config->interface[i]->num_altsetting;
+                       if (n < nintf)
+                       {
+                               ++config->interface[n]->num_altsetting;
+                       }
 
                } else if ((header->bDescriptorType == USB_DT_DEVICE ||
                    header->bDescriptorType == USB_DT_CONFIG) && j) {
@@ -279,11 +301,11 @@
                interface = config->interface[i];
                if (interface->num_altsetting > USB_MAXALTSETTING) {
                        warn("too many alternate settings for interface %d (%d max 
%d)\n",
-                           i, interface->num_altsetting, USB_MAXALTSETTING);
+                           inums[i], interface->num_altsetting, USB_MAXALTSETTING);
                        return -EINVAL;
                }
                if (interface->num_altsetting == 0) {
-                       warn("no alternate settings for interface %d", i);
+                       warn("no alternate settings for interface %d", inums[i]);
                        return -EINVAL;
                }
 
@@ -324,7 +346,7 @@
 
        /* Parse all the interface/altsetting descriptors */
        while (size >= sizeof(struct usb_descriptor_header)) {
-               retval = usb_parse_interface(config, buffer, size);
+               retval = usb_parse_interface(config, buffer, size, inums);
                if (retval < 0)
                        return retval;
 
@@ -337,7 +359,7 @@
                interface = config->interface[i];
                for (j = 0; j < interface->num_altsetting; ++j) {
                        if (!interface->altsetting[j].desc.bLength) {
-                               warn("missing altsetting %d for interface %d", j, i);
+                               warn("missing altsetting %d for interface %d", j, 
inums[i]);
                                return -EINVAL;
                        }
                }
-------------------- End of patch -----------------
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


-------------------------------------------------------
This SF.Net email is sponsored by Sleepycat Software
Learn developer strategies Cisco, Motorola, Ericsson & Lucent use to 
deliver higher performing products faster, at low TCO.
http://www.sleepycat.com/telcomwpreg.php?From=osdnemail3
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to