On Wed, 7 Dec 2011, Pratyush Anand wrote: > Hi, > > I am working with linux-2.6.38 and testing suspend to ram behaviour in > case usb2.0. > > 1.� I have connected a HS device, so it is enumerated on EHCI. > 2.� Now I do suspend to ram (echo mem > /sys/power/state). > 3.� When I do resume, I see that the same HS device is now enumerated by OHCI. > 4.� It happens because of following reasons: > ����� a . Power of controller is lost during suspend. By reading > following link it seems that power should not be lost. > http://comments.gmane.org/gmane.linux.usb.general/29432�;. But, we can > not prevent it , as USB controller and many other peripherals are in > same power island and , this island needs to be switched off in echo > mem operation. That's normal; lots of systems work that way. > ���� b.� Power on reset value of Configured flag (Bit 1 of EHCI offset > 0x50) is 0. So, default owner is companion controller. That's also normal. > Therefore, OHCI > takes over and now device is enumerated by it. But that isn't. The EHCI controller gets resumed before the devices that are attached to OHCI controllers, and the EHCI driver should re-initialize the controller. This will change ownership of the port back to EHCI. > A new sdb node is > created with new bus and device number. However, successive suspend > and resume creates same node, as now device is always with OHCI. > > 5.� Now question is, what should be workaround? No workaround should be needed. > I am doing following > workaround. Is this correct? or am I missing something and not able > to use already available feature of kernel? That's possible. What EHCI driver are you using? > a. In my controller specific suspend, I keep track of > configured_flag. If it is set in controller, I set my software flag > too. > b. If configured_flag is set, then I also save ehci port status > of all the ports. Neither a nor b should be necessary. > c. In resume, I check if configured flag was set. You shouldn't need to check that; you can assume it _was_ set. After all, the EHCI driver always sets the configured flag. What you _do_ need to check is whether CF is currently set. If it is, call ehci_prepare_ports_for_controller_resume() and re-enable the interrupt mask. If it isn't then the controller lost power during the suspend, so it needs to be reinitialized. Just follow the logic used by ehci_pci_resume() in ehci-pci.c. > d. If it was set, then I check if port was powered. > e. If it was powered, I set power bit (bit 12) and I check if a > device was present. You shouldn't have to do this either. If the controller lost power then you should _always_ turn on power to _all_ the ports, the way ehci_pci_resume() does. > f. If a device was present, then I wait (with a timeout) till > device present bit (bit 0) becomes 1. How long is the timeout? You might as well always wait the full time. Also, keep in mind that there already is an 8-ms delay in ehci_bus_resume(), so you might not need any extras delay at all. > g. With these modifications, I see that usb_port_resume function > is correctly able to see reset resume and device is enumerated with > same address and bus at EHCI. > > Please advice, if it is the right way. I don't think it is. 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