aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/iommu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/iommu.c')
-rw-r--r--arch/sparc64/kernel/iommu.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
index db3ffcf7a120..29af777d7ac9 100644
--- a/arch/sparc64/kernel/iommu.c
+++ b/arch/sparc64/kernel/iommu.c
@@ -10,7 +10,6 @@
10#include <linux/device.h> 10#include <linux/device.h>
11#include <linux/dma-mapping.h> 11#include <linux/dma-mapping.h>
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/scatterlist.h>
14 13
15#ifdef CONFIG_PCI 14#ifdef CONFIG_PCI
16#include <linux/pci.h> 15#include <linux/pci.h>
@@ -476,12 +475,11 @@ static void dma_4u_unmap_single(struct device *dev, dma_addr_t bus_addr,
476#define SG_ENT_PHYS_ADDRESS(SG) \ 475#define SG_ENT_PHYS_ADDRESS(SG) \
477 (__pa(page_address((SG)->page)) + (SG)->offset) 476 (__pa(page_address((SG)->page)) + (SG)->offset)
478 477
479static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, 478static void fill_sg(iopte_t *iopte, struct scatterlist *sg,
480 int nused, int nelems, 479 int nused, int nelems,
481 unsigned long iopte_protection) 480 unsigned long iopte_protection)
482{ 481{
483 struct scatterlist *dma_sg = sg; 482 struct scatterlist *dma_sg = sg;
484 struct scatterlist *sg_end = sg_last(sg, nelems);
485 int i; 483 int i;
486 484
487 for (i = 0; i < nused; i++) { 485 for (i = 0; i < nused; i++) {
@@ -517,6 +515,7 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg,
517 break; 515 break;
518 } 516 }
519 sg = sg_next(sg); 517 sg = sg_next(sg);
518 nelems--;
520 } 519 }
521 520
522 pteval = iopte_protection | (pteval & IOPTE_PAGE); 521 pteval = iopte_protection | (pteval & IOPTE_PAGE);
@@ -530,18 +529,20 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg,
530 529
531 pteval = (pteval & IOPTE_PAGE) + len; 530 pteval = (pteval & IOPTE_PAGE) + len;
532 sg = sg_next(sg); 531 sg = sg_next(sg);
532 nelems--;
533 533
534 /* Skip over any tail mappings we've fully mapped, 534 /* Skip over any tail mappings we've fully mapped,
535 * adjusting pteval along the way. Stop when we 535 * adjusting pteval along the way. Stop when we
536 * detect a page crossing event. 536 * detect a page crossing event.
537 */ 537 */
538 while (sg != sg_end && 538 while (nelems &&
539 (pteval << (64 - IO_PAGE_SHIFT)) != 0UL && 539 (pteval << (64 - IO_PAGE_SHIFT)) != 0UL &&
540 (pteval == SG_ENT_PHYS_ADDRESS(sg)) && 540 (pteval == SG_ENT_PHYS_ADDRESS(sg)) &&
541 ((pteval ^ 541 ((pteval ^
542 (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) { 542 (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) {
543 pteval += sg->length; 543 pteval += sg->length;
544 sg = sg_next(sg); 544 sg = sg_next(sg);
545 nelems--;
545 } 546 }
546 if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL) 547 if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL)
547 pteval = ~0UL; 548 pteval = ~0UL;