aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64')
-rw-r--r--arch/sparc64/kernel/iommu.c12
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c15
2 files changed, 15 insertions, 12 deletions
diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
index 5d4e96dba412..29af777d7ac9 100644
--- a/arch/sparc64/kernel/iommu.c
+++ b/arch/sparc64/kernel/iommu.c
@@ -475,12 +475,11 @@ static void dma_4u_unmap_single(struct device *dev, dma_addr_t bus_addr,
475#define SG_ENT_PHYS_ADDRESS(SG) \ 475#define SG_ENT_PHYS_ADDRESS(SG) \
476 (__pa(page_address((SG)->page)) + (SG)->offset) 476 (__pa(page_address((SG)->page)) + (SG)->offset)
477 477
478static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, 478static void fill_sg(iopte_t *iopte, struct scatterlist *sg,
479 int nused, int nelems, 479 int nused, int nelems,
480 unsigned long iopte_protection) 480 unsigned long iopte_protection)
481{ 481{
482 struct scatterlist *dma_sg = sg; 482 struct scatterlist *dma_sg = sg;
483 struct scatterlist *sg_end = sg_last(sg, nelems);
484 int i; 483 int i;
485 484
486 for (i = 0; i < nused; i++) { 485 for (i = 0; i < nused; i++) {
@@ -516,6 +515,7 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg,
516 break; 515 break;
517 } 516 }
518 sg = sg_next(sg); 517 sg = sg_next(sg);
518 nelems--;
519 } 519 }
520 520
521 pteval = iopte_protection | (pteval & IOPTE_PAGE); 521 pteval = iopte_protection | (pteval & IOPTE_PAGE);
@@ -529,18 +529,20 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg,
529 529
530 pteval = (pteval & IOPTE_PAGE) + len; 530 pteval = (pteval & IOPTE_PAGE) + len;
531 sg = sg_next(sg); 531 sg = sg_next(sg);
532 nelems--;
532 533
533 /* Skip over any tail mappings we've fully mapped, 534 /* Skip over any tail mappings we've fully mapped,
534 * adjusting pteval along the way. Stop when we 535 * adjusting pteval along the way. Stop when we
535 * detect a page crossing event. 536 * detect a page crossing event.
536 */ 537 */
537 while (sg != sg_end && 538 while (nelems &&
538 (pteval << (64 - IO_PAGE_SHIFT)) != 0UL && 539 (pteval << (64 - IO_PAGE_SHIFT)) != 0UL &&
539 (pteval == SG_ENT_PHYS_ADDRESS(sg)) && 540 (pteval == SG_ENT_PHYS_ADDRESS(sg)) &&
540 ((pteval ^ 541 ((pteval ^
541 (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) {
542 pteval += sg->length; 543 pteval += sg->length;
543 sg = sg_next(sg); 544 sg = sg_next(sg);
545 nelems--;
544 } 546 }
545 if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL) 547 if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL)
546 pteval = ~0UL; 548 pteval = ~0UL;
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index 119f8efa03d2..fe46ace3e59f 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -368,12 +368,11 @@ static void dma_4v_unmap_single(struct device *dev, dma_addr_t bus_addr,
368#define SG_ENT_PHYS_ADDRESS(SG) \ 368#define SG_ENT_PHYS_ADDRESS(SG) \
369 (__pa(page_address((SG)->page)) + (SG)->offset) 369 (__pa(page_address((SG)->page)) + (SG)->offset)
370 370
371static inline long fill_sg(long entry, struct device *dev, 371static long fill_sg(long entry, struct device *dev,
372 struct scatterlist *sg, 372 struct scatterlist *sg,
373 int nused, int nelems, unsigned long prot) 373 int nused, int nelems, unsigned long prot)
374{ 374{
375 struct scatterlist *dma_sg = sg; 375 struct scatterlist *dma_sg = sg;
376 struct scatterlist *sg_end = sg_last(sg, nelems);
377 unsigned long flags; 376 unsigned long flags;
378 int i; 377 int i;
379 378
@@ -414,6 +413,7 @@ static inline long fill_sg(long entry, struct device *dev,
414 break; 413 break;
415 } 414 }
416 sg = sg_next(sg); 415 sg = sg_next(sg);
416 nelems--;
417 } 417 }
418 418
419 pteval = (pteval & IOPTE_PAGE); 419 pteval = (pteval & IOPTE_PAGE);
@@ -432,19 +432,20 @@ static inline long fill_sg(long entry, struct device *dev,
432 432
433 pteval = (pteval & IOPTE_PAGE) + len; 433 pteval = (pteval & IOPTE_PAGE) + len;
434 sg = sg_next(sg); 434 sg = sg_next(sg);
435 nelems--;
435 436
436 /* Skip over any tail mappings we've fully mapped, 437 /* Skip over any tail mappings we've fully mapped,
437 * adjusting pteval along the way. Stop when we 438 * adjusting pteval along the way. Stop when we
438 * detect a page crossing event. 439 * detect a page crossing event.
439 */ 440 */
440 while ((pteval << (64 - IO_PAGE_SHIFT)) != 0UL && 441 while (nelems &&
442 (pteval << (64 - IO_PAGE_SHIFT)) != 0UL &&
441 (pteval == SG_ENT_PHYS_ADDRESS(sg)) && 443 (pteval == SG_ENT_PHYS_ADDRESS(sg)) &&
442 ((pteval ^ 444 ((pteval ^
443 (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) { 445 (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) {
444 pteval += sg->length; 446 pteval += sg->length;
445 if (sg == sg_end)
446 break;
447 sg = sg_next(sg); 447 sg = sg_next(sg);
448 nelems--;
448 } 449 }
449 if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL) 450 if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL)
450 pteval = ~0UL; 451 pteval = ~0UL;