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