The kernel sound drivers have been module-aware for a while now, but
the make config still doesn't know about it. The small patch below
makes the sound driver a tristate option so that it can be selected as
a module at config-time.
There was another problem with the old module code: it relied on being
able to obtain a large DMA buffer via kmalloc(), but kmalloc has a
small overhead in the blocks it allocates. If you specified a DMA
buffer size of 65536 for the sound driver as a module, kmalloc
wouldn't satisfy it and the driver failed to load. A DMA buffer of
32768 worked fine. This doesn't affect a sound driver compiled into
the kernel, since in that situation the driver reserves its memory in
a different manner.
Anyway, I've also done a quick patch to replace the module's default
kmalloc()/kfree() calls with __get_free_pages()/freepages(), and the
resulting module seems to be working fine with 64K DMA buffers.
Cheers,
Stephen.
-- Stephen Tweedie <sct@dcs.ed.ac.uk> Department of Computer Science, Edinburgh University, Scotland. ---------------------------------------------------------------- --- Makefile.~1~ Thu Sep 14 13:02:37 1995 +++ Makefile Thu Sep 14 14:22:43 1995 @@ -97,7 +97,7 @@ DRIVERS := $(DRIVERS) drivers/scsi/scsi.a endif -ifdef CONFIG_SOUND +ifeq ($(CONFIG_SOUND),y) DRIVERS := $(DRIVERS) drivers/sound/sound.a endif --- arch/i386/config.in.~1~ Mon Sep 11 12:05:02 1995 +++ arch/i386/config.in Thu Sep 14 12:21:17 1995 @@ -298,7 +298,7 @@ comment 'Sound' -bool 'Sound card support' CONFIG_SOUND n +tristate 'Sound card support' CONFIG_SOUND n comment 'Kernel hacking' --- drivers/Makefile.~1~ Thu Sep 7 13:16:15 1995 +++ drivers/Makefile Thu Sep 14 12:21:50 1995 @@ -20,11 +20,9 @@ MOD_SUB_DIRS += scsi endif -# I think this should have an else clause for modules, but the original -# makefile did not, so I am not adding it. -# -jln 12 Aug 1995 ifdef CONFIG_SOUND SUB_DIRS += sound +MOD_SUB_DIRS += sound endif include $(TOPDIR)/Rules.make --- drivers/sound/Makefile.~1~ Thu Sep 7 13:16:24 1995 +++ drivers/sound/Makefile Thu Sep 14 14:00:12 1995 @@ -17,7 +17,13 @@ sys_timer.o ics2101.o ad1848.o pss.o sscape.o trix.o aedsp16.o \ mad16.o +# Don't compile the sound driver during a normal kernel build if we have +# configured for a module build instead. +ifeq ($(CONFIG_SOUND),y) all: local.h sound.a +else +all: +endif sound.a: $(OBJS) -rm -f sound.a --- drivers/sound/soundcard.c.~1~ Mon Aug 7 14:37:23 1995 +++ drivers/sound/soundcard.c Thu Sep 14 15:07:36 1995 @@ -438,6 +438,7 @@ int dev, ret = 0; unsigned long dma_pagesize; char *start_addr, *end_addr; + int order, size; struct dma_buffparms *dmap; for (dev = 0; dev < num_audiodevs; dev++) @@ -497,8 +498,10 @@ } } #else - start_addr = kmalloc (audio_devs[dev]->buffsize, - GFP_DMA | GFP_KERNEL); + for (order = 0, size = PAGE_SIZE; + size < audio_devs[dev]->buffsize; + order++, size <<= 1); + start_addr = (char *) __get_free_pages(GFP_KERNEL, order, MAX_DMA_ADDRESS); #endif if (start_addr == NULL) ret = -ENOMEM; /* Can't stop the loop in this case, because @@ -545,8 +548,12 @@ } #else int dev, i; + int order, size; - for (dev = 0; dev < num_audiodevs; dev++) + for (dev = 0; dev < num_audiodevs; dev++) { + for (order = 0, size = PAGE_SIZE; + size < audio_devs[dev]->buffsize; + order++, size <<= 1); if (audio_devs[dev]->buffcount > 0 && audio_devs[dev]->dmachan >= 0) { for (i = 0; i < audio_devs[dev]->buffcount; i++) @@ -555,9 +562,11 @@ if (debugmem) printk ("sound: freeing 0x%lx\n", (long) (audio_devs[dev]->dmap->raw_buf[i])); - kfree (audio_devs[dev]->dmap->raw_buf[i]); + free_pages((unsigned long) audio_devs[dev]->dmap->raw_buf[i], + order); } } + } #endif } --- scripts/Configure.~1~ Thu Sep 7 13:17:26 1995 +++ scripts/Configure Thu Sep 14 12:35:31 1995 @@ -248,9 +248,9 @@ fi . $CONFIG_IN -if [ "$CONFIG_SOUND" = "y" ] ; then - $MAKE -C drivers/sound config || exit 1 -fi +case "$CONFIG_SOUND" in + [YyMm] ) $MAKE -C drivers/sound config || exit 1 ;; +esac rm -f .config.old if [ -f .config ]; then