Messages in this thread | | | Date | Tue, 3 Feb 2009 07:48:20 -0800 (PST) | From | Linus Torvalds <> | Subject | Re: PCI PM: Restore standard config registers of all devices early |
| |
On Tue, 3 Feb 2009, Benjamin Herrenschmidt wrote: > > Now where it gets funny is that I've added code to read the BAR and > command register content before, between, and after those calls and > print it and .. they are sane... Until i discovered that what happens is > that the new generic code seems to actually blast 0 all over my config > space if I don't call pci_save_state() in suspend(). I suppose I was > missing a "mandatory" call here... but the core should be more robust, > ie it shouldn't erase the config space of something because a driver > "forgot" to call pci_save_state() !
You've found a bug somewhere.
We _should_ be saving things, the legacy code does something like this:
if (drv && drv->suspend) { pci_dev->state_saved = false;
i = drv->suspend(pci_dev, state); suspend_report_result(drv->suspend, i); if (i) return i;
if (pci_dev->state_saved) goto Fixup;
if (WARN_ON_ONCE(pci_dev->current_state != PCI_D0)) goto Fixup; }
pci_save_state(pci_dev);
ie if your ->suspend function doesn't use pci_save_state() itself (which sets that "state_saved" flag to true), then the generic code will do it for you.
Also, on the resume path, we actually have
if (pci_dev->state_saved) pci_restore_standard_config(pci_dev);
so I wonder how the heck you got that blast of all zeroes - because we clearly shouldn't be trying to restore any unsaved state!
So if you can figure out how it does all that...
Linus
| |