pci: Arch hook to determine config space size

Arnd Bergmann arnd at arndb.de
Wed Feb 2 21:05:36 EST 2005


On Dinsdag 01 Februar 2005 05:57, Benjamin Herrenschmidt wrote:
> BTW. I'm thinking about moving all those PCI/VIO related fields out of
> struct device_node to their own structure and keep only a pointer to
> that structure in device_node. That way, we avoid the bloat for every
> single non-pci node in the system, and we can have different structures
> for different bus types (along with proper iommu function pointers and
> that sort-of-thing).

How about something along the lines of this patch? Instead of adding a
pointer to the pci data from the device node, it embeds the node inside
a new struct pci_device_node. The patch is not complete and therefore
not expected to work as is, but maybe you want to reuse it.

The interesting part that is missing is creating and destroying 
pci_device_nodes in prom.c, maybe you have an idea how to do that.

I'm also not sure about eeh. Are the eeh functions known to be called
only for device_nodes of PCI devices? If not, eeh_mode and 
eeh_config_addr might have to stay inside of device_node.

	Arnd <><

Signed-off-by: Arnd Bergmann <arnd at arndb.de>

Index: linux-2.6-64/arch/ppc64/kernel/pci.h
===================================================================
--- linux-2.6-64.orig/arch/ppc64/kernel/pci.h	2005-01-24 23:46:37.000000000 +0100
+++ linux-2.6-64/arch/ppc64/kernel/pci.h	2005-02-02 00:11:01.485740824 +0100
@@ -29,8 +29,8 @@
 
 /* PCI device_node operations */
 struct device_node;
-typedef void *(*traverse_func)(struct device_node *me, void *data);
-void *traverse_pci_devices(struct device_node *start, traverse_func pre,
+typedef void *(*traverse_func)(struct pci_device_node *me, void *data);
+void *traverse_pci_devices(struct pci_device_node *start, traverse_func pre,
 		void *data);
 
 void pci_devs_phb_init(void);
Index: linux-2.6-64/arch/ppc64/kernel/pSeries_iommu.c
===================================================================
--- linux-2.6-64.orig/arch/ppc64/kernel/pSeries_iommu.c	2005-02-01 22:53:00.673332472 +0100
+++ linux-2.6-64/arch/ppc64/kernel/pSeries_iommu.c	2005-02-02 00:11:01.486740672 +0100
@@ -48,7 +48,7 @@
 
 #define DBG(fmt...)
 
-extern int is_python(struct device_node *);
+extern int is_python(struct pci_device_node *);
 
 static void tce_build_pSeries(struct iommu_table *tbl, long index, 
 			      long npages, unsigned long uaddr, 
@@ -289,7 +289,7 @@
  * Currently we hard code these sizes (more or less).
  */
 static void iommu_table_setparms_lpar(struct pci_controller *phb,
-				      struct device_node *dn,
+				      struct pci_device_node *dn,
 				      struct iommu_table *tbl,
 				      unsigned int *dma_window)
 {
@@ -308,7 +308,7 @@
 
 static void iommu_bus_setup_pSeries(struct pci_bus *bus)
 {
-	struct device_node *dn, *pdn;
+	struct pci_device_node *dn, *pdn;
 
 	DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self);
 
@@ -331,7 +331,7 @@
 
 			DBG("Python root bus %s\n", bus->name);
 
-			iohole = (unsigned int *)get_property(dn, "io-hole", 0);
+			iohole = (unsigned int *)get_property(&dn->node, "io-hole", 0);
 
 			if (iohole) {
 				/* On first bus we need to leave room for the
@@ -349,7 +349,7 @@
 
 			tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
 
-			iommu_table_setparms(dn->phb, dn, tbl);
+			iommu_table_setparms(dn->phb, &dn->node, tbl);
 			dn->iommu_table = iommu_init_table(tbl);
 		} else {
 			/* 256 MB window by default */
@@ -368,7 +368,7 @@
 
 			tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
 
-			iommu_table_setparms(dn->phb, dn, tbl);
+			iommu_table_setparms(dn->phb, &dn->node, tbl);
 
 			dn->iommu_table = iommu_init_table(tbl);
 		} else {
@@ -382,17 +382,19 @@
 static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
 {
 	struct iommu_table *tbl;
-	struct device_node *dn, *pdn;
+	struct pci_device_node *dn, *pdn;
+	struct device_node *n;
 	unsigned int *dma_window = NULL;
 
 	dn = pci_bus_to_OF_node(bus);
 
 	/* Find nearest ibm,dma-window, walking up the device tree */
-	for (pdn = dn; pdn != NULL; pdn = pdn->parent) {
-		dma_window = (unsigned int *)get_property(pdn, "ibm,dma-window", NULL);
+	for (n = &dn->node; n; n = n->parent) {
+		dma_window = (unsigned int *)get_property(n, "ibm,dma-window", NULL);
 		if (dma_window != NULL)
 			break;
 	}
+	pdn = to_pci_node(n);
 
 	if (dma_window == NULL) {
 		DBG("iommu_bus_setup_pSeriesLP: bus %s seems to have no ibm,dma-window property\n", dn->full_name);
@@ -420,7 +422,7 @@
 
 static void iommu_dev_setup_pSeries(struct pci_dev *dev)
 {
-	struct device_node *dn, *mydn;
+	struct pci_device_node *dn, *mydn;
 
 	DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, dev->pretty_name);
 	/* Now copy the iommu_table ptr from the bus device down to the
@@ -430,7 +432,7 @@
 	mydn = dn = pci_device_to_OF_node(dev);
 
 	while (dn && dn->iommu_table == NULL)
-		dn = dn->parent;
+		dn = to_pci_node(dn->node.parent);
 
 	if (dn) {
 		mydn->iommu_table = dn->iommu_table;
Index: linux-2.6-64/include/asm-ppc64/pci-bridge.h
===================================================================
--- linux-2.6-64.orig/include/asm-ppc64/pci-bridge.h	2005-01-24 23:47:11.000000000 +0100
+++ linux-2.6-64/include/asm-ppc64/pci-bridge.h	2005-02-02 00:11:01.486740672 +0100
@@ -53,22 +53,23 @@
 /* Get a device_node from a pci_dev.  This code must be fast except in the case
  * where the sysdata is incorrect and needs to be fixed up (hopefully just once)
  */
-static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev)
+static inline struct pci_device_node *pci_device_to_OF_node(struct pci_dev *dev)
 {
 	struct device_node *dn = dev->sysdata;
+	struct pci_device_node *pdn = to_pci_node(dn);
 
-	if (dn->devfn == dev->devfn && dn->busno == dev->bus->number)
-		return dn;	/* fast path.  sysdata is good */
+	if (pdn->devfn == dev->devfn && pdn->busno == dev->bus->number)
+		return pdn;	/* fast path.  sysdata is good */
 	else
-		return fetch_dev_dn(dev);
+		return to_pci_node(fetch_dev_dn(dev));
 }
 
-static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
+static inline struct pci_device_node *pci_bus_to_OF_node(struct pci_bus *bus)
 {
 	if (bus->self)
 		return pci_device_to_OF_node(bus->self);
 	else
-		return bus->sysdata; /* Must be root bus (PHB) */
+		return to_pci_node(bus->sysdata); /* Must be root bus (PHB) */
 }
 
 extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
@@ -83,7 +84,7 @@
 	struct device_node *busdn = bus->sysdata;
 
 	BUG_ON(busdn == NULL);
-	return busdn->phb;
+	return to_pci_node(busdn)->phb;
 }
 
 #endif
Index: linux-2.6-64/include/asm-ppc64/eeh.h
===================================================================
--- linux-2.6-64.orig/include/asm-ppc64/eeh.h	2005-02-01 22:32:12.361104776 +0100
+++ linux-2.6-64/include/asm-ppc64/eeh.h	2005-02-02 00:11:01.487740520 +0100
@@ -27,7 +27,7 @@
 
 struct pci_dev;
 struct device_node;
-struct device_node;
+struct pci_device_node;
 struct notifier_block;
 
 #ifdef CONFIG_EEH
@@ -40,7 +40,7 @@
 void __init eeh_init(void);
 unsigned long eeh_check_failure(const volatile void __iomem *token,
 				unsigned long val);
-int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev);
+int eeh_dn_check_failure(struct pci_device_node *dn, struct pci_dev *dev);
 void __init pci_addr_cache_build(void);
 
 /**
@@ -52,7 +52,7 @@
  * device (including config space i/o).  Call eeh_add_device_late
  * to finish the eeh setup for this device.
  */
-void eeh_add_device_early(struct device_node *);
+void eeh_add_device_early(struct pci_device_node *);
 void eeh_add_device_late(struct pci_dev *);
 
 /**
Index: linux-2.6-64/arch/ppc64/kernel/sys_ppc32.c
===================================================================
--- linux-2.6-64.orig/arch/ppc64/kernel/sys_ppc32.c	2005-02-01 22:53:00.673332472 +0100
+++ linux-2.6-64/arch/ppc64/kernel/sys_ppc32.c	2005-02-02 00:11:01.487740520 +0100
@@ -744,7 +744,7 @@
 	struct pci_controller* hose;
 	struct list_head *ln;
 	struct pci_bus *bus = NULL;
-	struct device_node *hose_node;
+	struct pci_device_node *hose_node;
 
 	/* Argh ! Please forgive me for that hack, but that's the
 	 * simplest way to get existing XFree to not lockup on some
@@ -771,7 +771,7 @@
 	if (bus == NULL || bus->sysdata == NULL)
 		return -ENODEV;
 
-	hose_node = (struct device_node *)bus->sysdata;
+	hose_node = to_pci_node(bus->sysdata);
 	hose = hose_node->phb;
 
 	switch (which) {
Index: linux-2.6-64/arch/ppc64/kernel/iommu.c
===================================================================
--- linux-2.6-64.orig/arch/ppc64/kernel/iommu.c	2005-01-24 23:46:37.000000000 +0100
+++ linux-2.6-64/arch/ppc64/kernel/iommu.c	2005-02-02 00:11:01.488740368 +0100
@@ -432,7 +432,7 @@
 	return tbl;
 }
 
-void iommu_free_table(struct device_node *dn)
+void iommu_free_table(struct pci_device_node *dn)
 {
 	struct iommu_table *tbl = dn->iommu_table;
 	unsigned long bitmap_sz, i;
@@ -440,7 +440,7 @@
 
 	if (!tbl || !tbl->it_map) {
 		printk(KERN_ERR "%s: expected TCE map for %s\n", __FUNCTION__,
-				dn->full_name);
+				dn->node.full_name);
 		return;
 	}
 
@@ -449,7 +449,7 @@
 	for (i = 0; i < (tbl->it_size/64); i++) {
 		if (tbl->it_map[i] != 0) {
 			printk(KERN_WARNING "%s: Unexpected TCEs for %s\n",
-				__FUNCTION__, dn->full_name);
+				__FUNCTION__, dn->node.full_name);
 			break;
 		}
 	}
Index: linux-2.6-64/include/asm-ppc64/iommu.h
===================================================================
--- linux-2.6-64.orig/include/asm-ppc64/iommu.h	2005-01-24 23:47:11.000000000 +0100
+++ linux-2.6-64/include/asm-ppc64/iommu.h	2005-02-02 00:11:01.488740368 +0100
@@ -101,6 +101,7 @@
 #endif /* CONFIG_PPC_ISERIES */
 
 struct scatterlist;
+struct pci_device_node;
 
 #ifdef CONFIG_PPC_MULTIPLATFORM
 
@@ -109,14 +110,14 @@
 extern void iommu_setup_u3(void);
 
 /* Frees table for an individual device node */
-extern void iommu_free_table(struct device_node *dn);
+extern void iommu_free_table(struct pci_device_node *dn);
 
 #endif /* CONFIG_PPC_MULTIPLATFORM */
 
 #ifdef CONFIG_PPC_PSERIES
 
 /* Creates table for an individual device node */
-extern void iommu_devnode_init_pSeries(struct device_node *dn);
+extern void iommu_devnode_init_pSeries(struct pci_device_node *dn);
 
 #endif /* CONFIG_PPC_PSERIES */
 
Index: linux-2.6-64/arch/ppc64/kernel/pci.c
===================================================================
--- linux-2.6-64.orig/arch/ppc64/kernel/pci.c	2005-01-24 23:46:36.000000000 +0100
+++ linux-2.6-64/arch/ppc64/kernel/pci.c	2005-02-02 00:11:01.489740216 +0100
@@ -447,13 +447,13 @@
 static ssize_t pci_show_devspec(struct device *dev, char *buf)
 {
 	struct pci_dev *pdev;
-	struct device_node *np;
+	struct pci_device_node *np;
 
 	pdev = to_pci_dev (dev);
 	np = pci_device_to_OF_node(pdev);
-	if (np == NULL || np->full_name == NULL)
+	if (np == NULL || np->node.full_name == NULL)
 		return 0;
-	return sprintf(buf, "%s", np->full_name);
+	return sprintf(buf, "%s", np->node.full_name);
 }
 static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
 #endif /* CONFIG_PPC_MULTIPLATFORM */
@@ -734,7 +734,8 @@
  */
 int pcibios_scan_all_fns(struct pci_bus *bus, int devfn)
 {
-       struct device_node *busdn, *dn;
+       struct pci_device_node *busdn;
+       struct device_node *dn;
 
        if (bus->self)
                busdn = pci_device_to_OF_node(bus->self);
@@ -749,8 +750,8 @@
         * device tree.  If they are then we need to scan all the
         * functions of this slot.
         */
-       for (dn = busdn->child; dn; dn = dn->sibling)
-               if ((dn->devfn >> 3) == (devfn >> 3))
+       for (dn = busdn->node.child; dn; dn = dn->sibling)
+               if ((to_pci_node(dn)->devfn >> 3) == (devfn >> 3))
                        return 1;
 
        return 0;
@@ -851,7 +852,7 @@
 int pci_read_irq_line(struct pci_dev *pci_dev)
 {
 	u8 intpin;
-	struct device_node *node;
+	struct pci_device_node *node;
 
     	pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &intpin);
 	if (intpin == 0)
@@ -861,10 +862,10 @@
 	if (node == NULL)
 		return -1;
 
-	if (node->n_intrs == 0)
+	if (node->node.n_intrs == 0)
 		return -1;
 
-	pci_dev->irq = node->intrs[0].line;
+	pci_dev->irq = node->node.intrs[0].line;
 
 	pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, pci_dev->irq);
 
Index: linux-2.6-64/include/asm-ppc64/prom.h
===================================================================
--- linux-2.6-64.orig/include/asm-ppc64/prom.h	2005-02-01 22:32:12.365104168 +0100
+++ linux-2.6-64/include/asm-ppc64/prom.h	2005-02-02 00:11:01.490740064 +0100
@@ -131,15 +131,6 @@
 	struct	interrupt_info *intrs;
 	char	*full_name;
 
-	/* PCI stuff probably doesn't belong here */
-	int	busno;			/* for pci devices */
-	int	bussubno;		/* for pci devices */
-	int	devfn;			/* for pci devices */
-	int	eeh_mode;		/* See eeh.h for possible EEH_MODEs */
-	int	eeh_config_addr;
-	struct  pci_controller *phb;	/* for pci devices */
-	struct	iommu_table *iommu_table;	/* for phb's or bridges */
-
 	struct	property *properties;
 	struct	device_node *parent;
 	struct	device_node *child;
@@ -153,6 +144,22 @@
 	unsigned long _flags;
 };
 
+struct pci_device_node {
+	int	busno;
+	int	bussubno;
+	int	devfn;
+	int	eeh_mode;		/* See eeh.h for possible EEH_MODEs */
+	int	eeh_config_addr;
+	struct  pci_controller *phb;
+	struct	iommu_table *iommu_table;	/* for phb's or bridges */
+	struct  device_node node;
+};
+
+static inline struct pci_device_node *to_pci_node(struct device_node *n)
+{
+	return n ? container_of(n, struct pci_device_node, node) : NULL;
+}
+
 extern struct device_node *of_chosen;
 
 /* flag descriptions */
Index: linux-2.6-64/arch/ppc64/kernel/pci_iommu.c
===================================================================
--- linux-2.6-64.orig/arch/ppc64/kernel/pci_iommu.c	2005-01-24 23:46:37.000000000 +0100
+++ linux-2.6-64/arch/ppc64/kernel/pci_iommu.c	2005-02-02 00:11:01.490740064 +0100
@@ -48,7 +48,7 @@
  * pci_device_to_OF_node since ->sysdata will have been initialised
  * in the iommu init code for all devices.
  */
-#define PCI_GET_DN(dev) ((struct device_node *)((dev)->sysdata))
+#define PCI_GET_DN(dev) (to_pci_node(((dev)->sysdata)))
 
 static inline struct iommu_table *devnode_table(struct pci_dev *dev)
 {
Index: linux-2.6-64/arch/ppc64/kernel/pci_dn.c
===================================================================
--- linux-2.6-64.orig/arch/ppc64/kernel/pci_dn.c	2005-01-24 23:46:37.000000000 +0100
+++ linux-2.6-64/arch/ppc64/kernel/pci_dn.c	2005-02-02 00:11:01.490740064 +0100
@@ -34,13 +34,13 @@
  * Traverse_func that inits the PCI fields of the device node.
  * NOTE: this *must* be done before read/write config to the device.
  */
-static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
+static void * __devinit update_dn_pci_info(struct pci_device_node *dn, void *data)
 {
 	struct pci_controller *phb = data;
 	u32 *regs;
 
 	dn->phb = phb;
-	regs = (u32 *)get_property(dn, "reg", NULL);
+	regs = (u32 *)get_property(&dn->node, "reg", NULL);
 	if (regs) {
 		/* First register entry is addr (00BBSS00)  */
 		dn->busno = (regs[0] >> 16) & 0xff;
@@ -67,21 +67,21 @@
  * one of these nodes we also assume its siblings are non-pci for
  * performance.
  */
-void *traverse_pci_devices(struct device_node *start, traverse_func pre,
+void *traverse_pci_devices(struct pci_device_node *start, traverse_func pre,
 		void *data)
 {
 	struct device_node *dn, *nextdn;
 	void *ret;
 
 	/* We started with a phb, iterate all childs */
-	for (dn = start->child; dn; dn = nextdn) {
+	for (dn = start->node.child; dn; dn = nextdn) {
 		u32 *classp, class;
 
 		nextdn = NULL;
 		classp = (u32 *)get_property(dn, "class-code", NULL);
 		class = classp ? *classp : 0;
 
-		if (pre && ((ret = pre(dn, data)) != NULL))
+		if (pre && ((ret = pre(to_pci_node(dn), data)) != NULL))
 			return ret;
 
 		/* If we are a PCI bridge, go down */
@@ -96,7 +96,7 @@
 			/* Walk up to next valid sibling. */
 			do {
 				dn = dn->parent;
-				if (dn == start)
+				if (dn == &start->node)
 					return NULL;
 			} while (dn->sibling == NULL);
 			nextdn = dn->sibling;
@@ -107,7 +107,7 @@
 
 void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb)
 {
-	struct device_node * dn = (struct device_node *) phb->arch_data;
+	struct pci_device_node *dn = to_pci_node(phb->arch_data);
 
 	/* PHB nodes themselves must not match */
 	dn->devfn = dn->busno = -1;
@@ -121,7 +121,7 @@
  * Traversal func that looks for a <busno,devfcn> value.
  * If found, the device_node is returned (thus terminating the traversal).
  */
-static void *is_devfn_node(struct device_node *dn, void *data)
+static void *is_devfn_node(struct pci_device_node *dn, void *data)
 {
 	int busno = ((unsigned long)data >> 8) & 0xff;
 	int devfn = ((unsigned long)data) & 0xff;
@@ -144,13 +144,13 @@
  */
 struct device_node *fetch_dev_dn(struct pci_dev *dev)
 {
-	struct device_node *orig_dn = dev->sysdata;
+	struct pci_device_node *orig_dn = to_pci_node(dev->sysdata);
 	struct pci_controller *phb = orig_dn->phb; /* assume same phb as orig_dn */
-	struct device_node *phb_dn;
+	struct pci_device_node *phb_dn;
 	struct device_node *dn;
 	unsigned long searchval = (dev->bus->number << 8) | dev->devfn;
 
-	phb_dn = phb->arch_data;
+	phb_dn = to_pci_node(phb->arch_data);
 	dn = traverse_pci_devices(phb_dn, is_devfn_node, (void *)searchval);
 	if (dn)
 		dev->sysdata = dn;
Index: linux-2.6-64/arch/ppc64/kernel/eeh.c
===================================================================
--- linux-2.6-64.orig/arch/ppc64/kernel/eeh.c	2005-02-02 00:10:53.126011696 +0100
+++ linux-2.6-64/arch/ppc64/kernel/eeh.c	2005-02-02 00:11:06.039048616 +0100
@@ -254,7 +254,7 @@
 
 static void __pci_addr_cache_insert_device(struct pci_dev *dev)
 {
-	struct device_node *dn;
+	struct pci_device_node *dn;
 	int i;
 	int inserted = 0;
 
@@ -413,7 +413,7 @@
  * @dn: device node to read
  * @rets: array to return results in
  */
-static int read_slot_reset_state(struct device_node *dn, int rets[])
+static int read_slot_reset_state(struct pci_device_node *dn, int rets[])
 {
 	int token, outputs;
 
@@ -528,7 +528,7 @@
  *
  * It is safe to call this routine in an interrupt context.
  */
-int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
+int eeh_dn_check_failure(struct pci_device_node *dn, struct pci_dev *dev)
 {
 	int ret;
 	int rets[3];
@@ -603,7 +603,7 @@
 	spin_unlock_irqrestore(&slot_errbuf_lock, flags);
 
 	printk(KERN_INFO "EEH: MMIO failure (%d) on device: %s %s\n",
-	       rets[0], dn->name, dn->full_name);
+	       rets[0], dn->node.name, dn->node.full_name);
 	event = kmalloc(sizeof(*event), GFP_ATOMIC);
 	if (event == NULL) {
 		eeh_panic(dev, reset_state);
@@ -611,7 +611,7 @@
  	}
 
 	event->dev = dev;
-	event->dn = dn;
+	event->dn = &dn->node;
 	event->reset_state = reset_state;
 
 	/* We may or may not be called in an interrupt context */
@@ -647,7 +647,7 @@
 {
 	unsigned long addr;
 	struct pci_dev *dev;
-	struct device_node *dn;
+	struct pci_device_node *dn;
 
 	/* Finding the phys addr + pci device; this is pretty quick. */
 	addr = eeh_token_to_phys((unsigned long __force) token);
@@ -670,8 +670,9 @@
 };
 
 /* Enable eeh for the given device node. */
-static void *early_enable_eeh(struct device_node *dn, void *data)
+static void *early_enable_eeh(struct pci_device_node *pdn, void *data)
 {
+	struct device_node *dn = &pdn->node;
 	struct eeh_early_enable_info *info = data;
 	int ret;
 	char *status = get_property(dn, "status", NULL);
@@ -681,7 +682,7 @@
 	u32 *regs;
 	int enable;
 
-	dn->eeh_mode = 0;
+	pdn->eeh_mode = 0;
 
 	if (status && strcmp(status, "ok") != 0)
 		return NULL;	/* ignore devices with bad status */
@@ -692,7 +693,7 @@
 
 	/* There is nothing to check on PCI to ISA bridges */
 	if (dn->type && !strcmp(dn->type, "isa")) {
-		dn->eeh_mode |= EEH_MODE_NOCHECK;
+		pdn->eeh_mode |= EEH_MODE_NOCHECK;
 		return NULL;
 	}
 
@@ -709,7 +710,7 @@
 		enable = 0;
 
 	if (!enable)
-		dn->eeh_mode |= EEH_MODE_NOCHECK;
+		pdn->eeh_mode |= EEH_MODE_NOCHECK;
 
 	/* Ok... see if this device supports EEH.  Some do, some don't,
 	 * and the only way to find out is to check each and every one. */
@@ -722,8 +723,8 @@
 				EEH_ENABLE);
 		if (ret == 0) {
 			eeh_subsystem_enabled = 1;
-			dn->eeh_mode |= EEH_MODE_SUPPORTED;
-			dn->eeh_config_addr = regs[0];
+			pdn->eeh_mode |= EEH_MODE_SUPPORTED;
+			pdn->eeh_config_addr = regs[0];
 #ifdef DEBUG
 			printk(KERN_DEBUG "EEH: %s: eeh enabled\n", dn->full_name);
 #endif
@@ -731,10 +732,12 @@
 
 			/* This device doesn't support EEH, but it may have an
 			 * EEH parent, in which case we mark it as supported. */
-			if (dn->parent && (dn->parent->eeh_mode & EEH_MODE_SUPPORTED)) {
+			if (dn->parent && (to_pci_node(dn->parent)->eeh_mode
+							& EEH_MODE_SUPPORTED)) {
 				/* Parent supports EEH. */
-				dn->eeh_mode |= EEH_MODE_SUPPORTED;
-				dn->eeh_config_addr = dn->parent->eeh_config_addr;
+				pdn->eeh_mode |= EEH_MODE_SUPPORTED;
+				pdn->eeh_config_addr =
+					to_pci_node(dn->parent)->eeh_config_addr;
 				return NULL;
 			}
 		}
@@ -798,7 +801,7 @@
 
 		info.buid_lo = BUID_LO(buid);
 		info.buid_hi = BUID_HI(buid);
-		traverse_pci_devices(phb, early_enable_eeh, &info);
+		traverse_pci_devices(to_pci_node(phb), early_enable_eeh, &info);
 	}
 
 	if (eeh_subsystem_enabled)
@@ -819,7 +822,7 @@
  * on the CEC architecture, type of the device, on earlier boot
  * command-line arguments & etc.
  */
-void eeh_add_device_early(struct device_node *dn)
+void eeh_add_device_early(struct pci_device_node *dn)
 {
 	struct pci_controller *phb;
 	struct eeh_early_enable_info info;
Index: linux-2.6-64/arch/ppc64/kernel/prom.c
===================================================================
--- linux-2.6-64.orig/arch/ppc64/kernel/prom.c	2005-02-02 00:10:53.129011240 +0100
+++ linux-2.6-64/arch/ppc64/kernel/prom.c	2005-02-02 00:11:06.041048312 +0100
@@ -1802,8 +1802,11 @@
  */
 static void of_cleanup_node(struct device_node *np)
 {
-	if (np->iommu_table && get_property(np, "ibm,dma-window", NULL))
-		iommu_free_table(np);
+	if (get_property(np, "ibm,dma-window", NULL)) {
+		struct pci_device_node *p = to_pci_node(np);
+		if (p->iommu_table)
+			iommu_free_table(p);
+	}
 }
 
 /*
Index: linux-2.6-64/arch/ppc64/kernel/pSeries_pci.c
===================================================================
--- linux-2.6-64.orig/arch/ppc64/kernel/pSeries_pci.c	2005-02-02 00:10:53.127011544 +0100
+++ linux-2.6-64/arch/ppc64/kernel/pSeries_pci.c	2005-02-02 00:11:06.040048464 +0100
@@ -52,14 +52,12 @@
 
 extern struct mpic *pSeries_mpic;
 
-static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val)
+static int rtas_read_config(struct pci_device_node *dn, int where, int size, u32 *val)
 {
 	int returnval = -1;
 	unsigned long buid, addr;
 	int ret;
 
-	if (!dn)
-		return PCIBIOS_DEVICE_NOT_FOUND;
 	if (where & (size - 1))
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 
@@ -87,7 +85,8 @@
 				unsigned int devfn,
 				int where, int size, u32 *val)
 {
-	struct device_node *busdn, *dn;
+	struct pci_device_node *busdn;
+	struct device_node *dn;
 
 	if (bus->self)
 		busdn = pci_device_to_OF_node(bus->self);
@@ -95,13 +94,15 @@
 		busdn = bus->sysdata;	/* must be a phb */
 
 	/* Search only direct children of the bus */
-	for (dn = busdn->child; dn; dn = dn->sibling)
-		if (dn->devfn == devfn)
-			return rtas_read_config(dn, where, size, val);
+	for (dn = busdn->node.child; dn; dn = dn->sibling) {
+		struct pci_device_node *pdn = to_pci_node(dn);
+		if (pdn->devfn == devfn)
+			return rtas_read_config(pdn, where, size, val);
+	}
 	return PCIBIOS_DEVICE_NOT_FOUND;
 }
 
-static int rtas_write_config(struct device_node *dn, int where, int size, u32 val)
+static int rtas_write_config(struct pci_device_node *dn, int where, int size, u32 val)
 {
 	unsigned long buid, addr;
 	int ret;
@@ -129,7 +130,8 @@
 				 unsigned int devfn,
 				 int where, int size, u32 val)
 {
-	struct device_node *busdn, *dn;
+	struct pci_device_node *busdn;
+	struct device_node *dn;
 
 	if (bus->self)
 		busdn = pci_device_to_OF_node(bus->self);
@@ -137,9 +139,11 @@
 		busdn = bus->sysdata;	/* must be a phb */
 
 	/* Search only direct children of the bus */
-	for (dn = busdn->child; dn; dn = dn->sibling)
-		if (dn->devfn == devfn)
-			return rtas_write_config(dn, where, size, val);
+	for (dn = busdn->node.child; dn; dn = dn->sibling) {
+		struct pci_device_node *pdn = to_pci_node(dn);
+		if (pdn->devfn == devfn)
+			return rtas_write_config(pdn, where, size, val);
+	}
 	return PCIBIOS_DEVICE_NOT_FOUND;
 }
 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: signature
Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050202/a095da2d/attachment.pgp 


More information about the Linuxppc64-dev mailing list