This adds multi pass suspend/resume to the new bus framework, and changes some drivers to be multi pass aware. I've only tested this on PowerMac hardware, I do not have hardware to test on x86.
Details
Diff Detail
- Lint
Lint Skipped - Unit
Tests Skipped
Event Timeline
In general I think the suspend_child/resume_child changes are on track (modulo the DS_SUSPENDED issue I mentioned). We might want to start with just getting those changes into the tree and converting any other bus drivers that use custom suspend/resume methods to switch to using those instead. After that we can work on the multipass stuff next. I do think the multipass logic for root_suspend() and in the new bus_generic_suspend/resume methods generally looks correct as well.
dev/adb/adb_buttons.c | ||
---|---|---|
121 ↗ | (On Diff #360) | The devctl changes here look to be a separate change that should be split out and committed on their own. |
dev/pci/pci.c | ||
3712 | Presumably this logic would need to be codified by using early drivers for these devices? I think one problem though is that some of the devices probably don't have drivers (e.g. most of the PCIC_BASEPERIPH devices). Perhaps that won't matter, but we may need to keep a pci_resume() method that duplicates bus_generic_resume() but adds additional logic to resume these devices on the first pass if there is no driver attached to them. | |
kern/subr_bus.c | ||
3668 | I think you want a separate flag or bool in device_t instead of using a DS_ state. Busy devices need to be suspend, and devices that aren't attached also need to be suspend (e.g. if ACPI requests D2 for S3 for some system peripheral that doesn't have a driver, we still have to power that device down to D2 as part of going into S3). |
I'll break these up into smaller chunks for easier review and committing. Changing to use a flag should be trivial.
dev/adb/adb_buttons.c | ||
---|---|---|
121 ↗ | (On Diff #360) | Right, this and most of the powerpc-specific changes are not related specifically to the multi pass suspend/resume, it's a (mostly) cleaned up diff of my branch. On second thought, this really has nothing to do with the branch itself, so it makes more sense to just merge it separately anyway. |
dev/pci/pci.c | ||
3712 | Would it make more sense to have a simple driver that attaches (lowest priority) to all those devices? Why first pass, and not last pass, anyway? | |
kern/subr_bus.c | ||
3668 | This makes sense. This was originally how I had designed it. I went with the state method because it conceptually is a change in device state. However, I never considered that another source (ACPI) would request suspending of an unattached device. In my opinion, busy devices should never be suspended, because there's other hardware state that could get lost if you suspend the knowledge of a hardware device that can't actually be suspended. |
dev/pci/pci.c | ||
---|---|---|
3712 | The problem with a simple driver is we don't currently have a good way of forcing those drivers to detach if a "real" driver is kldloaded. You would want these in the first pass to resume (so early pass) to match the existing logic below. | |
kern/subr_bus.c | ||
3668 | Busy devices are just devices whose driver is trying to prevent kldunload. If you shut the lid on a laptop, you don't want that driver to keep your laptop from suspending by failing the suspend request. Also, in a suspend, all hardware needs to be powered down whether it has an attached driver or not. |
Reduce the diff to the multipass suspend/resume, removing other unrelated changes.
Switch to using a flag instead of a state for suspend.