*/
slot_buf = buffer;
for (i = 0; i < nslots; i++) {
+ slot_buf.page += slot_buf.offset >> PAGE_SHIFT;
+ slot_buf.offset &= PAGE_SIZE - 1;
io_tlb_orig_addr[index+i] = slot_buf;
slot_buf.offset += 1 << IO_TLB_SHIFT;
- if (slot_buf.offset >= PAGE_SIZE) {
- slot_buf.page++;
- slot_buf.offset -= PAGE_SIZE;
- }
}
if ((dir == DMA_TO_DEVICE) || (dir == DMA_BIDIRECTIONAL))
__sync_single(buffer, dma_addr, size, DMA_TO_DEVICE);
return dma_addr;
}
+struct phys_addr dma_addr_to_phys_addr(char *dma_addr)
+{
+ int index = (dma_addr - iotlb_virt_start) >> IO_TLB_SHIFT;
+ struct phys_addr buffer = io_tlb_orig_addr[index];
+ buffer.offset += (long)dma_addr & ((1 << IO_TLB_SHIFT) - 1);
+ buffer.page += buffer.offset >> PAGE_SHIFT;
+ buffer.offset &= PAGE_SIZE - 1;
+ return buffer;
+}
+
/*
* dma_addr is the kernel virtual address of the bounce buffer to unmap.
*/
unsigned long flags;
int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
int index = (dma_addr - iotlb_virt_start) >> IO_TLB_SHIFT;
- struct phys_addr buffer = io_tlb_orig_addr[index];
+ struct phys_addr buffer = dma_addr_to_phys_addr(dma_addr);
/*
* First, sync the memory before unmapping the entry
static void
sync_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
{
- int index = (dma_addr - iotlb_virt_start) >> IO_TLB_SHIFT;
- struct phys_addr buffer = io_tlb_orig_addr[index];
+ struct phys_addr buffer = dma_addr_to_phys_addr(dma_addr);
BUG_ON((dir != DMA_FROM_DEVICE) && (dir != DMA_TO_DEVICE));
__sync_single(buffer, dma_addr, size, dir);
}