diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2007-10-17 07:08:48 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2007-10-17 07:11:59 -0400 |
commit | 5804509e652fd26227f6da732d5445af444730d3 (patch) | |
tree | 2d518870a85913d0a3483eecadbc07be85e9a2cf /arch/sparc64/kernel/pci_sun4v.c | |
parent | 60573b874b03d22678614ca1e73f6b15c1b53b40 (diff) |
Fix loop terminating conditions in fill_sg().
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'arch/sparc64/kernel/pci_sun4v.c')
-rw-r--r-- | arch/sparc64/kernel/pci_sun4v.c | 15 |
1 files changed, 8 insertions, 7 deletions
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; |