-static struct swiotlb_phys_addr swiotlb_bus_to_phys_addr(char *dma_addr)
-{
- int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT;
- struct swiotlb_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;
-}
-
-static void
-__sync_single(struct swiotlb_phys_addr buffer, char *dma_addr, size_t size, int dir)
-{
- if (PageHighMem(buffer.page)) {
- size_t len, bytes;
- char *dev, *host, *kmp;
-
- len = size;
- while (len != 0) {
- unsigned long flags;
-
- bytes = len;
- if ((bytes + buffer.offset) > PAGE_SIZE)
- bytes = PAGE_SIZE - buffer.offset;
- local_irq_save(flags); /* protects KM_BOUNCE_READ */
- kmp = kmap_atomic(buffer.page, KM_BOUNCE_READ);
- dev = dma_addr + size - len;
- host = kmp + buffer.offset;
- if (dir == DMA_FROM_DEVICE)
- memcpy(host, dev, bytes);
+/*
+ * Bounce: copy the swiotlb buffer back to the original dma location
+ */
+static void swiotlb_bounce(phys_addr_t phys, char *dma_addr, size_t size,
+ enum dma_data_direction dir)
+{
+ unsigned long pfn = PFN_DOWN(phys);
+
+ if (PageHighMem(pfn_to_page(pfn))) {
+ /* The buffer does not have a mapping. Map it in and copy */
+ unsigned int offset = phys & ~PAGE_MASK;
+ char *buffer;
+ unsigned int sz = 0;
+ unsigned long flags;
+
+ while (size) {
+ sz = min(PAGE_SIZE - offset, size);
+
+ local_irq_save(flags);
+ buffer = kmap_atomic(pfn_to_page(pfn),
+ KM_BOUNCE_READ);
+ if (dir == DMA_TO_DEVICE)
+ memcpy(dma_addr, buffer + offset, sz);