[PATCH] fix dynamic PCI probe regression

John Rose johnrose at austin.ibm.com
Sat Feb 25 04:34:23 EST 2006


<separated and rebased from 2/21 post>

Hi Paul-

Some hotplug driver functions were migrated to the kernel for use by EEH
in the following set of changes:
http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=2bf6a8fa21570f37fd1789610da30f70a05ac5e3

Previously, the PCI Hotplug module had been changed to use the new
OFDT-based PCI probe when appropriate:
http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=5fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6

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.

Please apply if approriate.

Thanks-
John

Signed-off-by: John Rose <johnrose at austin.ibm.com>

diff -puN arch/powerpc/platforms/pseries/eeh.c~reorg_regress arch/powerpc/platforms/pseries/eeh.c
--- 2_6_linus_2/arch/powerpc/platforms/pseries/eeh.c~reorg_regress	2006-02-24 11:04:10.000000000 -0600
+++ 2_6_linus_2-johnrose/arch/powerpc/platforms/pseries/eeh.c	2006-02-24 11:04:10.000000000 -0600
@@ -893,6 +893,20 @@ void eeh_add_device_tree_early(struct de
 }
 EXPORT_SYMBOL_GPL(eeh_add_device_tree_early);
 
+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_add_device_late - perform EEH initialization for the indicated pci device
  * @dev: pci device for which to set up EEH
diff -puN arch/powerpc/platforms/pseries/pci_dlpar.c~reorg_regress arch/powerpc/platforms/pseries/pci_dlpar.c
--- 2_6_linus_2/arch/powerpc/platforms/pseries/pci_dlpar.c~reorg_regress	2006-02-24 11:04:10.000000000 -0600
+++ 2_6_linus_2-johnrose/arch/powerpc/platforms/pseries/pci_dlpar.c	2006-02-24 11:04: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 include/asm-powerpc/eeh.h~reorg_regress include/asm-powerpc/eeh.h
--- 2_6_linus_2/include/asm-powerpc/eeh.h~reorg_regress	2006-02-24 11:04:10.000000000 -0600
+++ 2_6_linus_2-johnrose/include/asm-powerpc/eeh.h	2006-02-24 11:06:50.000000000 -0600
@@ -27,6 +27,7 @@
 #include <linux/string.h>
 
 struct pci_dev;
+struct pci_bus;
 struct device_node;
 
 #ifdef CONFIG_EEH
@@ -61,7 +62,7 @@ void __init pci_addr_cache_build(void);
  */
 void eeh_add_device_early(struct device_node *);
 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_device - undo EEH setup for the indicated pci device
@@ -116,12 +117,12 @@ static inline void pci_addr_cache_build(
 
 static inline void eeh_add_device_early(struct device_node *dn) { }
 
-static inline void eeh_add_device_late(struct pci_dev *dev) { }
-
 static inline void eeh_remove_device(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