diff options
| -rw-r--r-- | arch/sparc64/kernel/iommu.c | 12 | ||||
| -rw-r--r-- | arch/sparc64/kernel/pci_sun4v.c | 15 |
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 | ||
| 478 | static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, | 478 | static 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 | ||
| 371 | static inline long fill_sg(long entry, struct device *dev, | 371 | static 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; |
