diff options
| -rw-r--r-- | arch/x86/kernel/pci-gart_64.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index cdab67849074..4d8efb05428d 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c | |||
| @@ -82,7 +82,8 @@ AGPEXTERN __u32 *agp_gatt_table; | |||
| 82 | static unsigned long next_bit; /* protected by iommu_bitmap_lock */ | 82 | static unsigned long next_bit; /* protected by iommu_bitmap_lock */ |
| 83 | static int need_flush; /* global flush state. set for each gart wrap */ | 83 | static int need_flush; /* global flush state. set for each gart wrap */ |
| 84 | 84 | ||
| 85 | static unsigned long alloc_iommu(struct device *dev, int size) | 85 | static unsigned long alloc_iommu(struct device *dev, int size, |
| 86 | unsigned long align_mask) | ||
| 86 | { | 87 | { |
| 87 | unsigned long offset, flags; | 88 | unsigned long offset, flags; |
| 88 | unsigned long boundary_size; | 89 | unsigned long boundary_size; |
| @@ -95,11 +96,12 @@ static unsigned long alloc_iommu(struct device *dev, int size) | |||
| 95 | 96 | ||
| 96 | spin_lock_irqsave(&iommu_bitmap_lock, flags); | 97 | spin_lock_irqsave(&iommu_bitmap_lock, flags); |
| 97 | offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, next_bit, | 98 | offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, next_bit, |
| 98 | size, base_index, boundary_size, 0); | 99 | size, base_index, boundary_size, align_mask); |
| 99 | if (offset == -1) { | 100 | if (offset == -1) { |
| 100 | need_flush = 1; | 101 | need_flush = 1; |
| 101 | offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, 0, | 102 | offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, 0, |
| 102 | size, base_index, boundary_size, 0); | 103 | size, base_index, boundary_size, |
| 104 | align_mask); | ||
| 103 | } | 105 | } |
| 104 | if (offset != -1) { | 106 | if (offset != -1) { |
| 105 | next_bit = offset+size; | 107 | next_bit = offset+size; |
| @@ -236,10 +238,10 @@ nonforced_iommu(struct device *dev, unsigned long addr, size_t size) | |||
| 236 | * Caller needs to check if the iommu is needed and flush. | 238 | * Caller needs to check if the iommu is needed and flush. |
| 237 | */ | 239 | */ |
| 238 | static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, | 240 | static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, |
| 239 | size_t size, int dir) | 241 | size_t size, int dir, unsigned long align_mask) |
| 240 | { | 242 | { |
| 241 | unsigned long npages = iommu_num_pages(phys_mem, size); | 243 | unsigned long npages = iommu_num_pages(phys_mem, size); |
| 242 | unsigned long iommu_page = alloc_iommu(dev, npages); | 244 | unsigned long iommu_page = alloc_iommu(dev, npages, align_mask); |
| 243 | int i; | 245 | int i; |
| 244 | 246 | ||
| 245 | if (iommu_page == -1) { | 247 | if (iommu_page == -1) { |
| @@ -262,7 +264,11 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, | |||
| 262 | static dma_addr_t | 264 | static dma_addr_t |
| 263 | gart_map_simple(struct device *dev, phys_addr_t paddr, size_t size, int dir) | 265 | gart_map_simple(struct device *dev, phys_addr_t paddr, size_t size, int dir) |
| 264 | { | 266 | { |
| 265 | dma_addr_t map = dma_map_area(dev, paddr, size, dir); | 267 | dma_addr_t map; |
| 268 | unsigned long align_mask; | ||
| 269 | |||
| 270 | align_mask = (1UL << get_order(size)) - 1; | ||
| 271 | map = dma_map_area(dev, paddr, size, dir, align_mask); | ||
| 266 | 272 | ||
| 267 | flush_gart(); | 273 | flush_gart(); |
| 268 | 274 | ||
| @@ -281,7 +287,8 @@ gart_map_single(struct device *dev, phys_addr_t paddr, size_t size, int dir) | |||
| 281 | if (!need_iommu(dev, paddr, size)) | 287 | if (!need_iommu(dev, paddr, size)) |
| 282 | return paddr; | 288 | return paddr; |
| 283 | 289 | ||
| 284 | bus = gart_map_simple(dev, paddr, size, dir); | 290 | bus = dma_map_area(dev, paddr, size, dir, 0); |
| 291 | flush_gart(); | ||
| 285 | 292 | ||
| 286 | return bus; | 293 | return bus; |
| 287 | } | 294 | } |
| @@ -340,7 +347,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg, | |||
| 340 | unsigned long addr = sg_phys(s); | 347 | unsigned long addr = sg_phys(s); |
| 341 | 348 | ||
| 342 | if (nonforced_iommu(dev, addr, s->length)) { | 349 | if (nonforced_iommu(dev, addr, s->length)) { |
| 343 | addr = dma_map_area(dev, addr, s->length, dir); | 350 | addr = dma_map_area(dev, addr, s->length, dir, 0); |
| 344 | if (addr == bad_dma_address) { | 351 | if (addr == bad_dma_address) { |
| 345 | if (i > 0) | 352 | if (i > 0) |
| 346 | gart_unmap_sg(dev, sg, i, dir); | 353 | gart_unmap_sg(dev, sg, i, dir); |
| @@ -362,7 +369,7 @@ static int __dma_map_cont(struct device *dev, struct scatterlist *start, | |||
| 362 | int nelems, struct scatterlist *sout, | 369 | int nelems, struct scatterlist *sout, |
| 363 | unsigned long pages) | 370 | unsigned long pages) |
| 364 | { | 371 | { |
| 365 | unsigned long iommu_start = alloc_iommu(dev, pages); | 372 | unsigned long iommu_start = alloc_iommu(dev, pages, 0); |
| 366 | unsigned long iommu_page = iommu_start; | 373 | unsigned long iommu_page = iommu_start; |
| 367 | struct scatterlist *s; | 374 | struct scatterlist *s; |
| 368 | int i; | 375 | int i; |
