diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/swiotlb.c | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/lib/swiotlb.c b/lib/swiotlb.c index d81afab85167..2bde54a40d86 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c | |||
@@ -482,7 +482,7 @@ found: | |||
482 | * dma_addr is the kernel virtual address of the bounce buffer to unmap. | 482 | * dma_addr is the kernel virtual address of the bounce buffer to unmap. |
483 | */ | 483 | */ |
484 | static void | 484 | static void |
485 | unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir) | 485 | do_unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir) |
486 | { | 486 | { |
487 | unsigned long flags; | 487 | unsigned long flags; |
488 | int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; | 488 | int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; |
@@ -591,7 +591,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, | |||
591 | (unsigned long long)dev_addr); | 591 | (unsigned long long)dev_addr); |
592 | 592 | ||
593 | /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ | 593 | /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ |
594 | unmap_single(hwdev, ret, size, DMA_TO_DEVICE); | 594 | do_unmap_single(hwdev, ret, size, DMA_TO_DEVICE); |
595 | return NULL; | 595 | return NULL; |
596 | } | 596 | } |
597 | *dma_handle = dev_addr; | 597 | *dma_handle = dev_addr; |
@@ -608,7 +608,7 @@ swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, | |||
608 | free_pages((unsigned long) vaddr, get_order(size)); | 608 | free_pages((unsigned long) vaddr, get_order(size)); |
609 | else | 609 | else |
610 | /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ | 610 | /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ |
611 | unmap_single(hwdev, vaddr, size, DMA_TO_DEVICE); | 611 | do_unmap_single(hwdev, vaddr, size, DMA_TO_DEVICE); |
612 | } | 612 | } |
613 | EXPORT_SYMBOL(swiotlb_free_coherent); | 613 | EXPORT_SYMBOL(swiotlb_free_coherent); |
614 | 614 | ||
@@ -688,17 +688,29 @@ EXPORT_SYMBOL_GPL(swiotlb_map_page); | |||
688 | * After this call, reads by the cpu to the buffer are guaranteed to see | 688 | * After this call, reads by the cpu to the buffer are guaranteed to see |
689 | * whatever the device wrote there. | 689 | * whatever the device wrote there. |
690 | */ | 690 | */ |
691 | void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr, | 691 | static void unmap_single(struct device *hwdev, dma_addr_t dev_addr, |
692 | size_t size, enum dma_data_direction dir, | 692 | size_t size, int dir) |
693 | struct dma_attrs *attrs) | ||
694 | { | 693 | { |
695 | char *dma_addr = swiotlb_bus_to_virt(dev_addr); | 694 | char *dma_addr = swiotlb_bus_to_virt(dev_addr); |
696 | 695 | ||
697 | BUG_ON(dir == DMA_NONE); | 696 | BUG_ON(dir == DMA_NONE); |
698 | if (is_swiotlb_buffer(dma_addr)) | 697 | |
699 | unmap_single(hwdev, dma_addr, size, dir); | 698 | if (is_swiotlb_buffer(dma_addr)) { |
700 | else if (dir == DMA_FROM_DEVICE) | 699 | do_unmap_single(hwdev, dma_addr, size, dir); |
701 | dma_mark_clean(dma_addr, size); | 700 | return; |
701 | } | ||
702 | |||
703 | if (dir != DMA_FROM_DEVICE) | ||
704 | return; | ||
705 | |||
706 | dma_mark_clean(dma_addr, size); | ||
707 | } | ||
708 | |||
709 | void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr, | ||
710 | size_t size, enum dma_data_direction dir, | ||
711 | struct dma_attrs *attrs) | ||
712 | { | ||
713 | unmap_single(hwdev, dev_addr, size, dir); | ||
702 | } | 714 | } |
703 | EXPORT_SYMBOL_GPL(swiotlb_unmap_page); | 715 | EXPORT_SYMBOL_GPL(swiotlb_unmap_page); |
704 | 716 | ||
@@ -850,13 +862,9 @@ swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl, | |||
850 | 862 | ||
851 | BUG_ON(dir == DMA_NONE); | 863 | BUG_ON(dir == DMA_NONE); |
852 | 864 | ||
853 | for_each_sg(sgl, sg, nelems, i) { | 865 | for_each_sg(sgl, sg, nelems, i) |
854 | if (sg->dma_address != swiotlb_phys_to_bus(hwdev, sg_phys(sg))) | 866 | unmap_single(hwdev, sg->dma_address, sg->dma_length, dir); |
855 | unmap_single(hwdev, swiotlb_bus_to_virt(sg->dma_address), | 867 | |
856 | sg->dma_length, dir); | ||
857 | else if (dir == DMA_FROM_DEVICE) | ||
858 | dma_mark_clean(swiotlb_bus_to_virt(sg->dma_address), sg->dma_length); | ||
859 | } | ||
860 | } | 868 | } |
861 | EXPORT_SYMBOL(swiotlb_unmap_sg_attrs); | 869 | EXPORT_SYMBOL(swiotlb_unmap_sg_attrs); |
862 | 870 | ||