patch-1.3.58 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: 513
- Date:
Tue Jan 9 00:37:41 1996
- Orig file:
v1.3.57/linux/drivers/sound/soundcard.c
- Orig date:
Tue Dec 26 04:45:37 1995
diff -u --recursive --new-file v1.3.57/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c
@@ -29,15 +29,12 @@
/*
* Created modular version by Peter Trattler (peter@sbox.tu-graz.ac.at)
*/
-#include <linux/module.h>
#include "sound_config.h"
-#ifdef CONFIGURE_SOUNDCARD
-
#include <linux/major.h>
-#ifndef EXCLUDE_PNP
+#ifdef CONFIG_PNP
#include <linux/pnp.h>
#endif
@@ -73,37 +70,37 @@
}
static int
-sound_read (struct inode *inode, struct file *file, char *buf, int count)
+sound_read (inode_handle * inode, file_handle * file, char *buf, int count)
{
int dev;
- dev = inode->i_rdev;
+ dev = inode_get_rdev (inode);
dev = MINOR (dev);
- files[dev].flags = file->f_flags;
+ files[dev].flags = file_get_flags (file);
return sound_read_sw (dev, &files[dev], buf, count);
}
static int
-sound_write (struct inode *inode, struct file *file, const char *buf, int count)
+sound_write (inode_handle * inode, file_handle * file, const char *buf, int count)
{
int dev;
- dev = inode->i_rdev;
+ dev = inode_get_rdev (inode);
dev = MINOR (dev);
- files[dev].flags = file->f_flags;
+ files[dev].flags = file_get_flags (file);
return sound_write_sw (dev, &files[dev], buf, count);
}
static int
-sound_lseek (struct inode *inode, struct file *file, off_t offset, int orig)
+sound_lseek (inode_handle * inode, file_handle * file, off_t offset, int orig)
{
return -EPERM;
}
static int
-sound_open (struct inode *inode, struct file *file)
+sound_open (inode_handle * inode, file_handle * file)
{
int dev, retval;
struct fileinfo tmp_file;
@@ -114,7 +111,7 @@
return -EBUSY;
}
- dev = inode->i_rdev;
+ dev = inode_get_rdev (inode);
dev = MINOR (dev);
if (!soundcard_configured && dev != SND_DEV_CTL && dev != SND_DEV_STATUS)
@@ -124,7 +121,7 @@
}
tmp_file.mode = 0;
- tmp_file.flags = file->f_flags;
+ tmp_file.flags = file_get_flags (file);
if ((tmp_file.flags & O_ACCMODE) == O_RDWR)
tmp_file.mode = OPEN_READWRITE;
@@ -145,13 +142,13 @@
}
static void
-sound_release (struct inode *inode, struct file *file)
+sound_release (inode_handle * inode, file_handle * file)
{
int dev;
- dev = inode->i_rdev;
+ dev = inode_get_rdev (inode);
dev = MINOR (dev);
- files[dev].flags = file->f_flags;
+ files[dev].flags = file_get_flags (file);
sound_release_sw (dev, &files[dev]);
#ifdef MODULE
@@ -160,31 +157,31 @@
}
static int
-sound_ioctl (struct inode *inode, struct file *file,
+sound_ioctl (inode_handle * inode, file_handle * file,
unsigned int cmd, unsigned long arg)
{
int dev, err;
- dev = inode->i_rdev;
+ dev = inode_get_rdev (inode);
dev = MINOR (dev);
- files[dev].flags = file->f_flags;
+ files[dev].flags = file_get_flags (file);
- if (cmd & IOC_INOUT)
+ if (_IOC_DIR (cmd) != _IOC_NONE)
{
/*
* Have to validate the address given by the process.
*/
int len;
- len = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
+ len = _IOC_SIZE (cmd);
- if (cmd & IOC_IN)
+ if (_IOC_DIR (cmd) == _IOC_WRITE)
{
if ((err = verify_area (VERIFY_READ, (void *) arg, len)) < 0)
return err;
}
- if (cmd & IOC_OUT)
+ if (_IOC_DIR (cmd) == _IOC_READ)
{
if ((err = verify_area (VERIFY_WRITE, (void *) arg, len)) < 0)
return err;
@@ -198,32 +195,32 @@
}
static int
-sound_select (struct inode *inode, struct file *file, int sel_type, select_table * wait)
+sound_select (inode_handle * inode, file_handle * file, int sel_type, select_table_handle * wait)
{
int dev;
- dev = inode->i_rdev;
+ dev = inode_get_rdev (inode);
dev = MINOR (dev);
- files[dev].flags = file->f_flags;
+ files[dev].flags = file_get_flags (file);
DEB (printk ("sound_select(dev=%d, type=0x%x)\n", dev, sel_type));
switch (dev & 0x0f)
{
-#ifndef EXCLUDE_SEQUENCER
+#ifdef CONFIG_SEQUENCER
case SND_DEV_SEQ:
case SND_DEV_SEQ2:
return sequencer_select (dev, &files[dev], sel_type, wait);
break;
#endif
-#ifndef EXCLUDE_MIDI
+#ifdef CONFIG_MIDI
case SND_DEV_MIDIN:
return MIDIbuf_select (dev, &files[dev], sel_type, wait);
break;
#endif
-#ifndef EXCLUDE_AUDIO
+#ifdef CONFIG_AUDIO
case SND_DEV_DSP:
case SND_DEV_DSP16:
case SND_DEV_AUDIO:
@@ -238,8 +235,98 @@
return 0;
}
+#ifdef ALLOW_BUFFER_MAPPING
+static int
+sound_mmap (inode_handle * inode, file_handle * file, vm_area_handle * vma)
+{
+ int dev, dev_class;
+ unsigned long size, i;
+ struct dma_buffparms *dmap = NULL;
+
+ dev = inode_get_rdev (inode);
+ dev = MINOR (dev);
+ files[dev].flags = file_get_flags (file);
+
+ 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_get_flags (vma) & (VM_READ | VM_WRITE)) == (VM_READ | VM_WRITE))
+ {
+ printk ("Sound: Cannot do read/write mmap()\n");
+ return -EINVAL;
+ }
+
+ if (vma_get_flags (vma) & VM_READ)
+ {
+ dmap = audio_devs[dev]->dmap_in;
+ }
+ else if (vma_get_flags (vma) & 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_get_offset (vma) != 0)
+ {
+ printk ("Sound: mmap() offset must be 0.\n");
+ return -EINVAL;
+ }
+
+ size = vma_get_end (vma) - vma_get_start (vma);
-static struct file_operations sound_fops =
+ 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_get_start (vma), dmap->raw_buf_phys,
+ vma_get_end (vma) - vma_get_start (vma),
+ vma_get_page_prot (vma)))
+ return -EAGAIN;
+
+ vma_set_inode (vma, inode);
+ inode_inc_count (inode);
+
+ dmap->mapping_flags |= DMA_MAP_MAPPED;
+
+ memset (dmap->raw_buf,
+ dmap->neutral_byte,
+ dmap->bytes_in_use);
+ return 0;
+}
+#endif
+
+static struct file_operation_handle sound_fops =
{
sound_lseek,
sound_read,
@@ -247,7 +334,11 @@
NULL, /* sound_readdir */
sound_select,
sound_ioctl,
+#ifdef ALLOW_BUFFER_MAPPING
+ sound_mmap,
+#else
NULL,
+#endif
sound_open,
sound_release
};
@@ -256,7 +347,7 @@
soundcard_init (void)
{
#ifndef MODULE
- register_chrdev (SOUND_MAJOR, "sound", &sound_fops);
+ module_register_chrdev (SOUND_MAJOR, "sound", &sound_fops);
chrdev_registered = 1;
#endif
@@ -265,14 +356,14 @@
sndtable_init (0); /* Initialize call tables and
* detect cards */
-#ifndef EXCLUDE_PNP
+#ifdef CONFIG_PNP
sound_pnp_init ();
#endif
if (sndtable_get_cardcount () == 0)
return; /* No cards detected */
-#ifndef EXCLUDE_AUDIO
+#ifdef CONFIG_AUDIO
if (num_audiodevs) /* Audio devices present */
{
DMAbuf_init (0);
@@ -280,12 +371,12 @@
}
#endif
-#ifndef EXCLUDE_MIDI
+#ifdef CONFIG_MIDI
if (num_midis)
MIDIbuf_init (0);
#endif
-#ifndef EXCLUDE_SEQUENCER
+#ifdef CONFIG_SEQUENCER
if (num_midis + num_synths)
sequencer_init (0);
#endif
@@ -309,6 +400,8 @@
irqs = 0;
}
+char kernel_version[] = UTS_RELEASE;
+
#endif
static int debugmem = 0; /* switched off by default */
@@ -323,7 +416,7 @@
int ints[21];
int i;
- if (0 < 0)
+ if (connect_wrapper (WRAPPER_VERSION) < 0)
{
printk ("Sound: Incompatible kernel (wrapper) version\n");
return -EINVAL;
@@ -340,7 +433,7 @@
if (i)
sound_setup ("sound=", ints);
- err = register_chrdev (SOUND_MAJOR, "sound", &sound_fops);
+ err = module_register_chrdev (SOUND_MAJOR, "sound", &sound_fops);
if (err)
{
printk ("sound: driver already loaded/included in kernel\n");
@@ -369,9 +462,9 @@
int i;
if (chrdev_registered)
- unregister_chrdev (SOUND_MAJOR, "sound");
+ module_unregister_chrdev (SOUND_MAJOR, "sound");
-#ifndef EXCLUDE_SEQUENCER
+#ifdef CONFIG_SEQUENCER
sound_stop_timer ();
#endif
sound_unload_drivers ();
@@ -388,7 +481,7 @@
sound_free_dma (i);
}
-#ifndef EXCLUDE_PNP
+#ifdef CONFIG_PNP
sound_pnp_disconnect ();
#endif
@@ -397,7 +490,7 @@
#endif
void
-tenmicrosec (void)
+tenmicrosec (sound_os_info * osp)
{
int i;
@@ -466,7 +559,7 @@
{
if (dma_alloc_map[chn] != DMA_MAP_FREE)
{
- printk ("sound_free_dma: Bad access to DMA channel %d\n", chn);
+ /* printk ("sound_free_dma: Bad access to DMA channel %d\n", chn); */
return;
}
free_dma (chn);
@@ -491,7 +584,7 @@
restore_flags (flags);
}
-#ifndef EXCLUDE_SEQUENCER
+#ifdef CONFIG_SEQUENCER
static struct timer_list seq_timer =
@@ -507,6 +600,7 @@
else
count += seq_time;
+ ;
{
seq_timer.expires = ((count - jiffies)) + jiffies;
@@ -521,7 +615,7 @@
}
#endif
-#ifndef EXCLUDE_AUDIO
+#ifdef CONFIG_AUDIO
#ifdef KMALLOC_DMA_BROKEN
fatal_error__This_version_is_not_compatible_with_this_kernel;
@@ -535,6 +629,10 @@
char *start_addr, *end_addr;
int i, dma_pagesize;
+#ifdef ALLOW_BUFFER_MAPPING
+ dmap->mapping_flags &= ~DMA_MAP_MAPPED;
+#endif
+
if (dmap->raw_buf != NULL)
return 0; /* Already done */
@@ -611,7 +709,7 @@
for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
{
- mem_map[i].reserved = 1;
+ mem_map_reserve (i);
}
return 0;
@@ -622,6 +720,12 @@
{
if (dmap->raw_buf == NULL)
return;
+
+#ifdef ALLOW_BUFFER_MAPPING
+ if (dmap->mapping_flags & DMA_MAP_MAPPED)
+ return; /* Don't free mmapped buffer. Will use it next time */
+#endif
+
{
int sz, size, i;
unsigned long start_addr, end_addr;
@@ -635,7 +739,7 @@
for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
{
- mem_map[i].reserved = 0;
+ mem_map_unreserve (i);
}
free_pages ((unsigned long) dmap->raw_buf, sz);
@@ -651,13 +755,45 @@
return -EINVAL;
}
-#else
-
void
-soundcard_init (void) /* Dummy version */
+conf_printf (char *name, struct address_info *hw_config)
{
+ if (!trace_init)
+ return;
+
+ printk ("<%s> at 0x%03x", name, hw_config->io_base);
+
+ if (hw_config->irq)
+ printk (" irq %d", hw_config->irq);
+
+ if (hw_config->dma != -1 || hw_config->dma2 != -1)
+ {
+ printk (" dma %d", hw_config->dma);
+ if (hw_config->dma2 != -1)
+ printk (",%d", hw_config->dma2);
+ }
+
+ printk ("\n");
}
-#endif
+void
+conf_printf2 (char *name, int base, int irq, int dma, int dma2)
+{
+ if (!trace_init)
+ return;
+
+ printk ("<%s> at 0x%03x", name, base);
+
+ if (irq)
+ printk (" irq %d", irq);
+ if (dma != -1 || dma2 != -1)
+ {
+ printk (" dma %d", dma);
+ if (dma2 != -1)
+ printk (",%d", dma2);
+ }
+
+ printk ("\n");
+}
#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