diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/pci-dma.c | 81 | ||||
-rw-r--r-- | arch/x86/kernel/pci-dma_32.c | 85 |
2 files changed, 81 insertions, 85 deletions
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 48ab52d052b6..967dfcfa2ad2 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c | |||
@@ -186,6 +186,87 @@ static __init int iommu_setup(char *p) | |||
186 | } | 186 | } |
187 | early_param("iommu", iommu_setup); | 187 | early_param("iommu", iommu_setup); |
188 | 188 | ||
189 | #ifdef CONFIG_X86_32 | ||
190 | int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, | ||
191 | dma_addr_t device_addr, size_t size, int flags) | ||
192 | { | ||
193 | void __iomem *mem_base = NULL; | ||
194 | int pages = size >> PAGE_SHIFT; | ||
195 | int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); | ||
196 | |||
197 | if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0) | ||
198 | goto out; | ||
199 | if (!size) | ||
200 | goto out; | ||
201 | if (dev->dma_mem) | ||
202 | goto out; | ||
203 | |||
204 | /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */ | ||
205 | |||
206 | mem_base = ioremap(bus_addr, size); | ||
207 | if (!mem_base) | ||
208 | goto out; | ||
209 | |||
210 | dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); | ||
211 | if (!dev->dma_mem) | ||
212 | goto out; | ||
213 | dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL); | ||
214 | if (!dev->dma_mem->bitmap) | ||
215 | goto free1_out; | ||
216 | |||
217 | dev->dma_mem->virt_base = mem_base; | ||
218 | dev->dma_mem->device_base = device_addr; | ||
219 | dev->dma_mem->size = pages; | ||
220 | dev->dma_mem->flags = flags; | ||
221 | |||
222 | if (flags & DMA_MEMORY_MAP) | ||
223 | return DMA_MEMORY_MAP; | ||
224 | |||
225 | return DMA_MEMORY_IO; | ||
226 | |||
227 | free1_out: | ||
228 | kfree(dev->dma_mem); | ||
229 | out: | ||
230 | if (mem_base) | ||
231 | iounmap(mem_base); | ||
232 | return 0; | ||
233 | } | ||
234 | EXPORT_SYMBOL(dma_declare_coherent_memory); | ||
235 | |||
236 | void dma_release_declared_memory(struct device *dev) | ||
237 | { | ||
238 | struct dma_coherent_mem *mem = dev->dma_mem; | ||
239 | |||
240 | if (!mem) | ||
241 | return; | ||
242 | dev->dma_mem = NULL; | ||
243 | iounmap(mem->virt_base); | ||
244 | kfree(mem->bitmap); | ||
245 | kfree(mem); | ||
246 | } | ||
247 | EXPORT_SYMBOL(dma_release_declared_memory); | ||
248 | |||
249 | void *dma_mark_declared_memory_occupied(struct device *dev, | ||
250 | dma_addr_t device_addr, size_t size) | ||
251 | { | ||
252 | struct dma_coherent_mem *mem = dev->dma_mem; | ||
253 | int pos, err; | ||
254 | int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1); | ||
255 | |||
256 | pages >>= PAGE_SHIFT; | ||
257 | |||
258 | if (!mem) | ||
259 | return ERR_PTR(-EINVAL); | ||
260 | |||
261 | pos = (device_addr - mem->device_base) >> PAGE_SHIFT; | ||
262 | err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages)); | ||
263 | if (err != 0) | ||
264 | return ERR_PTR(err); | ||
265 | return mem->virt_base + (pos << PAGE_SHIFT); | ||
266 | } | ||
267 | EXPORT_SYMBOL(dma_mark_declared_memory_occupied); | ||
268 | #endif /* CONFIG_X86_32 */ | ||
269 | |||
189 | int dma_supported(struct device *dev, u64 mask) | 270 | int dma_supported(struct device *dev, u64 mask) |
190 | { | 271 | { |
191 | #ifdef CONFIG_PCI | 272 | #ifdef CONFIG_PCI |
diff --git a/arch/x86/kernel/pci-dma_32.c b/arch/x86/kernel/pci-dma_32.c index eea52df68a3b..818d95efc3cb 100644 --- a/arch/x86/kernel/pci-dma_32.c +++ b/arch/x86/kernel/pci-dma_32.c | |||
@@ -18,14 +18,6 @@ | |||
18 | dma_addr_t bad_dma_address __read_mostly = 0x0; | 18 | dma_addr_t bad_dma_address __read_mostly = 0x0; |
19 | EXPORT_SYMBOL(bad_dma_address); | 19 | EXPORT_SYMBOL(bad_dma_address); |
20 | 20 | ||
21 | struct dma_coherent_mem { | ||
22 | void *virt_base; | ||
23 | u32 device_base; | ||
24 | int size; | ||
25 | int flags; | ||
26 | unsigned long *bitmap; | ||
27 | }; | ||
28 | |||
29 | void *dma_alloc_coherent(struct device *dev, size_t size, | 21 | void *dma_alloc_coherent(struct device *dev, size_t size, |
30 | dma_addr_t *dma_handle, gfp_t gfp) | 22 | dma_addr_t *dma_handle, gfp_t gfp) |
31 | { | 23 | { |
@@ -76,80 +68,3 @@ void dma_free_coherent(struct device *dev, size_t size, | |||
76 | free_pages((unsigned long)vaddr, order); | 68 | free_pages((unsigned long)vaddr, order); |
77 | } | 69 | } |
78 | EXPORT_SYMBOL(dma_free_coherent); | 70 | EXPORT_SYMBOL(dma_free_coherent); |
79 | |||
80 | int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, | ||
81 | dma_addr_t device_addr, size_t size, int flags) | ||
82 | { | ||
83 | void __iomem *mem_base = NULL; | ||
84 | int pages = size >> PAGE_SHIFT; | ||
85 | int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); | ||
86 | |||
87 | if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0) | ||
88 | goto out; | ||
89 | if (!size) | ||
90 | goto out; | ||
91 | if (dev->dma_mem) | ||
92 | goto out; | ||
93 | |||
94 | /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */ | ||
95 | |||
96 | mem_base = ioremap(bus_addr, size); | ||
97 | if (!mem_base) | ||
98 | goto out; | ||
99 | |||
100 | dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); | ||
101 | if (!dev->dma_mem) | ||
102 | goto out; | ||
103 | dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL); | ||
104 | if (!dev->dma_mem->bitmap) | ||
105 | goto free1_out; | ||
106 | |||
107 | dev->dma_mem->virt_base = mem_base; | ||
108 | dev->dma_mem->device_base = device_addr; | ||
109 | dev->dma_mem->size = pages; | ||
110 | dev->dma_mem->flags = flags; | ||
111 | |||
112 | if (flags & DMA_MEMORY_MAP) | ||
113 | return DMA_MEMORY_MAP; | ||
114 | |||
115 | return DMA_MEMORY_IO; | ||
116 | |||
117 | free1_out: | ||
118 | kfree(dev->dma_mem); | ||
119 | out: | ||
120 | if (mem_base) | ||
121 | iounmap(mem_base); | ||
122 | return 0; | ||
123 | } | ||
124 | EXPORT_SYMBOL(dma_declare_coherent_memory); | ||
125 | |||
126 | void dma_release_declared_memory(struct device *dev) | ||
127 | { | ||
128 | struct dma_coherent_mem *mem = dev->dma_mem; | ||
129 | |||
130 | if(!mem) | ||
131 | return; | ||
132 | dev->dma_mem = NULL; | ||
133 | iounmap(mem->virt_base); | ||
134 | kfree(mem->bitmap); | ||
135 | kfree(mem); | ||
136 | } | ||
137 | EXPORT_SYMBOL(dma_release_declared_memory); | ||
138 | |||
139 | void *dma_mark_declared_memory_occupied(struct device *dev, | ||
140 | dma_addr_t device_addr, size_t size) | ||
141 | { | ||
142 | struct dma_coherent_mem *mem = dev->dma_mem; | ||
143 | int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
144 | int pos, err; | ||
145 | |||
146 | if (!mem) | ||
147 | return ERR_PTR(-EINVAL); | ||
148 | |||
149 | pos = (device_addr - mem->device_base) >> PAGE_SHIFT; | ||
150 | err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages)); | ||
151 | if (err != 0) | ||
152 | return ERR_PTR(err); | ||
153 | return mem->virt_base + (pos << PAGE_SHIFT); | ||
154 | } | ||
155 | EXPORT_SYMBOL(dma_mark_declared_memory_occupied); | ||