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

Reply via email to