[PATCH 2/2] Fix dynamic PCI probe regression
John Rose
johnrose at austin.ibm.com
Wed Feb 22 07:55:41 EST 2006
Some hotplug driver functions were migrated to the kernel for use by EEH
in the following set of changes: http://tinyurl.com/qke9r
Previously, the PCI Hotplug module had been changed to use the new
OFDT-based PCI probe when appropriate: http://tinyurl.com/jy4jl
When rpaphp_pci_config_slot() was moved from the rpaphp driver to the
new kernel function pcibios_add_pci_devices(), the OFDT-based probe
stuff was dropped. This patch restores it.
Signed-off-by: John Rose <johnrose at austin.ibm.com>
diff -puN arch/powerpc/platforms/pseries/pci_dlpar.c~reorg_regress arch/powerpc/platforms/pseries/pci_dlpar.c
--- 2_6_linus/arch/powerpc/platforms/pseries/pci_dlpar.c~reorg_regress 2006-02-21 14:54:10.000000000 -0600
+++ 2_6_linus-johnrose/arch/powerpc/platforms/pseries/pci_dlpar.c 2006-02-21 14:54:10.000000000 -0600
@@ -106,6 +106,8 @@ pcibios_fixup_new_pci_devices(struct pci
}
}
}
+
+ eeh_add_device_tree_late(bus);
}
EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices);
@@ -114,7 +116,6 @@ pcibios_pci_config_bridge(struct pci_dev
{
u8 sec_busno;
struct pci_bus *child_bus;
- struct pci_dev *child_dev;
/* Get busno of downstream bus */
pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno);
@@ -129,10 +130,6 @@ pcibios_pci_config_bridge(struct pci_dev
pci_scan_child_bus(child_bus);
- list_for_each_entry(child_dev, &child_bus->devices, bus_list) {
- eeh_add_device_late(child_dev);
- }
-
/* Fixup new pci devices without touching bus struct */
pcibios_fixup_new_pci_devices(child_bus, 0);
@@ -160,18 +157,25 @@ pcibios_add_pci_devices(struct pci_bus *
eeh_add_device_tree_early(dn);
- /* pci_scan_slot should find all children */
- slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
- num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
- if (num) {
- pcibios_fixup_new_pci_devices(bus, 1);
- pci_bus_add_devices(bus);
- }
+ if (_machine == PLATFORM_PSERIES_LPAR) {
+ /* use ofdt-based probe */
+ of_scan_bus(dn, bus);
+ if (!list_empty(&bus->devices)) {
+ pcibios_fixup_new_pci_devices(bus, 0);
+ pci_bus_add_devices(bus);
+ }
+ } else {
+ /* use legacy probe */
+ slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
+ num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
+ if (num) {
+ pcibios_fixup_new_pci_devices(bus, 1);
+ pci_bus_add_devices(bus);
+ }
- list_for_each_entry(dev, &bus->devices, bus_list) {
- eeh_add_device_late (dev);
- if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
- pcibios_pci_config_bridge(dev);
+ list_for_each_entry(dev, &bus->devices, bus_list)
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
+ pcibios_pci_config_bridge(dev);
}
}
EXPORT_SYMBOL_GPL(pcibios_add_pci_devices);
diff -puN arch/powerpc/platforms/pseries/eeh.c~reorg_regress arch/powerpc/platforms/pseries/eeh.c
--- 2_6_linus/arch/powerpc/platforms/pseries/eeh.c~reorg_regress 2006-02-21 14:54:10.000000000 -0600
+++ 2_6_linus-johnrose/arch/powerpc/platforms/pseries/eeh.c 2006-02-21 14:54:10.000000000 -0600
@@ -917,6 +917,20 @@ void eeh_add_device_late(struct pci_dev
pci_addr_cache_insert_device (dev);
}
+void eeh_add_device_tree_late(struct pci_bus *bus)
+{
+ struct pci_dev *dev;
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ eeh_add_device_late(dev);
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+ struct pci_bus *subbus = dev->subordinate;
+ if (subbus)
+ eeh_add_device_tree_late(subbus);
+ }
+ }
+}
+
/**
* eeh_remove_device - undo EEH setup for the indicated pci device
* @dev: pci device to be removed
diff -puN include/asm-powerpc/eeh.h~reorg_regress include/asm-powerpc/eeh.h
--- 2_6_linus/include/asm-powerpc/eeh.h~reorg_regress 2006-02-21 14:54:10.000000000 -0600
+++ 2_6_linus-johnrose/include/asm-powerpc/eeh.h 2006-02-21 14:54:10.000000000 -0600
@@ -27,6 +27,7 @@
#include <linux/string.h>
struct pci_dev;
+struct pci_bus;
struct device_node;
#ifdef CONFIG_EEH
@@ -51,7 +52,7 @@ int eeh_dn_check_failure(struct device_n
void __init pci_addr_cache_build(void);
void eeh_add_device_tree_early(struct device_node *);
-void eeh_add_device_late(struct pci_dev *);
+void eeh_add_device_tree_late(struct pci_bus *);
/**
* eeh_remove_bus_device - undo EEH for device & children.
@@ -92,10 +93,10 @@ static inline int eeh_dn_check_failure(s
static inline void pci_addr_cache_build(void) { }
-static inline void eeh_add_device_late(struct pci_dev *dev) { }
-
static inline void eeh_add_device_tree_early(struct device_node *dn) { }
+static inline void eeh_add_device_tree_late(struct pci_bus *bus) { }
+
static inline void eeh_remove_bus_device(struct pci_dev *dev) { }
#define EEH_POSSIBLE_ERROR(val, type) (0)
#define EEH_IO_ERROR_VALUE(size) (-1UL)
_
More information about the Linuxppc64-dev
mailing list