Messages in this thread Patch in this message |  | | | Subject | Re: Sound error: Couldn't allocate DMA buffer | | From | Mark Gray <> | | Date | 12 Apr 1999 09:08:07 -0400 |
| |
jumeaux lists <lists@jumeaux.bc.ca> writes: > > > > Hi there. I keep getting this sort of thing in my syslog when > > > something's trying to play through /dev/dsp: > > > > > > Apr 9 13:11:29 odin kernel: Sound error: Couldn't allocate DMA buffer > > > Apr 9 13:12:00 odin last message repeated 48 times > > > Apr 9 13:13:01 odin last message repeated 121 times > > > > You are out of big physically contigious blobs of memory under 16MBs for > > DMA buffers. You can put in dmabuf=1 as an option to sound.o or set a > > config param at compile time if you dont use modules. > > thanks - thought it might be something to do with fragmentation, but i > wasn't aware of the <16mb restrictions on isa cards. > > *but*, does this solution apply to kernel 2.0.36? i see it in the docs > for 2.2, but not 2.0, and when i try adding
I have a quick and dirty patch that I have been using for 2.0.36 since November without problems ("Haven't got sick once"). If anyone is going to use it, they should understand it first, then take out the debugging printk's when and if they get some confidence in it: (Notice I use dmahack=1 instead of 2.2.*'s dmabuf=1)
-------------------cut here---------------------- --- drivers/sound/soundcard.c.ORIG Wed Aug 21 02:18:09 1996 +++ drivers/sound/soundcard.c Wed Nov 25 12:16:58 1998 @@ -296,7 +296,7 @@ vma_set_inode (vma, inode); inode_inc_count (inode); - + printk (KERN_DEBUG "sound: mmap being done.\n"); dmap->mapping_flags |= DMA_MAP_MAPPED; memset (dmap->raw_buf, @@ -389,6 +389,14 @@ static int sound[20] = {0}; +static int dmahack = 0; /* Non-zero to hold onto dma buffer */ + +static struct { + char *buf; + int buffsize; + int sz; +} dmasave = { NULL, 0, 0 }; /* If dmahack != 0 one dmabuffer saved here */ + int init_module (void) { @@ -470,6 +478,13 @@ sound_free_dma (i); } + if ( (dmahack != 0) && (dmasave.buf != NULL) ) + { + printk (KERN_DEBUG "sound: returning saved dma buffer at %p of size %u.\n", + dmasave.buf, dmasave.sz); + free_pages ((unsigned long) dmasave.buf, dmasave.sz); + dmasave.buf = NULL; /* better safe than sorry */ + } } #endif @@ -633,6 +648,20 @@ if (dmap->raw_buf != NULL) return 0; /* Already done */ + /* + * Here we must decide to call __get_dma_pages to try to get a new buffer or + * reuse the buffer last saved by sound_free_dmap to address dmasave.buf + * iff dmahack != 0 + */ + if ( (dmahack != 0) && (dmasave.buf != NULL) ) + { + start_addr = dmasave.buf; + dmasave.buf = NULL; /* better safe than sorry */ + audio_devs[dev]->buffsize = dmasave.buffsize; + end_addr = start_addr + audio_devs[dev]->buffsize - 1; + goto gotbuffer; + } + if (dma_buffsize < 4096) dma_buffsize = 4096; @@ -667,11 +696,13 @@ sz++, size <<= 1); audio_devs[dev]->buffsize = PAGE_SIZE * (1 << sz); + printk (KERN_DEBUG "sound: Trying buffsize[%d] = %lu\n", dev, audio_devs[dev]->buffsize); if ((start_addr = (char *) __get_dma_pages (GFP_ATOMIC, sz)) == NULL) audio_devs[dev]->buffsize /= 2; } + printk (KERN_DEBUG "sound: Got buffer of %lu at %p\n", audio_devs[dev]->buffsize, start_addr); if (start_addr == NULL) { printk ("Sound error: Couldn't allocate DMA buffer\n"); @@ -699,6 +730,8 @@ return -(EFAULT); } } + + gotbuffer: dmap->raw_buf = start_addr; dmap->raw_buf_phys = virt_to_bus (start_addr); @@ -719,8 +752,10 @@ if (dmap->raw_buf == NULL) return; - if (dmap->mapping_flags & DMA_MAP_MAPPED) + if (dmap->mapping_flags & DMA_MAP_MAPPED) { + printk (KERN_DEBUG "sound: mmapped buffer at %p not returned.\n", dmap->raw_buf); return; /* Don't free mmapped buffer. Will use it next time */ + } for (sz = 0, size = PAGE_SIZE; size < audio_devs[dev]->buffsize; @@ -733,7 +768,21 @@ { mem_map_unreserve (i); } - + /* + * Here we must either free or keep the dma pages based on dmahack + * If dmahack is zero, really free now, otherwise save address to + * dmasave.buf for next call to sound_alloc_dmap iff dmahack != 0 + */ + if ( (dmahack != 0) && (dmasave.buf == NULL) ) + { + printk (KERN_DEBUG "sound: keeping buffer at %p of size %u.\n", dmap->raw_buf, sz); + dmasave.buf = dmap->raw_buf; + dmasave.buffsize = audio_devs[dev]->buffsize; + dmasave.sz = sz; + dmap->raw_buf = NULL; + return; + } + printk (KERN_DEBUG "sound: returning buffer at %p of size %u.\n", dmap->raw_buf, sz); free_pages ((unsigned long) dmap->raw_buf, sz); dmap->raw_buf = NULL; }
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
|  |