|
@@ -76,6 +76,7 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl,
|
|
unsigned int align_order)
|
|
unsigned int align_order)
|
|
{
|
|
{
|
|
unsigned long n, end, i, start;
|
|
unsigned long n, end, i, start;
|
|
|
|
+ unsigned long start_addr, end_addr;
|
|
unsigned long limit;
|
|
unsigned long limit;
|
|
int largealloc = npages > 15;
|
|
int largealloc = npages > 15;
|
|
int pass = 0;
|
|
int pass = 0;
|
|
@@ -146,6 +147,15 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /* DMA cannot cross 4 GB boundary */
|
|
|
|
+ start_addr = (n + tbl->it_offset) << PAGE_SHIFT;
|
|
|
|
+ end_addr = (end + tbl->it_offset) << PAGE_SHIFT;
|
|
|
|
+ if ((start_addr >> 32) != (end_addr >> 32)) {
|
|
|
|
+ end_addr &= 0xffffffff00000000l;
|
|
|
|
+ start = (end_addr >> PAGE_SHIFT) - tbl->it_offset;
|
|
|
|
+ goto again;
|
|
|
|
+ }
|
|
|
|
+
|
|
for (i = n; i < end; i++)
|
|
for (i = n; i < end; i++)
|
|
if (test_bit(i, tbl->it_map)) {
|
|
if (test_bit(i, tbl->it_map)) {
|
|
start = i+1;
|
|
start = i+1;
|