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

Reply via email to