On Fri, 23 Jul 2004, Luc Dijon wrote:

> Thanks Alan for your Feedback.
> I have some troubles to apply the patch you sent. 2 (important I
> suppose) blocks were not updated successfully.
> I sent you in attach the resu of the exec of patch on hub.c + my orig hub.c.
> My kernel is from www.kernel.org 2.6.7. May be your original hub.c is
> even more recent than 2.6.7.
> Can you check ?

On Sat, 24 Jul 2004, Martin Pohlack wrote:

> Are you sure the patch is against 2.6.7? It does not apply completely.
> hub.c.rej is attached.

Yes, sorry -- I don't have a copy of 2.6.7 handy and so my patch wasn't 
against the right form of the source file.


On Sat, 24 Jul 2004, Luc Dijon wrote:

> Alan,
> Here is in attachment, the resulting log after applying the patch.
> I also attached the patched hub.c  just In case I did something wrong . 
> I hope not :-)
> Thanks,

I'm afraid your fixed-up patch did contain a mistake.

Never mind.  Below is new version of the patch which, I hope, will apply 
correctly to the 2.6.7 source.  Please try it out and see if it works any 
better than before.

Alan Stern

P.S.:  Luc, in the future please don't send 2000-line-long replies with 
your real message hidden away at the bottom; they are very hard to read.
Include only the relevant information.


===== drivers/usb/core/hub.c 1.184 vs edited =====
--- 1.184/drivers/usb/core/hub.c        Tue Jul 13 12:47:28 2004
+++ edited/drivers/usb/core/hub.c       Fri Jul 23 15:39:39 2004
@@ -1061,6 +1061,7 @@
        int                     i, j, retval;
        unsigned                delay = HUB_SHORT_RESET_TIME;
        enum usb_device_speed   oldspeed = udev->speed;
+       int                     get_descriptor_first = 0;
 
        /* root hub ports have a slightly longer reset period
         * (from USB 2.0 spec, section 7.1.7.5)
@@ -1095,19 +1096,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;
  
        /* set the address */
        if (udev->devnum <= 0) {
@@ -1143,17 +1143,60 @@
                        default:                speed = "?";    break;
                        }; speed;}),
                        udev->devnum);
- 
+
+       /* 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, 1);
+       usb_endpoint_running(udev, 0, 0);
+
        /* 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 the bMaxPacketSize0 field
+        * is initially set to 1 we will get the descriptor first,
+        * using a 64-byte transfer request.  This is what Windows does,
+        * so it may help with some non-standards-compliant devices.
         */
-       for (i = 0; i < GET_DESCRIPTOR_TRIES; ++i) {
+       if (udev->descriptor.bMaxPacketSize0 == 1)
+               get_descriptor_first = 1;
+
+       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);
+                       (void) 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 (udev->descriptor.bMaxPacketSize0 < 8) {
+                               retval = -EMSGSIZE;
+                               continue;
+                       }
+               }
+
                for (j = 0; j < SET_ADDRESS_TRIES; ++j) {
                        retval = hub_set_address(udev);
                        if (retval >= 0)
@@ -1177,10 +1220,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",
@@ -1338,6 +1383,7 @@
 
                /* reset, set address, get descriptor, add to hub's children */
                down (&udev->serialize);
+               udev->descriptor.bMaxPacketSize0 = (i & 1);
                status = hub_port_init(hdev, udev, port);
                if (status == -ENOTCONN)
                        break;





-------------------------------------------------------
This SF.Net email is sponsored by BEA Weblogic Workshop
FREE Java Enterprise J2EE developer tools!
Get your free copy of BEA WebLogic Workshop 8.1 today.
http://ads.osdn.com/?ad_id=4721&alloc_id=10040&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to