diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/Kconfig | 1 | ||||
-rw-r--r-- | arch/x86/kernel/pci-dma.c | 122 |
2 files changed, 3 insertions, 120 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 96e0c2ebc388..18a58ecfe684 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -27,6 +27,7 @@ config X86 | |||
27 | select HAVE_FTRACE | 27 | select HAVE_FTRACE |
28 | select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) | 28 | select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) |
29 | select HAVE_ARCH_KGDB if !X86_VOYAGER | 29 | select HAVE_ARCH_KGDB if !X86_VOYAGER |
30 | select HAVE_GENERIC_DMA_COHERENT if X86_32 | ||
30 | 31 | ||
31 | config ARCH_DEFCONFIG | 32 | config ARCH_DEFCONFIG |
32 | string | 33 | string |
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 8467ec2320f1..b7dd70fda031 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c | |||
@@ -201,124 +201,6 @@ static __init int iommu_setup(char *p) | |||
201 | } | 201 | } |
202 | early_param("iommu", iommu_setup); | 202 | early_param("iommu", iommu_setup); |
203 | 203 | ||
204 | #ifdef CONFIG_X86_32 | ||
205 | int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, | ||
206 | dma_addr_t device_addr, size_t size, int flags) | ||
207 | { | ||
208 | void __iomem *mem_base = NULL; | ||
209 | int pages = size >> PAGE_SHIFT; | ||
210 | int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); | ||
211 | |||
212 | if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0) | ||
213 | goto out; | ||
214 | if (!size) | ||
215 | goto out; | ||
216 | if (dev->dma_mem) | ||
217 | goto out; | ||
218 | |||
219 | /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */ | ||
220 | |||
221 | mem_base = ioremap(bus_addr, size); | ||
222 | if (!mem_base) | ||
223 | goto out; | ||
224 | |||
225 | dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); | ||
226 | if (!dev->dma_mem) | ||
227 | goto out; | ||
228 | dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL); | ||
229 | if (!dev->dma_mem->bitmap) | ||
230 | goto free1_out; | ||
231 | |||
232 | dev->dma_mem->virt_base = mem_base; | ||
233 | dev->dma_mem->device_base = device_addr; | ||
234 | dev->dma_mem->size = pages; | ||
235 | dev->dma_mem->flags = flags; | ||
236 | |||
237 | if (flags & DMA_MEMORY_MAP) | ||
238 | return DMA_MEMORY_MAP; | ||
239 | |||
240 | return DMA_MEMORY_IO; | ||
241 | |||
242 | free1_out: | ||
243 | kfree(dev->dma_mem); | ||
244 | out: | ||
245 | if (mem_base) | ||
246 | iounmap(mem_base); | ||
247 | return 0; | ||
248 | } | ||
249 | EXPORT_SYMBOL(dma_declare_coherent_memory); | ||
250 | |||
251 | void dma_release_declared_memory(struct device *dev) | ||
252 | { | ||
253 | struct dma_coherent_mem *mem = dev->dma_mem; | ||
254 | |||
255 | if (!mem) | ||
256 | return; | ||
257 | dev->dma_mem = NULL; | ||
258 | iounmap(mem->virt_base); | ||
259 | kfree(mem->bitmap); | ||
260 | kfree(mem); | ||
261 | } | ||
262 | EXPORT_SYMBOL(dma_release_declared_memory); | ||
263 | |||
264 | void *dma_mark_declared_memory_occupied(struct device *dev, | ||
265 | dma_addr_t device_addr, size_t size) | ||
266 | { | ||
267 | struct dma_coherent_mem *mem = dev->dma_mem; | ||
268 | int pos, err; | ||
269 | int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1); | ||
270 | |||
271 | pages >>= PAGE_SHIFT; | ||
272 | |||
273 | if (!mem) | ||
274 | return ERR_PTR(-EINVAL); | ||
275 | |||
276 | pos = (device_addr - mem->device_base) >> PAGE_SHIFT; | ||
277 | err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages)); | ||
278 | if (err != 0) | ||
279 | return ERR_PTR(err); | ||
280 | return mem->virt_base + (pos << PAGE_SHIFT); | ||
281 | } | ||
282 | EXPORT_SYMBOL(dma_mark_declared_memory_occupied); | ||
283 | |||
284 | static int dma_alloc_from_coherent_mem(struct device *dev, ssize_t size, | ||
285 | dma_addr_t *dma_handle, void **ret) | ||
286 | { | ||
287 | struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; | ||
288 | int order = get_order(size); | ||
289 | |||
290 | if (mem) { | ||
291 | int page = bitmap_find_free_region(mem->bitmap, mem->size, | ||
292 | order); | ||
293 | if (page >= 0) { | ||
294 | *dma_handle = mem->device_base + (page << PAGE_SHIFT); | ||
295 | *ret = mem->virt_base + (page << PAGE_SHIFT); | ||
296 | memset(*ret, 0, size); | ||
297 | } | ||
298 | if (mem->flags & DMA_MEMORY_EXCLUSIVE) | ||
299 | *ret = NULL; | ||
300 | } | ||
301 | return (mem != NULL); | ||
302 | } | ||
303 | |||
304 | static int dma_release_coherent(struct device *dev, int order, void *vaddr) | ||
305 | { | ||
306 | struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; | ||
307 | |||
308 | if (mem && vaddr >= mem->virt_base && vaddr < | ||
309 | (mem->virt_base + (mem->size << PAGE_SHIFT))) { | ||
310 | int page = (vaddr - mem->virt_base) >> PAGE_SHIFT; | ||
311 | |||
312 | bitmap_release_region(mem->bitmap, page, order); | ||
313 | return 1; | ||
314 | } | ||
315 | return 0; | ||
316 | } | ||
317 | #else | ||
318 | #define dma_alloc_from_coherent_mem(dev, size, handle, ret) (0) | ||
319 | #define dma_release_coherent(dev, order, vaddr) (0) | ||
320 | #endif /* CONFIG_X86_32 */ | ||
321 | |||
322 | int dma_supported(struct device *dev, u64 mask) | 204 | int dma_supported(struct device *dev, u64 mask) |
323 | { | 205 | { |
324 | #ifdef CONFIG_PCI | 206 | #ifdef CONFIG_PCI |
@@ -387,7 +269,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
387 | /* ignore region specifiers */ | 269 | /* ignore region specifiers */ |
388 | gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32); | 270 | gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32); |
389 | 271 | ||
390 | if (dma_alloc_from_coherent_mem(dev, size, dma_handle, &memory)) | 272 | if (dma_alloc_from_coherent(dev, size, dma_handle, &memory)) |
391 | return memory; | 273 | return memory; |
392 | 274 | ||
393 | if (!dev) { | 275 | if (!dev) { |
@@ -490,7 +372,7 @@ void dma_free_coherent(struct device *dev, size_t size, | |||
490 | { | 372 | { |
491 | int order = get_order(size); | 373 | int order = get_order(size); |
492 | WARN_ON(irqs_disabled()); /* for portability */ | 374 | WARN_ON(irqs_disabled()); /* for portability */ |
493 | if (dma_release_coherent(dev, order, vaddr)) | 375 | if (dma_release_from_coherent(dev, order, vaddr)) |
494 | return; | 376 | return; |
495 | if (dma_ops->unmap_single) | 377 | if (dma_ops->unmap_single) |
496 | dma_ops->unmap_single(dev, bus, size, 0); | 378 | dma_ops->unmap_single(dev, bus, size, 0); |