aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@huronp11.davemloft.net>2008-02-06 06:50:26 -0500
committerDavid S. Miller <davem@davemloft.net>2008-02-06 07:12:25 -0500
commit38192d52f159bc06b7f523800c10b583cdd661d5 (patch)
tree4cf695d583c0a657133642c0299cbfa536e25663
parentb3ff81dd8ae29ec431f6cc91aff601a51ef6fb8c (diff)
[SPARC64]: Temporarily remove IOMMU merging code.
Changeset fde6a3c82d67f592eb587be4d12222b0ae6d4321 ("iommu sg merging: sparc64: make iommu respect the segment size limits") broke sparc64 because whilst it added the segment limiting code to the first pass of SG mapping (in prepare_sg()) it did not add matching code to the second pass handling (in fill_sg()) As a result the two passes disagree where the segment boundaries should be, resulting in OOPSes, DMA corruption, and corrupted superblocks. Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/sparc64/kernel/Makefile2
-rw-r--r--arch/sparc64/kernel/iommu.c142
-rw-r--r--arch/sparc64/kernel/iommu_common.c248
-rw-r--r--arch/sparc64/kernel/iommu_common.h26
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c170
-rw-r--r--include/asm-sparc64/io.h2
6 files changed, 93 insertions, 497 deletions
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index ef50d217432f..4b78b24ef413 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -11,7 +11,7 @@ obj-y := process.o setup.o cpu.o idprom.o \
11 traps.o auxio.o una_asm.o sysfs.o iommu.o \ 11 traps.o auxio.o una_asm.o sysfs.o iommu.o \
12 irq.o ptrace.o time.o sys_sparc.o signal.o \ 12 irq.o ptrace.o time.o sys_sparc.o signal.o \
13 unaligned.o central.o pci.o starfire.o semaphore.o \ 13 unaligned.o central.o pci.o starfire.o semaphore.o \
14 power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \ 14 power.o sbus.o sparc64_ksyms.o chmc.o \
15 visemul.o prom.o of_device.o hvapi.o sstate.o mdesc.o 15 visemul.o prom.o of_device.o hvapi.o sstate.o mdesc.o
16 16
17obj-$(CONFIG_STACKTRACE) += stacktrace.o 17obj-$(CONFIG_STACKTRACE) += stacktrace.o
diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
index 4b9115a4d92e..5623a4d59dff 100644
--- a/arch/sparc64/kernel/iommu.c
+++ b/arch/sparc64/kernel/iommu.c
@@ -472,94 +472,15 @@ static void dma_4u_unmap_single(struct device *dev, dma_addr_t bus_addr,
472 spin_unlock_irqrestore(&iommu->lock, flags); 472 spin_unlock_irqrestore(&iommu->lock, flags);
473} 473}
474 474
475#define SG_ENT_PHYS_ADDRESS(SG) (__pa(sg_virt((SG))))
476
477static void fill_sg(iopte_t *iopte, struct scatterlist *sg,
478 int nused, int nelems,
479 unsigned long iopte_protection)
480{
481 struct scatterlist *dma_sg = sg;
482 int i;
483
484 for (i = 0; i < nused; i++) {
485 unsigned long pteval = ~0UL;
486 u32 dma_npages;
487
488 dma_npages = ((dma_sg->dma_address & (IO_PAGE_SIZE - 1UL)) +
489 dma_sg->dma_length +
490 ((IO_PAGE_SIZE - 1UL))) >> IO_PAGE_SHIFT;
491 do {
492 unsigned long offset;
493 signed int len;
494
495 /* If we are here, we know we have at least one
496 * more page to map. So walk forward until we
497 * hit a page crossing, and begin creating new
498 * mappings from that spot.
499 */
500 for (;;) {
501 unsigned long tmp;
502
503 tmp = SG_ENT_PHYS_ADDRESS(sg);
504 len = sg->length;
505 if (((tmp ^ pteval) >> IO_PAGE_SHIFT) != 0UL) {
506 pteval = tmp & IO_PAGE_MASK;
507 offset = tmp & (IO_PAGE_SIZE - 1UL);
508 break;
509 }
510 if (((tmp ^ (tmp + len - 1UL)) >> IO_PAGE_SHIFT) != 0UL) {
511 pteval = (tmp + IO_PAGE_SIZE) & IO_PAGE_MASK;
512 offset = 0UL;
513 len -= (IO_PAGE_SIZE - (tmp & (IO_PAGE_SIZE - 1UL)));
514 break;
515 }
516 sg = sg_next(sg);
517 nelems--;
518 }
519
520 pteval = iopte_protection | (pteval & IOPTE_PAGE);
521 while (len > 0) {
522 *iopte++ = __iopte(pteval);
523 pteval += IO_PAGE_SIZE;
524 len -= (IO_PAGE_SIZE - offset);
525 offset = 0;
526 dma_npages--;
527 }
528
529 pteval = (pteval & IOPTE_PAGE) + len;
530 sg = sg_next(sg);
531 nelems--;
532
533 /* Skip over any tail mappings we've fully mapped,
534 * adjusting pteval along the way. Stop when we
535 * detect a page crossing event.
536 */
537 while (nelems &&
538 (pteval << (64 - IO_PAGE_SHIFT)) != 0UL &&
539 (pteval == SG_ENT_PHYS_ADDRESS(sg)) &&
540 ((pteval ^
541 (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) {
542 pteval += sg->length;
543 sg = sg_next(sg);
544 nelems--;
545 }
546 if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL)
547 pteval = ~0UL;
548 } while (dma_npages != 0);
549 dma_sg = sg_next(dma_sg);
550 }
551}
552
553static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, 475static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
554 int nelems, enum dma_data_direction direction) 476 int nelems, enum dma_data_direction direction)
555{ 477{
556 struct iommu *iommu; 478 unsigned long flags, ctx, i, npages, iopte_protection;
479 struct scatterlist *sg;
557 struct strbuf *strbuf; 480 struct strbuf *strbuf;
558 unsigned long flags, ctx, npages, iopte_protection; 481 struct iommu *iommu;
559 iopte_t *base; 482 iopte_t *base;
560 u32 dma_base; 483 u32 dma_base;
561 struct scatterlist *sgtmp;
562 int used;
563 484
564 /* Fast path single entry scatterlists. */ 485 /* Fast path single entry scatterlists. */
565 if (nelems == 1) { 486 if (nelems == 1) {
@@ -578,11 +499,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
578 if (unlikely(direction == DMA_NONE)) 499 if (unlikely(direction == DMA_NONE))
579 goto bad_no_ctx; 500 goto bad_no_ctx;
580 501
581 /* Step 1: Prepare scatter list. */ 502 npages = calc_npages(sglist, nelems);
582
583 npages = prepare_sg(dev, sglist, nelems);
584
585 /* Step 2: Allocate a cluster and context, if necessary. */
586 503
587 spin_lock_irqsave(&iommu->lock, flags); 504 spin_lock_irqsave(&iommu->lock, flags);
588 505
@@ -599,18 +516,6 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
599 dma_base = iommu->page_table_map_base + 516 dma_base = iommu->page_table_map_base +
600 ((base - iommu->page_table) << IO_PAGE_SHIFT); 517 ((base - iommu->page_table) << IO_PAGE_SHIFT);
601 518
602 /* Step 3: Normalize DMA addresses. */
603 used = nelems;
604
605 sgtmp = sglist;
606 while (used && sgtmp->dma_length) {
607 sgtmp->dma_address += dma_base;
608 sgtmp = sg_next(sgtmp);
609 used--;
610 }
611 used = nelems - used;
612
613 /* Step 4: Create the mappings. */
614 if (strbuf->strbuf_enabled) 519 if (strbuf->strbuf_enabled)
615 iopte_protection = IOPTE_STREAMING(ctx); 520 iopte_protection = IOPTE_STREAMING(ctx);
616 else 521 else
@@ -618,13 +523,27 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
618 if (direction != DMA_TO_DEVICE) 523 if (direction != DMA_TO_DEVICE)
619 iopte_protection |= IOPTE_WRITE; 524 iopte_protection |= IOPTE_WRITE;
620 525
621 fill_sg(base, sglist, used, nelems, iopte_protection); 526 for_each_sg(sglist, sg, nelems, i) {
527 unsigned long paddr = SG_ENT_PHYS_ADDRESS(sg);
528 unsigned long slen = sg->length;
529 unsigned long this_npages;
622 530
623#ifdef VERIFY_SG 531 this_npages = iommu_num_pages(paddr, slen);
624 verify_sglist(sglist, nelems, base, npages);
625#endif
626 532
627 return used; 533 sg->dma_address = dma_base | (paddr & ~IO_PAGE_MASK);
534 sg->dma_length = slen;
535
536 paddr &= IO_PAGE_MASK;
537 while (this_npages--) {
538 iopte_val(*base) = iopte_protection | paddr;
539
540 base++;
541 paddr += IO_PAGE_SIZE;
542 dma_base += IO_PAGE_SIZE;
543 }
544 }
545
546 return nelems;
628 547
629bad: 548bad:
630 iommu_free_ctx(iommu, ctx); 549 iommu_free_ctx(iommu, ctx);
@@ -637,11 +556,10 @@ bad_no_ctx:
637static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist, 556static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist,
638 int nelems, enum dma_data_direction direction) 557 int nelems, enum dma_data_direction direction)
639{ 558{
640 struct iommu *iommu; 559 unsigned long flags, ctx, i, npages;
641 struct strbuf *strbuf; 560 struct strbuf *strbuf;
561 struct iommu *iommu;
642 iopte_t *base; 562 iopte_t *base;
643 unsigned long flags, ctx, i, npages;
644 struct scatterlist *sg, *sgprv;
645 u32 bus_addr; 563 u32 bus_addr;
646 564
647 if (unlikely(direction == DMA_NONE)) { 565 if (unlikely(direction == DMA_NONE)) {
@@ -654,15 +572,7 @@ static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist,
654 572
655 bus_addr = sglist->dma_address & IO_PAGE_MASK; 573 bus_addr = sglist->dma_address & IO_PAGE_MASK;
656 574
657 sgprv = NULL; 575 npages = calc_npages(sglist, nelems);
658 for_each_sg(sglist, sg, nelems, i) {
659 if (sg->dma_length == 0)
660 break;
661 sgprv = sg;
662 }
663
664 npages = (IO_PAGE_ALIGN(sgprv->dma_address + sgprv->dma_length) -
665 bus_addr) >> IO_PAGE_SHIFT;
666 576
667 base = iommu->page_table + 577 base = iommu->page_table +
668 ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT); 578 ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
diff --git a/arch/sparc64/kernel/iommu_common.c b/arch/sparc64/kernel/iommu_common.c
deleted file mode 100644
index 72a4acfe8c7b..000000000000
--- a/arch/sparc64/kernel/iommu_common.c
+++ /dev/null
@@ -1,248 +0,0 @@
1/* $Id: iommu_common.c,v 1.9 2001/12/17 07:05:09 davem Exp $
2 * iommu_common.c: UltraSparc SBUS/PCI common iommu code.
3 *
4 * Copyright (C) 1999 David S. Miller (davem@redhat.com)
5 */
6
7#include <linux/dma-mapping.h>
8#include "iommu_common.h"
9
10/* You are _strongly_ advised to enable the following debugging code
11 * any time you make changes to the sg code below, run it for a while
12 * with filesystems mounted read-only before buying the farm... -DaveM
13 */
14
15#ifdef VERIFY_SG
16static int verify_lengths(struct scatterlist *sglist, int nents, int npages)
17{
18 int sg_len, dma_len;
19 int i, pgcount;
20 struct scatterlist *sg;
21
22 sg_len = 0;
23 for_each_sg(sglist, sg, nents, i)
24 sg_len += sg->length;
25
26 dma_len = 0;
27 for_each_sg(sglist, sg, nents, i) {
28 if (!sg->dma_length)
29 break;
30 dma_len += sg->dma_length;
31 }
32
33 if (sg_len != dma_len) {
34 printk("verify_lengths: Error, different, sg[%d] dma[%d]\n",
35 sg_len, dma_len);
36 return -1;
37 }
38
39 pgcount = 0;
40 for_each_sg(sglist, sg, nents, i) {
41 unsigned long start, end;
42
43 if (!sg->dma_length)
44 break;
45
46 start = sg->dma_address;
47 start = start & IO_PAGE_MASK;
48
49 end = sg->dma_address + sg->dma_length;
50 end = (end + (IO_PAGE_SIZE - 1)) & IO_PAGE_MASK;
51
52 pgcount += ((end - start) >> IO_PAGE_SHIFT);
53 }
54
55 if (pgcount != npages) {
56 printk("verify_lengths: Error, page count wrong, "
57 "npages[%d] pgcount[%d]\n",
58 npages, pgcount);
59 return -1;
60 }
61
62 /* This test passes... */
63 return 0;
64}
65
66static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg, int nents, iopte_t **__iopte)
67{
68 struct scatterlist *sg = *__sg;
69 iopte_t *iopte = *__iopte;
70 u32 dlen = dma_sg->dma_length;
71 u32 daddr;
72 unsigned int sglen;
73 unsigned long sgaddr;
74
75 daddr = dma_sg->dma_address;
76 sglen = sg->length;
77 sgaddr = (unsigned long) sg_virt(sg);
78 while (dlen > 0) {
79 unsigned long paddr;
80
81 /* SG and DMA_SG must begin at the same sub-page boundary. */
82 if ((sgaddr & ~IO_PAGE_MASK) != (daddr & ~IO_PAGE_MASK)) {
83 printk("verify_one_map: Wrong start offset "
84 "sg[%08lx] dma[%08x]\n",
85 sgaddr, daddr);
86 nents = -1;
87 goto out;
88 }
89
90 /* Verify the IOPTE points to the right page. */
91 paddr = iopte_val(*iopte) & IOPTE_PAGE;
92 if ((paddr + PAGE_OFFSET) != (sgaddr & IO_PAGE_MASK)) {
93 printk("verify_one_map: IOPTE[%08lx] maps the "
94 "wrong page, should be [%08lx]\n",
95 iopte_val(*iopte), (sgaddr & IO_PAGE_MASK) - PAGE_OFFSET);
96 nents = -1;
97 goto out;
98 }
99
100 /* If this SG crosses a page, adjust to that next page
101 * boundary and loop.
102 */
103 if ((sgaddr & IO_PAGE_MASK) ^ ((sgaddr + sglen - 1) & IO_PAGE_MASK)) {
104 unsigned long next_page, diff;
105
106 next_page = (sgaddr + IO_PAGE_SIZE) & IO_PAGE_MASK;
107 diff = next_page - sgaddr;
108 sgaddr += diff;
109 daddr += diff;
110 sglen -= diff;
111 dlen -= diff;
112 if (dlen > 0)
113 iopte++;
114 continue;
115 }
116
117 /* SG wholly consumed within this page. */
118 daddr += sglen;
119 dlen -= sglen;
120
121 if (dlen > 0 && ((daddr & ~IO_PAGE_MASK) == 0))
122 iopte++;
123
124 sg = sg_next(sg);
125 if (--nents <= 0)
126 break;
127 sgaddr = (unsigned long) sg_virt(sg);
128 sglen = sg->length;
129 }
130 if (dlen < 0) {
131 /* Transfer overrun, big problems. */
132 printk("verify_one_map: Transfer overrun by %d bytes.\n",
133 -dlen);
134 nents = -1;
135 } else {
136 /* Advance to next dma_sg implies that the next iopte will
137 * begin it.
138 */
139 iopte++;
140 }
141
142out:
143 *__sg = sg;
144 *__iopte = iopte;
145 return nents;
146}
147
148static int verify_maps(struct scatterlist *sg, int nents, iopte_t *iopte)
149{
150 struct scatterlist *dma_sg = sg;
151 struct scatterlist *orig_dma_sg = dma_sg;
152 int orig_nents = nents;
153
154 for (;;) {
155 nents = verify_one_map(dma_sg, &sg, nents, &iopte);
156 if (nents <= 0)
157 break;
158 dma_sg = sg_next(dma_sg);
159 if (dma_sg->dma_length == 0)
160 break;
161 }
162
163 if (nents > 0) {
164 printk("verify_maps: dma maps consumed by some sgs remain (%d)\n",
165 nents);
166 return -1;
167 }
168
169 if (nents < 0) {
170 printk("verify_maps: Error, messed up mappings, "
171 "at sg %d dma_sg %d\n",
172 (int) (orig_nents + nents), (int) (dma_sg - orig_dma_sg));
173 return -1;
174 }
175
176 /* This test passes... */
177 return 0;
178}
179
180void verify_sglist(struct scatterlist *sglist, int nents, iopte_t *iopte, int npages)
181{
182 struct scatterlist *sg;
183
184 if (verify_lengths(sglist, nents, npages) < 0 ||
185 verify_maps(sglist, nents, iopte) < 0) {
186 int i;
187
188 printk("verify_sglist: Crap, messed up mappings, dumping, iodma at ");
189 printk("%016lx.\n", sglist->dma_address & IO_PAGE_MASK);
190
191 for_each_sg(sglist, sg, nents, i) {
192 printk("sg(%d): page_addr(%p) off(%x) length(%x) "
193 "dma_address[%016x] dma_length[%016x]\n",
194 i,
195 page_address(sg_page(sg)), sg->offset,
196 sg->length,
197 sg->dma_address, sg->dma_length);
198 }
199 }
200
201 /* Seems to be ok */
202}
203#endif
204
205unsigned long prepare_sg(struct device *dev, struct scatterlist *sg, int nents)
206{
207 struct scatterlist *dma_sg = sg;
208 unsigned long prev;
209 u32 dent_addr, dent_len;
210 unsigned int max_seg_size;
211
212 prev = (unsigned long) sg_virt(sg);
213 prev += (unsigned long) (dent_len = sg->length);
214 dent_addr = (u32) ((unsigned long)(sg_virt(sg)) & (IO_PAGE_SIZE - 1UL));
215 max_seg_size = dma_get_max_seg_size(dev);
216 while (--nents) {
217 unsigned long addr;
218
219 sg = sg_next(sg);
220 addr = (unsigned long) sg_virt(sg);
221 if (! VCONTIG(prev, addr) ||
222 dent_len + sg->length > max_seg_size) {
223 dma_sg->dma_address = dent_addr;
224 dma_sg->dma_length = dent_len;
225 dma_sg = sg_next(dma_sg);
226
227 dent_addr = ((dent_addr +
228 dent_len +
229 (IO_PAGE_SIZE - 1UL)) >> IO_PAGE_SHIFT);
230 dent_addr <<= IO_PAGE_SHIFT;
231 dent_addr += addr & (IO_PAGE_SIZE - 1UL);
232 dent_len = 0;
233 }
234 dent_len += sg->length;
235 prev = addr + sg->length;
236 }
237 dma_sg->dma_address = dent_addr;
238 dma_sg->dma_length = dent_len;
239
240 if (dma_sg != sg) {
241 dma_sg = sg_next(dma_sg);
242 dma_sg->dma_length = 0;
243 }
244
245 return ((unsigned long) dent_addr +
246 (unsigned long) dent_len +
247 (IO_PAGE_SIZE - 1UL)) >> IO_PAGE_SHIFT;
248}
diff --git a/arch/sparc64/kernel/iommu_common.h b/arch/sparc64/kernel/iommu_common.h
index a90d046e8024..4b5cafa2877a 100644
--- a/arch/sparc64/kernel/iommu_common.h
+++ b/arch/sparc64/kernel/iommu_common.h
@@ -30,6 +30,32 @@
30 */ 30 */
31#define IOMMU_PAGE_SHIFT 13 31#define IOMMU_PAGE_SHIFT 13
32 32
33#define SG_ENT_PHYS_ADDRESS(SG) (__pa(sg_virt((SG))))
34
35static inline unsigned long iommu_num_pages(unsigned long vaddr,
36 unsigned long slen)
37{
38 unsigned long npages;
39
40 npages = IO_PAGE_ALIGN(vaddr + slen) - (vaddr & IO_PAGE_MASK);
41 npages >>= IO_PAGE_SHIFT;
42
43 return npages;
44}
45
46static inline unsigned long calc_npages(struct scatterlist *sglist, int nelems)
47{
48 unsigned long i, npages = 0;
49 struct scatterlist *sg;
50
51 for_each_sg(sglist, sg, nelems, i) {
52 unsigned long paddr = SG_ENT_PHYS_ADDRESS(sg);
53 npages += iommu_num_pages(paddr, sg->length);
54 }
55
56 return npages;
57}
58
33/* You are _strongly_ advised to enable the following debugging code 59/* You are _strongly_ advised to enable the following debugging code
34 * any time you make changes to the sg code below, run it for a while 60 * any time you make changes to the sg code below, run it for a while
35 * with filesystems mounted read-only before buying the farm... -DaveM 61 * with filesystems mounted read-only before buying the farm... -DaveM
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index 5ea2eab1ccda..61baf8dc095e 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -365,113 +365,14 @@ static void dma_4v_unmap_single(struct device *dev, dma_addr_t bus_addr,
365 spin_unlock_irqrestore(&iommu->lock, flags); 365 spin_unlock_irqrestore(&iommu->lock, flags);
366} 366}
367 367
368#define SG_ENT_PHYS_ADDRESS(SG) (__pa(sg_virt((SG))))
369
370static long fill_sg(long entry, struct device *dev,
371 struct scatterlist *sg,
372 int nused, int nelems, unsigned long prot)
373{
374 struct scatterlist *dma_sg = sg;
375 unsigned long flags;
376 int i;
377
378 local_irq_save(flags);
379
380 iommu_batch_start(dev, prot, entry);
381
382 for (i = 0; i < nused; i++) {
383 unsigned long pteval = ~0UL;
384 u32 dma_npages;
385
386 dma_npages = ((dma_sg->dma_address & (IO_PAGE_SIZE - 1UL)) +
387 dma_sg->dma_length +
388 ((IO_PAGE_SIZE - 1UL))) >> IO_PAGE_SHIFT;
389 do {
390 unsigned long offset;
391 signed int len;
392
393 /* If we are here, we know we have at least one
394 * more page to map. So walk forward until we
395 * hit a page crossing, and begin creating new
396 * mappings from that spot.
397 */
398 for (;;) {
399 unsigned long tmp;
400
401 tmp = SG_ENT_PHYS_ADDRESS(sg);
402 len = sg->length;
403 if (((tmp ^ pteval) >> IO_PAGE_SHIFT) != 0UL) {
404 pteval = tmp & IO_PAGE_MASK;
405 offset = tmp & (IO_PAGE_SIZE - 1UL);
406 break;
407 }
408 if (((tmp ^ (tmp + len - 1UL)) >> IO_PAGE_SHIFT) != 0UL) {
409 pteval = (tmp + IO_PAGE_SIZE) & IO_PAGE_MASK;
410 offset = 0UL;
411 len -= (IO_PAGE_SIZE - (tmp & (IO_PAGE_SIZE - 1UL)));
412 break;
413 }
414 sg = sg_next(sg);
415 nelems--;
416 }
417
418 pteval = (pteval & IOPTE_PAGE);
419 while (len > 0) {
420 long err;
421
422 err = iommu_batch_add(pteval);
423 if (unlikely(err < 0L))
424 goto iommu_map_failed;
425
426 pteval += IO_PAGE_SIZE;
427 len -= (IO_PAGE_SIZE - offset);
428 offset = 0;
429 dma_npages--;
430 }
431
432 pteval = (pteval & IOPTE_PAGE) + len;
433 sg = sg_next(sg);
434 nelems--;
435
436 /* Skip over any tail mappings we've fully mapped,
437 * adjusting pteval along the way. Stop when we
438 * detect a page crossing event.
439 */
440 while (nelems &&
441 (pteval << (64 - IO_PAGE_SHIFT)) != 0UL &&
442 (pteval == SG_ENT_PHYS_ADDRESS(sg)) &&
443 ((pteval ^
444 (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) {
445 pteval += sg->length;
446 sg = sg_next(sg);
447 nelems--;
448 }
449 if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL)
450 pteval = ~0UL;
451 } while (dma_npages != 0);
452 dma_sg = sg_next(dma_sg);
453 }
454
455 if (unlikely(iommu_batch_end() < 0L))
456 goto iommu_map_failed;
457
458 local_irq_restore(flags);
459 return 0;
460
461iommu_map_failed:
462 local_irq_restore(flags);
463 return -1L;
464}
465
466static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, 368static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
467 int nelems, enum dma_data_direction direction) 369 int nelems, enum dma_data_direction direction)
468{ 370{
371 unsigned long flags, npages, i, prot;
372 struct scatterlist *sg;
469 struct iommu *iommu; 373 struct iommu *iommu;
470 unsigned long flags, npages, prot;
471 u32 dma_base;
472 struct scatterlist *sgtmp;
473 long entry, err; 374 long entry, err;
474 int used; 375 u32 dma_base;
475 376
476 /* Fast path single entry scatterlists. */ 377 /* Fast path single entry scatterlists. */
477 if (nelems == 1) { 378 if (nelems == 1) {
@@ -489,10 +390,8 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
489 if (unlikely(direction == DMA_NONE)) 390 if (unlikely(direction == DMA_NONE))
490 goto bad; 391 goto bad;
491 392
492 /* Step 1: Prepare scatter list. */ 393 npages = calc_npages(sglist, nelems);
493 npages = prepare_sg(dev, sglist, nelems);
494 394
495 /* Step 2: Allocate a cluster and context, if necessary. */
496 spin_lock_irqsave(&iommu->lock, flags); 395 spin_lock_irqsave(&iommu->lock, flags);
497 entry = arena_alloc(&iommu->arena, npages); 396 entry = arena_alloc(&iommu->arena, npages);
498 spin_unlock_irqrestore(&iommu->lock, flags); 397 spin_unlock_irqrestore(&iommu->lock, flags);
@@ -503,27 +402,45 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
503 dma_base = iommu->page_table_map_base + 402 dma_base = iommu->page_table_map_base +
504 (entry << IO_PAGE_SHIFT); 403 (entry << IO_PAGE_SHIFT);
505 404
506 /* Step 3: Normalize DMA addresses. */
507 used = nelems;
508
509 sgtmp = sglist;
510 while (used && sgtmp->dma_length) {
511 sgtmp->dma_address += dma_base;
512 sgtmp = sg_next(sgtmp);
513 used--;
514 }
515 used = nelems - used;
516
517 /* Step 4: Create the mappings. */
518 prot = HV_PCI_MAP_ATTR_READ; 405 prot = HV_PCI_MAP_ATTR_READ;
519 if (direction != DMA_TO_DEVICE) 406 if (direction != DMA_TO_DEVICE)
520 prot |= HV_PCI_MAP_ATTR_WRITE; 407 prot |= HV_PCI_MAP_ATTR_WRITE;
521 408
522 err = fill_sg(entry, dev, sglist, used, nelems, prot); 409 local_irq_save(flags);
410
411 iommu_batch_start(dev, prot, entry);
412
413 for_each_sg(sglist, sg, nelems, i) {
414 unsigned long paddr = SG_ENT_PHYS_ADDRESS(sg);
415 unsigned long slen = sg->length;
416 unsigned long this_npages;
417
418 this_npages = iommu_num_pages(paddr, slen);
419
420 sg->dma_address = dma_base | (paddr & ~IO_PAGE_MASK);
421 sg->dma_length = slen;
422
423 paddr &= IO_PAGE_MASK;
424 while (this_npages--) {
425 err = iommu_batch_add(paddr);
426 if (unlikely(err < 0L)) {
427 local_irq_restore(flags);
428 goto iommu_map_failed;
429 }
430
431 paddr += IO_PAGE_SIZE;
432 dma_base += IO_PAGE_SIZE;
433 }
434 }
435
436 err = iommu_batch_end();
437
438 local_irq_restore(flags);
439
523 if (unlikely(err < 0L)) 440 if (unlikely(err < 0L))
524 goto iommu_map_failed; 441 goto iommu_map_failed;
525 442
526 return used; 443 return nelems;
527 444
528bad: 445bad:
529 if (printk_ratelimit()) 446 if (printk_ratelimit())
@@ -541,12 +458,11 @@ iommu_map_failed:
541static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist, 458static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist,
542 int nelems, enum dma_data_direction direction) 459 int nelems, enum dma_data_direction direction)
543{ 460{
461 unsigned long flags, npages;
544 struct pci_pbm_info *pbm; 462 struct pci_pbm_info *pbm;
463 u32 devhandle, bus_addr;
545 struct iommu *iommu; 464 struct iommu *iommu;
546 unsigned long flags, i, npages;
547 struct scatterlist *sg, *sgprv;
548 long entry; 465 long entry;
549 u32 devhandle, bus_addr;
550 466
551 if (unlikely(direction == DMA_NONE)) { 467 if (unlikely(direction == DMA_NONE)) {
552 if (printk_ratelimit()) 468 if (printk_ratelimit())
@@ -558,16 +474,8 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist,
558 devhandle = pbm->devhandle; 474 devhandle = pbm->devhandle;
559 475
560 bus_addr = sglist->dma_address & IO_PAGE_MASK; 476 bus_addr = sglist->dma_address & IO_PAGE_MASK;
561 sgprv = NULL;
562 for_each_sg(sglist, sg, nelems, i) {
563 if (sg->dma_length == 0)
564 break;
565
566 sgprv = sg;
567 }
568 477
569 npages = (IO_PAGE_ALIGN(sgprv->dma_address + sgprv->dma_length) - 478 npages = calc_npages(sglist, nelems);
570 bus_addr) >> IO_PAGE_SHIFT;
571 479
572 entry = ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT); 480 entry = ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
573 481
diff --git a/include/asm-sparc64/io.h b/include/asm-sparc64/io.h
index c299b853b5ba..b6ece223562d 100644
--- a/include/asm-sparc64/io.h
+++ b/include/asm-sparc64/io.h
@@ -16,7 +16,7 @@
16/* BIO layer definitions. */ 16/* BIO layer definitions. */
17extern unsigned long kern_base, kern_size; 17extern unsigned long kern_base, kern_size;
18#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) 18#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
19#define BIO_VMERGE_BOUNDARY 8192 19#define BIO_VMERGE_BOUNDARY 0
20 20
21static inline u8 _inb(unsigned long addr) 21static inline u8 _inb(unsigned long addr)
22{ 22{