Re: PCI PM: Restore standard config registers of all devices early

Linus Torvalds
2009-02-03T15:49:13Z

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