diff options
| -rw-r--r-- | arch/x86/Kconfig | 1 | ||||
| -rw-r--r-- | arch/x86/kernel/pci-dma.c | 122 | ||||
| -rw-r--r-- | include/asm-x86/dma-mapping.h | 22 |
3 files changed, 4 insertions, 141 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index e0edaaa6920a..9d4714e0020c 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -25,6 +25,7 @@ config X86 | |||
| 25 | select HAVE_KRETPROBES | 25 | select HAVE_KRETPROBES |
| 26 | select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) | 26 | select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) |
| 27 | select HAVE_ARCH_KGDB if !X86_VOYAGER | 27 | select HAVE_ARCH_KGDB if !X86_VOYAGER |
| 28 | select HAVE_GENERIC_DMA_COHERENT if X86_32 | ||
| 28 | 29 | ||
| 29 | config ARCH_DEFCONFIG | 30 | config ARCH_DEFCONFIG |
| 30 | string | 31 | string |
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index dc00a1331ace..b75c81a8d3e6 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c | |||
| @@ -197,124 +197,6 @@ static __init int iommu_setup(char *p) | |||
| 197 | } | 197 | } |
| 198 | early_param("iommu", iommu_setup); | 198 | early_param("iommu", iommu_setup); |
| 199 | 199 | ||
| 200 | #ifdef CONFIG_X86_32 | ||
| 201 | int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, | ||
| 202 | dma_addr_t device_addr, size_t size, int flags) | ||
| 203 | { | ||
| 204 | void __iomem *mem_base = NULL; | ||
| 205 | int pages = size >> PAGE_SHIFT; | ||
| 206 | int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); | ||
| 207 | |||
| 208 | if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0) | ||
| 209 | goto out; | ||
| 210 | if (!size) | ||
| 211 | goto out; | ||
| 212 | if (dev->dma_mem) | ||
| 213 | goto out; | ||
| 214 | |||
| 215 | /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */ | ||
| 216 | |||
| 217 | mem_base = ioremap(bus_addr, size); | ||
| 218 | if (!mem_base) | ||
| 219 | goto out; | ||
| 220 | |||
| 221 | dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); | ||
| 222 | if (!dev->dma_mem) | ||
| 223 | goto out; | ||
| 224 | dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL); | ||
| 225 | if (!dev->dma_mem->bitmap) | ||
| 226 | goto free1_out; | ||
| 227 | |||
| 228 | dev->dma_mem->virt_base = mem_base; | ||
| 229 | dev->dma_mem->device_base = device_addr; | ||
| 230 | dev->dma_mem->size = pages; | ||
| 231 | dev->dma_mem->flags = flags; | ||
| 232 | |||
| 233 | if (flags & DMA_MEMORY_MAP) | ||
| 234 | return DMA_MEMORY_MAP; | ||
| 235 | |||
| 236 | return DMA_MEMORY_IO; | ||
| 237 | |||
| 238 | free1_out: | ||
| 239 | kfree(dev->dma_mem); | ||
| 240 | out: | ||
| 241 | if (mem_base) | ||
| 242 | iounmap(mem_base); | ||
| 243 | return 0; | ||
| 244 | } | ||
| 245 | EXPORT_SYMBOL(dma_declare_coherent_memory); | ||
| 246 | |||
| 247 | void dma_release_declared_memory(struct device *dev) | ||
| 248 | { | ||
| 249 | struct dma_coherent_mem *mem = dev->dma_mem; | ||
| 250 | |||
| 251 | if (!mem) | ||
| 252 | return; | ||
| 253 | dev->dma_mem = NULL; | ||
| 254 | iounmap(mem->virt_base); | ||
| 255 | kfree(mem->bitmap); | ||
| 256 | kfree(mem); | ||
| 257 | } | ||
| 258 | EXPORT_SYMBOL(dma_release_declared_memory); | ||
| 259 | |||
| 260 | void *dma_mark_declared_memory_occupied(struct device *dev, | ||
| 261 | dma_addr_t device_addr, size_t size) | ||
| 262 | { | ||
| 263 | struct dma_coherent_mem *mem = dev->dma_mem; | ||
| 264 | int pos, err; | ||
| 265 | int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1); | ||
| 266 | |||
| 267 | pages >>= PAGE_SHIFT; | ||
| 268 | |||
| 269 | if (!mem) | ||
| 270 | return ERR_PTR(-EINVAL); | ||
| 271 | |||
| 272 | pos = (device_addr - mem->device_base) >> PAGE_SHIFT; | ||
| 273 | err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages)); | ||
| 274 | if (err != 0) | ||
| 275 | return ERR_PTR(err); | ||
| 276 | return mem->virt_base + (pos << PAGE_SHIFT); | ||
| 277 | } | ||
| 278 | EXPORT_SYMBOL(dma_mark_declared_memory_occupied); | ||
| 279 | |||
| 280 | static int dma_alloc_from_coherent_mem(struct device *dev, ssize_t size, | ||
| 281 | dma_addr_t *dma_handle, void **ret) | ||
| 282 | { | ||
| 283 | struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; | ||
| 284 | int order = get_order(size); | ||
| 285 | |||
| 286 | if (mem) { | ||
| 287 | int page = bitmap_find_free_region(mem->bitmap, mem->size, | ||
| 288 | order); | ||
| 289 | if (page >= 0) { | ||
| 290 | *dma_handle = mem->device_base + (page << PAGE_SHIFT); | ||
| 291 | *ret = mem->virt_base + (page << PAGE_SHIFT); | ||
| 292 | memset(*ret, 0, size); | ||
| 293 | } | ||
| 294 | if (mem->flags & DMA_MEMORY_EXCLUSIVE) | ||
| 295 | *ret = NULL; | ||
| 296 | } | ||
| 297 | return (mem != NULL); | ||
| 298 | } | ||
| 299 | |||
| 300 | static int dma_release_coherent(struct device *dev, int order, void *vaddr) | ||
| 301 | { | ||
| 302 | struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; | ||
| 303 | |||
| 304 | if (mem && vaddr >= mem->virt_base && vaddr < | ||
| 305 | (mem->virt_base + (mem->size << PAGE_SHIFT))) { | ||
| 306 | int page = (vaddr - mem->virt_base) >> PAGE_SHIFT; | ||
| 307 | |||
| 308 | bitmap_release_region(mem->bitmap, page, order); | ||
| 309 | return 1; | ||
| 310 | } | ||
| 311 | return 0; | ||
| 312 | } | ||
| 313 | #else | ||
| 314 | #define dma_alloc_from_coherent_mem(dev, size, handle, ret) (0) | ||
| 315 | #define dma_release_coherent(dev, order, vaddr) (0) | ||
| 316 | #endif /* CONFIG_X86_32 */ | ||
| 317 | |||
| 318 | int dma_supported(struct device *dev, u64 mask) | 200 | int dma_supported(struct device *dev, u64 mask) |
| 319 | { | 201 | { |
| 320 | #ifdef CONFIG_PCI | 202 | #ifdef CONFIG_PCI |
| @@ -383,7 +265,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
| 383 | /* ignore region specifiers */ | 265 | /* ignore region specifiers */ |
| 384 | gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32); | 266 | gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32); |
| 385 | 267 | ||
| 386 | if (dma_alloc_from_coherent_mem(dev, size, dma_handle, &memory)) | 268 | if (dma_alloc_from_coherent(dev, size, dma_handle, &memory)) |
| 387 | return memory; | 269 | return memory; |
| 388 | 270 | ||
| 389 | if (!dev) { | 271 | if (!dev) { |
| @@ -486,7 +368,7 @@ void dma_free_coherent(struct device *dev, size_t size, | |||
| 486 | { | 368 | { |
| 487 | int order = get_order(size); | 369 | int order = get_order(size); |
| 488 | WARN_ON(irqs_disabled()); /* for portability */ | 370 | WARN_ON(irqs_disabled()); /* for portability */ |
| 489 | if (dma_release_coherent(dev, order, vaddr)) | 371 | if (dma_release_from_coherent(dev, order, vaddr)) |
| 490 | return; | 372 | return; |
| 491 | if (dma_ops->unmap_single) | 373 | if (dma_ops->unmap_single) |
| 492 | dma_ops->unmap_single(dev, bus, size, 0); | 374 | dma_ops->unmap_single(dev, bus, size, 0); |
diff --git a/include/asm-x86/dma-mapping.h b/include/asm-x86/dma-mapping.h index a1a4dc7fe6ec..c68f360ef564 100644 --- a/include/asm-x86/dma-mapping.h +++ b/include/asm-x86/dma-mapping.h | |||
| @@ -213,25 +213,5 @@ static inline int dma_get_cache_alignment(void) | |||
| 213 | 213 | ||
| 214 | #define dma_is_consistent(d, h) (1) | 214 | #define dma_is_consistent(d, h) (1) |
| 215 | 215 | ||
| 216 | #ifdef CONFIG_X86_32 | 216 | #include <asm-generic/dma-coherent.h> |
| 217 | # define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY | ||
| 218 | struct dma_coherent_mem { | ||
| 219 | void *virt_base; | ||
| 220 | u32 device_base; | ||
| 221 | int size; | ||
| 222 | int flags; | ||
| 223 | unsigned long *bitmap; | ||
| 224 | }; | ||
| 225 | |||
| 226 | extern int | ||
| 227 | dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, | ||
| 228 | dma_addr_t device_addr, size_t size, int flags); | ||
| 229 | |||
| 230 | extern void | ||
| 231 | dma_release_declared_memory(struct device *dev); | ||
| 232 | |||
| 233 | extern void * | ||
| 234 | dma_mark_declared_memory_occupied(struct device *dev, | ||
| 235 | dma_addr_t device_addr, size_t size); | ||
| 236 | #endif /* CONFIG_X86_32 */ | ||
| 237 | #endif | 217 | #endif |
