patch-2.1.88 linux/drivers/sound/soundcard.c
Next file: linux/drivers/sound/sscape.c
Previous file: linux/drivers/sound/sound_timer.c
Back to the patch index
Back to the overall index
- Lines: 581
- Date:
Thu Feb 19 14:46:15 1998
- Orig file:
v2.1.87/linux/drivers/sound/soundcard.c
- Orig date:
Thu Feb 12 20:56:10 1998
diff -u --recursive --new-file v2.1.87/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c
@@ -25,6 +25,8 @@
#include <linux/signal.h>
#include <linux/fcntl.h>
#include <linux/ctype.h>
+#include <linux/stddef.h>
+#include <linux/kerneld.h>
#ifdef __KERNEL__
#include <asm/io.h>
#include <asm/segment.h>
@@ -60,8 +62,6 @@
static int soundcard_configured = 0;
-static struct fileinfo files[SND_NDEVS];
-
static char dma_alloc_map[8] =
{0};
@@ -118,7 +118,9 @@
if (__copy_from_user(&buf, arg, sizeof(buf)))
return -EFAULT;
load_mixer_volumes(buf.name, buf.levels, 0);
- return __copy_to_user(arg, &buf, sizeof(buf));
+ if (__copy_to_user(arg, &buf, sizeof(buf)))
+ return -EFAULT;
+ return 0;
}
static int get_mixer_levels(caddr_t arg)
@@ -129,7 +131,9 @@
return -EFAULT;
if (n < 0 || n >= num_mixer_volumes)
return -EINVAL;
- return __copy_to_user(arg, &mixer_vols[n], sizeof(mixer_vol_table));
+ if (__copy_to_user(arg, &mixer_vols[n], sizeof(mixer_vol_table)))
+ return -EFAULT;
+ return 0;
}
static int sound_proc_get_info(char *buffer, char **start, off_t offset, int length, int inout)
@@ -351,7 +355,6 @@
{
int dev = MINOR(file->f_dentry->d_inode->i_rdev);
- files[dev].flags = file->f_flags;
DEB(printk("sound_read(dev=%d, count=%d)\n", dev, count));
switch (dev & 0x0f) {
case SND_DEV_STATUS:
@@ -361,18 +364,18 @@
case SND_DEV_DSP:
case SND_DEV_DSP16:
case SND_DEV_AUDIO:
- return audio_read(dev, &files[dev], buf, count);
+ return audio_read(dev, file, buf, count);
#endif
#ifdef CONFIG_SEQUENCER
case SND_DEV_SEQ:
case SND_DEV_SEQ2:
- return sequencer_read(dev, &files[dev], buf, count);
+ return sequencer_read(dev, file, buf, count);
#endif
#ifdef CONFIG_MIDI
case SND_DEV_MIDIN:
- return MIDIbuf_read(dev, &files[dev], buf, count);
+ return MIDIbuf_read(dev, file, buf, count);
#endif
default:;
@@ -384,25 +387,24 @@
{
int dev = MINOR(file->f_dentry->d_inode->i_rdev);
- files[dev].flags = file->f_flags;
DEB(printk("sound_write(dev=%d, count=%d)\n", dev, count));
switch (dev & 0x0f) {
#ifdef CONFIG_SEQUENCER
case SND_DEV_SEQ:
case SND_DEV_SEQ2:
- return sequencer_write(dev, &files[dev], buf, count);
+ return sequencer_write(dev, file, buf, count);
#endif
#ifdef CONFIG_AUDIO
case SND_DEV_DSP:
case SND_DEV_DSP16:
case SND_DEV_AUDIO:
- return audio_write(dev, &files[dev], buf, count);
+ return audio_write(dev, file, buf, count);
#endif
#ifdef CONFIG_MIDI
case SND_DEV_MIDIN:
- return MIDIbuf_write(dev, &files[dev], buf, count);
+ return MIDIbuf_write(dev, file, buf, count);
#endif
}
return -EINVAL;
@@ -416,7 +418,6 @@
static int sound_open(struct inode *inode, struct file *file)
{
int dev, retval;
- struct fileinfo tmp_file;
if (is_unloading) {
/* printk(KERN_ERR "Sound: Driver partially removed. Can't open device\n");*/
@@ -427,15 +428,6 @@
/* printk("SoundCard Error: The soundcard system has not been configured\n");*/
return -ENXIO;
}
- tmp_file.mode = 0;
- tmp_file.flags = file->f_flags;
-
- if ((tmp_file.flags & O_ACCMODE) == O_RDWR)
- tmp_file.mode = OPEN_READWRITE;
- if ((tmp_file.flags & O_ACCMODE) == O_RDONLY)
- tmp_file.mode = OPEN_READ;
- if ((tmp_file.flags & O_ACCMODE) == O_WRONLY)
- tmp_file.mode = OPEN_WRITE;
DEB(printk("sound_open(dev=%d)\n", dev));
if ((dev >= SND_NDEVS) || (dev < 0)) {
printk(KERN_ERR "Invalid minor device %d\n", dev);
@@ -446,21 +438,29 @@
break;
case SND_DEV_CTL:
- if ((dev & 0xf0) && ((dev & 0xf0) >> 4) >= num_mixers)
+ dev >>= 4;
+#ifdef CONFIG_KERNELD
+ if (dev >= 0 && dev < MAX_MIXER_DEV && mixer_devs[dev] == NULL) {
+ char modname[20];
+ sprintf(modname, "mixer%d", dev);
+ request_module(modname);
+ }
+#endif
+ if (dev && (dev >= num_mixers || mixer_devs[dev] == NULL))
return -ENXIO;
break;
#ifdef CONFIG_SEQUENCER
case SND_DEV_SEQ:
case SND_DEV_SEQ2:
- if ((retval = sequencer_open(dev, &tmp_file)) < 0)
+ if ((retval = sequencer_open(dev, file)) < 0)
return retval;
break;
#endif
#ifdef CONFIG_MIDI
case SND_DEV_MIDIN:
- if ((retval = MIDIbuf_open(dev, &tmp_file)) < 0)
+ if ((retval = MIDIbuf_open(dev, file)) < 0)
return retval;
break;
#endif
@@ -469,7 +469,7 @@
case SND_DEV_DSP:
case SND_DEV_DSP16:
case SND_DEV_AUDIO:
- if ((retval = audio_open(dev, &tmp_file)) < 0)
+ if ((retval = audio_open(dev, file)) < 0)
return retval;
break;
#endif
@@ -482,7 +482,6 @@
#ifdef MODULE
SOUND_INC_USE_COUNT;
#endif
- memcpy(&files[dev], &tmp_file, sizeof(tmp_file));
return 0;
}
@@ -490,7 +489,6 @@
{
int dev = MINOR(inode->i_rdev);
- files[dev].flags = file->f_flags;
DEB(printk("sound_release(dev=%d)\n", dev));
switch (dev & 0x0f) {
case SND_DEV_STATUS:
@@ -500,13 +498,13 @@
#ifdef CONFIG_SEQUENCER
case SND_DEV_SEQ:
case SND_DEV_SEQ2:
- sequencer_release(dev, &files[dev]);
+ sequencer_release(dev, file);
break;
#endif
#ifdef CONFIG_MIDI
case SND_DEV_MIDIN:
- MIDIbuf_release(dev, &files[dev]);
+ MIDIbuf_release(dev, file);
break;
#endif
@@ -514,7 +512,7 @@
case SND_DEV_DSP:
case SND_DEV_DSP16:
case SND_DEV_AUDIO:
- audio_release(dev, &files[dev]);
+ audio_release(dev, file);
break;
#endif
@@ -531,14 +529,10 @@
static int get_mixer_info(int dev, caddr_t arg)
{
mixer_info info;
- int i;
- if (dev < 0 || dev >= num_mixers)
- return -ENXIO;
- strcpy(info.id, mixer_devs[dev]->id);
- for (i = 0; i < 32 && mixer_devs[dev]->name; i++)
- info.name[i] = mixer_devs[dev]->name[i];
- info.name[i] = 0;
+ strncpy(info.id, mixer_devs[dev]->id, sizeof(info.id));
+ strncpy(info.name, mixer_devs[dev]->name, sizeof(info.name));
+ info.name[sizeof(info.name)-1] = 0;
info.modify_counter = mixer_devs[dev]->modify_counter;
if (__copy_to_user(arg, &info, sizeof(info)))
return -EFAULT;
@@ -548,21 +542,29 @@
static int get_old_mixer_info(int dev, caddr_t arg)
{
_old_mixer_info info;
- int i;
- if (dev < 0 || dev >= num_mixers)
- return -ENXIO;
- strcpy(info.id, mixer_devs[dev]->id);
- for (i = 0; i < 32 && mixer_devs[dev]->name; i++)
- info.name[i] = mixer_devs[dev]->name[i];
- info.name[i] = 0;
- if (__copy_to_user(arg, &info, sizeof(info)))
+ strncpy(info.id, mixer_devs[dev]->id, sizeof(info.id));
+ strncpy(info.name, mixer_devs[dev]->name, sizeof(info.name));
+ info.name[sizeof(info.name)-1] = 0;
+ if (copy_to_user(arg, &info, sizeof(info)))
return -EFAULT;
return 0;
}
static int sound_mixer_ioctl(int mixdev, unsigned int cmd, caddr_t arg)
{
+ if (mixdev < 0 || mixdev >= MAX_MIXER_DEV)
+ return -ENXIO;
+#ifdef CONFIG_KERNELD
+ /* Try to load the mixer... */
+ if (mixer_devs[mixdev] == NULL) {
+ char modname[20];
+ sprintf(modname, "mixer%d", mixdev);
+ request_module(modname);
+ }
+#endif /* CONFIG_KERNELD */
+ if (mixdev >= num_mixers || !mixer_devs[mixdev])
+ return -ENXIO;
if (cmd == SOUND_MIXER_INFO)
return get_mixer_info(mixdev, arg);
if (cmd == SOUND_OLD_MIXER_INFO)
@@ -577,10 +579,9 @@
static int sound_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- int err, len = 0, dtype, mixdev;
+ int err, len = 0, dtype;
int dev = MINOR(inode->i_rdev);
- files[dev].flags = file->f_flags;
if (_SIOC_DIR(cmd) != _SIOC_NONE && _SIOC_DIR(cmd) != 0) {
/*
* Have to validate the address given by the process.
@@ -599,55 +600,47 @@
if (cmd == OSS_GETVERSION)
return __put_user(SOUND_VERSION, (int *)arg);
- if (((cmd >> 8) & 0xff) == 'M' && num_mixers > 0) /* Mixer ioctl */
- if ((dev & 0x0f) != SND_DEV_CTL) {
- dtype = dev & 0x0f;
- switch (dtype) {
+ if (_IOC_TYPE(cmd) == 'M' && num_mixers > 0 && /* Mixer ioctl */
+ (dev & 0x0f) != SND_DEV_CTL) {
+ dtype = dev & 0x0f;
+ switch (dtype) {
#ifdef CONFIG_AUDIO
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- mixdev = audio_devs[dev >> 4]->mixer_dev;
- if (mixdev < 0 || mixdev >= num_mixers)
- return -ENXIO;
- return sound_mixer_ioctl(mixdev, cmd, (caddr_t)arg);
-#endif
-
- default:
- return sound_mixer_ioctl(dev, cmd, (caddr_t)arg);
- }
+ case SND_DEV_DSP:
+ case SND_DEV_DSP16:
+ case SND_DEV_AUDIO:
+ return sound_mixer_ioctl(audio_devs[dev >> 4]->mixer_dev,
+ cmd, (caddr_t)arg);
+#endif
+
+ default:
+ return sound_mixer_ioctl(dev >> 4, cmd, (caddr_t)arg);
}
+ }
switch (dev & 0x0f) {
case SND_DEV_CTL:
if (cmd == SOUND_MIXER_GETLEVELS)
return get_mixer_levels((caddr_t)arg);
if (cmd == SOUND_MIXER_SETLEVELS)
return set_mixer_levels((caddr_t)arg);
- if (!num_mixers)
- return -ENXIO;
- dev = dev >> 4;
- if (dev >= num_mixers)
- return -ENXIO;
- return sound_mixer_ioctl(dev, cmd, (caddr_t)arg);
- break;
+ return sound_mixer_ioctl(dev >> 4, cmd, (caddr_t)arg);
#ifdef CONFIG_SEQUENCER
case SND_DEV_SEQ:
case SND_DEV_SEQ2:
- return sequencer_ioctl(dev, &files[dev], cmd, (caddr_t)arg);
+ return sequencer_ioctl(dev, file, cmd, (caddr_t)arg);
#endif
#ifdef CONFIG_AUDIO
case SND_DEV_DSP:
case SND_DEV_DSP16:
case SND_DEV_AUDIO:
- return audio_ioctl(dev, &files[dev], cmd, (caddr_t)arg);
+ return audio_ioctl(dev, file, cmd, (caddr_t)arg);
break;
#endif
#ifdef CONFIG_MIDI
case SND_DEV_MIDIN:
- return MIDIbuf_ioctl(dev, &files[dev], cmd, (caddr_t)arg);
+ return MIDIbuf_ioctl(dev, file, cmd, (caddr_t)arg);
break;
#endif
@@ -655,47 +648,34 @@
return -EINVAL;
}
-static int sound_select(struct inode *inode, struct file *file, int sel_type, poll_table * wait)
+static unsigned int sound_poll(struct file *file, poll_table * wait)
{
+ struct inode *inode = file->f_dentry->d_inode;
int dev = MINOR(inode->i_rdev);
- files[dev].flags = file->f_flags;
- DEB(printk("sound_select(dev=%d, type=0x%x)\n", dev, sel_type));
+ DEB(printk("sound_poll(dev=%d)\n", dev));
switch (dev & 0x0f) {
#if defined(CONFIG_SEQUENCER) || defined(MODULE)
case SND_DEV_SEQ:
case SND_DEV_SEQ2:
- return sequencer_select(dev, &files[dev], sel_type, wait);
+ return sequencer_poll(dev, file, wait);
#endif
#if defined(CONFIG_MIDI)
case SND_DEV_MIDIN:
- return MIDIbuf_select(dev, &files[dev], sel_type, wait);
+ return MIDIbuf_poll(dev, file, wait);
#endif
#if defined(CONFIG_AUDIO) || defined(MODULE)
case SND_DEV_DSP:
case SND_DEV_DSP16:
case SND_DEV_AUDIO:
- return DMAbuf_select(dev >> 4, &files[dev], sel_type, wait);
+ return DMAbuf_poll(dev >> 4, wait);
#endif
}
return 0;
}
-static unsigned int sound_poll(struct file *file, poll_table * wait)
-{
- struct inode *inode;
- int ret = 0;
-
- inode = file->f_dentry->d_inode;
- if (sound_select(inode, file, SEL_IN, wait))
- ret |= POLLIN;
- if (sound_select(inode, file, SEL_OUT, wait))
- ret |= POLLOUT;
- return ret;
-}
-
static int sound_mmap(struct file *file, struct vm_area_struct *vma)
{
int dev_class;
@@ -703,8 +683,6 @@
struct dma_buffparms *dmap = NULL;
int dev = MINOR(file->f_dentry->d_inode->i_rdev);
- files[dev].flags = file->f_flags;
-
dev_class = dev & 0x0f;
dev >>= 4;
@@ -832,8 +810,6 @@
#endif
-static int debugmem = 0; /* switched off by default */
-
static int sound[20] =
{0};
@@ -918,11 +894,6 @@
}
#endif
-void tenmicrosec(int *osp)
-{
- udelay(10);
-}
-
int snd_set_irq_handler(int interrupt_level, void (*iproc) (int, void *, struct pt_regs *), char *name, int *osp)
{
int retcode;
@@ -1053,143 +1024,6 @@
}
#endif
-#ifdef CONFIG_AUDIO
-
-static int dma_buffsize = DSP_BUFFSIZE;
-
-int sound_alloc_dmap(int dev, struct dma_buffparms *dmap, int chan)
-{
- char *start_addr, *end_addr;
- int i, dma_pagesize;
-
- dmap->mapping_flags &= ~DMA_MAP_MAPPED;
-
- if (dmap->raw_buf != NULL)
- return 0; /* Already done */
-
- if (dma_buffsize < 4096)
- dma_buffsize = 4096;
-
- if (chan < 4)
- dma_pagesize = 64 * 1024;
- else
- dma_pagesize = 128 * 1024;
-
- dmap->raw_buf = NULL;
-
- dmap->buffsize = dma_buffsize;
-
- if (dmap->buffsize > dma_pagesize)
- dmap->buffsize = dma_pagesize;
-
- start_addr = NULL;
-
-/*
- * Now loop until we get a free buffer. Try to get smaller buffer if
- * it fails. Don't accept smaller than 8k buffer for performance
- * reasons.
- */
-
- while (start_addr == NULL && dmap->buffsize > PAGE_SIZE)
- {
- int sz, size;
-
- for (sz = 0, size = PAGE_SIZE;
- size < dmap->buffsize;
- sz++, size <<= 1);
-
- dmap->buffsize = PAGE_SIZE * (1 << sz);
-
- if ((start_addr = (char *) __get_free_pages(GFP_ATOMIC|GFP_DMA, sz)) == NULL)
- dmap->buffsize /= 2;
- }
-
- if (start_addr == NULL)
- {
- printk(KERN_WARNING "Sound error: Couldn't allocate DMA buffer\n");
- return -ENOMEM;
- }
- else
- {
- /* make some checks */
- end_addr = start_addr + dmap->buffsize - 1;
-
- if (debugmem)
- printk(KERN_DEBUG "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 *) (MAX_DMA_ADDRESS))
- {
- printk(KERN_ERR "sound: Got invalid address 0x%lx for %db DMA-buffer\n", (long) start_addr, dmap->buffsize);
- return -EFAULT;
- }
- }
- dmap->raw_buf = start_addr;
- dmap->raw_buf_phys = virt_to_bus(start_addr);
-
- for (i = MAP_NR(start_addr); i <= MAP_NR(end_addr); i++)
- {
- set_bit(PG_reserved, &mem_map[i].flags);;
- }
-
- return 0;
-}
-
-void sound_free_dmap(int dev, struct dma_buffparms *dmap, int chan)
-{
- int sz, size, i;
- unsigned long start_addr, end_addr;
-
- if (dmap->raw_buf == NULL)
- return;
-
- if (dmap->mapping_flags & DMA_MAP_MAPPED)
- return; /* Don't free mmapped buffer. Will use it next time */
-
- for (sz = 0, size = PAGE_SIZE; size < dmap->buffsize; sz++, size <<= 1);
-
- start_addr = (unsigned long) dmap->raw_buf;
- end_addr = start_addr + dmap->buffsize;
-
- for (i = MAP_NR(start_addr); i <= MAP_NR(end_addr); i++)
- {
- clear_bit(PG_reserved, &mem_map[i].flags);;
- }
-
- free_pages((unsigned long) dmap->raw_buf, sz);
- dmap->raw_buf = NULL;
-}
-
-
-/* Intel version !!!!!!!!! */
-
-int sound_start_dma(int dev, struct dma_buffparms *dmap, int chan,
- unsigned long physaddr,
- int count, int dma_mode, int autoinit)
-{
- unsigned long flags;
-
- /* printk( "Start DMA%d %d, %d\n", chan, (int)(physaddr-dmap->raw_buf_phys), count); */
- if (autoinit)
- dma_mode |= DMA_AUTOINIT;
- save_flags(flags);
- cli();
- disable_dma(chan);
- clear_dma_ff(chan);
- set_dma_mode(chan, dma_mode);
- set_dma_addr(chan, physaddr);
- set_dma_count(chan, count);
- enable_dma(chan);
- restore_flags(flags);
-
- return 0;
-}
-
-#endif
-
void conf_printf(char *name, struct address_info *hw_config)
{
if (!trace_init)
@@ -1258,4 +1092,3 @@
ct++;
}
}
-
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov