summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-09-20 22:01:23 +0000
committerJohannes Weiner <hannes@cmpxchg.org>2018-09-20 22:01:23 +0000
commitdf1018b937507fd03e3af62a562f2b1e85322ecc (patch)
treee5f446d84c610d6624df4cfed788b32713547fa1
parent30c418fb21f5d6f7dee46f5c7aefbeba05bc0de1 (diff)
pci: test for unexpectedly disabled bridgesv4.19-rc4-mmotm-2018-09-20-14-08
The all-ones value is not just a "device didn't exist" case, it's also potentially a quite valid value, so not restoring it would be wrong. What *would* be interesting is to hear where the bad values came from in the first place. It sounds like the device state is saved after the PCI bus controller in front of the device has been crapped on, resulting in the PCI config cycles never reaching the device at all. Something along this patch (together with suspend/resume debugging output) migth help pinpoint it. But it really sounds like something totally brokenly turned off the PCI bridge (some ACPI shutdown crud? I wouldn't be entirely surprised) Cc: Greg KH <greg@kroah.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-rw-r--r--drivers/pci/pci.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 1835f3a7aa8d..03227b7da4a6 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1271,6 +1271,15 @@ static void pci_restore_pcix_state(struct pci_dev *dev)
int pci_save_state(struct pci_dev *dev)
{
int i;
+ u32 val;
+
+ /* Unable to read PCI device/manufacturer state? Something is seriously wrong! */
+ if (pci_read_config_dword(dev, 0, &val) || val == 0xffffffff) {
+ printk("Broken read from PCI device %s\n", pci_name(dev));
+ WARN_ON(1);
+ return -1;
+ }
+
/* XXX: 100% dword access ok here? */
for (i = 0; i < 16; i++)
pci_read_config_dword(dev, i * 4, &dev->saved_config_space[i]);