[PATCH] PPC64: p615 IOMMU fix

Olof Johansson olof at austin.ibm.com
Sat Jan 29 07:09:01 EST 2005


Hi,

pSeries p615 happens to have a bus hierarchy where the IDE controller for
the built-in CD is connected directly to the PHB without an intermediate
EADS bridge. The new iommu/bus setup code assumed that all systems
with EADS will have all devices under them, so this resulted in the IDE
controller not having an iommu table allocated.

To avoid this, always allocate a small table at the PHB level. It will
never be used for regular devices, and it's allocated out of the 256MB
that we previously skipped.

Signed-off-by: Olof Johansson <olof at austin.ibm.com>



---

 linux-2.5-olof/arch/ppc64/kernel/pSeries_iommu.c |   34 ++++++++++++++++-------
 1 files changed, 25 insertions(+), 9 deletions(-)

diff -puN arch/ppc64/kernel/pSeries_iommu.c~p615-iommu arch/ppc64/kernel/pSeries_iommu.c
--- linux-2.5/arch/ppc64/kernel/pSeries_iommu.c~p615-iommu	2005-01-28 14:04:48.971761000 -0600
+++ linux-2.5-olof/arch/ppc64/kernel/pSeries_iommu.c	2005-01-28 14:04:48.984759024 -0600
@@ -309,6 +309,7 @@ static void iommu_table_setparms_lpar(st
 static void iommu_bus_setup_pSeries(struct pci_bus *bus)
 {
 	struct device_node *dn, *pdn;
+	struct iommu_table *tbl;
 
 	DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self);
 
@@ -326,7 +327,6 @@ static void iommu_bus_setup_pSeries(stru
 	if (!bus->self) {
 		/* Root bus */
 		if (is_python(dn)) {
-			struct iommu_table *tbl;
 			unsigned int *iohole;
 
 			DBG("Python root bus %s\n", bus->name);
@@ -352,19 +352,35 @@ static void iommu_bus_setup_pSeries(stru
 			iommu_table_setparms(dn->phb, dn, tbl);
 			dn->iommu_table = iommu_init_table(tbl);
 		} else {
-			/* 256 MB window by default */
-			dn->phb->dma_window_size = 1 << 28;
-			/* always skip the first 256MB */
-			dn->phb->dma_window_base_cur = 1 << 28;
+			/* Do a 128MB table at root. This is used for the IDE
+			 * controller on some SMP-mode POWER4 machines. It
+			 * doesn't hurt to allocate it on other machines
+			 * -- it'll just be unused since new tables are
+			 * allocated on the EADS level.
+			 *
+			 * Allocate at offset 128MB to avoid having to deal
+			 * with ISA holes; 128MB table for IDE is plenty.
+			 */
+			dn->phb->dma_window_size = 1 << 27;
+			dn->phb->dma_window_base_cur = 1 << 27;
+
+			tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
 
-			/* No table at PHB level for non-python PHBs */
+			iommu_table_setparms(dn->phb, dn, tbl);
+			dn->iommu_table = iommu_init_table(tbl);
+
+			/* All child buses have 256MB tables */
+			dn->phb->dma_window_size = 1 << 28;
 		}
 	} else {
 		pdn = pci_bus_to_OF_node(bus->parent);
 
-		if (!pdn->iommu_table) {
+		if (!bus->parent->self && !is_python(pdn)) {
 			struct iommu_table *tbl;
-			/* First child, allocate new table (256MB window) */
+			/* First child and not python means this is the EADS
+			 * level. Allocate new table for this slot with 256MB
+			 * window.
+			 */
 
 			tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
 
@@ -372,7 +388,7 @@ static void iommu_bus_setup_pSeries(stru
 
 			dn->iommu_table = iommu_init_table(tbl);
 		} else {
-			/* Lower than first child or under python, copy parent table */
+			/* Lower than first child or under python, use parent table */
 			dn->iommu_table = pdn->iommu_table;
 		}
 	}

_



More information about the Linuxppc64-dev mailing list