On Fri, Jul 22, 2011 at 01:33:09PM -0400, Alan Stern wrote: > On Fri, 22 Jul 2011, Sarah Sharp wrote: > > > For USB 3.0 LPM, I think we need to add some code to the USB core to > > keep track of the exit latencies in the usb_device structure. I'm not > > sure yet whether we need a separate sysfs file for whether to enable U1 > > or U2. I think we should test, see if we find any broken devices, and > > then add that if necessary. I think until we find broken devices, we > > should enable USB 3.0 LPM by default, even if the device suspend sysfs > > files (power/control) disallow auto-suspend (U3). > > LPM for hubs is more complicated than it is for devices, because with > hubs you have to worry about the latency requirements of all the > downstream devices. I don't think so, at least for hardware-initiated USB 3.0 LPM. The highest level link state is propagated up the tree. If there is a device with, say, a high U1 max exit latency, the USB core will set a large U1 timeout, which will get reset whenever there is traffic on the link. If the timeout is longer than the periodic polling interval, then the parent hub shouldn't ever request that device go into U1. So even if the other downstream links under the parent hub are in U2, the upstream link will still be in U1 because of that device. If we're using hardware-initiated LPM, the hubs will reject a request from their parent's hub to go into a lower power link state if any of the downstream devices are not yet in that lower power link state. So I think we shouldn't have to track any latency requirements for the hub's children, just per device. > > I think the policy decision for USB 3.0 LPM needs to happen in the USB > > core, since the device autosuspend policy mechanisms also resides there. > > They aren't necessarily all that closely related, apart from the > obvious fact that autosuspend implies U3. I think you have to request the device go into U0 before you can put into U3. You can't directly go from U1 or U2 into U3. So the USB core might need disable the U1/U2 timers and bring the device out of U1 or U2 before suspending it into U3. > > The USB core can look at the exit latencies of all devices in the path > > of a particular device, the periodic polling interval, and decide > > whether to enable U1 or U2. > > There can be more than one periodic endpoint, with various polling > intervals and different phases. > > In fact, usbcore doesn't have access to all that information. Which information doesn't it have access to? It's got the device descriptors, and the xHCI driver will certainly use the polling interval there, although I think it can't tell whether any driver will actually use those endpoints. It can perhaps tell that an interface is claimed by a driver, and use that info to infer which endpoints might be used. > Besides, you probably want to start with powering-down just the last > hop to the device, not the entire path. Yes, we could probably do that for a first pass. Hubs do try to automatically propagate the lowest power link state up the tree. However, a hub won't allow a downstream port to go into U1/U2 if the timeout value is set to zero, so if the hub attached to the last link tried to set its upstream link into U1 or U2, its parent hub will reject it. > > Then the xHCI roothub only has to be > > modified to understand the USB 3.0 hub commands to set the U1 and U2 > > timeouts for the devices attached to the roothubs. That way the code > > for enabling USB 3.0 LPM for both the roothub and external hubs will be > > the same. > > Right. > > > The other bit that will need to be added is a way to update the xHCI > > device structures to set the max exit latency for a device, before > > enabling U1/U2 timeouts in the parent. We have to give the host > > controller a chance to reject the U1/U2 enabling, in case it can't find > > room to schedule Ping requests to wake up links in U1/U2 before sending > > isochronous transfers. That would require an Evaluate Context command, > > I think. So there probably needs to be a new host controller to USB > > core API to ask whether U1/U2 can be enabled, and pass in the new > > possible max exit latencies. Maybe something like: > > > > xhci_enable_usb3_lpm(struct usb_hcd *hcd, struct usb_device *udev, > > unsigned int u1_max_exit_latency, unsigned int > > u2_max_exit_latency) > > > > Or possibly two functions, one for U1 and one for U2. It's likely that > > enabling U1 will work while U2 might not due to the increased exit > > latency. > > > > Alan, any opinions on this plan? > > I don't know. When do you decide to put a link into a low-power state? With hardware initiated LPM, either the device asks the parent hub to go into a lower power link state, or the parent's U1 or U2 timer expires and it asks the device to go into a lower power state. Once software sets the U1 or U2 timers, it's really up to the hardware when to transition the link. > Once you do, does it automatically return to that state after carrying > out a transfer, or do you have to tell it explicitly to go back? When a hub receives a packet for a downstream port in a lower power link state, it defers the packet, wakes up the link, and then the device sends an ACK asking for the packet. Once the transfer is done, ideally a periodic device that knows how big the transfer size should be would immediately put its link into a lower power state. For example, after the camera finishes transferring a frame, it knows software isn't going to ask for another frame for a while, so it could choose to save power by immediately going to a lower power link state after the frame is done. For devices that aren't so smart (or have asynchronous endpoints), the parent hub will ask the device to suspend when the U1 or U2 timeout expires. Of course, this is all pretty different for software initiated LPM, for either USB 2.0 or USB 3.0. I'm not an expert on USB 2.0 LPM, so I really don't know the process there. I don't even think the EHCI driver really enables USB 2.0 LPM from some of the conversations I've seen go by with Jacob Pan, who was working on the Moorestown EHCI controller with LPM. > At some point, constantly telling a link to change state uses up more > power than leaving the link in U0 permanently. I believe the hubs reset the U1/U2 timeout value after a device rejects a U1 or U2 transition, so it's not like it will be constantly telling a link to change state for USB 3.0 hardware-initiated LPM. But yes, we probably need to do some serious power management with a device that really supports U1 and U2 to find out whether we're setting the timeout values sensibly. Sarah Sharp -- 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