aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/pci-dma.c31
-rw-r--r--arch/x86/kernel/pci-nommu.c39
-rw-r--r--include/asm-x86/dma-mapping.h3
3 files changed, 35 insertions, 38 deletions
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 0a1408abcc62..4e612d20170a 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -134,6 +134,37 @@ unsigned long iommu_num_pages(unsigned long addr, unsigned long len)
134EXPORT_SYMBOL(iommu_num_pages); 134EXPORT_SYMBOL(iommu_num_pages);
135#endif 135#endif
136 136
137void *dma_generic_alloc_coherent(struct device *dev, size_t size,
138 dma_addr_t *dma_addr, gfp_t flag)
139{
140 unsigned long dma_mask;
141 struct page *page;
142 dma_addr_t addr;
143
144 dma_mask = dma_alloc_coherent_mask(dev, flag);
145
146 flag |= __GFP_ZERO;
147again:
148 page = alloc_pages_node(dev_to_node(dev), flag, get_order(size));
149 if (!page)
150 return NULL;
151
152 addr = page_to_phys(page);
153 if (!is_buffer_dma_capable(dma_mask, addr, size)) {
154 __free_pages(page, get_order(size));
155
156 if (dma_mask < DMA_32BIT_MASK && !(flag & GFP_DMA)) {
157 flag = (flag & ~GFP_DMA32) | GFP_DMA;
158 goto again;
159 }
160
161 return NULL;
162 }
163
164 *dma_addr = addr;
165 return page_address(page);
166}
167
137/* 168/*
138 * See <Documentation/x86_64/boot-options.txt> for the iommu kernel parameter 169 * See <Documentation/x86_64/boot-options.txt> for the iommu kernel parameter
139 * documentation. 170 * documentation.
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c
index 1c1c98a31d57..c70ab5a5d4c8 100644
--- a/arch/x86/kernel/pci-nommu.c
+++ b/arch/x86/kernel/pci-nommu.c
@@ -72,43 +72,6 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
72 return nents; 72 return nents;
73} 73}
74 74
75static void *
76nommu_alloc_coherent(struct device *hwdev, size_t size,
77 dma_addr_t *dma_addr, gfp_t gfp)
78{
79 unsigned long dma_mask;
80 int node;
81 struct page *page;
82 dma_addr_t addr;
83
84 dma_mask = dma_alloc_coherent_mask(hwdev, gfp);
85
86 gfp |= __GFP_ZERO;
87
88 node = dev_to_node(hwdev);
89again:
90 page = alloc_pages_node(node, gfp, get_order(size));
91 if (!page)
92 return NULL;
93
94 addr = page_to_phys(page);
95 if (!is_buffer_dma_capable(dma_mask, addr, size) && !(gfp & GFP_DMA)) {
96 free_pages((unsigned long)page_address(page), get_order(size));
97 gfp |= GFP_DMA;
98 goto again;
99 }
100
101 if (check_addr("alloc_coherent", hwdev, addr, size)) {
102 *dma_addr = addr;
103 flush_write_buffers();
104 return page_address(page);
105 }
106
107 free_pages((unsigned long)page_address(page), get_order(size));
108
109 return NULL;
110}
111
112static void nommu_free_coherent(struct device *dev, size_t size, void *vaddr, 75static void nommu_free_coherent(struct device *dev, size_t size, void *vaddr,
113 dma_addr_t dma_addr) 76 dma_addr_t dma_addr)
114{ 77{
@@ -116,7 +79,7 @@ static void nommu_free_coherent(struct device *dev, size_t size, void *vaddr,
116} 79}
117 80
118struct dma_mapping_ops nommu_dma_ops = { 81struct dma_mapping_ops nommu_dma_ops = {
119 .alloc_coherent = nommu_alloc_coherent, 82 .alloc_coherent = dma_generic_alloc_coherent,
120 .free_coherent = nommu_free_coherent, 83 .free_coherent = nommu_free_coherent,
121 .map_single = nommu_map_single, 84 .map_single = nommu_map_single,
122 .map_sg = nommu_map_sg, 85 .map_sg = nommu_map_sg,
diff --git a/include/asm-x86/dma-mapping.h b/include/asm-x86/dma-mapping.h
index f408e6dd1778..3b808e9bb72c 100644
--- a/include/asm-x86/dma-mapping.h
+++ b/include/asm-x86/dma-mapping.h
@@ -89,6 +89,9 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
89extern int dma_supported(struct device *hwdev, u64 mask); 89extern int dma_supported(struct device *hwdev, u64 mask);
90extern int dma_set_mask(struct device *dev, u64 mask); 90extern int dma_set_mask(struct device *dev, u64 mask);
91 91
92extern void *dma_generic_alloc_coherent(struct device *dev, size_t size,
93 dma_addr_t *dma_addr, gfp_t flag);
94
92static inline dma_addr_t 95static inline dma_addr_t
93dma_map_single(struct device *hwdev, void *ptr, size_t size, 96dma_map_single(struct device *hwdev, void *ptr, size_t size,
94 int direction) 97 int direction)