public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Papik Meli <papik78@yahoo.it>
To: linux-kernel@vger.kernel.org
Subject: [PATCH] USB (invalid interface number error) kernel 2.6.5
Date: Mon, 10 May 2004 01:01:24 +0200	[thread overview]
Message-ID: <200405100101.24265.papik78@yahoo.it> (raw)

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 -----------------

                 reply	other threads:[~2004-05-09 23:01 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200405100101.24265.papik78@yahoo.it \
    --to=papik78@yahoo.it \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox