Commit 8965eb19 authored by Takashi Iwai's avatar Takashi Iwai Committed by Ingo Molnar

x86/pci: fix broken ISA DMA

Rene Herman reported:

> commit 8779f2fc
>
> "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: default avatarRene Herman <rene.herman@keyaccess.nl>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Tested-by: default avatarRene Herman <rene.herman@keyaccess.nl>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 492c2e47
...@@ -385,11 +385,13 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, ...@@ -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, ...@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment