[PATCH] PCI PHB unit id detection interface change

linas at austin.ibm.com linas at austin.ibm.com
Sat Jun 12 09:32:32 EST 2004


Hi,

I'm looking for sanity-check/review of the following patch.
Turns out ath the kernel has been using a deprecated firmware
interface for discovring the PCI PHB Unit Id's.   The PHN Unit
ID's are used for a variety of PCI operations.  The patch
below is a change to use the recommended API.

Its been tested on one-each of power3,4,and 5 boxes; however,
given that its an API change,  I have some concern that someone
might get broken by this.  Please review.

--linas
-------------- next part --------------
Index: arch/ppc64/kernel/pSeries_pci.c
===================================================================
RCS file: /home/linas/cvsroot/eeh/arch/ppc64/kernel/pSeries_pci.c,v
retrieving revision 1.1
diff -u -p -r1.1 pSeries_pci.c
--- a/arch/ppc64/kernel/pSeries_pci.c	8 Jun 2004 22:52:54 -0000	1.1
+++ b/arch/ppc64/kernel/pSeries_pci.c	11 Jun 2004 21:56:41 -0000
@@ -353,6 +353,55 @@ static void python_countermeasures(unsig
 	iounmap(chip_regs);
 }

+void init_pci_config_tokens (void)
+{
+	read_pci_config = rtas_token("read-pci-config");
+	write_pci_config = rtas_token("write-pci-config");
+	ibm_read_pci_config = rtas_token("ibm,read-pci-config");
+	ibm_write_pci_config = rtas_token("ibm,write-pci-config");
+}
+
+unsigned long get_phb_buid (struct device_node *phb)
+{
+	int addr_cells;
+	unsigned int *buid_vals;
+	unsigned int len;
+	unsigned long buid;
+
+#define NEW_STYLE_BUIDS
+#ifdef NEW_STYLE_BUIDS
+	if (-1 == ibm_read_pci_config) return 0;
+
+	/* PHB's will always be children of the root node,
+	 * or so it is promised by the current firmware. */
+	if (NULL == phb->parent) return 0;
+	if (phb->parent->parent) return 0;
+
+	buid_vals = (unsigned int *) get_property(phb, "reg", &len);
+	if (NULL == buid_vals) return 0;
+
+	addr_cells = prom_n_addr_cells(phb);
+	if (addr_cells == 1) {
+		buid = (unsigned long) buid_vals[0];
+	} else {
+		buid = (((unsigned long)buid_vals[0]) << 32UL) |
+			(((unsigned long)buid_vals[1]) & 0xffffffff);
+	}
+#else
+	// The use of ibm,fw-phb-id is deprecated.  Keep a copy of this
+	// code for reference, in case the above code needs to be rolled back.
+	buid_vals = (int *) get_property(phb, "ibm,fw-phb-id", &len);
+	if (buid_vals == NULL) return 0;
+	if (len < 2 * sizeof(int)) {
+			buid = (unsigned long) buid_vals[0];
+	} else {
+		buid = (((unsigned long)buid_vals[0]) << 32UL) |
+			(((unsigned long)buid_vals[1]) & 0xffffffff);
+	}
+#endif
+	return buid;
+}
+
 struct pci_controller *alloc_phb(struct device_node *dev,
 				 unsigned int addr_size_words)
 {
@@ -360,7 +409,6 @@ struct pci_controller *alloc_phb(struct
 	unsigned int *ui_ptr = NULL, len;
 	struct reg_property64 reg_struct;
 	int *bus_range;
-	int *buid_vals;
 	char *model;
 	enum phb_types phb_type;
  	struct property *of_prop;
@@ -431,18 +479,7 @@ struct pci_controller *alloc_phb(struct
 	phb->arch_data   = dev;
 	phb->ops = &rtas_pci_ops;

-	buid_vals = (int *) get_property(dev, "ibm,fw-phb-id", &len);
-
-	if (buid_vals == NULL) {
-		phb->buid = 0;
-	} else {
-		if (len < 2 * sizeof(int))
-			// Support for new OF that only has 1 integer for buid.
-			phb->buid = (unsigned long)buid_vals[0];
-		else
-			phb->buid = (((unsigned long)buid_vals[0]) << 32UL) |
-				(((unsigned long)buid_vals[1]) & 0xffffffff);
-	}
+	phb->buid = get_phb_buid (dev);

 	return phb;
 }
@@ -456,10 +493,7 @@ unsigned long __init find_and_init_phbs(
 	unsigned int *opprop;
 	struct device_node *root = of_find_node_by_path("/");

-	read_pci_config = rtas_token("read-pci-config");
-	write_pci_config = rtas_token("write-pci-config");
-	ibm_read_pci_config = rtas_token("ibm,read-pci-config");
-	ibm_write_pci_config = rtas_token("ibm,write-pci-config");
+	init_pci_config_tokens();

 	if (naca->interrupt_controller == IC_OPEN_PIC) {
 		opprop = (unsigned int *)get_property(root,
--- arch/ppc64/kernel/eeh.c.7.69-orig	2004-06-11 14:10:19.000000000 -0500
+++ arch/ppc64/kernel/eeh.c	2004-06-11 16:50:55.000000000 -0500
@@ -40,6 +40,10 @@
 #define CONFIG_ADDR(busno, devfn) \
 		(((((busno) & 0xff) << 8) | ((devfn) & 0xf8)) << 8)

+/* From pSeries_pci.h */
+extern void init_pci_config_tokens (void);
+extern unsigned long get_phb_buid (struct device_node *);
+
 /* RTAS tokens */
 static int ibm_set_eeh_option;
 static int ibm_set_slot_reset;
@@ -645,7 +649,7 @@ static void *early_enable_eeh(struct dev
 			       dn->full_name);
 #endif
 		} else {
-			printk(KERN_WARNING "EEH: %s: rtas_call failed.\n",
+			printk(KERN_WARNING "EEH: %s: could not enable EEH, rtas_call failed.\n",
 			       dn->full_name);
 		}
 	} else {
@@ -709,24 +713,16 @@ void __init eeh_init(void)
 	}

 	/* Enable EEH for all adapters.  Note that eeh requires buid's */
+	init_pci_config_tokens();
 	for (phb = of_find_node_by_name(NULL, "pci"); phb;
 	     phb = of_find_node_by_name(phb, "pci")) {
-		int len;
-		int *buid_vals;
+		unsigned long buid;

-		buid_vals = (int *)get_property(phb, "ibm,fw-phb-id", &len);
-		if (!buid_vals)
-			continue;
-		if (len == sizeof(int)) {
-			info.buid_lo = buid_vals[0];
-			info.buid_hi = 0;
-		} else if (len == sizeof(int)*2) {
-			info.buid_hi = buid_vals[0];
-			info.buid_lo = buid_vals[1];
-		} else {
-			printk(KERN_INFO "EEH: odd ibm,fw-phb-id len returned: %d\n", len);
-			continue;
-		}
+		buid = get_phb_buid (phb);
+		if (0 == buid) continue;
+
+		info.buid_lo = BUID_LO(buid);
+		info.buid_hi = BUID_HI(buid);
 		traverse_pci_devices(phb, early_enable_eeh, NULL, &info);
 	}



More information about the Linuxppc64-dev mailing list