diff options
-rw-r--r-- | drivers/xen/swiotlb-xen.c | 4 | ||||
-rw-r--r-- | include/linux/swiotlb.h | 3 | ||||
-rw-r--r-- | lib/swiotlb.c | 37 |
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 | ||
46 | extern void swiotlb_tbl_unmap_single(struct device *hwdev, char *dma_addr, | 46 | extern 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 | ||
49 | extern void swiotlb_tbl_sync_single(struct device *hwdev, char *dma_addr, | 50 | extern 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 | */ |
518 | void | 518 | void swiotlb_tbl_unmap_single(struct device *hwdev, phys_addr_t tlb_addr, |
519 | swiotlb_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 | } |
657 | EXPORT_SYMBOL(swiotlb_free_coherent); | 658 | EXPORT_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 | ||