For the iommu offset we just need and offset into the page.  Calculate
that using the physical address instead of using the virtual address
so that we don't require a virtual mapping.

Signed-off-by: Christoph Hellwig <h...@lst.de>
---
 arch/sparc/mm/io-unit.c | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
index f311bf2..82f97ae 100644
--- a/arch/sparc/mm/io-unit.c
+++ b/arch/sparc/mm/io-unit.c
@@ -91,13 +91,14 @@ static int __init iounit_init(void)
 subsys_initcall(iounit_init);
 
 /* One has to hold iounit->lock to call this */
-static unsigned long iounit_get_area(struct iounit_struct *iounit, unsigned 
long vaddr, int size)
+static dma_addr_t iounit_get_area(struct iounit_struct *iounit,
+               unsigned long paddr, int size)
 {
        int i, j, k, npages;
-       unsigned long rotor, scan, limit;
+       unsigned long rotor, scan, limit, dma_addr;
        iopte_t iopte;
 
-        npages = ((vaddr & ~PAGE_MASK) + size + (PAGE_SIZE-1)) >> PAGE_SHIFT;
+        npages = ((paddr & ~PAGE_MASK) + size + (PAGE_SIZE-1)) >> PAGE_SHIFT;
 
        /* A tiny bit of magic ingredience :) */
        switch (npages) {
@@ -106,7 +107,7 @@ static unsigned long iounit_get_area(struct iounit_struct 
*iounit, unsigned long
        default: i = 0x0213; break;
        }
        
-       IOD(("iounit_get_area(%08lx,%d[%d])=", vaddr, size, npages));
+       IOD(("iounit_get_area(%08lx,%d[%d])=", paddr, size, npages));
        
 next:  j = (i & 15);
        rotor = iounit->rotor[j - 1];
@@ -121,7 +122,7 @@ nexti:      scan = find_next_zero_bit(iounit->bmap, limit, 
scan);
                }
                i >>= 4;
                if (!(i & 15))
-                       panic("iounit_get_area: Couldn't find free iopte slots 
for (%08lx,%d)\n", vaddr, size);
+                       panic("iounit_get_area: Couldn't find free iopte slots 
for (%08lx,%d)\n", paddr, size);
                goto next;
        }
        for (k = 1, scan++; k < npages; k++)
@@ -129,14 +130,14 @@ nexti:    scan = find_next_zero_bit(iounit->bmap, limit, 
scan);
                        goto nexti;
        iounit->rotor[j - 1] = (scan < limit) ? scan : iounit->limit[j - 1];
        scan -= npages;
-       iopte = MKIOPTE(__pa(vaddr & PAGE_MASK));
-       vaddr = IOUNIT_DMA_BASE + (scan << PAGE_SHIFT) + (vaddr & ~PAGE_MASK);
+       iopte = MKIOPTE(paddr & PAGE_MASK);
+       dma_addr = IOUNIT_DMA_BASE + (scan << PAGE_SHIFT) + (paddr & 
~PAGE_MASK);
        for (k = 0; k < npages; k++, iopte = __iopte(iopte_val(iopte) + 0x100), 
scan++) {
                set_bit(scan, iounit->bmap);
                sbus_writel(iopte, &iounit->page_table[scan]);
        }
-       IOD(("%08lx\n", vaddr));
-       return vaddr;
+       IOD(("%08lx\n", dma_addr));
+       return dma_addr;
 }
 
 static __u32 iounit_get_scsi_one(struct device *dev, char *vaddr, unsigned 
long len)
@@ -145,7 +146,7 @@ static __u32 iounit_get_scsi_one(struct device *dev, char 
*vaddr, unsigned long
        unsigned long ret, flags;
        
        spin_lock_irqsave(&iounit->lock, flags);
-       ret = iounit_get_area(iounit, (unsigned long)vaddr, len);
+       ret = iounit_get_area(iounit, virt_to_phys(vaddr), len);
        spin_unlock_irqrestore(&iounit->lock, flags);
        return ret;
 }
@@ -159,7 +160,7 @@ static void iounit_get_scsi_sgl(struct device *dev, struct 
scatterlist *sg, int
        spin_lock_irqsave(&iounit->lock, flags);
        while (sz != 0) {
                --sz;
-               sg->dma_address = iounit_get_area(iounit, (unsigned long) 
sg_virt(sg), sg->length);
+               sg->dma_address = iounit_get_area(iounit, sg_phys(sg), 
sg->length);
                sg->dma_length = sg->length;
                sg = sg_next(sg);
        }
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to