[PATCH] PPC64 pSeries iommu cleanups

John Rose johnrose at austin.ibm.com
Fri Nov 5 08:29:30 EST 2004


Hi Paul-

Here's a resend of the last iommu patch I sent, re-based against current 
linus bk.

This patch changes the following iommu-related things:

- Renames the [i,p]series versions of iommu_devnode_init(), to keep things 
  logically separate where possible.
  
- Moves iommu_free_table() to generic iommu.c

- Creates of_cleanup_node(), which will directly precede the dynamic removal of
  any device node

Comments welcome.

Thanks-
John

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

diff -puN arch/ppc64/kernel/iSeries_iommu.c~iommu_free_table_fix4 arch/ppc64/kernel/iSeries_iommu.c
--- 2_6_ketchup/arch/ppc64/kernel/iSeries_iommu.c~iommu_free_table_fix4	2004-11-04 15:22:10.000000000 -0600
+++ 2_6_ketchup-johnrose/arch/ppc64/kernel/iSeries_iommu.c	2004-11-04 15:22:10.000000000 -0600
@@ -171,7 +171,7 @@ static void iommu_table_getparms(struct 
 }
 
 
-void iommu_devnode_init(struct iSeries_Device_Node *dn) {
+void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn) {
 	struct iommu_table *tbl;
 
 	tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
diff -puN arch/ppc64/kernel/iSeries_pci.c~iommu_free_table_fix4 arch/ppc64/kernel/iSeries_pci.c
--- 2_6_ketchup/arch/ppc64/kernel/iSeries_pci.c~iommu_free_table_fix4	2004-11-04 15:22:10.000000000 -0600
+++ 2_6_ketchup-johnrose/arch/ppc64/kernel/iSeries_pci.c	2004-11-04 15:22:10.000000000 -0600
@@ -329,7 +329,7 @@ void __init iSeries_pci_final_fixup(void
 			iSeries_Device_Information(pdev, Buffer,
 					sizeof(Buffer));
 			printk("%d. %s\n", DeviceCount, Buffer);
-			iommu_devnode_init(node);
+			iommu_devnode_init_iSeries(node);
 		} else
 			printk("PCI: Device Tree not found for 0x%016lX\n",
 					(unsigned long)pdev);
diff -puN arch/ppc64/kernel/iommu.c~iommu_free_table_fix4 arch/ppc64/kernel/iommu.c
--- 2_6_ketchup/arch/ppc64/kernel/iommu.c~iommu_free_table_fix4	2004-11-04 15:22:10.000000000 -0600
+++ 2_6_ketchup-johnrose/arch/ppc64/kernel/iommu.c	2004-11-04 15:22:10.000000000 -0600
@@ -425,6 +425,39 @@ struct iommu_table *iommu_init_table(str
 	return tbl;
 }
 
+void iommu_free_table(struct device_node *dn)
+{
+	struct iommu_table *tbl = dn->iommu_table;
+	unsigned long bitmap_sz, i;
+	unsigned int order;
+
+	if (!tbl || !tbl->it_map) {
+		printk(KERN_ERR "%s: expected TCE map for %s\n", __FUNCTION__,
+				dn->full_name);
+		return;
+	}
+
+	/* verify that table contains no entries */
+	/* it_mapsize is in entries, and we're examining 64 at a time */
+	for (i = 0; i < (tbl->it_mapsize/64); i++) {
+		if (tbl->it_map[i] != 0) {
+			printk(KERN_WARNING "%s: Unexpected TCEs for %s\n",
+				__FUNCTION__, dn->full_name);
+			break;
+		}
+	}
+
+	/* calculate bitmap size in bytes */
+	bitmap_sz = (tbl->it_mapsize + 7) / 8;
+
+	/* free bitmap */
+	order = get_order(bitmap_sz);
+	free_pages((unsigned long) tbl->it_map, order);
+
+	/* free table */
+	kfree(tbl);
+}
+
 /* Creates TCEs for a user provided buffer.  The user buffer must be
  * contiguous real kernel storage (not vmalloc).  The address of the buffer
  * passed here is the kernel (virtual) address of the buffer.  The buffer
diff -puN arch/ppc64/kernel/pSeries_iommu.c~iommu_free_table_fix4 arch/ppc64/kernel/pSeries_iommu.c
--- 2_6_ketchup/arch/ppc64/kernel/pSeries_iommu.c~iommu_free_table_fix4	2004-11-04 15:22:10.000000000 -0600
+++ 2_6_ketchup-johnrose/arch/ppc64/kernel/pSeries_iommu.c	2004-11-04 15:22:10.000000000 -0600
@@ -276,7 +276,7 @@ static void iommu_buses_init(void)
 		first_phb = 0;
 
 		for (dn = first_dn; dn != NULL; dn = dn->sibling)
-			iommu_devnode_init(dn);
+			iommu_devnode_init_pSeries(dn);
 	}
 }
 
@@ -298,7 +298,7 @@ static void iommu_buses_init_lpar(struct
 			 * Do it now because iommu_table_setparms_lpar needs it.
 			 */
 			busdn->bussubno = bus->number;
-			iommu_devnode_init(busdn);
+			iommu_devnode_init_pSeries(busdn);
 		}
 
 		/* look for a window on a bridge even if the PHB had one */
@@ -397,7 +397,7 @@ static void iommu_table_setparms_lpar(st
 }
 
 
-void iommu_devnode_init(struct device_node *dn)
+void iommu_devnode_init_pSeries(struct device_node *dn)
 {
 	struct iommu_table *tbl;
 
@@ -412,39 +412,6 @@ void iommu_devnode_init(struct device_no
 	dn->iommu_table = iommu_init_table(tbl);
 }
 
-void iommu_free_table(struct device_node *dn)
-{
-	struct iommu_table *tbl = dn->iommu_table;
-	unsigned long bitmap_sz, i;
-	unsigned int order;
-
-	if (!tbl || !tbl->it_map) {
-		printk(KERN_ERR "%s: expected TCE map for %s\n", __FUNCTION__,
-				dn->full_name);
-		return;
-	}
-
-	/* verify that table contains no entries */
-	/* it_mapsize is in entries, and we're examining 64 at a time */
-	for (i = 0; i < (tbl->it_mapsize/64); i++) {
-		if (tbl->it_map[i] != 0) {
-			printk(KERN_WARNING "%s: Unexpected TCEs for %s\n",
-				__FUNCTION__, dn->full_name);
-			break;
-		}
-	}
-
-	/* calculate bitmap size in bytes */
-	bitmap_sz = (tbl->it_mapsize + 7) / 8;
-
-	/* free bitmap */
-	order = get_order(bitmap_sz);
-	free_pages((unsigned long) tbl->it_map, order);
-
-	/* free table */
-	kfree(tbl);
-}
-
 void iommu_setup_pSeries(void)
 {
 	struct pci_dev *dev = NULL;
@@ -469,7 +436,6 @@ void iommu_setup_pSeries(void)
 	}
 }
 
-
 /* These are called very early. */
 void tce_init_pSeries(void)
 {
diff -puN arch/ppc64/kernel/prom.c~iommu_free_table_fix4 arch/ppc64/kernel/prom.c
--- 2_6_ketchup/arch/ppc64/kernel/prom.c~iommu_free_table_fix4	2004-11-04 15:22:10.000000000 -0600
+++ 2_6_ketchup-johnrose/arch/ppc64/kernel/prom.c	2004-11-04 15:22:10.000000000 -0600
@@ -1740,7 +1740,7 @@ static int of_finish_dynamic_node(struct
 	if (strcmp(node->name, "pci") == 0 &&
 	    get_property(node, "ibm,dma-window", NULL)) {
 		node->bussubno = node->busno;
-		iommu_devnode_init(node);
+		iommu_devnode_init_pSeries(node);
 	} else
 		node->iommu_table = parent->iommu_table;
 #endif /* CONFIG_PPC_PSERIES */
@@ -1802,6 +1802,15 @@ int of_add_node(const char *path, struct
 }
 
 /*
+ * Prepare an OF node for removal from system
+ */
+static void of_cleanup_node(struct device_node *np)
+{
+	if (np->iommu_table && get_property(np, "ibm,dma-window", NULL))
+		iommu_free_table(np);
+}
+
+/*
  * Remove an OF device node from the system.
  * Caller should have already "gotten" np.
  */
@@ -1818,13 +1827,7 @@ int of_remove_node(struct device_node *n
 		return -EBUSY;
 	}
 
-	/* XXX This is a layering violation, should be moved to the caller
-	 * --BenH.
-	 */
-#ifdef CONFIG_PPC_PSERIES
-	if (np->iommu_table)
-		iommu_free_table(np);
-#endif /* CONFIG_PPC_PSERIES */
+	of_cleanup_node(np);
 
 	write_lock(&devtree_lock);
 	OF_MARK_STALE(np);
diff -puN include/asm-ppc64/iommu.h~iommu_free_table_fix4 include/asm-ppc64/iommu.h
--- 2_6_ketchup/include/asm-ppc64/iommu.h~iommu_free_table_fix4	2004-11-04 15:22:10.000000000 -0600
+++ 2_6_ketchup-johnrose/include/asm-ppc64/iommu.h	2004-11-04 15:22:10.000000000 -0600
@@ -110,22 +110,18 @@ struct scatterlist;
 extern void iommu_setup_pSeries(void);
 extern void iommu_setup_u3(void);
 
-/* Creates table for an individual device node */
-/* XXX: This isn't generic, please name it accordingly or add
- * some ppc_md. hooks for iommu implementations to do what they
- * need to do. --BenH.
- */
-extern void iommu_devnode_init(struct device_node *dn);
-
 /* Frees table for an individual device node */
-/* XXX: This isn't generic, please name it accordingly or add
- * some ppc_md. hooks for iommu implementations to do what they
- * need to do. --BenH.
- */
 extern void iommu_free_table(struct 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);
+
+#endif /* CONFIG_PPC_PSERIES */
+
 #ifdef CONFIG_PPC_ISERIES
 
 /* Walks all buses and creates iommu tables */
@@ -136,7 +132,7 @@ extern void __init iommu_vio_init(void);
 
 struct iSeries_Device_Node;
 /* Creates table for an individual device node */
-extern void iommu_devnode_init(struct iSeries_Device_Node *dn);
+extern void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn);
 
 #endif /* CONFIG_PPC_ISERIES */
 

_






More information about the Linuxppc64-dev mailing list