On Fri, 8 Oct 2004, martin f krafft wrote: > Okay, let's go after this, I disabled all modules that I could and > am now going to try to see how I can reproduce the error. USB > debugging is enabled in the kernel. > > To recap, the whole thing is about weird messages about ep0in > timeouts and the inability to use the affected device. With USB > debugging, this is more verbose! > > kernel: usb 3-2: new full speed USB device using address 2 > kernel: usb 3-2: control timeout on ep0in > kernel: uhci_hcd 0000:00:10.2: uhci_result_control: failed with status 440000 > kernel: [f6d42240] link (36d421e2) element (1f0f7040) > kernel: 0: [df0f7040] link (1f0f7080) e0 Stalled CRC/Timeo Length=7 MaxLen=7 DT0 > EndPt=0 Dev=0, PID=2d(SETUP) (buf=0372bc40) > kernel: 1: [df0f7080] link (00000001) e3 IOC Active Length=0 MaxLen=7ff DT1 > EndPt=0 Dev=0, PID=69(IN) (buf=00000000) > kernel: > kernel: uhci_hcd 0000:00:10.2: uhci_result_control: failed with status 440000 > kernel: [f6d42240] link (36d421e2) element (1f0f7040) > kernel: 0: [df0f7040] link (1f0f7080) e0 Stalled CRC/Timeo Length=7 MaxLen=7 DT0 > EndPt=0 Dev=0, PID=2d(SETUP) (buf=0372bc40) > kernel: 1: [df0f7080] link (00000001) e3 IOC Active Length=0 MaxLen=7ff DT1 > EndPt=0 Dev=0, PID=69(IN) (buf=00000000) > kernel: > kernel: usb 3-2: device not accepting address 2, error -71
What kind of device is this, can you say? And did it used to work with earlier versions of 2.6? If it did, can you pinpoint at which release it stopped working? The second of the two patches below _might_ help. No guarantees. > I am also seeing these now after another reboot (after completing > the rest of this email, which forced me to reboot). > > kernel: usb 4-6: new high speed USB device using address 65 > kernel: usb 4-6: control timeout on ep0in > kernel: ehci_hcd 0000:00:10.3: devpath 6 ep0out 3strikes > kernel: ehci_hcd 0000:00:10.3: devpath 6 ep0out 3strikes > kernel: usb 4-6: device not accepting address 65, error -71 > kernel: ehci_hcd 0000:00:10.3: GetStatus port 6 status 001803 POWER sig=j CSC > CONNECT 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. > Stopping hotplug worked once. However, after starting and stopping > it a second time, khubd crashed. It seems that the problem is on > removal of ehci-hcd, at least that's the last thing the strace says. > > In http://albatross.madduck.net/~madduck/scratch/hotplug-khubd-traces.tar.bz2 > (about 0.5Mb) you may find dmesg and strace -f outputs of: > > - hotplug-stop-success.1: a successful hotplug stop > - hotplug-start-success.2: the subsequent successful hotplug start > - hotplug-stop-FAILURE.3: the final and subsequent failed hotplug stop > > I hope this is useful information. If you have any questions or need > anything more, please contact me. I would be glad to do whatever > I can to help you guys solve this problem once and for all! 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. Alan Stern First patch: --- 2.6.9-rc3/drivers/usb/core/usb.c.orig 2004-10-08 13:02:04.000000000 -0400 +++ 2.6.9-rc3/drivers/usb/core/usb.c 2004-10-08 13:03:22.000000000 -0400 @@ -759,7 +759,11 @@ init_MUTEX(&dev->serialize); if (dev->bus->op->allocate) - dev->bus->op->allocate(dev); + if (dev->bus->op->allocate(dev)) { + usb_bus_put(bus); + kfree(dev); + return NULL; + } return dev; } Second patch: --- 2.6.9-rc3/drivers/usb/core/hub.c.orig 2004-10-08 12:45:25.000000000 -0400 +++ 2.6.9-rc3/drivers/usb/core/hub.c 2004-10-08 12:47:27.000000000 -0400 @@ -1283,7 +1283,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 @@ -1994,7 +1994,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); @@ -2033,6 +2034,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. @@ -2042,19 +2044,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", @@ -2079,17 +2080,61 @@ 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; /* 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); + (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 (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) @@ -2108,10 +2153,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", @@ -2296,7 +2343,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; @@ -2712,7 +2759,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 || @@ -2743,8 +2790,17 @@ dev_err(&udev->dev, "Can't locate device's port!\n"); return -ENOENT; } - - ret = hub_port_init(parent, udev, port); + + /* ep0 maxpacket size may change; let the HCD know about it. + * Other endpoints will be handled by re-enumeration. */ + usb_disable_endpoint(udev, 0 + USB_DIR_IN); + usb_disable_endpoint(udev, 0 + USB_DIR_OUT); + + 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
