[PATCH] iommu fixes, round 3
John Rose
johnrose at austin.ibm.com
Fri Oct 29 07:28:36 EST 2004
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-10-28 16:16:13.000000000 -0500
+++ 2_6_ketchup-johnrose/arch/ppc64/kernel/iSeries_iommu.c 2004-10-28 16:16:13.000000000 -0500
@@ -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-10-28 16:16:13.000000000 -0500
+++ 2_6_ketchup-johnrose/arch/ppc64/kernel/iSeries_pci.c 2004-10-28 16:16:13.000000000 -0500
@@ -235,7 +235,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-10-28 16:16:13.000000000 -0500
+++ 2_6_ketchup-johnrose/arch/ppc64/kernel/iommu.c 2004-10-28 16:16:13.000000000 -0500
@@ -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-10-28 16:16:13.000000000 -0500
+++ 2_6_ketchup-johnrose/arch/ppc64/kernel/pSeries_iommu.c 2004-10-28 16:16:13.000000000 -0500
@@ -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-10-28 16:16:13.000000000 -0500
+++ 2_6_ketchup-johnrose/arch/ppc64/kernel/prom.c 2004-10-28 16:17:06.000000000 -0500
@@ -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-10-28 16:16:13.000000000 -0500
+++ 2_6_ketchup-johnrose/include/asm-ppc64/iommu.h 2004-10-28 16:16:13.000000000 -0500
@@ -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