diff options
Diffstat (limited to 'arch/x86_64/kernel/pci-gart.c')
-rw-r--r-- | arch/x86_64/kernel/pci-gart.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c index c37fc77..dd0718d 100644 --- a/arch/x86_64/kernel/pci-gart.c +++ b/arch/x86_64/kernel/pci-gart.c @@ -310,7 +310,7 @@ void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int di for (i = 0; i < nents; i++) { struct scatterlist *s = &sg[i]; - if (!s->dma_length || !s->length) + if (!s->dma_length) break; dma_unmap_single(dev, s->dma_address, s->dma_length, dir); } @@ -364,7 +364,6 @@ static int __dma_map_cont(struct scatterlist *sg, int start, int stopat, BUG_ON(i > start && s->offset); if (i == start) { - *sout = *s; sout->dma_address = iommu_bus_base; sout->dma_address += iommu_page*PAGE_SIZE + s->offset; sout->dma_length = s->length; @@ -379,7 +378,7 @@ static int __dma_map_cont(struct scatterlist *sg, int start, int stopat, SET_LEAK(iommu_page); addr += PAGE_SIZE; iommu_page++; - } + } } BUG_ON(iommu_page - iommu_start != pages); return 0; @@ -391,7 +390,6 @@ static inline int dma_map_cont(struct scatterlist *sg, int start, int stopat, { if (!need) { BUG_ON(stopat - start != 1); - *sout = sg[start]; sout->dma_length = sg[start].length; return 0; } @@ -457,9 +455,12 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) error: flush_gart(NULL); gart_unmap_sg(dev, sg, nents, dir); - /* When it was forced try again unforced */ - if (force_iommu) - return dma_map_sg_nonforce(dev, sg, nents, dir); + /* When it was forced or merged try again in a dumb way */ + if (force_iommu || iommu_merge) { + out = dma_map_sg_nonforce(dev, sg, nents, dir); + if (out > 0) + return out; + } if (panic_on_overflow) panic("dma_map_sg: overflow on %lu pages\n", pages); iommu_full(dev, pages << PAGE_SHIFT, dir); @@ -642,9 +643,18 @@ static int __init pci_iommu_init(void) (no_agp && init_k8_gatt(&info) < 0)) { no_iommu = 1; no_iommu_init(); + printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n"); + if (end_pfn > MAX_DMA32_PFN) { + printk(KERN_ERR "WARNING more than 4GB of memory " + "but IOMMU not compiled in.\n" + KERN_ERR "WARNING 32bit PCI may malfunction.\n" + KERN_ERR "You might want to enable " + "CONFIG_GART_IOMMU\n"); + } return -1; } + printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n"); aper_size = info.aper_size * 1024 * 1024; iommu_size = check_iommu_size(info.aper_base, aper_size); iommu_pages = iommu_size >> PAGE_SHIFT; @@ -718,7 +728,6 @@ static int __init pci_iommu_init(void) flush_gart(NULL); - printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n"); dma_ops = &gart_dma_ops; return 0; |