diff options
-rw-r--r-- | arch/ia64/Kconfig | 4 | ||||
-rw-r--r-- | arch/ia64/lib/Makefile | 2 | ||||
-rw-r--r-- | arch/x86_64/kernel/Makefile | 2 | ||||
-rw-r--r-- | include/asm-x86_64/dma-mapping.h | 31 | ||||
-rw-r--r-- | include/asm-x86_64/swiotlb.h | 8 | ||||
-rw-r--r-- | lib/Makefile | 2 | ||||
-rw-r--r-- | lib/swiotlb.c (renamed from arch/ia64/lib/swiotlb.c) | 142 |
7 files changed, 139 insertions, 52 deletions
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 1642375fb14e..3b4248cff9a7 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
@@ -26,6 +26,10 @@ config MMU | |||
26 | bool | 26 | bool |
27 | default y | 27 | default y |
28 | 28 | ||
29 | config SWIOTLB | ||
30 | bool | ||
31 | default y | ||
32 | |||
29 | config RWSEM_XCHGADD_ALGORITHM | 33 | config RWSEM_XCHGADD_ALGORITHM |
30 | bool | 34 | bool |
31 | default y | 35 | default y |
diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile index cb1af597370b..ac64664a1807 100644 --- a/arch/ia64/lib/Makefile +++ b/arch/ia64/lib/Makefile | |||
@@ -9,7 +9,7 @@ lib-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \ | |||
9 | bitop.o checksum.o clear_page.o csum_partial_copy.o \ | 9 | bitop.o checksum.o clear_page.o csum_partial_copy.o \ |
10 | clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o \ | 10 | clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o \ |
11 | flush.o ip_fast_csum.o do_csum.o \ | 11 | flush.o ip_fast_csum.o do_csum.o \ |
12 | memset.o strlen.o swiotlb.o | 12 | memset.o strlen.o |
13 | 13 | ||
14 | lib-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o | 14 | lib-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o |
15 | lib-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o | 15 | lib-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o |
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile index bcdd0a805fe7..14328cab5d3a 100644 --- a/arch/x86_64/kernel/Makefile +++ b/arch/x86_64/kernel/Makefile | |||
@@ -27,7 +27,6 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq/ | |||
27 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 27 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
28 | obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o | 28 | obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o |
29 | obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o | 29 | obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o |
30 | obj-$(CONFIG_SWIOTLB) += swiotlb.o | ||
31 | obj-$(CONFIG_KPROBES) += kprobes.o | 30 | obj-$(CONFIG_KPROBES) += kprobes.o |
32 | obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o | 31 | obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o |
33 | 32 | ||
@@ -41,7 +40,6 @@ CFLAGS_vsyscall.o := $(PROFILING) -g0 | |||
41 | bootflag-y += ../../i386/kernel/bootflag.o | 40 | bootflag-y += ../../i386/kernel/bootflag.o |
42 | cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o | 41 | cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o |
43 | topology-y += ../../i386/mach-default/topology.o | 42 | topology-y += ../../i386/mach-default/topology.o |
44 | swiotlb-$(CONFIG_SWIOTLB) += ../../ia64/lib/swiotlb.o | ||
45 | microcode-$(subst m,y,$(CONFIG_MICROCODE)) += ../../i386/kernel/microcode.o | 43 | microcode-$(subst m,y,$(CONFIG_MICROCODE)) += ../../i386/kernel/microcode.o |
46 | intel_cacheinfo-y += ../../i386/kernel/cpu/intel_cacheinfo.o | 44 | intel_cacheinfo-y += ../../i386/kernel/cpu/intel_cacheinfo.o |
47 | quirks-y += ../../i386/kernel/quirks.o | 45 | quirks-y += ../../i386/kernel/quirks.o |
diff --git a/include/asm-x86_64/dma-mapping.h b/include/asm-x86_64/dma-mapping.h index 54a380efed41..36d16dfbac88 100644 --- a/include/asm-x86_64/dma-mapping.h +++ b/include/asm-x86_64/dma-mapping.h | |||
@@ -85,10 +85,33 @@ static inline void dma_sync_single_for_device(struct device *hwdev, | |||
85 | flush_write_buffers(); | 85 | flush_write_buffers(); |
86 | } | 86 | } |
87 | 87 | ||
88 | #define dma_sync_single_range_for_cpu(dev, dma_handle, offset, size, dir) \ | 88 | static inline void dma_sync_single_range_for_cpu(struct device *hwdev, |
89 | dma_sync_single_for_cpu(dev, dma_handle, size, dir) | 89 | dma_addr_t dma_handle, |
90 | #define dma_sync_single_range_for_device(dev, dma_handle, offset, size, dir) \ | 90 | unsigned long offset, |
91 | dma_sync_single_for_device(dev, dma_handle, size, dir) | 91 | size_t size, int direction) |
92 | { | ||
93 | if (direction == DMA_NONE) | ||
94 | out_of_line_bug(); | ||
95 | |||
96 | if (swiotlb) | ||
97 | return swiotlb_sync_single_range_for_cpu(hwdev,dma_handle,offset,size,direction); | ||
98 | |||
99 | flush_write_buffers(); | ||
100 | } | ||
101 | |||
102 | static inline void dma_sync_single_range_for_device(struct device *hwdev, | ||
103 | dma_addr_t dma_handle, | ||
104 | unsigned long offset, | ||
105 | size_t size, int direction) | ||
106 | { | ||
107 | if (direction == DMA_NONE) | ||
108 | out_of_line_bug(); | ||
109 | |||
110 | if (swiotlb) | ||
111 | return swiotlb_sync_single_range_for_device(hwdev,dma_handle,offset,size,direction); | ||
112 | |||
113 | flush_write_buffers(); | ||
114 | } | ||
92 | 115 | ||
93 | static inline void dma_sync_sg_for_cpu(struct device *hwdev, | 116 | static inline void dma_sync_sg_for_cpu(struct device *hwdev, |
94 | struct scatterlist *sg, | 117 | struct scatterlist *sg, |
diff --git a/include/asm-x86_64/swiotlb.h b/include/asm-x86_64/swiotlb.h index 7cbfd10ecc3c..dddf1b218681 100644 --- a/include/asm-x86_64/swiotlb.h +++ b/include/asm-x86_64/swiotlb.h | |||
@@ -15,6 +15,14 @@ extern void swiotlb_sync_single_for_cpu(struct device *hwdev, | |||
15 | extern void swiotlb_sync_single_for_device(struct device *hwdev, | 15 | extern void swiotlb_sync_single_for_device(struct device *hwdev, |
16 | dma_addr_t dev_addr, | 16 | dma_addr_t dev_addr, |
17 | size_t size, int dir); | 17 | size_t size, int dir); |
18 | extern void swiotlb_sync_single_range_for_cpu(struct device *hwdev, | ||
19 | dma_addr_t dev_addr, | ||
20 | unsigned long offset, | ||
21 | size_t size, int dir); | ||
22 | extern void swiotlb_sync_single_range_for_device(struct device *hwdev, | ||
23 | dma_addr_t dev_addr, | ||
24 | unsigned long offset, | ||
25 | size_t size, int dir); | ||
18 | extern void swiotlb_sync_sg_for_cpu(struct device *hwdev, | 26 | extern void swiotlb_sync_sg_for_cpu(struct device *hwdev, |
19 | struct scatterlist *sg, int nelems, | 27 | struct scatterlist *sg, int nelems, |
20 | int dir); | 28 | int dir); |
diff --git a/lib/Makefile b/lib/Makefile index 44a46750690a..8535f4d7d1c3 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
@@ -44,6 +44,8 @@ obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o | |||
44 | obj-$(CONFIG_TEXTSEARCH_BM) += ts_bm.o | 44 | obj-$(CONFIG_TEXTSEARCH_BM) += ts_bm.o |
45 | obj-$(CONFIG_TEXTSEARCH_FSM) += ts_fsm.o | 45 | obj-$(CONFIG_TEXTSEARCH_FSM) += ts_fsm.o |
46 | 46 | ||
47 | obj-$(CONFIG_SWIOTLB) += swiotlb.o | ||
48 | |||
47 | hostprogs-y := gen_crc32table | 49 | hostprogs-y := gen_crc32table |
48 | clean-files := crc32table.h | 50 | clean-files := crc32table.h |
49 | 51 | ||
diff --git a/arch/ia64/lib/swiotlb.c b/lib/swiotlb.c index 96edcc0fdcd9..57216f3544ca 100644 --- a/arch/ia64/lib/swiotlb.c +++ b/lib/swiotlb.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Dynamic DMA mapping support. | 2 | * Dynamic DMA mapping support. |
3 | * | 3 | * |
4 | * This implementation is for IA-64 platforms that do not support | 4 | * This implementation is for IA-64 and EM64T platforms that do not support |
5 | * I/O TLBs (aka DMA address translation hardware). | 5 | * I/O TLBs (aka DMA address translation hardware). |
6 | * Copyright (C) 2000 Asit Mallick <Asit.K.Mallick@intel.com> | 6 | * Copyright (C) 2000 Asit Mallick <Asit.K.Mallick@intel.com> |
7 | * Copyright (C) 2000 Goutham Rao <goutham.rao@intel.com> | 7 | * Copyright (C) 2000 Goutham Rao <goutham.rao@intel.com> |
@@ -11,21 +11,23 @@ | |||
11 | * 03/05/07 davidm Switch from PCI-DMA to generic device DMA API. | 11 | * 03/05/07 davidm Switch from PCI-DMA to generic device DMA API. |
12 | * 00/12/13 davidm Rename to swiotlb.c and add mark_clean() to avoid | 12 | * 00/12/13 davidm Rename to swiotlb.c and add mark_clean() to avoid |
13 | * unnecessary i-cache flushing. | 13 | * unnecessary i-cache flushing. |
14 | * 04/07/.. ak Better overflow handling. Assorted fixes. | 14 | * 04/07/.. ak Better overflow handling. Assorted fixes. |
15 | * 05/09/10 linville Add support for syncing ranges, support syncing for | ||
16 | * DMA_BIDIRECTIONAL mappings, miscellaneous cleanup. | ||
15 | */ | 17 | */ |
16 | 18 | ||
17 | #include <linux/cache.h> | 19 | #include <linux/cache.h> |
20 | #include <linux/dma-mapping.h> | ||
18 | #include <linux/mm.h> | 21 | #include <linux/mm.h> |
19 | #include <linux/module.h> | 22 | #include <linux/module.h> |
20 | #include <linux/pci.h> | ||
21 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
22 | #include <linux/string.h> | 24 | #include <linux/string.h> |
23 | #include <linux/types.h> | 25 | #include <linux/types.h> |
24 | #include <linux/ctype.h> | 26 | #include <linux/ctype.h> |
25 | 27 | ||
26 | #include <asm/io.h> | 28 | #include <asm/io.h> |
27 | #include <asm/pci.h> | ||
28 | #include <asm/dma.h> | 29 | #include <asm/dma.h> |
30 | #include <asm/scatterlist.h> | ||
29 | 31 | ||
30 | #include <linux/init.h> | 32 | #include <linux/init.h> |
31 | #include <linux/bootmem.h> | 33 | #include <linux/bootmem.h> |
@@ -58,6 +60,14 @@ | |||
58 | */ | 60 | */ |
59 | #define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT) | 61 | #define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT) |
60 | 62 | ||
63 | /* | ||
64 | * Enumeration for sync targets | ||
65 | */ | ||
66 | enum dma_sync_target { | ||
67 | SYNC_FOR_CPU = 0, | ||
68 | SYNC_FOR_DEVICE = 1, | ||
69 | }; | ||
70 | |||
61 | int swiotlb_force; | 71 | int swiotlb_force; |
62 | 72 | ||
63 | /* | 73 | /* |
@@ -117,7 +127,7 @@ __setup("swiotlb=", setup_io_tlb_npages); | |||
117 | 127 | ||
118 | /* | 128 | /* |
119 | * Statically reserve bounce buffer space and initialize bounce buffer data | 129 | * Statically reserve bounce buffer space and initialize bounce buffer data |
120 | * structures for the software IO TLB used to implement the PCI DMA API. | 130 | * structures for the software IO TLB used to implement the DMA API. |
121 | */ | 131 | */ |
122 | void | 132 | void |
123 | swiotlb_init_with_default_size (size_t default_size) | 133 | swiotlb_init_with_default_size (size_t default_size) |
@@ -397,21 +407,28 @@ unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir) | |||
397 | } | 407 | } |
398 | 408 | ||
399 | static void | 409 | static void |
400 | sync_single(struct device *hwdev, char *dma_addr, size_t size, int dir) | 410 | sync_single(struct device *hwdev, char *dma_addr, size_t size, |
411 | int dir, int target) | ||
401 | { | 412 | { |
402 | int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; | 413 | int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; |
403 | char *buffer = io_tlb_orig_addr[index]; | 414 | char *buffer = io_tlb_orig_addr[index]; |
404 | 415 | ||
405 | /* | 416 | switch (target) { |
406 | * bounce... copy the data back into/from the original buffer | 417 | case SYNC_FOR_CPU: |
407 | * XXX How do you handle DMA_BIDIRECTIONAL here ? | 418 | if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)) |
408 | */ | 419 | memcpy(buffer, dma_addr, size); |
409 | if (dir == DMA_FROM_DEVICE) | 420 | else if (dir != DMA_TO_DEVICE) |
410 | memcpy(buffer, dma_addr, size); | 421 | BUG(); |
411 | else if (dir == DMA_TO_DEVICE) | 422 | break; |
412 | memcpy(dma_addr, buffer, size); | 423 | case SYNC_FOR_DEVICE: |
413 | else | 424 | if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)) |
425 | memcpy(dma_addr, buffer, size); | ||
426 | else if (dir != DMA_FROM_DEVICE) | ||
427 | BUG(); | ||
428 | break; | ||
429 | default: | ||
414 | BUG(); | 430 | BUG(); |
431 | } | ||
415 | } | 432 | } |
416 | 433 | ||
417 | void * | 434 | void * |
@@ -485,24 +502,24 @@ swiotlb_full(struct device *dev, size_t size, int dir, int do_panic) | |||
485 | /* | 502 | /* |
486 | * Ran out of IOMMU space for this operation. This is very bad. | 503 | * Ran out of IOMMU space for this operation. This is very bad. |
487 | * Unfortunately the drivers cannot handle this operation properly. | 504 | * Unfortunately the drivers cannot handle this operation properly. |
488 | * unless they check for pci_dma_mapping_error (most don't) | 505 | * unless they check for dma_mapping_error (most don't) |
489 | * When the mapping is small enough return a static buffer to limit | 506 | * When the mapping is small enough return a static buffer to limit |
490 | * the damage, or panic when the transfer is too big. | 507 | * the damage, or panic when the transfer is too big. |
491 | */ | 508 | */ |
492 | printk(KERN_ERR "PCI-DMA: Out of SW-IOMMU space for %lu bytes at " | 509 | printk(KERN_ERR "DMA: Out of SW-IOMMU space for %lu bytes at " |
493 | "device %s\n", size, dev ? dev->bus_id : "?"); | 510 | "device %s\n", size, dev ? dev->bus_id : "?"); |
494 | 511 | ||
495 | if (size > io_tlb_overflow && do_panic) { | 512 | if (size > io_tlb_overflow && do_panic) { |
496 | if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL) | 513 | if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) |
497 | panic("PCI-DMA: Memory would be corrupted\n"); | 514 | panic("DMA: Memory would be corrupted\n"); |
498 | if (dir == PCI_DMA_TODEVICE || dir == PCI_DMA_BIDIRECTIONAL) | 515 | if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) |
499 | panic("PCI-DMA: Random memory would be DMAed\n"); | 516 | panic("DMA: Random memory would be DMAed\n"); |
500 | } | 517 | } |
501 | } | 518 | } |
502 | 519 | ||
503 | /* | 520 | /* |
504 | * Map a single buffer of the indicated size for DMA in streaming mode. The | 521 | * Map a single buffer of the indicated size for DMA in streaming mode. The |
505 | * PCI address to use is returned. | 522 | * physical address to use is returned. |
506 | * | 523 | * |
507 | * Once the device is given the dma address, the device owns this memory until | 524 | * Once the device is given the dma address, the device owns this memory until |
508 | * either swiotlb_unmap_single or swiotlb_dma_sync_single is performed. | 525 | * either swiotlb_unmap_single or swiotlb_dma_sync_single is performed. |
@@ -589,39 +606,73 @@ swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size, | |||
589 | * after a transfer. | 606 | * after a transfer. |
590 | * | 607 | * |
591 | * If you perform a swiotlb_map_single() but wish to interrogate the buffer | 608 | * If you perform a swiotlb_map_single() but wish to interrogate the buffer |
592 | * using the cpu, yet do not wish to teardown the PCI dma mapping, you must | 609 | * using the cpu, yet do not wish to teardown the dma mapping, you must |
593 | * call this function before doing so. At the next point you give the PCI dma | 610 | * call this function before doing so. At the next point you give the dma |
594 | * address back to the card, you must first perform a | 611 | * address back to the card, you must first perform a |
595 | * swiotlb_dma_sync_for_device, and then the device again owns the buffer | 612 | * swiotlb_dma_sync_for_device, and then the device again owns the buffer |
596 | */ | 613 | */ |
597 | void | 614 | static inline void |
598 | swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, | 615 | swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr, |
599 | size_t size, int dir) | 616 | size_t size, int dir, int target) |
600 | { | 617 | { |
601 | char *dma_addr = phys_to_virt(dev_addr); | 618 | char *dma_addr = phys_to_virt(dev_addr); |
602 | 619 | ||
603 | if (dir == DMA_NONE) | 620 | if (dir == DMA_NONE) |
604 | BUG(); | 621 | BUG(); |
605 | if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) | 622 | if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) |
606 | sync_single(hwdev, dma_addr, size, dir); | 623 | sync_single(hwdev, dma_addr, size, dir, target); |
607 | else if (dir == DMA_FROM_DEVICE) | 624 | else if (dir == DMA_FROM_DEVICE) |
608 | mark_clean(dma_addr, size); | 625 | mark_clean(dma_addr, size); |
609 | } | 626 | } |
610 | 627 | ||
611 | void | 628 | void |
629 | swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, | ||
630 | size_t size, int dir) | ||
631 | { | ||
632 | swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_CPU); | ||
633 | } | ||
634 | |||
635 | void | ||
612 | swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, | 636 | swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, |
613 | size_t size, int dir) | 637 | size_t size, int dir) |
614 | { | 638 | { |
615 | char *dma_addr = phys_to_virt(dev_addr); | 639 | swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_DEVICE); |
640 | } | ||
641 | |||
642 | /* | ||
643 | * Same as above, but for a sub-range of the mapping. | ||
644 | */ | ||
645 | static inline void | ||
646 | swiotlb_sync_single_range(struct device *hwdev, dma_addr_t dev_addr, | ||
647 | unsigned long offset, size_t size, | ||
648 | int dir, int target) | ||
649 | { | ||
650 | char *dma_addr = phys_to_virt(dev_addr) + offset; | ||
616 | 651 | ||
617 | if (dir == DMA_NONE) | 652 | if (dir == DMA_NONE) |
618 | BUG(); | 653 | BUG(); |
619 | if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) | 654 | if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) |
620 | sync_single(hwdev, dma_addr, size, dir); | 655 | sync_single(hwdev, dma_addr, size, dir, target); |
621 | else if (dir == DMA_FROM_DEVICE) | 656 | else if (dir == DMA_FROM_DEVICE) |
622 | mark_clean(dma_addr, size); | 657 | mark_clean(dma_addr, size); |
623 | } | 658 | } |
624 | 659 | ||
660 | void | ||
661 | swiotlb_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dev_addr, | ||
662 | unsigned long offset, size_t size, int dir) | ||
663 | { | ||
664 | swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir, | ||
665 | SYNC_FOR_CPU); | ||
666 | } | ||
667 | |||
668 | void | ||
669 | swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr, | ||
670 | unsigned long offset, size_t size, int dir) | ||
671 | { | ||
672 | swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir, | ||
673 | SYNC_FOR_DEVICE); | ||
674 | } | ||
675 | |||
625 | /* | 676 | /* |
626 | * Map a set of buffers described by scatterlist in streaming mode for DMA. | 677 | * Map a set of buffers described by scatterlist in streaming mode for DMA. |
627 | * This is the scatter-gather version of the above swiotlb_map_single | 678 | * This is the scatter-gather version of the above swiotlb_map_single |
@@ -696,9 +747,9 @@ swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nelems, | |||
696 | * The same as swiotlb_sync_single_* but for a scatter-gather list, same rules | 747 | * The same as swiotlb_sync_single_* but for a scatter-gather list, same rules |
697 | * and usage. | 748 | * and usage. |
698 | */ | 749 | */ |
699 | void | 750 | static inline void |
700 | swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, | 751 | swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sg, |
701 | int nelems, int dir) | 752 | int nelems, int dir, int target) |
702 | { | 753 | { |
703 | int i; | 754 | int i; |
704 | 755 | ||
@@ -708,22 +759,21 @@ swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, | |||
708 | for (i = 0; i < nelems; i++, sg++) | 759 | for (i = 0; i < nelems; i++, sg++) |
709 | if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) | 760 | if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) |
710 | sync_single(hwdev, (void *) sg->dma_address, | 761 | sync_single(hwdev, (void *) sg->dma_address, |
711 | sg->dma_length, dir); | 762 | sg->dma_length, dir, target); |
763 | } | ||
764 | |||
765 | void | ||
766 | swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, | ||
767 | int nelems, int dir) | ||
768 | { | ||
769 | swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_CPU); | ||
712 | } | 770 | } |
713 | 771 | ||
714 | void | 772 | void |
715 | swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, | 773 | swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, |
716 | int nelems, int dir) | 774 | int nelems, int dir) |
717 | { | 775 | { |
718 | int i; | 776 | swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE); |
719 | |||
720 | if (dir == DMA_NONE) | ||
721 | BUG(); | ||
722 | |||
723 | for (i = 0; i < nelems; i++, sg++) | ||
724 | if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) | ||
725 | sync_single(hwdev, (void *) sg->dma_address, | ||
726 | sg->dma_length, dir); | ||
727 | } | 777 | } |
728 | 778 | ||
729 | int | 779 | int |
@@ -733,9 +783,9 @@ swiotlb_dma_mapping_error(dma_addr_t dma_addr) | |||
733 | } | 783 | } |
734 | 784 | ||
735 | /* | 785 | /* |
736 | * Return whether the given PCI device DMA address mask can be supported | 786 | * Return whether the given device DMA address mask can be supported |
737 | * properly. For example, if your device can only drive the low 24-bits | 787 | * properly. For example, if your device can only drive the low 24-bits |
738 | * during PCI bus mastering, then you would pass 0x00ffffff as the mask to | 788 | * during bus mastering, then you would pass 0x00ffffff as the mask to |
739 | * this function. | 789 | * this function. |
740 | */ | 790 | */ |
741 | int | 791 | int |
@@ -751,6 +801,8 @@ EXPORT_SYMBOL(swiotlb_map_sg); | |||
751 | EXPORT_SYMBOL(swiotlb_unmap_sg); | 801 | EXPORT_SYMBOL(swiotlb_unmap_sg); |
752 | EXPORT_SYMBOL(swiotlb_sync_single_for_cpu); | 802 | EXPORT_SYMBOL(swiotlb_sync_single_for_cpu); |
753 | EXPORT_SYMBOL(swiotlb_sync_single_for_device); | 803 | EXPORT_SYMBOL(swiotlb_sync_single_for_device); |
804 | EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_cpu); | ||
805 | EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_device); | ||
754 | EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu); | 806 | EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu); |
755 | EXPORT_SYMBOL(swiotlb_sync_sg_for_device); | 807 | EXPORT_SYMBOL(swiotlb_sync_sg_for_device); |
756 | EXPORT_SYMBOL(swiotlb_dma_mapping_error); | 808 | EXPORT_SYMBOL(swiotlb_dma_mapping_error); |