diff options
Diffstat (limited to 'arch/x86/kernel/pci-dma_32.c')
-rw-r--r-- | arch/x86/kernel/pci-dma_32.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/arch/x86/kernel/pci-dma_32.c b/arch/x86/kernel/pci-dma_32.c index 5450bd142cb0..f134de3833a2 100644 --- a/arch/x86/kernel/pci-dma_32.c +++ b/arch/x86/kernel/pci-dma_32.c | |||
@@ -116,12 +116,42 @@ again: | |||
116 | gfp = (gfp & ~GFP_DMA32) | GFP_DMA; | 116 | gfp = (gfp & ~GFP_DMA32) | GFP_DMA; |
117 | goto again; | 117 | goto again; |
118 | } | 118 | } |
119 | |||
120 | /* Let low level make its own zone decisions */ | ||
121 | gfp &= ~(GFP_DMA32|GFP_DMA); | ||
122 | |||
123 | if (dma_ops->alloc_coherent) | ||
124 | return dma_ops->alloc_coherent(dev, size, | ||
125 | dma_handle, gfp); | ||
126 | return NULL; | ||
127 | |||
119 | } | 128 | } |
120 | memset(ret, 0, size); | 129 | memset(ret, 0, size); |
121 | *dma_handle = bus; | 130 | if (!mmu) { |
131 | *dma_handle = bus; | ||
132 | return ret; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | if (dma_ops->alloc_coherent) { | ||
137 | free_pages((unsigned long)ret, get_order(size)); | ||
138 | gfp &= ~(GFP_DMA|GFP_DMA32); | ||
139 | return dma_ops->alloc_coherent(dev, size, dma_handle, gfp); | ||
140 | } | ||
141 | |||
142 | if (dma_ops->map_simple) { | ||
143 | *dma_handle = dma_ops->map_simple(dev, virt_to_phys(ret), | ||
144 | size, | ||
145 | PCI_DMA_BIDIRECTIONAL); | ||
146 | if (*dma_handle != bad_dma_address) | ||
147 | return ret; | ||
122 | } | 148 | } |
123 | 149 | ||
124 | return ret; | 150 | if (panic_on_overflow) |
151 | panic("dma_alloc_coherent: IOMMU overflow by %lu bytes\n", | ||
152 | (unsigned long)size); | ||
153 | free_pages((unsigned long)ret, get_order(size)); | ||
154 | return NULL; | ||
125 | } | 155 | } |
126 | EXPORT_SYMBOL(dma_alloc_coherent); | 156 | EXPORT_SYMBOL(dma_alloc_coherent); |
127 | 157 | ||