On Thu, 2005-11-24 at 18:18 -0500, Alan Stern wrote:
> On Fri, 25 Nov 2005, Benjamin Herrenschmidt wrote:
> 
> > Ok, so my driver should dpm_runtime_suspend() on itself, which will
> > cause the driver->suspend() routine to be called from which I can then
> > call usb_suspend_device(), right ?
> 
> It's hard to answer your question, partly because you haven't explained
> the context.  Are you worried about suspending a root hub, a USB device,
> an interface driver, or what?

In my driver for device XXX (for example a keyspan serial adapter, just
a random example), I want to suspend the device when all ports are
closed (no clients using it). Suspending the device means having the
parent hub suspend the port, isn't this what usb_suspend_device() is
supposed to do ?

> Also, what you wrote is a little mixed up.  Normally usb_suspend_device 
> calls driver->suspend, not the other way around.

No. usb_generic_suspend() does it. (the PM core callback in the bus_type
structure). It calls usb_suspend_device() when there is no driver (or
rather, the generic driver) or calls the driver's->suspend() when there
is a driver.

What usb_suspend_device() does according to my understanding of the code
in hub.c is to call hub_port_suspend() for the parent hub, in order to
suspend the port to which the device is connected.

That leads to 2 things unless I missed something:

 - If a device has a driver, it should call usb_suspend_device() itself
from it's suspend() routine or the hub port won't be suspended (and thus
the device). Or did I miss another code path ?

 - If a device wants to suspend itself (that is suspend the hub port
it's connected to, whatever it is, a hub or a root hub) at any time for
local power management (for example, usb storage could do that if no
request have been issued for a while, usb serial could do that when no
port is openeed, etc etc ...), it should call usb_suspend_device().
However, in order to get the locking right, usb_suspend_device() should
be called with the PM core semaphore held, right ? So according to your
own explanation previously, the right way to do it is for the driver to
call dpm_device_suspend() on itself, which in turn causes
driver->suspend() to be called with the PM sem held, which can itself
call usb_suspend_device() as I wrote in my previous email.

Now, please, let me know if I missed something in the code, I may well
have missed some subtle device driver vs. interface driver issue or
something similar here ...

> Drivers for USB devices?  Okay.  To suspend a USB device, you need to call
> dpm_runtime_suspend for each of the device's interface, and then for the
> device itself.

Ok, so I think my walking though the code missed some subtlety with
device vs. interfaces. However, still, the point is, the only thing that
ever calls usb_suspend_device() (in order to suspend the hub port) is
usb_generic_suspend() and only if there is no driver (that is the
generic driver). Thus I suppose if there is a driver attached, that
driver should be responsible for calling usb_generic_suspend(), right ?

> When the infrastructure is in place, it will automatically take care of 
> suspending the device once all the interfaces are suspended.  For now, 
> however, that's your responsibility.

Ok.

Ben.




-------------------------------------------------------
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

Reply via email to