Re: [RFT & RFC] USB: Fix USB device disconnects on resume.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 21 Aug 2013, Sarah Sharp wrote:

> Background
> ----------
> 
> The USB 2.0 specification, section 7.1.7.7, says that upon device remote
> wakeup signaling, the first active hub (which is often the roothub) must
> rebroadcast the resume signaling for at least 20 ms (TDRSMDN).  After
> that's done, the hub's suspend status change bit will be set, and system
> software must not access the device for at least 10 ms (TRSMRCY).
> 
> It turns out that TRSMRCY is a *minimum*, not a *maximum*, according to
> Table 7-14.  That means the port can actually take longer than TRSMRCY
> to resume.  Any attempt to communicate with the device, or reset the
> device, will result in a USB device disconnect.

By the way, I just noticed your Google+ posting about this.  I think 
you (and perhaps the engineers you spoke with) may have misunderstood 
what Table 7-14 means when it lists 10 ms as the _minimum_ value for 
TRSMRCY.

This delay value is a requirement on the OS.  The host system must not
access the device until at least 10 ms after the resume is complete.  
The system can wait longer than that if it wants -- that's why 10 ms is
a minimum.  It just has to avoid accessing the device sooner.

A _minimum_ value on the host side translates into a _maximum_ value on 
the device side.  The device can safely assume that it can spend up to 
10 ms getting back into shape after a resume, but no more.  After 10 
ms, the host may try to communicate with it.

> Then, when the USB core calls into get port status, it transitions the
> port from the Resume state to the RExit state by changing the port link
> state to U0.  The xHCI driver will get a port status change event when
> that transition is complete, but that port status change event is
> currently ignored.

The excess delay you observe with xHCI is the time spent in the RExit
substate?  That probably should not be counted as part of the TRSMRCY
period.  It's hard to say for certain, because TRSMRCY is described
only in the USB-2 spec and not in the xHCI spec, and vice versa for
RExit.  Still, it's reasonable to assume that the TRSMRCY period should
begin when the port changes back to U0, not when it leaves the RESUME
state and enters RExit.

So in the end this appears to be a simple bug in xhci-hcd.  The
Get-Port-Status request that terminates the resume signalling should
wait until the port goes back into U0 (which agrees with what you have
already decided, of course).  ehci-hcd does something similar:

			/* stop resume signaling */
			temp &= ~(PORT_RWC_BITS | PORT_SUSPEND | PORT_RESUME);
			ehci_writel(ehci, temp, status_reg);
			clear_bit(wIndex, &ehci->resuming_ports);
			retval = ehci_handshake(ehci, status_reg,
					PORT_RESUME, 0, 2000 /* 2msec */);

The ehci_handshake call busy-waits until the controller turns off the
PORT_RESUME bit, which happens when the port has switched to a
high-speed idle.  It's supposed to take no more than 2 ms but hopefully
is a lot faster.  (Hmmm, maybe the private lock should be dropped
during this handshake...)

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux