On Fri, 8 Oct 2004, martin f krafft wrote:

> > Sometimes errors like this and the ones above are just temporary.
> > The device takes a moment to warm up and start working right.  You
> > only need to worry about it if the device doesn't work in the end.
> 
> I do have another device (a USB servo controller) which gives the
> same messages and does not work at all. USB on the machine is fine
> though. Thus, may I conclude that the device firmware is whacked?

No, not necessarily.  A lot of devices seem to be having these problems, 
and many of them work okay under 2.4.  I don't know what the real reason 
for the problem is -- although I assume that a truly _correctly_ working 
device wouldn't have any difficulties.

> > I found the reason for your oops.  It has already been fixed in the USB
> > development kernel but the fix isn't in 2.6.9-rc3.  It's the first patch
> > below.
> 
> Superb. I will try 2.6.9-rc3 then.

No -- I said the fix _isn't_ in 2.6.9-rc3.

> But first I will try 2.6.8.1 with the two patches. Might be
> a couple of days.

The patches I sent were for 2.6.9-rc3.  The first one might work all right
2.6.8.1 but the second one definitely won't.  Below is a version of the 
second patch for 2.6.8.1.

Alan Stern


--- 2.6.8.1/drivers/usb/core/hub.c.orig 2004-10-04 15:39:26.000000000 -0400
+++ 2.6.8.1/drivers/usb/core/hub.c      2004-10-07 14:10:32.000000000 -0400
@@ -1127,7 +1127,7 @@
 #define PORT_RESET_TRIES       5
 #define SET_ADDRESS_TRIES      2
 #define GET_DESCRIPTOR_TRIES   2
-#define SET_CONFIG_TRIES       2
+#define SET_CONFIG_TRIES       4
 
 #define HUB_ROOT_RESET_TIME    50      /* times are in msec */
 #define HUB_SHORT_RESET_TIME   10
@@ -1352,7 +1352,8 @@
  * pointers, it's not necessary to lock the device.
  */
 static int
-hub_port_init (struct usb_device *hdev, struct usb_device *udev, int port)
+hub_port_init (struct usb_device *hdev, struct usb_device *udev, int port,
+               int get_descriptor_first)
 {
        static DECLARE_MUTEX(usb_address0_sem);
 
@@ -1387,6 +1388,7 @@
                dev_dbg(&udev->dev, "device reset changed speed!\n");
                goto fail;
        }
+       oldspeed = udev->speed;
   
        /* USB 2.0 section 5.5.3 talks about ep0 maxpacket ...
         * it's fixed size except for full speed devices.
@@ -1396,19 +1398,18 @@
                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 and
+                * then correct our initial guess.
                 */
-               // FALLTHROUGH
+               i = 64;
+               break;
        case USB_SPEED_LOW:             /* fixed at 8 */
                i = 8;
                break;
        default:
                goto fail;
        }
-       udev->epmaxpacketin [0] = i;
-       udev->epmaxpacketout[0] = i;
  
        dev_info (&udev->dev,
                        "%s %s speed USB device using address %d\n",
@@ -1433,17 +1434,63 @@
                udev->tt = &hub->tt;
                udev->ttport = port + 1;
        }
+
+       /* Clear out any stale HC state pertaining to device 0 endpoint 0 */
+       j = udev->devnum;
+       udev->devnum = 0;
+       usb_disable_endpoint(udev, 0 + USB_DIR_IN);
+       usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
+       udev->devnum = j;
+       udev->epmaxpacketin [0] = i;
+       udev->epmaxpacketout[0] = i;
+       usb_endpoint_running(udev, 0, 0);
+       usb_endpoint_running(udev, 0, 1);
  
        /* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way?
         * Because device hardware and firmware is sometimes buggy in
         * this area, and this is how Linux has done it for ages.
         * Change it cautiously.
         *
-        * NOTE:  Windows gets the descriptor first, seemingly to help
-        * work around device bugs like "can't use addresses with bit 3
-        * set in certain configurations".  Yes, really.
+        * NOTE:  For full-speed devices, if get_descriptor_first
+        * is set we will start by issuing a 64-byte GET_DESCRIPTOR
+        * request.  This is what Windows does, so it may help with some
+        * non-standards-compliant devices.  Otherwise we start with
+        * SET_ADDRESS and then try to read the first 8 bytes of the
+        * device descriptor to get the ep0 maxpacket value.
         */
-       for (i = 0; i < GET_DESCRIPTOR_TRIES; ++i) {
+       for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) {
+               if (get_descriptor_first) {
+                       struct usb_device_descriptor *buf;
+
+                       buf = kmalloc(64, GFP_NOIO);
+                       if (!buf) {
+                               retval = -ENOMEM;
+                               continue;
+                       }
+                       memset(buf, 0, 64);
+                       j = usb_control_msg(udev,
+                                               /* Address 0 */
+                                       (PIPE_CONTROL << 30) | USB_DIR_IN,
+                                       USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
+                                       USB_DT_DEVICE << 8, 0,
+                                       buf, 64,
+                                       HZ * USB_CTRL_GET_TIMEOUT);
+                       udev->descriptor = *buf;
+                       kfree(buf);
+
+                       retval = hub_port_reset(hdev, port, udev, delay);
+                       if (retval < 0)         /* error or disconnect */
+                               goto fail;
+                       if (oldspeed != udev->speed) {
+                               retval = -ENODEV;
+                               goto fail;
+                       }
+                       if (udev->descriptor.bMaxPacketSize0 < 8) {
+                               retval = -EMSGSIZE;
+                               continue;
+                       }
+               }
+
                for (j = 0; j < SET_ADDRESS_TRIES; ++j) {
                        retval = hub_set_address(udev);
                        if (retval >= 0)
@@ -1462,10 +1511,12 @@
                 *  - read ep0 maxpacket even for high and low speed,
                 */
                msleep(10);
-               retval = usb_get_device_descriptor(udev, 8);
+               if (get_descriptor_first)
+                       retval = 8;
+               else
+                       retval = usb_get_device_descriptor(udev, 8);
                if (retval >= 8)
                        break;
-               msleep(100);
        }
        if (retval != 8) {
                dev_err(&udev->dev, "device descriptor read/%s, error %d\n",
@@ -1645,7 +1696,7 @@
                }
 
                /* reset and get descriptor */
-               status = hub_port_init(hdev, udev, port);
+               status = hub_port_init(hdev, udev, port, (i < 2));
                if (status < 0)
                        goto loop;
 
@@ -2060,7 +2111,7 @@
 {
        struct usb_device *parent = udev->parent;
        struct usb_device_descriptor descriptor = udev->descriptor;
-       int i, ret, port = -1;
+       int i, ret = 0, port = -1;
        struct usb_hub *hub;
 
        if (udev->state == USB_STATE_NOTATTACHED ||
@@ -2092,7 +2143,11 @@
                return -ENOENT;
        }
 
-       ret = hub_port_init(parent, udev, port);
+       for (i = 0; i < SET_CONFIG_TRIES; ++i) {
+               ret = hub_port_init(parent, udev, port, (i < 2));
+               if (ret >= 0)
+                       break;
+       }
        if (ret < 0)
                goto re_enumerate;
  



-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to