On Sat, 23 Oct 2004, David Brownell wrote: > Call me paranoid ... the hub driver is in usbcore, right between > the HCDs (which don't all handle the necessary suspend transitions > right yet) and the PM core (which doesn't do so either). So while > I agree with "should", it seems far from "will" (not intefere)...
I didn't promise that it would work correctly! Just that it wouldn't interfere with what you're doing. In fact, this will probably end up depending on your stuff. > We should deploy autosuspend in some other drivers first. Storage > would be a good trial ... all the control goes from CPU to device, there > are no status or wakeup events going the other direction. I'd be > pleasantly surprised if autosuspend there turned up no problems... Autosuspend for usb-storage is all very well, but when should it autoresume? The next time a SCSI command is queued? In some respects it would be _more_ complicated than autosuspend for hubs, because usb-storage always has an active child (the SCSI host) whereas a hub would autosuspend only when all its children are already suspended. > > Furthermore, we may be talking about two slightly different things. The > > new autosuspend I'm proposing would work through usb_suspend_device(), > > which means changing the hub's state to USB_STATE_SUSPENDED plus doing all > > the stuff that goes with it. You can't do this in interrupt context. > > I certainly see the state as SUSPENDED ... also, it's not "interrupt context" > unless by that you include irqs blocked and the HC's spinlock held; It takes place during the root hub's timer call, and timer callbacks run in interrupt context, not process context. Looking at the code, I see you've duplicated the functionality of usb_suspend_device. That doesn't strike me as a good way to do things. > because that's the only place an HCD can really establish that it's "free" > to turn things off. (As in, it boils down to one register write.) As soon as > the HCD drops the spinlock, events can arrive which make it stop being > "free". One advantage of doing this in the HCDs is elimination of failure > modes ... and failure modes are bad, because it handling them always > involves rarely-executed and hard-to-maintain code. Obviously the actual work has to be done by the HCD. The decision of when to do it doesn't have to be. > > What you're doing in OHCI is probably a lot like what UHCI does. It > > doesn't interact cleanly with the standard USB device suspend code and > > it's complicated by the need to maintain a state machine so that the > > necessary actions (and their multi-millisecond delays) can be handled > > in_interrupt. > > OHCI won't autosuspend if any delay is needed. From what little I know > of UHCI, it could do about the same thing. See the CONFIG_PM bit at > the end of ohci_hub_status_data() ... it's really simple. UHCI uses delays not in the suspend path but in the resume path. Now that I look back on it, though, those delays may not be necessary. Here's the relevant text from the UHCI spec: Force Global Resume (FGR). 1=Host Controller sends the Global Resume signal on the USB. Software sets this bit to 0 after 20 ms has elapsed to stop sending the Global Resume signal. At that time all USB devices should be ready for bus activity. The Host Controller sets this bit to 1 when a resume event (connect, disconnect, or K-state) is detected while in global suspend mode. Software resets this bit to 0 to end Global Resume signaling. The 1 to 0 transition causes the port to send a low speed EOP signal. This bit will remain a 1 until the EOP has completed. This is how the root hub implements the TransmitR state described in 11.5.1.8. If all the ports are suspended or disabled then this step shouldn't be necessary. It's only needed when some ports were active before the root hub was suspended and hence will become active again as the root hub resumes. So perhaps all complication from the delays can be removed. That would certainly make life easier. > Another way to say this is that it's possible to look at suspending any hub > (root or external) in two parts: downstream links, and upstream ones. And > that while most hubs use standard mechanisms, like IN-interrupt transfers > or IRQs, to pass resume (and wakeup) events upstream, on some boards > UHCI root hubs need an alternate implementation ... all the USB events > behave, but the PCI ones are less functional than may be desired. That's not really accurate... For the broken UHCI systems I mentioned before the PCI events behave okay; it's the USB side that causes problems. The controller thinks that the overcurrent input counts as a port status change and will generate wakeup requests whenever the OC input is on. (Note: that's OC, not OC-change!) Since some laptops have the OC inputs on their unused ports permanently wired high, it's impossible to suspend their controllers with wakeup enabled -- a wakeup request is generated immediately. > I'm thinking that's another argument in favor of usbcore ensuring that > HCDs can implement root hub suspend directly ... whatever we decide that > means, and with some way we can (regresssion) test them so we know they > all act compatibly. I see it rather as an argument that the HCDs should implement "half-suspend" and it should only be used when the regular hub autosuspend mechanism isn't available. Maybe it should be implemented directly, as you say, without the involvement of the hub driver -- I haven't made up my mind. But if all you want to do is automatically suspend the root hub, in a normal sort of way, why not rely on the hub driver's autosuspend facility instead of adding a separate version to each HCD? > > My use of terms isn't the same as yours, although I agree in substance. > > I say that the root hub isn't suspended because it can receive and reply > > to URBs and because root_hub->state is USB_STATE_CONFIGURED, not > > USB_STATE_SUSPENDED. In other words, as far as usbcore is concerned the > > root hub isn't suspended. (And as far as the hardware is concerned the > > root hub isn't running.) > > That is, you're agreeing with me ... OHCI root hub state *is* SUSPENDED. Um, yes -- it really is SUSPENDED. Not "half-suspended". I see that now from looking at the code. And we can agree on the difference in meaning between those two terms. > We probably look at the upstream link a bit differently though, since > you're thinking of UHCI hubs where the root hub timer needs to poll > the registers, so that port change events get reported ... so it can't > be SUSPENDED. Exactly so. The same _could_ be made to apply to OHCI and EHCI root hubs, particularly if CONFIG_PM isn't set. Although you might feel that it's unnecessary... > I'm trying to use "wakeup" mainly to refer to system events, > and "resume" for the USB events. So "resume" doesn't imply > "wakeup", and we can say "root hub resumes" without any > assumptions about the previous system state. That puts you in a bind when trying to talk about the "Device Remote Wakeup" feature selector (Section 9.4, Table 9.6) for an autosuspended or selectively suspended device. Even though that's the official name, you would want to say that it ought to be "Device Remote Resume Request"! > For now, it looks like that "half suspended" state will be mostly > UHCI-specific. Most OHCI boards don't seem to need it, though > I certainly expect some of the external transceiver arrangements > (mostly on embeded boards) will add up to the same thing. Most UHCI boards don't need it either. It might nevertheless turn out to be useful, for example if wakeup_enable has been turned off or if CONFIG_PM is off. Alan Stern ------------------------------------------------------- This SF.net email is sponsored by: IT Product Guide on ITManagersJournal Use IT products in your business? Tell us what you think of them. Give us Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more http://productguide.itmanagersjournal.com/guidepromo.tmpl _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel