On Mon, 19 Sep 2005, David Brownell wrote: > > ... Suspending an external hub's interface won't > > have any effect on the downstream ports; they will be affected only when > > you call usb_suspend_device for the children. > > True, but that must always have happened before the interface can suspend > in any case...
Not so. There's no reason why we can't suspend a hub's interface without suspending its downstream ports. If the child devices actually were children of the hub interface, instead of being children of the hub device, then I would agree with you. We're victims of poor initial design. I've simply been trying to follow through the implications of that design. > Linux won't manage downstream ports except through the hub interface. That's not entirely true. Linux allows the possibility of controlling a hub from userspace, using usbfs. You wouldn't be able to create child devices that way, but you could still manage the downstream ports. And you could do it without binding to the hub's interface, although this is merely a consequence of the fact that the USB spec defines Get-Port-Status, Set-Port-Feature, and Clear-Port-Feature to have a bRequestType recipient of OTHER rather than INTERFACE. (Does this mean that the USB-IF believes that hub ports need not be managed through the interface?) All right, let's cut through the rest of the arguments. I'm willing to accept that we should do our best to manage the downstream ports through the hub interface, even though the driver-model design doesn't mirror this logically. We do at least have one thing in our favor: Since the hub interface is registered before any child devices, the reverse-order-of-registration used for system suspend callbacks will not try to suspend the interface before the children. (BTW, is there any possibility of changing things so that downstream devices really _are_ children of the hub interface instead of children of the hub device? This would have repercussions for userspace, since the sysfs pathnames would change -- which makes me suspect it's not feasible politically.) The hub.c:hub_suspend routine should be changed so that for PM_FREEZE and PM_SUSPEND events it skips checking the state of the child devices. We can trust the PM core to have already put them in the correct state. Only for PM_RUNTIME events (which haven't been defined yet!) does it need to check that the children are all suspended -- or suspend them itself, if you want to keep the recursion. None of the above answers the original question about where the call to hcd->hub_suspend belongs. I still say it should go in usb_generic_suspend intead of hub.c:hub_suspend. Here's a reason which I think is conclusive: When you suspend an external hub's interface but not the hub itself (i.e., not its upstream port), the hub won't generate remote wakeup requests. Port status changes would show up only in the status URB, and the hub driver will have unlinked that URB. But with a root hub, calling hcd->hub_suspend _does_ enable remote wakeup. So hcd->hub_suspend should be called as part of the hub device suspend, not part of the hub interface suspend. Having said that, I should also point out that in the long run, the difference will be minimal. As part of the runtime PM design I'm working on, USB devices will automatically be suspended as soon as all their interfaces are -- that's the upward propagation of PM state changes. So suspending a hub's interface will _cause_ the hub device to be suspended. Alan Stern ------------------------------------------------------- SF.Net email is sponsored by: Tame your development challenges with Apache's Geronimo App Server. Download it for free - -and be entered to win a 42" plasma tv or your very own Sony(tm)PSP. Click here to play: http://sourceforge.net/geronimo.php _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel