On Thu, 11 Jan 2007, Jon Smirl wrote:

> Attached dmesg may explain what is happening.

I don't think so.

> I renamed all my sound and usb input modules so that they wouldn't
> load at boot. I then manually modprobe'd usbhid in.
> 
> The device implements two profiles, sound and hid. How is error
> processing going to work if both of these modules attach to the device
> at the same time?

Firstly, they can't bind at the same time.  Binding a driver to a USB
interface requires holding the device's lock.

Secondly, even if they could bind at the same time, it wouldn't affect
error processing.  (Although if one driver to reset the device while the
other was still binding there could be trouble -- that's why binding
requires the lock.)

> Trace from when I probed usbhid, snd-usb-audio was still disabled.
> usbcore: registered new interface driver hiddev
> usbhid 3-2:1.3: usb_probe_interface
> usbhid 3-2:1.3: usb_probe_interface - got id
> usb usb3: usb auto-resume
> usb usb3: finish resume
> hub 3-0:1.0: hub_resume
> usb usb3: wakeup_rh
> hub 3-0:1.0: state 7 ports 2 chg 0000 evt 0000
> usb 3-2: usb auto-resume
> uhci_hcd 0000:00:1d.2: port 2 portsc 1085,01

Here we see a resume that failed.  The key indicator is the 0x1000 bit in
the portsc value; it means the port is still suspended even after it was
supposed to have resumed.  This is the Intel hardware-resume bug I
described earlier.  I have seen it on a few occasions but I cannot 
duplicate it reproducibly.  If you can, your system would make a good test 
case.  Try applying the diagnostic patch below and see what happens.

When this sort of error occurs, the USB core resets the device and
re-enumerates it.

> hub 3-0:1.0: port 2 status 0004.0107 after resume, 0
> hub 3-0:1.0: logical disconnect on port 2
> usb 3-2: can't resume, status -19

This shows the core realizing that the resume failed.

> hub 3-0:1.0: state 7 ports 2 chg 0004 evt 0000
> uhci_hcd 0000:00:1d.2: port 2 portsc 0081,01
> hub 3-0:1.0: resume on port 2, status 0
> hub 3-0:1.0: port 2, status 0101, change 0004, 12 Mb/s
> usb 3-2: USB disconnect, address 2
> usb 3-2: unregistering device
> usb 3-2: usb_disable_device nuking all URBs
> usb 3-2: unregistering interface 3-2:1.0
> usb 3-2:1.0: uevent
> usb 3-2: unregistering interface 3-2:1.1
> usb 3-2:1.1: uevent
> usb 3-2: unregistering interface 3-2:1.2
> usb 3-2:1.2: uevent
> usb 3-2: unregistering interface 3-2:1.3
>  usbdev3.2_ep83: ep_device_release called for usbdev3.2_ep83
> usb 3-2:1.3: uevent
>  usbdev3.2_ep00: ep_device_release called for usbdev3.2_ep00

That was the device being logically disconnected.

> usb 3-2: uevent
> usb 3-2: new full speed USB device using uhci_hcd and address 3
> usb 3-2: ep0 maxpacket = 8
> usb 3-2: skipped 8 descriptors after interface
> usb 3-2: skipped 2 descriptors after interface
> usb 3-2: skipped 1 descriptor after endpoint
> usb 3-2: skipped 2 descriptors after interface
> usb 3-2: skipped 1 descriptor after endpoint
> usb 3-2: skipped 1 descriptor after interface
> usb 3-2: default language 0x0409
> usb 3-2: new device strings: Mfr=1, Product=2, SerialNumber=0
> usb 3-2: Product: Philips PSC805
> usb 3-2: Manufacturer: Philips Electronics
> usb 3-2: uevent

This was the device being logically re-connected, reset, and 
re-enumerated.

> usb 3-2: usb_probe_device
> usb 3-2: configuration #1 chosen from 1 choice
> usb 3-2: adding 3-2:1.0 (config #1, interface 0)
> usb 3-2:1.0: uevent

If you had kept on going, you would have seen usbhid binding to the new 
device instance.

Alan Stern


Index: usb-2.6/drivers/usb/host/uhci-hub.c
===================================================================
--- usb-2.6.orig/drivers/usb/host/uhci-hub.c
+++ usb-2.6/drivers/usb/host/uhci-hub.c
@@ -95,6 +95,7 @@ static void uhci_finish_suspend(struct u
 {
        int status;
        int i;
+       int j;
 
        if (inw(port_addr) & (USBPORTSC_SUSP | USBPORTSC_RD)) {
                CLR_RH_PORTSTAT(USBPORTSC_SUSP | USBPORTSC_RD);
@@ -106,11 +107,16 @@ static void uhci_finish_suspend(struct u
                 * which is supposed to take 3 bit times (= 2 microseconds).
                 * Experiments show that some controllers take longer, so
                 * we'll poll for completion. */
+       for (j = 0; j < 1000; ++j) {
                for (i = 0; i < 10; ++i) {
                        if (!(inw(port_addr) & USBPORTSC_RD))
-                               break;
+                               goto done; //break;
                        udelay(1);
                }
+               CLR_RH_PORTSTAT(USBPORTSC_SUSP | USBPORTSC_RD);
+       }
+done:          dev_info(uhci_dev(uhci), "port %d resume iterations %d:%d\n",
+                               port+1, j, i);
        }
        clear_bit(port, &uhci->resuming_ports);
 }


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to