X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fpowerpc%2Fplatforms%2Fiseries%2Fiommu.c;fp=arch%2Fpowerpc%2Fplatforms%2Fiseries%2Fiommu.c;h=bea0b703f4095c216c1b290119199ac15bdac047;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=e3bd2015f2c92b9d8a88c9f94e50bedd61340f90;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index e3bd2015f..bea0b703f 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c @@ -4,7 +4,6 @@ * Rewrite, cleanup: * * Copyright (C) 2004 Olof Johansson , IBM Corporation - * Copyright (C) 2006 Olof Johansson * * Dynamic DMA mapping support, iSeries-specific parts. * @@ -32,37 +31,42 @@ #include #include #include -#include #include #include -#include + +#include "iommu.h" + +extern struct list_head iSeries_Global_Device_List; + static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages, unsigned long uaddr, enum dma_data_direction direction) { u64 rc; - u64 tce, rpn; + union tce_entry tce; index <<= TCE_PAGE_FACTOR; npages <<= TCE_PAGE_FACTOR; while (npages--) { - rpn = virt_to_abs(uaddr) >> TCE_SHIFT; - tce = (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; + tce.te_word = 0; + tce.te_bits.tb_rpn = virt_to_abs(uaddr) >> TCE_SHIFT; if (tbl->it_type == TCE_VB) { /* Virtual Bus */ - tce |= TCE_VALID|TCE_ALLIO; + tce.te_bits.tb_valid = 1; + tce.te_bits.tb_allio = 1; if (direction != DMA_TO_DEVICE) - tce |= TCE_VB_WRITE; + tce.te_bits.tb_rdwr = 1; } else { /* PCI Bus */ - tce |= TCE_PCI_READ; /* Read allowed */ + tce.te_bits.tb_rdwr = 1; /* Read allowed */ if (direction != DMA_TO_DEVICE) - tce |= TCE_PCI_WRITE; + tce.te_bits.tb_pciwr = 1; } - rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, tce); + rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, + tce.te_word); if (rc) panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", rc); @@ -120,7 +124,7 @@ void iommu_table_getparms_iSeries(unsigned long busno, /* itc_size is in pages worth of table, it_size is in # of entries */ tbl->it_size = ((parms->itc_size * TCE_PAGE_SIZE) / - TCE_ENTRY_SIZE) >> TCE_PAGE_FACTOR; + sizeof(union tce_entry)) >> TCE_PAGE_FACTOR; tbl->it_busno = parms->itc_busno; tbl->it_offset = parms->itc_offset >> TCE_PAGE_FACTOR; tbl->it_index = parms->itc_index; @@ -138,15 +142,10 @@ void iommu_table_getparms_iSeries(unsigned long busno, */ static struct iommu_table *iommu_table_find(struct iommu_table * tbl) { - struct device_node *node; + struct pci_dn *pdn; - for (node = NULL; (node = of_find_all_nodes(node)); ) { - struct pci_dn *pdn = PCI_DN(node); - struct iommu_table *it; - - if (pdn == NULL) - continue; - it = pdn->iommu_table; + list_for_each_entry(pdn, &iSeries_Global_Device_List, Device_List) { + struct iommu_table *it = pdn->iommu_table; if ((it != NULL) && (it->it_type == TCE_PCI) && (it->it_offset == tbl->it_offset) && @@ -162,18 +161,15 @@ void iommu_devnode_init_iSeries(struct device_node *dn) { struct iommu_table *tbl; struct pci_dn *pdn = PCI_DN(dn); - u32 *lsn = (u32 *)get_property(dn, "linux,logical-slot-number", NULL); - - BUG_ON(lsn == NULL); tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); - iommu_table_getparms_iSeries(pdn->busno, *lsn, 0, tbl); + iommu_table_getparms_iSeries(pdn->busno, pdn->LogicalSlot, 0, tbl); /* Look for existing tce table */ pdn->iommu_table = iommu_table_find(tbl); if (pdn->iommu_table == NULL) - pdn->iommu_table = iommu_init_table(tbl, -1); + pdn->iommu_table = iommu_init_table(tbl); else kfree(tbl); }