diff options
authorLinas Vepstas <linas@austin.ibm.com>2007-01-10 19:16:29 -0600
committerPaul Mackerras <paulus@samba.org>2007-01-22 21:27:35 +1100
commit77319254f109963213f33cbb15e0103f2e81a64a (patch)
parent6984ee797a8798128e94ab2447c8ed91f0156eb5 (diff)
[POWERPC] Fix broken DMA on non-LPAR pSeries
It appears that the iommu table address is never stored, and thus never found, on non-lpar systems. Thus, for example, during boot: <7>[ 93.067916] PCI: Scanning bus 0001:41 <7>[ 93.068542] PCI: Found 0001:41:01.0 [8086/100f] 000200 00 <7>[ 93.068550] PCI: Calling quirk c0000000007822e0 for 0001:41:01.0 <7>[ 93.069815] PCI: Fixups for bus 0001:41 <4>[ 93.070167] iommu: Device 0001:41:01.0 has no iommu table <7>[ 93.070251] PCI: Bus scan for 0001:41 returning with max=41 No iommu table? How can that be? Well, circa line 471 of arch/powerpc/platforms/pseries/iommu.c we see the code: while (dn && PCI_DN(dn) && PCI_DN(dn)->iommu_table == NULL) dn = dn->parent; and a few lines later is the surprising print statement about the missing table. Seems that this loop ran unto the end, never once finding a non-null PCI_DN(dn)->iommu_table. The problem can be found a few lines earlier: it sems that the value of PCI_DN(dn)->iommu_table is never ever set. Thus, the patch sets it. The patch was tested on a Power4 system running in full system partition mode, which is where I saw the problem. It works; I've not done any wider testing. Had a brief discussion on this on irc. Signed-off-by: Linas Vepstas <linas@austin.ibm.com> Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
1 files changed, 2 insertions, 1 deletions
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 3c95392f4f41..e6653a868b91 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -459,7 +459,8 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
iommu_table_setparms(phb, dn, tbl);
- dev->dev.archdata.dma_data = iommu_init_table(tbl, phb->node);
+ PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node);
+ dev->dev.archdata.dma_data = PCI_DN(dn)->iommu_table;