On Mon, 14 Aug 2006, David Brownell wrote:

> > Before worrying about STR, standby, or STD, you should just try some
> > simple tests using runtime suspend.  They should be doable on any machine
> > with an EHCI controller.
> 
> All that stuff used to work just fine, and I don't recall changing any
> of it.  You're right, if that stuff has broken, it needs investigation.
> Time allowing.

You know, I can't remember if I tested this stuff on my machines before a
couple of months ago.  It's possible that the behavior has changed...  
although the driver would have had to change as well (which is also quite
possible).

> Well, I guess I'll see that when I go look again.  What I saw in your
> patch was adding an event in a path that wasn't supposed to need it, and
> in which there was no guarantee the event could be handled correctly.

Discussed at great length below.

> > >  Your change makes it so the
> > > controller isn't necessarily going to be running when khubd comes in,
> > 
> > I.e., the controller might be suspended (as in PCI D3)? 
> 
> No, running -- there's a bit that turns the controller on enough to
> make it do USB work.  Controller != hub; the hub can be suspended
> while the controller is still running.

Are you talking about the CMD_RUN (officially named Run/Stop or RS) bit in 
the command register?

> > But perhaps you meant to say that my patch might kick khubd at a time when 
> > the root hub isn't running?  Well of course it does -- that's the whole 
> > point.  The root hub is suspended and it needs to be resumed; that's 
> > exactly what usb_hcd_resume_root_hub() is intended to accomplish.
> 
> But "suspended" doesn't mean the RUN bit isn't set.  It does mean that
> none of the downstream ports are both enabled and not-suspended.

See below.

> > Are we miscommunicating somehow?
> 
> It would seem so.  That RUN bit is important ... some implementations
> of EHCI don't hook root hub operations up to it, so that it's possible
> to more or less treat their root hubs as a bitbang/gpio problem.  That's
> nice, but unfortunately the EHCI 1.0 spec was revised to insist that the
> controller also have that RUN bit set.

Well, obviously we want the driver to work correctly with all sorts of 
EHCI controllers.

First let's agree on some nomenclature.  Let's call the hardware that
manages the EHCI's connection to the computer's bus the "upper
controller".  Normally this would be the PCI interface hardware built into
the EHCI, although some systems use a different type of bus instead.  I
mention this just to dismiss it; we can concentrate on the case where the
upper controller is active, not suspended -- with PCI, it's in D0 and
enabled for IRQs & DMA.

Let's call the hardware that manages the EHCI's connection to the USB bus
the "lower controller".  This includes doing DMA, executing the schedule,
and sending packets out to all the enabled non-suspended downstream ports.  
When the lower controller is suspended, the entire USB bus goes into the
"global" suspend mode.  The lower controller is what gets suspended when
we call hcd->driver->bus_suspend.

According to the EHCI 1.0 spec, turning off CMD_RUN is what suspends the
lower controller (even though some older hardware might do things
differently).  This is supported by the facts that in ehci-hcd, the
bus_suspend routine turns off CMD_RUN (by calling ehci_halt) and the
bus_resume routine turns it back on.  So "lower controller suspended",
"bus suspend", and "CMD_RUN off" all mean the same thing.

But you want to consider a different category of "suspended" state -- the
state in which all the enabled downstream ports are suspended.  I can't
think of a good name for it, so let's call it "downstream-suspended"
(ugh).

Now in principle, whether the lower controller is suspended is independent 
of whether it is downstream-suspended.  For instance, if the only USB 
device on bus 1 is plugged into port 3, then

        echo -n 2 >/sys/devices/.../usb1/1-3/power/state

would leave the lower controller unsuspended and downstream-suspended.  
Similarly, an efficient implementation of PMSG_FREEZE would leave the 
lower controller suspended and downstream-unsuspended.  The two concepts 
are completely separate, albeit related.

You may want to argue that the first example above is artificial, that
devices on the USB bus can't tell the difference between bus-suspended and
downstream-suspended.  True enough, they can't -- but _we_ can distinguish
them according to the setting of the CMD_RUN bit.  (And just as
significantly, by the value of hcd->bus.root_hub->state: either 
USB_STATE_CONFIGURED or USB_STATE_SUSPENDED.)

Here's the important part:  usb_hcd_resume_root_hub is designed for taking
the lower controller out of the suspended state.  It doesn't know or care
whether the controller is downstream-suspended.  The same can be said of
hcd->driver->bus_resume.  That's why my patch adds a call to
usb_hcd_resume_root_hub whenever a port change is detected and CMD_RUN
isn't set:  The fact that CMD_RUN isn't set means that bus_suspend has 
been called, which means that the hub driver doesn't have a status URB 
submitted, which means that usbcore won't learn about the port-change 
event.

That's also why my patch removes the call to usb_hcd_resume_root_hub in
the case where a port change is detected and one of the ports is
suspended.  The state of the downstream ports is completely unrelated to
whether or not resume_root_hub should be called; that routine has nothing
to do with the downstream-suspended state.  If CMD_RUN wasn't set then we 
have already called resume_root_hub anyway, and if it was set then calling 
resume_root_hub won't accomplish anything.

> > So how could my
> > changes cause khubd to kick in when the controller is suspended?
> 
> That "running" bit wouldn't have been properly set.

I trust this has all been explained now.  When CMD_RUN isn't set, calling
usb_hcd_resume_root_hub causes khubd to kick in and see that the root-hub
device wants to be resumed.  So khubd will resume the root hub, thereby
invoking the bus_resume method and causing CMD_RUN to be turned on, before
doing anything else.

Alan Stern


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to