x86/PCI: fix broken ISA DMA
Rene Herman reported:
> commit 8779f2fc3b
>
> "x86: don't try to allocate from DMA zone at first"
>
> breaks all of ISA DMA. Or all of ALSA ISA DMA at least. All
> ISA soundcards are silent following that commit -- no error
> messages, everything appears fine, just silence.
That patch is buggy. We had an implicit assumption that
dev = NULL for ISA devices that require 24bit DMA.
The recent work on x86 dma_alloc_coherent() breaks the ISA DMA buffer
allocation, which is represented by "dev = NULL" and requires 24bit
DMA implicitly.
Bisected-by: Rene Herman <rene.herman@keyaccess.nl>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
This commit is contained in:
Родитель
21e2b0a5ef
Коммит
4a367f3a9d
|
@ -385,11 +385,13 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
|
||||||
if (dma_alloc_from_coherent_mem(dev, size, dma_handle, &memory))
|
if (dma_alloc_from_coherent_mem(dev, size, dma_handle, &memory))
|
||||||
return memory;
|
return memory;
|
||||||
|
|
||||||
if (!dev)
|
if (!dev) {
|
||||||
dev = &fallback_dev;
|
dev = &fallback_dev;
|
||||||
|
gfp |= GFP_DMA;
|
||||||
|
}
|
||||||
dma_mask = dev->coherent_dma_mask;
|
dma_mask = dev->coherent_dma_mask;
|
||||||
if (dma_mask == 0)
|
if (dma_mask == 0)
|
||||||
dma_mask = DMA_32BIT_MASK;
|
dma_mask = (gfp & GFP_DMA) ? DMA_24BIT_MASK : DMA_32BIT_MASK;
|
||||||
|
|
||||||
/* Device not DMA able */
|
/* Device not DMA able */
|
||||||
if (dev->dma_mask == NULL)
|
if (dev->dma_mask == NULL)
|
||||||
|
@ -403,7 +405,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
|
||||||
larger than 16MB and in this case we have a chance of
|
larger than 16MB and in this case we have a chance of
|
||||||
finding fitting memory in the next higher zone first. If
|
finding fitting memory in the next higher zone first. If
|
||||||
not retry with true GFP_DMA. -AK */
|
not retry with true GFP_DMA. -AK */
|
||||||
if (dma_mask <= DMA_32BIT_MASK)
|
if (dma_mask <= DMA_32BIT_MASK && !(gfp & GFP_DMA))
|
||||||
gfp |= GFP_DMA32;
|
gfp |= GFP_DMA32;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче