Alan Stern wrote:
You could move the root hub vs. normal device distinction from
__usb_suspend_device() down into hub_port_suspend(). Then root hubs would
be suspended just like other devices, so they could be resumed the same
way too.
The hub to which the root hub is attached, and through a port on
which it'd be suspended, is ... what? :)
The root hub is a special kind of device, and that special nature
shows up in the top level usb_{suspend,resume}_device() logic in
much the same way. The rest of the suspend/resume logic doesn't
need to know or care, and shouldn't -- it deals with interfaces,
not devices.
And a suspended device
(hub or otherwise) can generate remote-wakeup requests if they are
enabled, regardless of whether its parent port was selectively suspended
or the entire bus is in global suspend. The fact that in practice we
won't enable remote-wakeup generation until the parent port is selectively
suspended is kind of a side issue. (A very minor one, considering that
your implementation doesn't do a global suspend _until_ all connected
ports have been selectively suspended.)
Are we agreeing yet? :-)
Close enough. Except that in the context of your original question,
that "side issue" was what simplifies the answer ... when you explore
the other parts of the problem, it complexifies instead! As you saw.
That is, the difference is that PCI-suspended devices can't issue
normal IRQs. Or do DMA, and only config space registers are visible
so the virtual root hub timer can't poll any more ... all of which
can be done when just the root hub suspends.
Hence the driver will need to know when the whole device is suspended so
that it can fail attempts to examine the controller registers via procfs
or sysfs. In fact some sort of locking will be needed, probably
root_hub->serialize. But the necessary information is available through
root_hub->dev.power.power_state, right?
That, and root_hub->bus->controller->power.power_state ... which says
whether the controller itself is suspended (vs just the root hub).
You don't receive PME# as an IRQ, it's supposed to morph into a
pci resume() driver call. So it _does_ matter which path is in use.
(They can/should be independently debugged.)
What happens is PME# causes the power management routines to issue the PCI
resume() driver call. Then the controller, now in D0, issues its
resume-detected IRQ and the driver must handle that. The driver resumes
the root hub. What will resume all the devices beneath? Will the PCI/bus
glue code take care of it as part of the PCI resume?
Near as I noticed, the only times Linux takes care of the PM
parent/child trees are (a) during system suspend/resume, or
(b) when the CONFIG_USB_SUSPEND patch suspends a hub.
Not as good as it should eventually be.
which sort has occurred? Is this a good reason for keeping both pairs of
suspend/resume callbacks in struct hc_driver?
That's an orthogonal question. There are certainly going to be
two chunks of logic (one a superset of the other), one of which
is called from the bus glue and could eventually be moved out
of hc_driver ... likely when that structure itself gets cleaned
up, which seems more like 2.7 than anything else.
You seem to be saying that there will indeed have to be two pairs of
callbacks, although it's yet to be determined whether they will be in
hc_driver or some other structure, right? Clearly the HCD _does_ need the
PCI-level suspend/resume pair, so it can restore the device registers.
PCI/bus glue can't do that for it.
For the moment, it's determined they're in hc_driver ... even the
hook used by the (pci) bus glue.
How will the HCD know whether it is resuming from D3hot vs. D3cold? In
one case a USB global bus reset isn't needed, in the other it is.
OHCI sees D3cold by having the controller be in RESET state on resume,
instead of SUSPEND (or RESUME/wakeup). Which was a messy case that
deadlocked 2.6.5 and earlier kernels inside the PM code, because it
thinks devices can't disappear on resume.
If the whole system is woken up (from suspend-to-ram, for example), does
the PM layer take care of resuming every device, not just the one that
caused the wakeup? If yes, presumably it won't hurt that the USB code
will already have resumed every USB device...
Yes it does start to resume them, and it should notice right away that
the device already resumed and then go to the next one. If it doesn't,
that'd be a bug. (That assumes CONFIG_USB_SUSPEND.) Likewise on
suspend ... there, it's USB that should be noticing the devices have
already been suspended.
- Dave
-------------------------------------------------------
This SF.Net email is sponsored by the new InstallShield X.
From Windows to Linux, servers to mobile, InstallShield X is the one
installation-authoring solution that does it all. Learn more and
evaluate today! http://www.installshield.com/Dev2Dev/0504
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel