X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fppc64%2Fkernel%2FiSeries_iommu.c;h=4e1a47c8a8026a0a132d54c414848db56030e948;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=c09ea2aaa1899325c420b39f286fe2218561765a;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/arch/ppc64/kernel/iSeries_iommu.c b/arch/ppc64/kernel/iSeries_iommu.c index c09ea2aaa..4e1a47c8a 100644 --- a/arch/ppc64/kernel/iSeries_iommu.c +++ b/arch/ppc64/kernel/iSeries_iommu.c @@ -25,30 +25,14 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include #include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include +#include -#include -#include #include -#include -#include - #include - -#include "pci.h" - +#include +#include extern struct list_head iSeries_Global_Device_List; @@ -76,12 +60,11 @@ static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages, tce.te_bits.tb_pciwr = 1; } - rc = HvCallXm_setTce((u64)tbl->it_index, - (u64)index, - tce.te_word); + 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); - + panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", + rc); index++; uaddr += PAGE_SIZE; } @@ -90,20 +73,14 @@ static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages, static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages) { u64 rc; - union tce_entry tce; while (npages--) { - tce.te_word = 0; - rc = HvCallXm_setTce((u64)tbl->it_index, - (u64)index, - tce.te_word); - + rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, 0); if (rc) - panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", rc); - + panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", + rc); index++; } - } @@ -115,17 +92,14 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl) { struct iSeries_Device_Node *dp; - for (dp = (struct iSeries_Device_Node *)iSeries_Global_Device_List.next; - dp != (struct iSeries_Device_Node *)&iSeries_Global_Device_List; - dp = (struct iSeries_Device_Node *)dp->Device_List.next) - if (dp->iommu_table != NULL && - dp->iommu_table->it_type == TCE_PCI && - dp->iommu_table->it_offset == tbl->it_offset && - dp->iommu_table->it_index == tbl->it_index && - dp->iommu_table->it_size == tbl->it_size) + list_for_each_entry(dp, &iSeries_Global_Device_List, Device_List) { + if ((dp->iommu_table != NULL) && + (dp->iommu_table->it_type == TCE_PCI) && + (dp->iommu_table->it_offset == tbl->it_offset) && + (dp->iommu_table->it_index == tbl->it_index) && + (dp->iommu_table->it_size == tbl->it_size)) return dp->iommu_table; - - + } return NULL; } @@ -143,15 +117,14 @@ static void iommu_table_getparms(struct iSeries_Device_Node* dn, { struct iommu_table_cb *parms; - parms = (struct iommu_table_cb*)kmalloc(sizeof(*parms), GFP_KERNEL); - + parms = kmalloc(sizeof(*parms), GFP_KERNEL); if (parms == NULL) panic("PCI_DMA: TCE Table Allocation failed."); memset(parms, 0, sizeof(*parms)); - parms->itc_busno = ISERIES_BUS(dn); - parms->itc_slotno = dn->LogicalSlot; + parms->itc_busno = ISERIES_BUS(dn); + parms->itc_slotno = dn->LogicalSlot; parms->itc_virtbus = 0; HvCallXm_getTceTableParms(ISERIES_HV_ADDR(parms)); @@ -159,41 +132,44 @@ static void iommu_table_getparms(struct iSeries_Device_Node* dn, if (parms->itc_size == 0) panic("PCI_DMA: parms->size is zero, parms is 0x%p", parms); - tbl->it_size = parms->itc_size; - tbl->it_busno = parms->itc_busno; - tbl->it_offset = parms->itc_offset; - tbl->it_index = parms->itc_index; - tbl->it_entrysize = sizeof(union tce_entry); - tbl->it_blocksize = 1; - tbl->it_type = TCE_PCI; + /* itc_size is in pages worth of table, it_size is in # of entries */ + tbl->it_size = (parms->itc_size * PAGE_SIZE) / sizeof(union tce_entry); + tbl->it_busno = parms->itc_busno; + tbl->it_offset = parms->itc_offset; + tbl->it_index = parms->itc_index; + tbl->it_blocksize = 1; + tbl->it_type = TCE_PCI; kfree(parms); } -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); + tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); iommu_table_getparms(dn, tbl); /* Look for existing tce table */ dn->iommu_table = iommu_table_find(tbl); - if (dn->iommu_table == NULL) dn->iommu_table = iommu_init_table(tbl); else kfree(tbl); - - return; } +static void iommu_dev_setup_iSeries(struct pci_dev *dev) { } +static void iommu_bus_setup_iSeries(struct pci_bus *bus) { } -void tce_init_iSeries(void) +void iommu_init_early_iSeries(void) { ppc_md.tce_build = tce_build_iSeries; ppc_md.tce_free = tce_free_iSeries; + ppc_md.iommu_dev_setup = iommu_dev_setup_iSeries; + ppc_md.iommu_bus_setup = iommu_bus_setup_iSeries; + pci_iommu_init(); }