aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/iommu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/iommu.c')
-rw-r--r--arch/powerpc/kernel/iommu.c93
1 files changed, 38 insertions, 55 deletions
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index a3c406aca664..8f1f4e539c4b 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -31,6 +31,7 @@
31#include <linux/string.h> 31#include <linux/string.h>
32#include <linux/dma-mapping.h> 32#include <linux/dma-mapping.h>
33#include <linux/bitops.h> 33#include <linux/bitops.h>
34#include <linux/iommu-helper.h>
34#include <asm/io.h> 35#include <asm/io.h>
35#include <asm/prom.h> 36#include <asm/prom.h>
36#include <asm/iommu.h> 37#include <asm/iommu.h>
@@ -81,17 +82,19 @@ static int __init setup_iommu(char *str)
81__setup("protect4gb=", setup_protect4gb); 82__setup("protect4gb=", setup_protect4gb);
82__setup("iommu=", setup_iommu); 83__setup("iommu=", setup_iommu);
83 84
84static unsigned long iommu_range_alloc(struct iommu_table *tbl, 85static unsigned long iommu_range_alloc(struct device *dev,
86 struct iommu_table *tbl,
85 unsigned long npages, 87 unsigned long npages,
86 unsigned long *handle, 88 unsigned long *handle,
87 unsigned long mask, 89 unsigned long mask,
88 unsigned int align_order) 90 unsigned int align_order)
89{ 91{
90 unsigned long n, end, i, start; 92 unsigned long n, end, start;
91 unsigned long limit; 93 unsigned long limit;
92 int largealloc = npages > 15; 94 int largealloc = npages > 15;
93 int pass = 0; 95 int pass = 0;
94 unsigned long align_mask; 96 unsigned long align_mask;
97 unsigned long boundary_size;
95 98
96 align_mask = 0xffffffffffffffffl >> (64 - align_order); 99 align_mask = 0xffffffffffffffffl >> (64 - align_order);
97 100
@@ -136,14 +139,17 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl,
136 start &= mask; 139 start &= mask;
137 } 140 }
138 141
139 n = find_next_zero_bit(tbl->it_map, limit, start); 142 if (dev)
140 143 boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
141 /* Align allocation */ 144 1 << IOMMU_PAGE_SHIFT);
142 n = (n + align_mask) & ~align_mask; 145 else
143 146 boundary_size = ALIGN(1UL << 32, 1 << IOMMU_PAGE_SHIFT);
144 end = n + npages; 147 /* 4GB boundary for iseries_hv_alloc and iseries_hv_map */
145 148
146 if (unlikely(end >= limit)) { 149 n = iommu_area_alloc(tbl->it_map, limit, start, npages,
150 tbl->it_offset, boundary_size >> IOMMU_PAGE_SHIFT,
151 align_mask);
152 if (n == -1) {
147 if (likely(pass < 2)) { 153 if (likely(pass < 2)) {
148 /* First failure, just rescan the half of the table. 154 /* First failure, just rescan the half of the table.
149 * Second failure, rescan the other half of the table. 155 * Second failure, rescan the other half of the table.
@@ -158,14 +164,7 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl,
158 } 164 }
159 } 165 }
160 166
161 for (i = n; i < end; i++) 167 end = n + npages;
162 if (test_bit(i, tbl->it_map)) {
163 start = i+1;
164 goto again;
165 }
166
167 for (i = n; i < end; i++)
168 __set_bit(i, tbl->it_map);
169 168
170 /* Bump the hint to a new block for small allocs. */ 169 /* Bump the hint to a new block for small allocs. */
171 if (largealloc) { 170 if (largealloc) {
@@ -184,16 +183,17 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl,
184 return n; 183 return n;
185} 184}
186 185
187static dma_addr_t iommu_alloc(struct iommu_table *tbl, void *page, 186static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl,
188 unsigned int npages, enum dma_data_direction direction, 187 void *page, unsigned int npages,
189 unsigned long mask, unsigned int align_order) 188 enum dma_data_direction direction,
189 unsigned long mask, unsigned int align_order)
190{ 190{
191 unsigned long entry, flags; 191 unsigned long entry, flags;
192 dma_addr_t ret = DMA_ERROR_CODE; 192 dma_addr_t ret = DMA_ERROR_CODE;
193 193
194 spin_lock_irqsave(&(tbl->it_lock), flags); 194 spin_lock_irqsave(&(tbl->it_lock), flags);
195 195
196 entry = iommu_range_alloc(tbl, npages, NULL, mask, align_order); 196 entry = iommu_range_alloc(dev, tbl, npages, NULL, mask, align_order);
197 197
198 if (unlikely(entry == DMA_ERROR_CODE)) { 198 if (unlikely(entry == DMA_ERROR_CODE)) {
199 spin_unlock_irqrestore(&(tbl->it_lock), flags); 199 spin_unlock_irqrestore(&(tbl->it_lock), flags);
@@ -224,7 +224,6 @@ static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
224 unsigned int npages) 224 unsigned int npages)
225{ 225{
226 unsigned long entry, free_entry; 226 unsigned long entry, free_entry;
227 unsigned long i;
228 227
229 entry = dma_addr >> IOMMU_PAGE_SHIFT; 228 entry = dma_addr >> IOMMU_PAGE_SHIFT;
230 free_entry = entry - tbl->it_offset; 229 free_entry = entry - tbl->it_offset;
@@ -246,9 +245,7 @@ static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
246 } 245 }
247 246
248 ppc_md.tce_free(tbl, entry, npages); 247 ppc_md.tce_free(tbl, entry, npages);
249 248 iommu_area_free(tbl->it_map, free_entry, npages);
250 for (i = 0; i < npages; i++)
251 __clear_bit(free_entry+i, tbl->it_map);
252} 249}
253 250
254static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, 251static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
@@ -270,16 +267,18 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
270 spin_unlock_irqrestore(&(tbl->it_lock), flags); 267 spin_unlock_irqrestore(&(tbl->it_lock), flags);
271} 268}
272 269
273int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist, 270int iommu_map_sg(struct device *dev, struct scatterlist *sglist,
274 int nelems, unsigned long mask, 271 int nelems, unsigned long mask,
275 enum dma_data_direction direction) 272 enum dma_data_direction direction)
276{ 273{
274 struct iommu_table *tbl = dev->archdata.dma_data;
277 dma_addr_t dma_next = 0, dma_addr; 275 dma_addr_t dma_next = 0, dma_addr;
278 unsigned long flags; 276 unsigned long flags;
279 struct scatterlist *s, *outs, *segstart; 277 struct scatterlist *s, *outs, *segstart;
280 int outcount, incount, i; 278 int outcount, incount, i;
281 unsigned int align; 279 unsigned int align;
282 unsigned long handle; 280 unsigned long handle;
281 unsigned int max_seg_size;
283 282
284 BUG_ON(direction == DMA_NONE); 283 BUG_ON(direction == DMA_NONE);
285 284
@@ -298,6 +297,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
298 297
299 spin_lock_irqsave(&(tbl->it_lock), flags); 298 spin_lock_irqsave(&(tbl->it_lock), flags);
300 299
300 max_seg_size = dma_get_max_seg_size(dev);
301 for_each_sg(sglist, s, nelems, i) { 301 for_each_sg(sglist, s, nelems, i) {
302 unsigned long vaddr, npages, entry, slen; 302 unsigned long vaddr, npages, entry, slen;
303 303
@@ -314,7 +314,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
314 if (IOMMU_PAGE_SHIFT < PAGE_SHIFT && slen >= PAGE_SIZE && 314 if (IOMMU_PAGE_SHIFT < PAGE_SHIFT && slen >= PAGE_SIZE &&
315 (vaddr & ~PAGE_MASK) == 0) 315 (vaddr & ~PAGE_MASK) == 0)
316 align = PAGE_SHIFT - IOMMU_PAGE_SHIFT; 316 align = PAGE_SHIFT - IOMMU_PAGE_SHIFT;
317 entry = iommu_range_alloc(tbl, npages, &handle, 317 entry = iommu_range_alloc(dev, tbl, npages, &handle,
318 mask >> IOMMU_PAGE_SHIFT, align); 318 mask >> IOMMU_PAGE_SHIFT, align);
319 319
320 DBG(" - vaddr: %lx, size: %lx\n", vaddr, slen); 320 DBG(" - vaddr: %lx, size: %lx\n", vaddr, slen);
@@ -344,7 +344,8 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
344 /* We cannot merge if: 344 /* We cannot merge if:
345 * - allocated dma_addr isn't contiguous to previous allocation 345 * - allocated dma_addr isn't contiguous to previous allocation
346 */ 346 */
347 if (novmerge || (dma_addr != dma_next)) { 347 if (novmerge || (dma_addr != dma_next) ||
348 (outs->dma_length + s->length > max_seg_size)) {
348 /* Can't merge: create a new segment */ 349 /* Can't merge: create a new segment */
349 segstart = s; 350 segstart = s;
350 outcount++; 351 outcount++;
@@ -452,9 +453,6 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
452struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) 453struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
453{ 454{
454 unsigned long sz; 455 unsigned long sz;
455 unsigned long start_index, end_index;
456 unsigned long entries_per_4g;
457 unsigned long index;
458 static int welcomed = 0; 456 static int welcomed = 0;
459 struct page *page; 457 struct page *page;
460 458
@@ -476,6 +474,7 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
476 474
477#ifdef CONFIG_CRASH_DUMP 475#ifdef CONFIG_CRASH_DUMP
478 if (ppc_md.tce_get) { 476 if (ppc_md.tce_get) {
477 unsigned long index;
479 unsigned long tceval; 478 unsigned long tceval;
480 unsigned long tcecount = 0; 479 unsigned long tcecount = 0;
481 480
@@ -506,23 +505,6 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
506 ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); 505 ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size);
507#endif 506#endif
508 507
509 /*
510 * DMA cannot cross 4 GB boundary. Mark last entry of each 4
511 * GB chunk as reserved.
512 */
513 if (protect4gb) {
514 entries_per_4g = 0x100000000l >> IOMMU_PAGE_SHIFT;
515
516 /* Mark the last bit before a 4GB boundary as used */
517 start_index = tbl->it_offset | (entries_per_4g - 1);
518 start_index -= tbl->it_offset;
519
520 end_index = tbl->it_size;
521
522 for (index = start_index; index < end_index - 1; index += entries_per_4g)
523 __set_bit(index, tbl->it_map);
524 }
525
526 if (!welcomed) { 508 if (!welcomed) {
527 printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", 509 printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n",
528 novmerge ? "disabled" : "enabled"); 510 novmerge ? "disabled" : "enabled");
@@ -570,9 +552,9 @@ void iommu_free_table(struct iommu_table *tbl, const char *node_name)
570 * need not be page aligned, the dma_addr_t returned will point to the same 552 * need not be page aligned, the dma_addr_t returned will point to the same
571 * byte within the page as vaddr. 553 * byte within the page as vaddr.
572 */ 554 */
573dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, 555dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl,
574 size_t size, unsigned long mask, 556 void *vaddr, size_t size, unsigned long mask,
575 enum dma_data_direction direction) 557 enum dma_data_direction direction)
576{ 558{
577 dma_addr_t dma_handle = DMA_ERROR_CODE; 559 dma_addr_t dma_handle = DMA_ERROR_CODE;
578 unsigned long uaddr; 560 unsigned long uaddr;
@@ -589,7 +571,7 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
589 ((unsigned long)vaddr & ~PAGE_MASK) == 0) 571 ((unsigned long)vaddr & ~PAGE_MASK) == 0)
590 align = PAGE_SHIFT - IOMMU_PAGE_SHIFT; 572 align = PAGE_SHIFT - IOMMU_PAGE_SHIFT;
591 573
592 dma_handle = iommu_alloc(tbl, vaddr, npages, direction, 574 dma_handle = iommu_alloc(dev, tbl, vaddr, npages, direction,
593 mask >> IOMMU_PAGE_SHIFT, align); 575 mask >> IOMMU_PAGE_SHIFT, align);
594 if (dma_handle == DMA_ERROR_CODE) { 576 if (dma_handle == DMA_ERROR_CODE) {
595 if (printk_ratelimit()) { 577 if (printk_ratelimit()) {
@@ -621,8 +603,9 @@ void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
621 * Returns the virtual address of the buffer and sets dma_handle 603 * Returns the virtual address of the buffer and sets dma_handle
622 * to the dma address (mapping) of the first page. 604 * to the dma address (mapping) of the first page.
623 */ 605 */
624void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, 606void *iommu_alloc_coherent(struct device *dev, struct iommu_table *tbl,
625 dma_addr_t *dma_handle, unsigned long mask, gfp_t flag, int node) 607 size_t size, dma_addr_t *dma_handle,
608 unsigned long mask, gfp_t flag, int node)
626{ 609{
627 void *ret = NULL; 610 void *ret = NULL;
628 dma_addr_t mapping; 611 dma_addr_t mapping;
@@ -656,7 +639,7 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
656 /* Set up tces to cover the allocated range */ 639 /* Set up tces to cover the allocated range */
657 nio_pages = size >> IOMMU_PAGE_SHIFT; 640 nio_pages = size >> IOMMU_PAGE_SHIFT;
658 io_order = get_iommu_order(size); 641 io_order = get_iommu_order(size);
659 mapping = iommu_alloc(tbl, ret, nio_pages, DMA_BIDIRECTIONAL, 642 mapping = iommu_alloc(dev, tbl, ret, nio_pages, DMA_BIDIRECTIONAL,
660 mask >> IOMMU_PAGE_SHIFT, io_order); 643 mask >> IOMMU_PAGE_SHIFT, io_order);
661 if (mapping == DMA_ERROR_CODE) { 644 if (mapping == DMA_ERROR_CODE) {
662 free_pages((unsigned long)ret, order); 645 free_pages((unsigned long)ret, order);