summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/xen/swiotlb-xen.c4
-rw-r--r--include/linux/swiotlb.h3
-rw-r--r--lib/swiotlb.c37
3 files changed, 23 insertions, 21 deletions
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 8a6035aa69c9..4cedc284b5df 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -364,7 +364,7 @@ dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
364 * Ensure that the address returned is DMA'ble 364 * Ensure that the address returned is DMA'ble
365 */ 365 */
366 if (!dma_capable(dev, dev_addr, size)) { 366 if (!dma_capable(dev, dev_addr, size)) {
367 swiotlb_tbl_unmap_single(dev, phys_to_virt(map), size, dir); 367 swiotlb_tbl_unmap_single(dev, map, size, dir);
368 dev_addr = 0; 368 dev_addr = 0;
369 } 369 }
370 return dev_addr; 370 return dev_addr;
@@ -388,7 +388,7 @@ static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
388 388
389 /* NOTE: We use dev_addr here, not paddr! */ 389 /* NOTE: We use dev_addr here, not paddr! */
390 if (is_xen_swiotlb_buffer(dev_addr)) { 390 if (is_xen_swiotlb_buffer(dev_addr)) {
391 swiotlb_tbl_unmap_single(hwdev, phys_to_virt(paddr), size, dir); 391 swiotlb_tbl_unmap_single(hwdev, paddr, size, dir);
392 return; 392 return;
393 } 393 }
394 394
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 1995f3e04fed..291643c6b88b 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -43,7 +43,8 @@ extern phys_addr_t swiotlb_tbl_map_single(struct device *hwdev,
43 phys_addr_t phys, size_t size, 43 phys_addr_t phys, size_t size,
44 enum dma_data_direction dir); 44 enum dma_data_direction dir);
45 45
46extern void swiotlb_tbl_unmap_single(struct device *hwdev, char *dma_addr, 46extern void swiotlb_tbl_unmap_single(struct device *hwdev,
47 phys_addr_t tlb_addr,
47 size_t size, enum dma_data_direction dir); 48 size_t size, enum dma_data_direction dir);
48 49
49extern void swiotlb_tbl_sync_single(struct device *hwdev, char *dma_addr, 50extern void swiotlb_tbl_sync_single(struct device *hwdev, char *dma_addr,
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 3adc148bb8d8..d7701dcf407f 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -515,20 +515,20 @@ phys_addr_t map_single(struct device *hwdev, phys_addr_t phys, size_t size,
515/* 515/*
516 * dma_addr is the kernel virtual address of the bounce buffer to unmap. 516 * dma_addr is the kernel virtual address of the bounce buffer to unmap.
517 */ 517 */
518void 518void swiotlb_tbl_unmap_single(struct device *hwdev, phys_addr_t tlb_addr,
519swiotlb_tbl_unmap_single(struct device *hwdev, char *dma_addr, size_t size, 519 size_t size, enum dma_data_direction dir)
520 enum dma_data_direction dir)
521{ 520{
522 unsigned long flags; 521 unsigned long flags;
523 int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; 522 int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
524 int index = (dma_addr - (char *)phys_to_virt(io_tlb_start)) >> IO_TLB_SHIFT; 523 int index = (tlb_addr - io_tlb_start) >> IO_TLB_SHIFT;
525 phys_addr_t phys = io_tlb_orig_addr[index]; 524 phys_addr_t orig_addr = io_tlb_orig_addr[index];
526 525
527 /* 526 /*
528 * First, sync the memory before unmapping the entry 527 * First, sync the memory before unmapping the entry
529 */ 528 */
530 if (phys && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))) 529 if (phys && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL)))
531 swiotlb_bounce(phys, dma_addr, size, DMA_FROM_DEVICE); 530 swiotlb_bounce(orig_addr, phys_to_virt(tlb_addr),
531 size, DMA_FROM_DEVICE);
532 532
533 /* 533 /*
534 * Return the buffer to the free list by setting the corresponding 534 * Return the buffer to the free list by setting the corresponding
@@ -621,17 +621,18 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size,
621 621
622 ret = phys_to_virt(paddr); 622 ret = phys_to_virt(paddr);
623 dev_addr = phys_to_dma(hwdev, paddr); 623 dev_addr = phys_to_dma(hwdev, paddr);
624 }
625 624
626 /* Confirm address can be DMA'd by device */ 625 /* Confirm address can be DMA'd by device */
627 if (dev_addr + size - 1 > dma_mask) { 626 if (dev_addr + size - 1 > dma_mask) {
628 printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016Lx\n", 627 printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016Lx\n",
629 (unsigned long long)dma_mask, 628 (unsigned long long)dma_mask,
630 (unsigned long long)dev_addr); 629 (unsigned long long)dev_addr);
631 630
632 /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ 631 /* DMA_TO_DEVICE to avoid memcpy in unmap_single */
633 swiotlb_tbl_unmap_single(hwdev, ret, size, DMA_TO_DEVICE); 632 swiotlb_tbl_unmap_single(hwdev, paddr,
634 return NULL; 633 size, DMA_TO_DEVICE);
634 return NULL;
635 }
635 } 636 }
636 637
637 *dma_handle = dev_addr; 638 *dma_handle = dev_addr;
@@ -652,7 +653,7 @@ swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
652 free_pages((unsigned long)vaddr, get_order(size)); 653 free_pages((unsigned long)vaddr, get_order(size));
653 else 654 else
654 /* DMA_TO_DEVICE to avoid memcpy in swiotlb_tbl_unmap_single */ 655 /* DMA_TO_DEVICE to avoid memcpy in swiotlb_tbl_unmap_single */
655 swiotlb_tbl_unmap_single(hwdev, vaddr, size, DMA_TO_DEVICE); 656 swiotlb_tbl_unmap_single(hwdev, paddr, size, DMA_TO_DEVICE);
656} 657}
657EXPORT_SYMBOL(swiotlb_free_coherent); 658EXPORT_SYMBOL(swiotlb_free_coherent);
658 659
@@ -716,7 +717,7 @@ dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
716 717
717 /* Ensure that the address returned is DMA'ble */ 718 /* Ensure that the address returned is DMA'ble */
718 if (!dma_capable(dev, dev_addr, size)) { 719 if (!dma_capable(dev, dev_addr, size)) {
719 swiotlb_tbl_unmap_single(dev, phys_to_virt(map), size, dir); 720 swiotlb_tbl_unmap_single(dev, map, size, dir);
720 return phys_to_dma(dev, io_tlb_overflow_buffer); 721 return phys_to_dma(dev, io_tlb_overflow_buffer);
721 } 722 }
722 723
@@ -740,7 +741,7 @@ static void unmap_single(struct device *hwdev, dma_addr_t dev_addr,
740 BUG_ON(dir == DMA_NONE); 741 BUG_ON(dir == DMA_NONE);
741 742
742 if (is_swiotlb_buffer(paddr)) { 743 if (is_swiotlb_buffer(paddr)) {
743 swiotlb_tbl_unmap_single(hwdev, phys_to_virt(paddr), size, dir); 744 swiotlb_tbl_unmap_single(hwdev, paddr, size, dir);
744 return; 745 return;
745 } 746 }
746 747