On Thursday 01 December 2005 1:21 pm, Alan Stern wrote: > On Mon, 28 Nov 2005, David Brownell wrote: > > > > Maybe it would make more sense to have the method formerly known as > > > "reset" prepare almost everything, leaving the hardware essentially in > > > bus-suspend state. > > > > I'd say "bus off", actually. There are some devices that can't enumerate > > properly unless they get a full VBUS power cycle, and switching power off > > during USB startup is a big help. (I'm thinking of a particular MGS UPS, > > oddly enough.) > > > > That in fact is what the OHCI and EHCI init/setup/reset routine should be > > doing now. > > How much distinction do we want to draw between stop/start and > suspend/resume?
When resume() works "ideally", all the active USB power sessions have been maintained. Otherwise, they must all be cleanly shut down (devices disconnected) ... and the controller might as well be re-initialized from scratch, even if it might not need that. > Power cycling the ports is one difference; you want to do > it during a start (or a restart) but not during a resume. The same is > true for resetting the controller -- in fact, power cycling should be > _part_ of resetting the controller. Actually, the critical point is maintaining the power session. The controller doesn't matter ... reset it during resume if you like (see how EHCI is specified, it's a fairly small appendix which shows how the PCI Vaux power well can keep _part_ of the USB hardware powered) so long as you don't break the power session during the "suspend" cycle. (The phrase "power session" is from the OTG spec. It's important because of the "Session Request Protocol" ... SRP allows hosts to stop powering idle devices. It's an even more aggressive power savings scheme than "USB suspend". Non-SRP hosts manage the same sort of power sessions, but they only terminate sessions on host power-down or certain system suspend modes.) > > > Then instead of calling start, we could just call > > > bus_resume. Likewise, for remove processing we would call bus_suspend > > > followed by a new "destroy" method. > > > > Sounds like a good approach to me. There's some confusion about just > > what stop() does ... currently it includes some of what I'd expect that > > destroy() to handle. > > > > How would that work for the resume-after-poweroff scenario though? > > It'd be nice if that were basically the same HCD startup sequence. > > The way I see it, during resume the driver has to check and see whether > the old controller state is still intact. That means suspend power was on > and the firmware didn't change any settings. If the state has been > changed then the driver has to do a complete reset, otherwise the reset > can be skipped. The only state that _necessarily_ matters is the port power session; when that terminates, the port gets disabled. Some controllers can (and do!) reset during suspend, but that would only matter if the power session was broken. Consider the case of a controller using an external transceiver to maintain the power session (and potentially issue wakeup IRQs). Resetting the controller doesn't necessarily mean resetting the transceiver. There is in fact no controller state that the resume() method can't recreate (like the entire schedule tree), excepting maybe the frame counter (which by definition doesn't matter). Of course, some controllers can't reset without also breaking their port power sessions. Point being that there can be no hard and fast rule applying to all controllers, beyond the one about power sessions. > This complete reset should be essentially the same as an normal startup. Agreed, if the ports lose power we're better off having one startup sequence than adding a special one for the "non-ideal resume" cases. > The business about telling khubd to disconnect all the children can be an > extra addition or it can be part of the normal startup as well (where it > will do nothing). In either case, the resume procedure leaves the > controller on and the root hub suspended, so it makes sense for the start > procedure to do the same thing. But then there's a chicken-and-egg > problem if the root hub hasn't yet been registered... True. Maybe registering the hub should be what starts the controller the first time, then resume() could assume it's already registered. (Or root_hub.set_interface could start it ...) > Perhaps it's time to start thinking about updating the HCD glue layer's > API in this regard. Common tasks include such things as: > > Allocate the hcd structure and the root hub > > Allocate the I/O or memory resources (PCI only) > > Other PCI-centric device initialization (set_master, etc) > > Initialize the private data structures > > Initialize the controller hardware and the USB bus > > Allocate the irq > > Register the root hub > > Resume the root hub and the bus > > Suspend the root hub and the bus > > Unregister the root hub > > Release the irq > > Destroy the private data structures > > Turn off PCI settings > > Release I/O or memory resources > > Free the hcd structure and the root hub > > Not necessarily in that order. The problem is to find a logical > organization. Also a reasonable interlock between key stages of HCD bringup, including enabling the IRQ, starting polling, and doing whatever control register write is activating the controller. There's a related point. With OTG-capable hardware, those final activation stages need to hold off until the gadget driver (say, file_storage) is registered and the peripheral side is ready to go too. There'd normally be just one "go" bit that applies to both state machine roles. - Dave ------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Do you grep through log files for problems? Stop! Download the new AJAX search engine that makes searching your log files as easy as surfing the web. DOWNLOAD SPLUNK! http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel