public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* 2.6.x support for prism2 USB wireless adapter?
@ 2004-02-23  1:11 Robert Gadsdon
  2004-02-23  2:02 ` Greg KH
  2004-02-23 14:54 ` [linux-usb-devel] " Alan Stern
  0 siblings, 2 replies; 8+ messages in thread
From: Robert Gadsdon @ 2004-02-23  1:11 UTC (permalink / raw)
  To: linux kernel, Linux-USB

I had my Linksys prism2 USB wireless adapter (WUSB11 v2.5) working 
reasonably well with kernel 2.4.23, but with kernel 2.6.3 (and udev 018) 
I get:

usb 1-1: new full speed USB device using address 5
drivers/usb/core/config.c: invalid interface number (1/1)
usb 1-1: can't read configurations, error -22

#modprobe prism2_usb     gives:
prism2usb_init: prism2_usb.o: 0.2.1-pre20 Loaded
prism2usb_init: dev_info is: prism2_usb
drivers/usb/core/usb.c: registered new driver prism2_usb

#lsusb     does not show the device at all...

Is this still 'work in progress'?


Robert Gadsdon


^ permalink raw reply	[flat|nested] 8+ messages in thread
* Re: [linux-usb-devel] 2.6.x support for prism2 USB wireless adapter?
@ 2004-05-04 16:09 rm
  0 siblings, 0 replies; 8+ messages in thread
From: rm @ 2004-05-04 16:09 UTC (permalink / raw)
  To: linux-kernel

hi, 
	i modified Alan Stern's original patch that allows usb
interfaces numbered from 1 to work (which was against 2.6.3) to apply
against 2.6.5.
	it seems to work, but i'm suspicious of having to do this:

+		/*interface->dev.release = usb_release_intf;*/
+		/*device_initialize(&interface->dev);*/

	Alan, can you provide an update of the patch for 2.6.5?

	rob

--- drivers/usb/core/config.c.orig	2004-04-03 22:36:14.000000000 -0500
+++ drivers/usb/core/config.c	2004-05-04 10:23:14.000000000 -0400
@@ -87,7 +87,7 @@
 	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, u8 inums[])
 {
 	unsigned char *buffer0 = buffer;
 	struct usb_interface_descriptor	*d;
@@ -106,8 +106,16 @@
 		return -EINVAL;
 	}
 
+	interface = NULL;
 	inum = d->bInterfaceNumber;
-	if (inum >= config->desc.bNumInterfaces) {
+	for (i = 0; i < config->desc.bNumInterfaces; ++i) {
+		if (inums[i] == inum) {
+			interface = config->interface[i];
+			break;
+		}
+	}
+	if (!interface) {
+
 
 		/* Skip to the next interface descriptor */
 		buffer += d->bLength;
@@ -123,7 +131,7 @@
 		return buffer - buffer0;
 	}
 
-	interface = config->interface[inum];
+
 	asnum = d->bAlternateSetting;
 	if (asnum >= interface->num_altsetting) {
 		warn("invalid alternate setting %d for interface %d",
@@ -207,6 +215,8 @@
 	int numskipped, len;
 	char *begin;
 	int retval;
+	int n;
+	u8 inums[USB_MAXINTERFACES], nalts[USB_MAXINTERFACES];
 
 	memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE);
 	if (config->desc.bDescriptorType != USB_DT_CONFIG ||
@@ -223,22 +233,15 @@
 		config->desc.bNumInterfaces = nintf = USB_MAXINTERFACES;
 	}
 
-	for (i = 0; i < nintf; ++i) {
-		interface = config->interface[i] =
-		    kmalloc(sizeof(struct usb_interface), GFP_KERNEL);
-		dbg("kmalloc IF %p, numif %i", interface, i);
-		if (!interface) {
-			err("out of memory");
-			return -ENOMEM;
-		}
-		memset(interface, 0, sizeof(struct usb_interface));
-	}
+	if (nintf == 0)
+		warn("no interfaces?");
 
 	/* Go through the descriptors, checking their length and counting the
 	 * number of altsettings for each interface */
+	n = 0; 
 	buffer2 = buffer;
 	size2 = size;
-	j = 0;
+
 	while (size2 >= sizeof(struct usb_descriptor_header)) {
 		header = (struct usb_descriptor_header *) buffer2;
 		if ((header->bLength > size2) || (header->bLength < 2)) {
@@ -248,42 +251,73 @@
 
 		if (header->bDescriptorType == USB_DT_INTERFACE) {
 			struct usb_interface_descriptor *d;
+			int inum; 
 
 			if (header->bLength < USB_DT_INTERFACE_SIZE) {
 				warn("invalid interface descriptor");
 				return -EINVAL;
 			}
 			d = (struct usb_interface_descriptor *) header;
-			i = d->bInterfaceNumber;
-			if (i >= nintf_orig) {
+			inum = d->bInterfaceNumber;
+			if (inum > nintf_orig) {
 				warn("invalid interface number (%d/%d)",
-				    i, nintf_orig);
+				    inum, nintf_orig);
+				return -EINVAL;
+			}
+
+
+			/* Have we already encountered this interface? */
+			for (i = n - 1; i >= 0; --i) {
+				if (inums[i] == inum)
+					break;
+			}
+			if (i >= 0)
+				++nalts[i];
+			else if (n >= nintf_orig) {
+				warn("too many interfaces (> %d)", nintf_orig);
 				return -EINVAL;
+			} else if (n < nintf) {
+				inums[n] = inum;
+				nalts[n] = 1;
+				++n;
 			}
-			if (i < nintf)
-				++config->interface[i]->num_altsetting;
+
+
 
 		} else if ((header->bDescriptorType == USB_DT_DEVICE ||
-		    header->bDescriptorType == USB_DT_CONFIG) && j) {
+			    header->bDescriptorType == USB_DT_CONFIG) && buffer2 > buffer) {
 			warn("unexpected descriptor type 0x%X", header->bDescriptorType);
 			return -EINVAL;
 		}
 
-		j = 1;
+
 		buffer2 += header->bLength;
 		size2 -= header->bLength;
 	}
 
-	/* Allocate the altsetting arrays */
-	for (i = 0; i < config->desc.bNumInterfaces; ++i) {
-		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);
-			return -EINVAL;
+	if (n < nintf) {
+		warn("not enough interfaces (%d/%d)", n, nintf);
+		return -EINVAL;
+	}
+
+	/* Allocate the interfaces and altsetting arrays */
+	for (i = 0; i < nintf; ++i) {
+		interface = config->interface[i] =
+		    kmalloc(sizeof(struct usb_interface), GFP_KERNEL);
+		dbg("kmalloc IF %p, numif %i", interface, i);
+		if (!interface) {
+			err("out of memory");
+			return -ENOMEM;
 		}
-		if (interface->num_altsetting == 0) {
-			warn("no alternate settings for interface %d", i);
+		memset(interface, 0, sizeof(struct usb_interface));
+		/*interface->dev.release = usb_release_intf;*/
+		/*device_initialize(&interface->dev);*/
+
+		interface->num_altsetting = nalts[i];
+
+		if (interface->num_altsetting > USB_MAXALTSETTING) {
+		  warn("too many alternate settings for interface %d (%d max %d)\n",
+		       inums[i], interface->num_altsetting, USB_MAXALTSETTING);
 			return -EINVAL;
 		}
 
@@ -324,7 +358,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;
 





----
Robert Melby
Georgia Institute of Technology, Atlanta Georgia, 30332
uucp:     ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!gt4255a
Internet: async!cc!gatech!edu!...

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2004-05-04 16:10 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-02-23  1:11 2.6.x support for prism2 USB wireless adapter? Robert Gadsdon
2004-02-23  2:02 ` Greg KH
2004-02-23  9:31   ` Robert Gadsdon
2004-02-23 17:37     ` Greg KH
2004-02-23 14:54 ` [linux-usb-devel] " Alan Stern
2004-02-24  0:15   ` Robert Gadsdon
2004-04-17 21:15   ` Guido Classen
  -- strict thread matches above, loose matches on Subject: below --
2004-05-04 16:09 rm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox