diff options
author | Linas Vepstas <linas@austin.ibm.com> | 2007-07-27 08:33:58 +1000 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-08-17 11:01:50 +1000 |
commit | 093eda3ce5dc3758c9a5e806ea6573bfffed3ff7 (patch) | |
tree | 4bc69489b35b2861daf4f8254a2ae1a8211c64a4 /arch | |
parent | 12588da7cb57edc25355c8ae2a245f66d0d067d1 (diff) | |
download | blackbird-op-linux-093eda3ce5dc3758c9a5e806ea6573bfffed3ff7.tar.gz blackbird-op-linux-093eda3ce5dc3758c9a5e806ea6573bfffed3ff7.zip |
[POWERPC] EEH: Fix PCI bridge handling bug
The EEH code needs to ignore PCI bridges; sort-of. It was ignoring
them in the wrong place, and thus failing to set up the
PCI_DN(dn)->pcidev pointer. Imprudent dereferencing of this pointer
would lead to a crash on cards with bridges.
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
----
arch/powerpc/platforms/pseries/eeh_cache.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/pseries/eeh_cache.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c index e49c815eae23..1e83fcd0df31 100644 --- a/arch/powerpc/platforms/pseries/eeh_cache.c +++ b/arch/powerpc/platforms/pseries/eeh_cache.c @@ -225,6 +225,10 @@ void pci_addr_cache_insert_device(struct pci_dev *dev) { unsigned long flags; + /* Ignore PCI bridges */ + if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) + return; + spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags); __pci_addr_cache_insert_device(dev); spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags); @@ -285,16 +289,13 @@ void __init pci_addr_cache_build(void) spin_lock_init(&pci_io_addr_cache_root.piar_lock); while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - /* Ignore PCI bridges */ - if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) - continue; pci_addr_cache_insert_device(dev); dn = pci_device_to_OF_node(dev); if (!dn) continue; - pci_dev_get (dev); /* matching put is in eeh_remove_device() */ + pci_dev_get(dev); /* matching put is in eeh_remove_device() */ PCI_DN(dn)->pcidev = dev; eeh_sysfs_add_device(dev); |