diff options
Diffstat (limited to 'arch/powerpc/kernel/iommu.c')
-rw-r--r-- | arch/powerpc/kernel/iommu.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 95edad4faf26..c50d7072f305 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c | |||
@@ -76,6 +76,7 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl, | |||
76 | unsigned int align_order) | 76 | unsigned int align_order) |
77 | { | 77 | { |
78 | unsigned long n, end, i, start; | 78 | unsigned long n, end, i, start; |
79 | unsigned long start_addr, end_addr; | ||
79 | unsigned long limit; | 80 | unsigned long limit; |
80 | int largealloc = npages > 15; | 81 | int largealloc = npages > 15; |
81 | int pass = 0; | 82 | int pass = 0; |
@@ -146,6 +147,15 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl, | |||
146 | } | 147 | } |
147 | } | 148 | } |
148 | 149 | ||
150 | /* DMA cannot cross 4 GB boundary */ | ||
151 | start_addr = (n + tbl->it_offset) << PAGE_SHIFT; | ||
152 | end_addr = (end + tbl->it_offset) << PAGE_SHIFT; | ||
153 | if ((start_addr >> 32) != (end_addr >> 32)) { | ||
154 | end_addr &= 0xffffffff00000000l; | ||
155 | start = (end_addr >> PAGE_SHIFT) - tbl->it_offset; | ||
156 | goto again; | ||
157 | } | ||
158 | |||
149 | for (i = n; i < end; i++) | 159 | for (i = n; i < end; i++) |
150 | if (test_bit(i, tbl->it_map)) { | 160 | if (test_bit(i, tbl->it_map)) { |
151 | start = i+1; | 161 | start = i+1; |