Alan,

Finally got a chance to look at this some more. I basically used only the 
first portion of your patch. For full_speed devices (I'm assuming this is the 
only ones that need this), I call usb_get_descriptor() before 
usb_set_address() in order to get the length of the descriptor and max packet 
size. It looks like both are needed. Then I use these for the 
usb_get_descriptor() after usb_set_address(). This sequence appears to work 
with the devices I have been testing with. 

I also had to change usb_submit_urb to not check for dev->devnum == 0.

Below is the patch for my version of usb.c.

Let me know if there is something else you want me to try. Thanks for your 
help.

Kyle.

--- linux-2.6.0-rmk2/drivers/usb/core/usb.c     Wed Dec 17 21:58:49 2003
+++ linux/drivers/usb/core/usb.c        Fri Aug  6 16:33:27 2004
@@ -991,6 +992,8 @@
        int err = -EINVAL;
        int i;
        int j;
+       char *buf;
+       int blength;

        /*
         * Set the driver for the usb device to point to the "generic" driver.
@@ -1020,11 +1027,12 @@
                i = 64;
                break;
        case USB_SPEED_FULL:            /* 8, 16, 32, or 64 */
-               /* to determine the ep0 maxpacket size, read the first 8
-                * bytes from the device descriptor to get bMaxPacketSize0;
-                * then correct our initial (small) guess.
+               /* to determine the ep0 maxpacket size, try to read
+                * the device descriptor to get bMaxPacketSize0;
+                * then correct our initial (large) guess.
                 */
-               // FALLTHROUGH
+               i = 64;
+               break;
        case USB_SPEED_LOW:             /* fixed at 8 */
                i = 8;
                break;
@@ -1034,6 +1042,38 @@
        dev->epmaxpacketin [0] = i;
        dev->epmaxpacketout[0] = i;

+       /*
+        * Some devices fail if the initial get_descriptor after set_addess
+        * does not request actual descriptor length and correct packet size.
+        */
+       if (dev->speed == USB_SPEED_FULL)
+       {
+               buf = kmalloc(64, GFP_KERNEL);
+               if (!buf) {
+                       clear_bit(dev->devnum, dev->bus->devmap.devicemap);
+                       dev->devnum = -1;
+                       return 1;
+               }
+               i = dev->devnum;
+               dev->devnum = 0;
+               err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, buf, 64);
+               if (err < 8) {
+                       err("USB device failed initial GET_DESCRIPTOR 
(err=%d)", err);
+                       clear_bit(i, dev->bus->devmap.devicemap);
+                       dev->devnum = -1;
+                       kfree(buf);
+                       return 1;
+               }
+               dev->devnum = i;
+               dev->epmaxpacketin[0] = dev->epmaxpacketout[0] =
+                  ((struct usb_device_descriptor *) buf)->bMaxPacketSize0;
+               blength = ((struct usb_device_descriptor *) buf)->bLength;
+               kfree(buf);
+       }
+       else
+               blength = 8;
+
+
        for (i = 0; i < NEW_DEVICE_RETRYS; ++i) {

                for (j = 0; j < SET_ADDRESS_RETRYS; ++j) {
@@ -1052,9 +1092,10 @@
                wait_ms(10);    /* Let the SET_ADDRESS settle */

                /* high and low speed devices don't need this... */
-               err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, 
&dev->descriptor, 8);
-               if (err >= 8)
+               err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, 
&dev->descriptor, blength);
+               if (err >= blength)
                        break;
+
                wait_ms(100);
        }

@@ -1058,7 +1099,7 @@
                wait_ms(100);
        }

-       if (err < 8) {
+       if (err < blength) {
                dev_err(&dev->dev, "device descriptor read/8, error %d\n", 
err);                goto fail;
        }


-------------------------------------------------------
This SF.Net email is sponsored by OSTG. Have you noticed the changes on
Linux.com, ITManagersJournal and NewsForge in the past few weeks? Now,
one more big change to announce. We are now OSTG- Open Source Technology
Group. Come see the changes on the new OSTG site. www.ostg.com
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to