aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci_sun4v.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/pci_sun4v.c')
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c278
1 files changed, 144 insertions, 134 deletions
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index 61baf8dc095e..ddca6c6c0b49 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -1,6 +1,6 @@
1/* pci_sun4v.c: SUN4V specific PCI controller support. 1/* pci_sun4v.c: SUN4V specific PCI controller support.
2 * 2 *
3 * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net) 3 * Copyright (C) 2006, 2007, 2008 David S. Miller (davem@davemloft.net)
4 */ 4 */
5 5
6#include <linux/kernel.h> 6#include <linux/kernel.h>
@@ -89,6 +89,17 @@ static long iommu_batch_flush(struct iommu_batch *p)
89 return 0; 89 return 0;
90} 90}
91 91
92static inline void iommu_batch_new_entry(unsigned long entry)
93{
94 struct iommu_batch *p = &__get_cpu_var(iommu_batch);
95
96 if (p->entry + p->npages == entry)
97 return;
98 if (p->entry != ~0UL)
99 iommu_batch_flush(p);
100 p->entry = entry;
101}
102
92/* Interrupts must be disabled. */ 103/* Interrupts must be disabled. */
93static inline long iommu_batch_add(u64 phys_page) 104static inline long iommu_batch_add(u64 phys_page)
94{ 105{
@@ -113,54 +124,6 @@ static inline long iommu_batch_end(void)
113 return iommu_batch_flush(p); 124 return iommu_batch_flush(p);
114} 125}
115 126
116static long arena_alloc(struct iommu_arena *arena, unsigned long npages)
117{
118 unsigned long n, i, start, end, limit;
119 int pass;
120
121 limit = arena->limit;
122 start = arena->hint;
123 pass = 0;
124
125again:
126 n = find_next_zero_bit(arena->map, limit, start);
127 end = n + npages;
128 if (unlikely(end >= limit)) {
129 if (likely(pass < 1)) {
130 limit = start;
131 start = 0;
132 pass++;
133 goto again;
134 } else {
135 /* Scanned the whole thing, give up. */
136 return -1;
137 }
138 }
139
140 for (i = n; i < end; i++) {
141 if (test_bit(i, arena->map)) {
142 start = i + 1;
143 goto again;
144 }
145 }
146
147 for (i = n; i < end; i++)
148 __set_bit(i, arena->map);
149
150 arena->hint = end;
151
152 return n;
153}
154
155static void arena_free(struct iommu_arena *arena, unsigned long base,
156 unsigned long npages)
157{
158 unsigned long i;
159
160 for (i = base; i < (base + npages); i++)
161 __clear_bit(i, arena->map);
162}
163
164static void *dma_4v_alloc_coherent(struct device *dev, size_t size, 127static void *dma_4v_alloc_coherent(struct device *dev, size_t size,
165 dma_addr_t *dma_addrp, gfp_t gfp) 128 dma_addr_t *dma_addrp, gfp_t gfp)
166{ 129{
@@ -185,11 +148,11 @@ static void *dma_4v_alloc_coherent(struct device *dev, size_t size,
185 iommu = dev->archdata.iommu; 148 iommu = dev->archdata.iommu;
186 149
187 spin_lock_irqsave(&iommu->lock, flags); 150 spin_lock_irqsave(&iommu->lock, flags);
188 entry = arena_alloc(&iommu->arena, npages); 151 entry = iommu_range_alloc(dev, iommu, npages, NULL);
189 spin_unlock_irqrestore(&iommu->lock, flags); 152 spin_unlock_irqrestore(&iommu->lock, flags);
190 153
191 if (unlikely(entry < 0L)) 154 if (unlikely(entry == DMA_ERROR_CODE))
192 goto arena_alloc_fail; 155 goto range_alloc_fail;
193 156
194 *dma_addrp = (iommu->page_table_map_base + 157 *dma_addrp = (iommu->page_table_map_base +
195 (entry << IO_PAGE_SHIFT)); 158 (entry << IO_PAGE_SHIFT));
@@ -219,10 +182,10 @@ static void *dma_4v_alloc_coherent(struct device *dev, size_t size,
219iommu_map_fail: 182iommu_map_fail:
220 /* Interrupts are disabled. */ 183 /* Interrupts are disabled. */
221 spin_lock(&iommu->lock); 184 spin_lock(&iommu->lock);
222 arena_free(&iommu->arena, entry, npages); 185 iommu_range_free(iommu, *dma_addrp, npages);
223 spin_unlock_irqrestore(&iommu->lock, flags); 186 spin_unlock_irqrestore(&iommu->lock, flags);
224 187
225arena_alloc_fail: 188range_alloc_fail:
226 free_pages(first_page, order); 189 free_pages(first_page, order);
227 return NULL; 190 return NULL;
228} 191}
@@ -243,7 +206,7 @@ static void dma_4v_free_coherent(struct device *dev, size_t size, void *cpu,
243 206
244 spin_lock_irqsave(&iommu->lock, flags); 207 spin_lock_irqsave(&iommu->lock, flags);
245 208
246 arena_free(&iommu->arena, entry, npages); 209 iommu_range_free(iommu, dvma, npages);
247 210
248 do { 211 do {
249 unsigned long num; 212 unsigned long num;
@@ -281,10 +244,10 @@ static dma_addr_t dma_4v_map_single(struct device *dev, void *ptr, size_t sz,
281 npages >>= IO_PAGE_SHIFT; 244 npages >>= IO_PAGE_SHIFT;
282 245
283 spin_lock_irqsave(&iommu->lock, flags); 246 spin_lock_irqsave(&iommu->lock, flags);
284 entry = arena_alloc(&iommu->arena, npages); 247 entry = iommu_range_alloc(dev, iommu, npages, NULL);
285 spin_unlock_irqrestore(&iommu->lock, flags); 248 spin_unlock_irqrestore(&iommu->lock, flags);
286 249
287 if (unlikely(entry < 0L)) 250 if (unlikely(entry == DMA_ERROR_CODE))
288 goto bad; 251 goto bad;
289 252
290 bus_addr = (iommu->page_table_map_base + 253 bus_addr = (iommu->page_table_map_base +
@@ -319,7 +282,7 @@ bad:
319iommu_map_fail: 282iommu_map_fail:
320 /* Interrupts are disabled. */ 283 /* Interrupts are disabled. */
321 spin_lock(&iommu->lock); 284 spin_lock(&iommu->lock);
322 arena_free(&iommu->arena, entry, npages); 285 iommu_range_free(iommu, bus_addr, npages);
323 spin_unlock_irqrestore(&iommu->lock, flags); 286 spin_unlock_irqrestore(&iommu->lock, flags);
324 287
325 return DMA_ERROR_CODE; 288 return DMA_ERROR_CODE;
@@ -350,9 +313,9 @@ static void dma_4v_unmap_single(struct device *dev, dma_addr_t bus_addr,
350 313
351 spin_lock_irqsave(&iommu->lock, flags); 314 spin_lock_irqsave(&iommu->lock, flags);
352 315
353 entry = (bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT; 316 iommu_range_free(iommu, bus_addr, npages);
354 arena_free(&iommu->arena, entry, npages);
355 317
318 entry = (bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT;
356 do { 319 do {
357 unsigned long num; 320 unsigned long num;
358 321
@@ -368,88 +331,131 @@ static void dma_4v_unmap_single(struct device *dev, dma_addr_t bus_addr,
368static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, 331static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
369 int nelems, enum dma_data_direction direction) 332 int nelems, enum dma_data_direction direction)
370{ 333{
371 unsigned long flags, npages, i, prot; 334 struct scatterlist *s, *outs, *segstart;
372 struct scatterlist *sg; 335 unsigned long flags, handle, prot;
336 dma_addr_t dma_next = 0, dma_addr;
337 unsigned int max_seg_size;
338 int outcount, incount, i;
373 struct iommu *iommu; 339 struct iommu *iommu;
374 long entry, err; 340 long err;
375 u32 dma_base; 341
376 342 BUG_ON(direction == DMA_NONE);
377 /* Fast path single entry scatterlists. */
378 if (nelems == 1) {
379 sglist->dma_address =
380 dma_4v_map_single(dev, sg_virt(sglist),
381 sglist->length, direction);
382 if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
383 return 0;
384 sglist->dma_length = sglist->length;
385 return 1;
386 }
387 343
388 iommu = dev->archdata.iommu; 344 iommu = dev->archdata.iommu;
345 if (nelems == 0 || !iommu)
346 return 0;
389 347
390 if (unlikely(direction == DMA_NONE)) 348 prot = HV_PCI_MAP_ATTR_READ;
391 goto bad; 349 if (direction != DMA_TO_DEVICE)
392 350 prot |= HV_PCI_MAP_ATTR_WRITE;
393 npages = calc_npages(sglist, nelems);
394 351
395 spin_lock_irqsave(&iommu->lock, flags); 352 outs = s = segstart = &sglist[0];
396 entry = arena_alloc(&iommu->arena, npages); 353 outcount = 1;
397 spin_unlock_irqrestore(&iommu->lock, flags); 354 incount = nelems;
355 handle = 0;
398 356
399 if (unlikely(entry < 0L)) 357 /* Init first segment length for backout at failure */
400 goto bad; 358 outs->dma_length = 0;
401 359
402 dma_base = iommu->page_table_map_base + 360 spin_lock_irqsave(&iommu->lock, flags);
403 (entry << IO_PAGE_SHIFT);
404 361
405 prot = HV_PCI_MAP_ATTR_READ; 362 iommu_batch_start(dev, prot, ~0UL);
406 if (direction != DMA_TO_DEVICE)
407 prot |= HV_PCI_MAP_ATTR_WRITE;
408 363
409 local_irq_save(flags); 364 max_seg_size = dma_get_max_seg_size(dev);
365 for_each_sg(sglist, s, nelems, i) {
366 unsigned long paddr, npages, entry, slen;
410 367
411 iommu_batch_start(dev, prot, entry); 368 slen = s->length;
369 /* Sanity check */
370 if (slen == 0) {
371 dma_next = 0;
372 continue;
373 }
374 /* Allocate iommu entries for that segment */
375 paddr = (unsigned long) SG_ENT_PHYS_ADDRESS(s);
376 npages = iommu_num_pages(paddr, slen);
377 entry = iommu_range_alloc(dev, iommu, npages, &handle);
412 378
413 for_each_sg(sglist, sg, nelems, i) { 379 /* Handle failure */
414 unsigned long paddr = SG_ENT_PHYS_ADDRESS(sg); 380 if (unlikely(entry == DMA_ERROR_CODE)) {
415 unsigned long slen = sg->length; 381 if (printk_ratelimit())
416 unsigned long this_npages; 382 printk(KERN_INFO "iommu_alloc failed, iommu %p paddr %lx"
383 " npages %lx\n", iommu, paddr, npages);
384 goto iommu_map_failed;
385 }
417 386
418 this_npages = iommu_num_pages(paddr, slen); 387 iommu_batch_new_entry(entry);
419 388
420 sg->dma_address = dma_base | (paddr & ~IO_PAGE_MASK); 389 /* Convert entry to a dma_addr_t */
421 sg->dma_length = slen; 390 dma_addr = iommu->page_table_map_base +
391 (entry << IO_PAGE_SHIFT);
392 dma_addr |= (s->offset & ~IO_PAGE_MASK);
422 393
394 /* Insert into HW table */
423 paddr &= IO_PAGE_MASK; 395 paddr &= IO_PAGE_MASK;
424 while (this_npages--) { 396 while (npages--) {
425 err = iommu_batch_add(paddr); 397 err = iommu_batch_add(paddr);
426 if (unlikely(err < 0L)) { 398 if (unlikely(err < 0L))
427 local_irq_restore(flags);
428 goto iommu_map_failed; 399 goto iommu_map_failed;
400 paddr += IO_PAGE_SIZE;
401 }
402
403 /* If we are in an open segment, try merging */
404 if (segstart != s) {
405 /* We cannot merge if:
406 * - allocated dma_addr isn't contiguous to previous allocation
407 */
408 if ((dma_addr != dma_next) ||
409 (outs->dma_length + s->length > max_seg_size)) {
410 /* Can't merge: create a new segment */
411 segstart = s;
412 outcount++;
413 outs = sg_next(outs);
414 } else {
415 outs->dma_length += s->length;
429 } 416 }
417 }
430 418
431 paddr += IO_PAGE_SIZE; 419 if (segstart == s) {
432 dma_base += IO_PAGE_SIZE; 420 /* This is a new segment, fill entries */
421 outs->dma_address = dma_addr;
422 outs->dma_length = slen;
433 } 423 }
424
425 /* Calculate next page pointer for contiguous check */
426 dma_next = dma_addr + slen;
434 } 427 }
435 428
436 err = iommu_batch_end(); 429 err = iommu_batch_end();
437 430
438 local_irq_restore(flags);
439
440 if (unlikely(err < 0L)) 431 if (unlikely(err < 0L))
441 goto iommu_map_failed; 432 goto iommu_map_failed;
442 433
443 return nelems; 434 spin_unlock_irqrestore(&iommu->lock, flags);
444 435
445bad: 436 if (outcount < incount) {
446 if (printk_ratelimit()) 437 outs = sg_next(outs);
447 WARN_ON(1); 438 outs->dma_address = DMA_ERROR_CODE;
448 return 0; 439 outs->dma_length = 0;
440 }
441
442 return outcount;
449 443
450iommu_map_failed: 444iommu_map_failed:
451 spin_lock_irqsave(&iommu->lock, flags); 445 for_each_sg(sglist, s, nelems, i) {
452 arena_free(&iommu->arena, entry, npages); 446 if (s->dma_length != 0) {
447 unsigned long vaddr, npages;
448
449 vaddr = s->dma_address & IO_PAGE_MASK;
450 npages = iommu_num_pages(s->dma_address, s->dma_length);
451 iommu_range_free(iommu, vaddr, npages);
452 /* XXX demap? XXX */
453 s->dma_address = DMA_ERROR_CODE;
454 s->dma_length = 0;
455 }
456 if (s == outs)
457 break;
458 }
453 spin_unlock_irqrestore(&iommu->lock, flags); 459 spin_unlock_irqrestore(&iommu->lock, flags);
454 460
455 return 0; 461 return 0;
@@ -458,39 +464,43 @@ iommu_map_failed:
458static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist, 464static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist,
459 int nelems, enum dma_data_direction direction) 465 int nelems, enum dma_data_direction direction)
460{ 466{
461 unsigned long flags, npages;
462 struct pci_pbm_info *pbm; 467 struct pci_pbm_info *pbm;
463 u32 devhandle, bus_addr; 468 struct scatterlist *sg;
464 struct iommu *iommu; 469 struct iommu *iommu;
465 long entry; 470 unsigned long flags;
471 u32 devhandle;
466 472
467 if (unlikely(direction == DMA_NONE)) { 473 BUG_ON(direction == DMA_NONE);
468 if (printk_ratelimit())
469 WARN_ON(1);
470 }
471 474
472 iommu = dev->archdata.iommu; 475 iommu = dev->archdata.iommu;
473 pbm = dev->archdata.host_controller; 476 pbm = dev->archdata.host_controller;
474 devhandle = pbm->devhandle; 477 devhandle = pbm->devhandle;
475 478
476 bus_addr = sglist->dma_address & IO_PAGE_MASK;
477
478 npages = calc_npages(sglist, nelems);
479
480 entry = ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
481
482 spin_lock_irqsave(&iommu->lock, flags); 479 spin_lock_irqsave(&iommu->lock, flags);
483 480
484 arena_free(&iommu->arena, entry, npages); 481 sg = sglist;
485 482 while (nelems--) {
486 do { 483 dma_addr_t dma_handle = sg->dma_address;
487 unsigned long num; 484 unsigned int len = sg->dma_length;
485 unsigned long npages, entry;
486
487 if (!len)
488 break;
489 npages = iommu_num_pages(dma_handle, len);
490 iommu_range_free(iommu, dma_handle, npages);
491
492 entry = ((dma_handle - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
493 while (npages) {
494 unsigned long num;
495
496 num = pci_sun4v_iommu_demap(devhandle, HV_PCI_TSBID(0, entry),
497 npages);
498 entry += num;
499 npages -= num;
500 }
488 501
489 num = pci_sun4v_iommu_demap(devhandle, HV_PCI_TSBID(0, entry), 502 sg = sg_next(sg);
490 npages); 503 }
491 entry += num;
492 npages -= num;
493 } while (npages != 0);
494 504
495 spin_unlock_irqrestore(&iommu->lock, flags); 505 spin_unlock_irqrestore(&iommu->lock, flags);
496} 506}