This is against 2.6.8.1
Changes -
Change the way that a device is enumerated since some devices fail if the
initial get_device_descriptor does not request the actual descriptor length.
diff -X dontdiff -NurbB linux-2.6.8.orig/drivers/usb/core/hub.c
linux/drivers/usb/core/hub.c
--- linux-2.6.8.orig/drivers/usb/core/hub.c Sat Aug 14 01:36:57 2004
+++ linux/drivers/usb/core/hub.c Wed Sep 22 20:44:19 2004
@@ -1359,6 +1359,8 @@
int i, j, retval;
unsigned delay = HUB_SHORT_RESET_TIME;
enum usb_device_speed oldspeed = udev->speed;
+ int blength=8;
+ char *buf;
/* root hub ports have a slightly longer reset period
* (from USB 2.0 spec, section 7.1.7.5)
@@ -1400,7 +1402,8 @@
* bytes from the device descriptor to get bMaxPacketSize0;
* then correct our initial (small) guess.
*/
- // FALLTHROUGH
+ i = 64;
+ break;
case USB_SPEED_LOW: /* fixed at 8 */
i = 8;
break;
@@ -1410,6 +1413,42 @@
udev->epmaxpacketin [0] = i;
udev->epmaxpacketout[0] = i;
+ /*
+ * Some devices fail if the initial get_descriptor after set_addess
+ * does not request actual descriptor length and correct packet size.
+ * This sequence performs an initial get_descriptor at address 0 to
+ * get the actual descriptor lenght. Then the device is reset and the
+ * actual bLength is used after set_address.
+ */
+ if (udev->speed == USB_SPEED_FULL) {
+ buf = kmalloc(64, GFP_KERNEL);
+ if (!buf) {
+ clear_bit(udev->devnum, udev->bus->devmap.devicemap);
+ udev->devnum = -1;
+ goto fail;
+ }
+ i = udev->devnum;
+ udev->devnum = 0;
+ retval = usb_get_descriptor(udev, USB_DT_DEVICE, 0, buf, 64);
+ if (retval < 8) {
+ err("USB device failed initial GET_DESCRIPTOR
(err=%d)", retval);
+ clear_bit(i, udev->bus->devmap.devicemap);
+ udev->devnum = -1;
+ kfree(buf);
+ goto fail;
+ }
+ udev->devnum = i;
+ udev->epmaxpacketin[0] = udev->epmaxpacketout[0] =
+ ((struct usb_device_descriptor *) buf)->bMaxPacketSize0;
+ blength = ((struct usb_device_descriptor *) buf)->bLength;
+ kfree(buf);
+ retval = hub_port_reset(hdev, port, udev, delay);
+ if (retval < 0)
+ goto fail;
+ }
+ else
+ blength = 8;
+
dev_info (&udev->dev,
"%s %s speed USB device using address %d\n",
(udev->config) ? "reset" : "new",
@@ -1462,12 +1501,12 @@
* - read ep0 maxpacket even for high and low speed,
*/
msleep(10);
- retval = usb_get_device_descriptor(udev, 8);
- if (retval >= 8)
+ retval = usb_get_device_descriptor(udev, blength);
+ if (retval >= blength)
break;
msleep(100);
}
- if (retval != 8) {
+ if (retval != blength) {
dev_err(&udev->dev, "device descriptor read/%s, error %d\n",
"8", retval);
if (retval >= 0)
@@ -1811,8 +1850,10 @@
ret = hub_port_status(hdev, i,
&portstatus, &portchange);
+ printk("i %d s %x c %x r %d\n", i, portstatus,
portchange, ret); if (ret < 0)
continue;
+
if (portchange & USB_PORT_STAT_C_CONNECTION) {
clear_port_feature(hdev,
diff -X dontdiff -NurbB linux-2.6.8.orig/drivers/usb/core/urb.c
linux/drivers/usb/core/urb.c
--- linux-2.6.8.orig/drivers/usb/core/urb.c Sat Aug 14 01:37:15 2004
+++ linux/drivers/usb/core/urb.c Wed Sep 22 20:21:48 2004
@@ -233,9 +233,13 @@
if (!urb || urb->hcpriv || !urb->complete)
return -EINVAL;
+ /*
+ * Allow devnum == 0 when performing initial get_descriptor before
+ * set_address.
+ */
if (!(dev = urb->dev) ||
(dev->state < USB_STATE_DEFAULT) ||
- (!dev->bus) || (dev->devnum <= 0))
+ (!dev->bus) || (dev->devnum < 0))
return -ENODEV;
if (dev->state == USB_STATE_SUSPENDED)
return -EHOSTUNREACH;
-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel