patch-1.3.34 linux/drivers/sound/soundcard.c
Next file: linux/drivers/sound/soundvers.h
Previous file: linux/drivers/sound/sound_timer.c
Back to the patch index
Back to the overall index
- Lines: 929
- Date:
Wed Oct 11 07:55:42 1995
- Orig file:
v1.3.33/linux/drivers/sound/soundcard.c
- Orig date:
Tue Oct 10 18:46:37 1995
diff -u --recursive --new-file v1.3.33/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c
@@ -36,20 +36,36 @@
#include <linux/major.h>
-static int soundcards_installed = 0; /* Number of installed
+#ifndef EXCLUDE_PNP
+#include <linux/pnp.h>
+#endif
+
+static int soundcards_installed = 0; /* Number of installed cards */
+
+/*
+ * Table for permanently allocated memory (used when unloading the module)
+ */
+caddr_t sound_mem_blocks[1024];
+int sound_num_blocks = 0;
- * soundcards */
static int soundcard_configured = 0;
static struct fileinfo files[SND_NDEVS];
+static char dma_alloc_map[8] =
+{0};
+
+#define DMA_MAP_UNAVAIL 0
+#define DMA_MAP_FREE 1
+#define DMA_MAP_BUSY 2
+
int
snd_ioctl_return (int *addr, int value)
{
if (value < 0)
return value;
- PUT_WORD_TO_USER (addr, 0, value);
+ put_fs_long (value, (long *) &((addr)[0]));
return 0;
}
@@ -58,7 +74,8 @@
{
int dev;
- dev = MINOR(inode->i_rdev);
+ dev = inode->i_rdev;
+ dev = MINOR (dev);
return sound_read_sw (dev, &files[dev], buf, count);
}
@@ -68,12 +85,8 @@
{
int dev;
-#ifdef MODULE
- int err;
-
-#endif
-
- dev = MINOR(inode->i_rdev);
+ dev = inode->i_rdev;
+ dev = MINOR (dev);
return sound_write_sw (dev, &files[dev], buf, count);
}
@@ -81,7 +94,7 @@
static int
sound_lseek (struct inode *inode, struct file *file, off_t offset, int orig)
{
- return RET_ERROR (EPERM);
+ return -EPERM;
}
static int
@@ -90,12 +103,13 @@
int dev, retval;
struct fileinfo tmp_file;
- dev = MINOR(inode->i_rdev);
+ dev = inode->i_rdev;
+ dev = MINOR (dev);
if (!soundcard_configured && dev != SND_DEV_CTL && dev != SND_DEV_STATUS)
{
printk ("SoundCard Error: The soundcard system has not been configured\n");
- return RET_ERROR (ENXIO);
+ return -ENXIO;
}
tmp_file.mode = 0;
@@ -124,7 +138,8 @@
{
int dev;
- dev = MINOR(inode->i_rdev);
+ dev = inode->i_rdev;
+ dev = MINOR (dev);
sound_release_sw (dev, &files[dev]);
#ifdef MODULE
@@ -136,16 +151,37 @@
sound_ioctl (struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- int dev;
+ int dev, err;
+
+ dev = inode->i_rdev;
+ dev = MINOR (dev);
+
+ if (cmd == 1)
+ {
+ int i;
- dev = MINOR(inode->i_rdev);
+ unsigned char *p;
+
+
+ if (!audio_devs[dev >> 4]->dmap_out)
+ return 0;
+ if (!audio_devs[dev >> 4]->dmap_out->raw_buf)
+ return 0;
+
+ p = audio_devs[dev >> 4]->dmap_out->raw_buf;
+
+ for (i = 0; i < 256; i++)
+ printk ("%02x ", p[i]);
+ printk ("\n");
+ return 0;
+ }
if (cmd & IOC_INOUT)
{
/*
* Have to validate the address given by the process.
*/
- int len, err;
+ int len;
len = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
@@ -163,7 +199,9 @@
}
- return sound_ioctl_sw (dev, &files[dev], cmd, arg);
+ err = sound_ioctl_sw (dev, &files[dev], cmd, (caddr_t) arg);
+
+ return err;
}
static int
@@ -171,7 +209,8 @@
{
int dev;
- dev = MINOR(inode->i_rdev);
+ dev = inode->i_rdev;
+ dev = MINOR (dev);
DEB (printk ("sound_select(dev=%d, type=0x%x)\n", dev, sel_type));
@@ -205,6 +244,92 @@
return 0;
}
+static int
+sound_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma)
+{
+ int dev, dev_class;
+ unsigned long size;
+ struct dma_buffparms *dmap = NULL;
+
+ dev = inode->i_rdev;
+ dev = MINOR (dev);
+
+ dev_class = dev & 0x0f;
+ dev >>= 4;
+
+ if (dev_class != SND_DEV_DSP && dev_class != SND_DEV_DSP16 && dev_class != SND_DEV_AUDIO)
+ {
+ printk ("Sound: mmap() not supported for other than audio devices\n");
+ return -EINVAL;
+ }
+
+ if ((vma->vm_flags & (VM_READ | VM_WRITE)) == (VM_READ | VM_WRITE))
+ {
+ printk ("Sound: Cannot do read/write mmap()\n");
+ return -EINVAL;
+ }
+
+ if (vma->vm_flags & VM_READ)
+ {
+ dmap = audio_devs[dev]->dmap_in;
+ }
+ else if (vma->vm_flags & VM_WRITE)
+ {
+ dmap = audio_devs[dev]->dmap_out;
+ }
+ else
+ {
+ printk ("Sound: Undefined mmap() access\n");
+ return -EINVAL;
+ }
+
+ if (dmap == NULL)
+ {
+ printk ("Sound: mmap() error. dmap == NULL\n");
+ return -EIO;
+ }
+
+ if (dmap->raw_buf == NULL)
+ {
+ printk ("Sound: mmap() called when raw_buf == NULL\n");
+ return -EIO;
+ }
+
+ if (dmap->mapping_flags)
+ {
+ printk ("Sound: mmap() called twice for the same DMA buffer\n");
+ return -EIO;
+ }
+
+ if (vma->vm_offset != 0)
+ {
+ printk ("Sound: mmap() offset must be 0.\n");
+ return -EINVAL;
+ }
+
+ size = vma->vm_end - vma->vm_start;
+
+ if (size != dmap->bytes_in_use)
+ {
+ printk ("Sound: mmap() size = %ld. Should be %d\n",
+ size, dmap->bytes_in_use);
+ }
+
+ if (remap_page_range (vma->vm_start, dmap->raw_buf_phys, vma->vm_end - vma->vm_start, vma->vm_page_prot))
+ return -EAGAIN;
+
+
+ vma->vm_inode = inode;
+ inode->i_count++;
+
+ dmap->mapping_flags |= DMA_MAP_MAPPED;
+
+ memset (dmap->raw_buf,
+ dmap->neutral_byte,
+ dmap->bytes_in_use);
+ return 0;
+}
+
static struct file_operations sound_fops =
{
sound_lseek,
@@ -213,12 +338,12 @@
NULL, /* sound_readdir */
sound_select,
sound_ioctl,
- NULL,
+ sound_mmap,
sound_open,
sound_release
};
-int
+void
soundcard_init (void)
{
#ifndef MODULE
@@ -227,39 +352,38 @@
soundcard_configured = 1;
- sndtable_init (); /* Initialize call tables and
- * detect cards */
+ sndtable_init (0); /* Initialize call tables and
+ * detect cards */
+#ifndef EXCLUDE_PNP
+ sound_pnp_init ();
+#endif
if (!(soundcards_installed = sndtable_get_cardcount ()))
- return 0; /* No cards detected */
+ return; /* No cards detected */
#ifndef EXCLUDE_AUDIO
if (num_audiodevs) /* Audio devices present */
{
- DMAbuf_init ();
- audio_init ();
+ DMAbuf_init (0);
+ audio_init (0);
}
#endif
#ifndef EXCLUDE_MIDI
if (num_midis)
- MIDIbuf_init ();
+ MIDIbuf_init (0);
#endif
#ifndef EXCLUDE_SEQUENCER
if (num_midis + num_synths)
- sequencer_init ();
+ sequencer_init (0);
#endif
- return 0;
}
-#ifdef MODULE
static unsigned long irqs = 0;
-void snd_release_irq (int);
-static int module_sound_mem_init (void);
-static void module_sound_mem_release (void);
+#ifdef MODULE
static void
free_all_irqs (void)
{
@@ -267,60 +391,56 @@
for (i = 0; i < 31; i++)
if (irqs & (1ul << i))
- snd_release_irq (i);
+ {
+ printk ("Sound warning: IRQ%d was left allocated. Fixed.\n", i);
+ snd_release_irq (i);
+ }
irqs = 0;
}
char kernel_version[] = UTS_RELEASE;
-static long memory_pool = 0;
-static int memsize = 70 * 1024;
+#endif
+
static int debugmem = 0; /* switched off by default */
+static int sound[20] =
+{0};
+
int
init_module (void)
{
- long lastbyte;
int err;
+ int ints[21];
+ int i;
+
+ /*
+ * "sound=" command line handling by Harald Milz.
+ */
+ i = 0;
+ while (i < 20 && sound[i])
+ ints[i + 1] = sound[i++];
+ ints[0] = i;
+
+ if (i)
+ sound_setup ("sound=", ints);
- printk ("sound: made modular by Peter Trattler (peter@sbox.tu-graz.ac.at)\n");
err = register_chrdev (SOUND_MAJOR, "sound", &sound_fops);
if (err)
{
printk ("sound: driver already loaded/included in kernel\n");
return err;
}
- memory_pool = (long) kmalloc (memsize, GFP_KERNEL);
- if (memory_pool == 0l)
- {
- unregister_chrdev (SOUND_MAJOR, "sound");
- return -ENOMEM;
- }
- lastbyte = soundcard_init (memory_pool);
- if (lastbyte > memory_pool + memsize)
- {
- printk ("sound: Not enough memory; use : 'insmod sound.o memsize=%ld'\n",
- lastbyte - memory_pool);
- kfree ((void *) memory_pool);
- unregister_chrdev (SOUND_MAJOR, "sound");
- free_all_irqs ();
- return -ENOMEM;
- }
- err = module_sound_mem_init ();
- if (err)
- {
- module_sound_mem_release ();
- kfree ((void *) memory_pool);
- unregister_chrdev (SOUND_MAJOR, "sound");
- free_all_irqs ();
- return err;
- }
- if (lastbyte < memory_pool + memsize)
- printk ("sound: (Suggestion) too much memory; use : 'insmod sound.o memsize=%ld'\n",
- lastbyte - memory_pool);
+
+ soundcard_init ();
+
+ if (sound_num_blocks >= 1024)
+ printk ("Sound warning: Deallocation table was too small.\n");
+
return 0;
}
+#ifdef MODULE
void
cleanup_module (void)
{
@@ -328,13 +448,31 @@
printk ("sound: module busy -- remove delayed\n");
else
{
- kfree ((void *) memory_pool);
+ int i;
+
unregister_chrdev (SOUND_MAJOR, "sound");
- free_all_irqs ();
- module_sound_mem_release ();
+
+ sound_stop_timer ();
+ sound_unload_drivers ();
+
+ for (i = 0; i < sound_num_blocks; i++)
+ kfree (sound_mem_blocks[i]);
+
+ free_all_irqs (); /* If something was left allocated by accident */
+
+ for (i = 0; i < 8; i++)
+ if (dma_alloc_map[i] != DMA_MAP_UNAVAIL)
+ {
+ printk ("Sound: Hmm, DMA%d was left allocated\n", i);
+ sound_free_dma (i);
+ }
+
+#ifndef EXCLUDE_PNP
+ sound_pnp_disconnect ();
+#endif
+
}
}
-
#endif
void
@@ -347,19 +485,17 @@
}
int
-snd_set_irq_handler (int interrupt_level, INT_HANDLER_PROTO (), char *name)
+snd_set_irq_handler (int interrupt_level, void (*hndlr) (int, struct pt_regs *), char *name, sound_os_info * osp)
{
int retcode;
- retcode = request_irq (interrupt_level, hndlr, SA_INTERRUPT, name);
+ retcode = request_irq (interrupt_level, hndlr, 0 /* SA_INTERRUPT */ , name);
if (retcode < 0)
{
printk ("Sound: IRQ%d already in use\n", interrupt_level);
}
-#ifdef MODULE
else
irqs |= (1ul << interrupt_level);
-#endif
return retcode;
}
@@ -367,19 +503,79 @@
void
snd_release_irq (int vect)
{
-#ifdef MODULE
irqs &= ~(1ul << vect);
-#endif
free_irq (vect);
}
+int
+sound_alloc_dma (int chn, char *deviceID)
+{
+ int err;
+
+ if ((err = request_dma (chn, deviceID)) != 0)
+ return err;
+
+ dma_alloc_map[chn] = DMA_MAP_FREE;
+
+ return 0;
+}
+
+int
+sound_open_dma (int chn, char *deviceID)
+{
+ unsigned long flags;
+
+ save_flags (flags);
+ cli ();
+
+ if (dma_alloc_map[chn] != DMA_MAP_FREE)
+ {
+ printk ("sound_open_dma: DMA channel %d busy or not allocated\n", chn);
+ restore_flags (flags);
+ return 1;
+ }
+
+ dma_alloc_map[chn] = DMA_MAP_BUSY;
+ restore_flags (flags);
+ return 0;
+}
+
+void
+sound_free_dma (int chn)
+{
+ if (dma_alloc_map[chn] != DMA_MAP_FREE)
+ {
+ printk ("sound_free_dma: Bad access to DMA channel %d\n", chn);
+ return;
+ }
+ free_dma (chn);
+ dma_alloc_map[chn] = DMA_MAP_UNAVAIL;
+}
+
+void
+sound_close_dma (int chn)
+{
+ unsigned long flags;
+
+ save_flags (flags);
+ cli ();
+
+ if (dma_alloc_map[chn] != DMA_MAP_BUSY)
+ {
+ printk ("sound_close_dma: Bad access to DMA channel %d\n", chn);
+ restore_flags (flags);
+ return;
+ }
+ dma_alloc_map[chn] = DMA_MAP_FREE;
+ restore_flags (flags);
+}
+
#ifndef EXCLUDE_SEQUENCER
void
request_sound_timer (int count)
{
extern unsigned long seq_time;
-#if 1
if (count < 0)
count = jiffies + (-count);
else
@@ -387,7 +583,6 @@
timer_table[SOUND_TIMER].fn = sequencer_timer;
timer_table[SOUND_TIMER].expires = count;
timer_active |= 1 << SOUND_TIMER;
-#endif
}
#endif
@@ -395,264 +590,150 @@
void
sound_stop_timer (void)
{
-#if 1
timer_table[SOUND_TIMER].expires = 0;
timer_active &= ~(1 << SOUND_TIMER);
-#endif
}
#ifndef EXCLUDE_AUDIO
-static int
-valid_dma_page (unsigned long addr, unsigned long dev_buffsize, unsigned long dma_pagesize)
-{
- if (((addr & (dma_pagesize - 1)) + dev_buffsize) <= dma_pagesize)
- return 1;
- else
- return 0;
-}
-
-#ifdef MODULE
#ifdef KMALLOC_DMA_BROKEN
-#define KMALLOC_MEM_REGIONS 20
-
-static char *dma_list[KMALLOC_MEM_REGIONS];
-static int dma_last = 0;
-inline void
-add_to_dma_list (char *adr)
-{
- dma_list[dma_last++] = adr;
-}
-
+fatal_error__This_version_is_not_compatible_with_this_kernel;
#endif
-static int
-module_sound_mem_init (void)
+static int dma_buffsize = DSP_BUFFSIZE;
+
+int
+sound_alloc_dmap (int dev, struct dma_buffparms *dmap, int chan)
{
- 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++)
- if (audio_devs[dev]->buffcount > 0 && audio_devs[dev]->dmachan >= 0)
- {
- dmap = audio_devs[dev]->dmap;
- if (audio_devs[dev]->flags & DMA_AUTOMODE)
- audio_devs[dev]->buffcount = 1;
-
- if (audio_devs[dev]->dmachan > 3)
- dma_pagesize = 131072; /* 16bit dma: 128k */
- else
- dma_pagesize = 65536; /* 8bit dma: 64k */
- if (debugmem)
- printk ("sound: dma-page-size %lu\n", dma_pagesize);
- /* More sanity checks */
-
- if (audio_devs[dev]->buffsize > dma_pagesize)
- audio_devs[dev]->buffsize = dma_pagesize;
- audio_devs[dev]->buffsize &= 0xfffff000; /* Truncate to n*4k */
- if (audio_devs[dev]->buffsize < 4096)
- audio_devs[dev]->buffsize = 4096;
- if (debugmem)
- printk ("sound: buffsize %lu\n", audio_devs[dev]->buffsize);
- /* Now allocate the buffers */
- for (dmap->raw_count = 0; dmap->raw_count < audio_devs[dev]->buffcount;
- dmap->raw_count++)
- {
-#ifdef KMALLOC_DMA_BROKEN
- start_addr = kmalloc (audio_devs[dev]->buffsize, GFP_KERNEL);
- if (start_addr)
- {
- if (debugmem)
- printk ("sound: trying 0x%lx for DMA\n", (long) start_addr);
- if (valid_dma_page ((unsigned long) start_addr,
- audio_devs[dev]->buffsize,
- dma_pagesize))
- add_to_dma_list (start_addr);
- else
- {
- kfree (start_addr);
- start_addr = kmalloc (audio_devs[dev]->buffsize * 2,
- GFP_KERNEL); /* what a waste :-( */
- if (start_addr)
- {
- if (debugmem)
- printk ("sound: failed; trying 0x%lx aligned to",
- (long) start_addr);
- add_to_dma_list (start_addr);
- /* now align it to the next dma-page boundary */
- start_addr = (char *) (((long) start_addr
- + dma_pagesize - 1)
- & ~(dma_pagesize - 1));
- if (debugmem)
- printk (" 0x%lx\n", (long) start_addr);
- }
- }
- }
-#else
- 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
- * ...->raw_buf [...] must be initilized
- * to valid values (at least to NULL)
- */
- else
- {
- /* make some checks */
- end_addr = start_addr + audio_devs[dev]->buffsize - 1;
- if (debugmem)
- printk ("sound: start 0x%lx, end 0x%lx\n",
- (long) start_addr, (long) end_addr);
- /* now check if it fits into the same dma-pagesize */
- if (((long) start_addr & ~(dma_pagesize - 1))
- != ((long) end_addr & ~(dma_pagesize - 1))
- || end_addr >= (char *) (16 * 1024 * 1024))
- {
- printk (
- "sound: kmalloc returned invalid address 0x%lx for %ld Bytes DMA-buffer\n",
- (long) start_addr,
- audio_devs[dev]->buffsize);
- ret = -EFAULT;
- }
- }
- dmap->raw_buf[dmap->raw_count] = start_addr;
- dmap->raw_buf_phys[dmap->raw_count] = (unsigned long) start_addr;
- }
- }
- return ret;
-}
+ int i, dma_pagesize;
-static void
-module_sound_mem_release (void)
-{
-#ifdef KMALLOC_DMA_BROKEN
- int i;
+ if (dmap->raw_buf != NULL)
+ return 0; /* Already done */
- for (i = 0; i < dma_last; i++)
- {
- if (debugmem)
- printk ("sound: freeing 0x%lx\n", (long) dma_list[i]);
- kfree (dma_list[i]);
- }
-#else
- int dev, i;
- int order, size;
+ if (dma_buffsize < 4096)
+ dma_buffsize = 4096;
- 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++)
- if (audio_devs[dev]->dmap->raw_buf[i])
- {
- if (debugmem)
- printk ("sound: freeing 0x%lx\n",
- (long) (audio_devs[dev]->dmap->raw_buf[i]));
- free_pages((unsigned long) audio_devs[dev]->dmap->raw_buf[i],
- order);
- }
- }
- }
-#endif
-}
+ if (chan < 4)
+ dma_pagesize = 64 * 1024;
+ else
+ dma_pagesize = 128 * 1024;
-#else /* !MODULE */
+ dmap->raw_buf = NULL;
-void
-sound_mem_init (void)
-{
- int i, dev;
- unsigned long start_addr, end_addr, mem_ptr, dma_pagesize;
- struct dma_buffparms *dmap;
+ if (debugmem)
+ printk ("sound: buffsize%d %lu\n", dev, audio_devs[dev]->buffsize);
- mem_ptr = high_memory;
+ audio_devs[dev]->buffsize = dma_buffsize;
- /* Some sanity checks */
+ if (audio_devs[dev]->buffsize > dma_pagesize)
+ audio_devs[dev]->buffsize = dma_pagesize;
- if (mem_ptr > (16 * 1024 * 1024))
- mem_ptr = 16 * 1024 * 1024; /* Limit to 16M */
+ start_addr = NULL;
- for (dev = 0; dev < num_audiodevs; dev++) /* Enumerate devices */
- if (audio_devs[dev]->buffcount > 0 && audio_devs[dev]->dmachan >= 0)
- {
- dmap = audio_devs[dev]->dmap;
+/*
+ * Now loop until we get a free buffer. Try to get smaller buffer if
+ * it fails.
+ */
- if (audio_devs[dev]->flags & DMA_AUTOMODE)
- audio_devs[dev]->buffcount = 1;
+ while (start_addr == NULL && audio_devs[dev]->buffsize > PAGE_SIZE)
+ {
+ int sz, size;
- if (audio_devs[dev]->dmachan > 3 && audio_devs[dev]->buffsize > 65536)
- dma_pagesize = 131072; /* 128k */
- else
- dma_pagesize = 65536;
+ for (sz = 0, size = PAGE_SIZE;
+ size < audio_devs[dev]->buffsize;
+ sz++, size <<= 1);
- /* More sanity checks */
+ audio_devs[dev]->buffsize = PAGE_SIZE * (1 << sz);
- if (audio_devs[dev]->buffsize > dma_pagesize)
- audio_devs[dev]->buffsize = dma_pagesize;
- audio_devs[dev]->buffsize &= 0xfffff000; /* Truncate to n*4k */
- if (audio_devs[dev]->buffsize < 4096)
- audio_devs[dev]->buffsize = 4096;
+ if ((start_addr = (char *) __get_free_pages (GFP_ATOMIC, sz, MAX_DMA_ADDRESS)) == NULL)
+ audio_devs[dev]->buffsize /= 2;
+ }
- /* Now allocate the buffers */
+ if (start_addr == NULL)
+ {
+ printk ("Sound error: Couldn't allocate DMA buffer\n");
+ return -ENOMEM;
+ }
+ else
+ {
+ /* make some checks */
+ end_addr = start_addr + audio_devs[dev]->buffsize - 1;
- for (dmap->raw_count = 0; dmap->raw_count < audio_devs[dev]->buffcount; dmap->raw_count++)
- {
- start_addr = mem_ptr - audio_devs[dev]->buffsize;
- if (!valid_dma_page (start_addr, audio_devs[dev]->buffsize, dma_pagesize))
- start_addr &= ~(dma_pagesize - 1); /* Align address to
- * dma_pagesize */
-
- end_addr = start_addr + audio_devs[dev]->buffsize - 1;
-
- dmap->raw_buf[dmap->raw_count] = (char *) start_addr;
- dmap->raw_buf_phys[dmap->raw_count] = start_addr;
- mem_ptr = start_addr;
-
- for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
- {
- if (mem_map[i].reserved || mem_map[i].count)
- panic ("sound_mem_init: Page not free (driver incompatible with kernel).\n");
+ if (debugmem)
+ printk ("sound: start 0x%lx, end 0x%lx\n",
+ (long) start_addr, (long) end_addr);
- mem_map[i].reserved = 1;
- }
- }
- } /* for dev */
-}
+ /* now check if it fits into the same dma-pagesize */
-#endif /* !MODULE */
+ if (((long) start_addr & ~(dma_pagesize - 1))
+ != ((long) end_addr & ~(dma_pagesize - 1))
+ || end_addr >= (char *) (16 * 1024 * 1024))
+ {
+ printk (
+ "sound: kmalloc returned invalid address 0x%lx for %ld Bytes DMA-buffer\n",
+ (long) start_addr,
+ audio_devs[dev]->buffsize);
+ return -EFAULT;
+ }
+ }
+ dmap->raw_buf = start_addr;
+ dmap->raw_buf_phys = (unsigned long) start_addr;
+ for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
+ {
+#ifdef MAP_PAGE_RESERVED
+ mem_map[i] |= MAP_PAGE_RESERVED;
+#else
+ mem_map[i].reserved = 1;
#endif
+ }
-#else
+ return 0;
+}
-long
-soundcard_init (long mem_start) /* Dummy version */
+void
+sound_free_dmap (int dev, struct dma_buffparms *dmap)
{
- return mem_start;
-}
+ if (dmap->raw_buf == NULL)
+ return;
+ {
+ int sz, size, i;
+ unsigned long start_addr, end_addr;
+
+ for (sz = 0, size = PAGE_SIZE;
+ size < audio_devs[dev]->buffsize;
+ sz++, size <<= 1);
+ start_addr = (unsigned long) dmap->raw_buf;
+ end_addr = start_addr + audio_devs[dev]->buffsize;
+
+ for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
+ {
+#ifdef MAP_PAGE_RESERVED
+ mem_map[i] &= ~MAP_PAGE_RESERVED;
+#else
+ mem_map[i].reserved = 0;
#endif
+ }
+ free_pages ((unsigned long) dmap->raw_buf, sz);
+ }
+ dmap->raw_buf = NULL;
+}
-#if !defined(CONFIGURE_SOUNDCARD) || defined(EXCLUDE_AUDIO)
-void
-sound_mem_init (void)
+int
+soud_map_buffer (int dev, struct dma_buffparms *dmap, buffmem_desc * info)
{
- /* Dummy version */
+ printk ("Entered sound_map_buffer()\n");
+ printk ("Exited sound_map_buffer()\n");
+ return -EINVAL;
}
-#ifdef MODULE
-static int
-module_sound_mem_init (void)
+#else
+
+void
+soundcard_init (void) /* Dummy version */
{
- return 0; /* no error */
}
#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this