fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / sound / oss / soundcard.c
index ee1f493..a89108c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/sound/soundcard.c
+ * linux/sound/oss/soundcard.c
  *
  * Sound card driver for Linux
  *
@@ -22,7 +22,6 @@
  * Christoph Hellwig : Some cleanup work (2000/03/01)
  */
 
-#include <linux/config.h>
 
 #include "sound_config.h"
 #include <linux/init.h>
 #include <linux/wait.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/major.h>
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
 #include <linux/smp_lock.h>
 #include <linux/module.h>
+#include <linux/mm.h>
 
 /*
  * This ought to be moved into include/asm/dma.h
@@ -55,7 +54,7 @@
 /*
  * Table for permanently allocated memory (used when unloading the module)
  */
-caddr_t         sound_mem_blocks[1024];
+void *          sound_mem_blocks[1024];
 int             sound_nblocks = 0;
 
 /* Persistent DMA buffers */
@@ -73,7 +72,7 @@ static char     dma_alloc_map[MAX_DMA_CHANNELS];
 
 
 unsigned long seq_time = 0;    /* Time for /dev/sequencer */
-extern struct class_simple *sound_class;
+extern struct class *sound_class;
 
 /*
  * Table for configurable mixer volume handling
@@ -109,8 +108,9 @@ int *load_mixer_volumes(char *name, int *levels, int present)
                mixer_vols[n].levels[i] = levels[i];
        return mixer_vols[n].levels;
 }
+EXPORT_SYMBOL(load_mixer_volumes);
 
-static int set_mixer_levels(caddr_t arg)
+static int set_mixer_levels(void __user * arg)
 {
         /* mixer_vol_table is 174 bytes, so IMHO no reason to not allocate it on the stack */
        mixer_vol_table buf;   
@@ -123,11 +123,11 @@ static int set_mixer_levels(caddr_t arg)
        return 0;
 }
 
-static int get_mixer_levels(caddr_t arg)
+static int get_mixer_levels(void __user * arg)
 {
        int n;
 
-       if (__get_user(n, (int *)(&(((mixer_vol_table *)arg)->num))))
+       if (__get_user(n, (int __user *)(&(((mixer_vol_table __user *)arg)->num))))
                return -EFAULT;
        if (n < 0 || n >= num_mixer_volumes)
                return -EINVAL;
@@ -139,9 +139,9 @@ static int get_mixer_levels(caddr_t arg)
 /* 4K page size but our output routines use some slack for overruns */
 #define PROC_BLOCK_SIZE (3*1024)
 
-static ssize_t sound_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+static ssize_t sound_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 {
-       int dev = iminor(file->f_dentry->d_inode);
+       int dev = iminor(file->f_path.dentry->d_inode);
        int ret = -EINVAL;
 
        /*
@@ -172,9 +172,9 @@ static ssize_t sound_read(struct file *file, char *buf, size_t count, loff_t *pp
        return ret;
 }
 
-static ssize_t sound_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+static ssize_t sound_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
-       int dev = iminor(file->f_dentry->d_inode);
+       int dev = iminor(file->f_path.dentry->d_inode);
        int ret = -EINVAL;
        
        lock_kernel();
@@ -282,7 +282,7 @@ static int sound_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static int get_mixer_info(int dev, caddr_t arg)
+static int get_mixer_info(int dev, void __user *arg)
 {
        mixer_info info;
        memset(&info, 0, sizeof(info));
@@ -294,7 +294,7 @@ static int get_mixer_info(int dev, caddr_t arg)
        return 0;
 }
 
-static int get_old_mixer_info(int dev, caddr_t arg)
+static int get_old_mixer_info(int dev, void __user *arg)
 {
        _old_mixer_info info;
        memset(&info, 0, sizeof(info));
@@ -305,7 +305,7 @@ static int get_old_mixer_info(int dev, caddr_t arg)
        return 0;
 }
 
-static int sound_mixer_ioctl(int mixdev, unsigned int cmd, caddr_t arg)
+static int sound_mixer_ioctl(int mixdev, unsigned int cmd, void __user *arg)
 {
        if (mixdev < 0 || mixdev >= MAX_MIXER_DEV)
                return -ENXIO;
@@ -329,26 +329,27 @@ static int sound_mixer_ioctl(int mixdev, unsigned int cmd, caddr_t arg)
 static int sound_ioctl(struct inode *inode, struct file *file,
                       unsigned int cmd, unsigned long arg)
 {
-       int err, len = 0, dtype;
+       int len = 0, dtype;
        int dev = iminor(inode);
+       void __user *p = (void __user *)arg;
 
        if (_SIOC_DIR(cmd) != _SIOC_NONE && _SIOC_DIR(cmd) != 0) {
                /*
                 * Have to validate the address given by the process.
                 */
                len = _SIOC_SIZE(cmd);
-               if (len < 1 || len > 65536 || arg == 0)
+               if (len < 1 || len > 65536 || !p)
                        return -EFAULT;
                if (_SIOC_DIR(cmd) & _SIOC_WRITE)
-                       if ((err = verify_area(VERIFY_READ, (void *)arg, len)) < 0)
-                               return err;
+                       if (!access_ok(VERIFY_READ, p, len))
+                               return -EFAULT;
                if (_SIOC_DIR(cmd) & _SIOC_READ)
-                       if ((err = verify_area(VERIFY_WRITE, (void *)arg, len)) < 0)
-                               return err;
+                       if (!access_ok(VERIFY_WRITE, p, len))
+                               return -EFAULT;
        }
        DEB(printk("sound_ioctl(dev=%d, cmd=0x%x, arg=0x%x)\n", dev, cmd, arg));
        if (cmd == OSS_GETVERSION)
-               return __put_user(SOUND_VERSION, (int *)arg);
+               return __put_user(SOUND_VERSION, (int __user *)p);
        
        if (_IOC_TYPE(cmd) == 'M' && num_mixers > 0 &&   /* Mixer ioctl */
            (dev & 0x0f) != SND_DEV_CTL) {              
@@ -358,32 +359,32 @@ static int sound_ioctl(struct inode *inode, struct file *file,
                case SND_DEV_DSP16:
                case SND_DEV_AUDIO:
                        return sound_mixer_ioctl(audio_devs[dev >> 4]->mixer_dev,
-                                                cmd, (caddr_t)arg);
+                                                cmd, p);
                        
                default:
-                       return sound_mixer_ioctl(dev >> 4, cmd, (caddr_t)arg);
+                       return sound_mixer_ioctl(dev >> 4, cmd, p);
                }
        }
        switch (dev & 0x0f) {
        case SND_DEV_CTL:
                if (cmd == SOUND_MIXER_GETLEVELS)
-                       return get_mixer_levels((caddr_t)arg);
+                       return get_mixer_levels(p);
                if (cmd == SOUND_MIXER_SETLEVELS)
-                       return set_mixer_levels((caddr_t)arg);
-               return sound_mixer_ioctl(dev >> 4, cmd, (caddr_t)arg);
+                       return set_mixer_levels(p);
+               return sound_mixer_ioctl(dev >> 4, cmd, p);
 
        case SND_DEV_SEQ:
        case SND_DEV_SEQ2:
-               return sequencer_ioctl(dev, file, cmd, (caddr_t)arg);
+               return sequencer_ioctl(dev, file, cmd, p);
 
        case SND_DEV_DSP:
        case SND_DEV_DSP16:
        case SND_DEV_AUDIO:
-               return audio_ioctl(dev, file, cmd, (caddr_t)arg);
+               return audio_ioctl(dev, file, cmd, p);
                break;
 
        case SND_DEV_MIDIN:
-               return MIDIbuf_ioctl(dev, file, cmd, (caddr_t)arg);
+               return MIDIbuf_ioctl(dev, file, cmd, p);
                break;
 
        }
@@ -392,7 +393,7 @@ static int sound_ioctl(struct inode *inode, struct file *file,
 
 static unsigned int sound_poll(struct file *file, poll_table * wait)
 {
-       struct inode *inode = file->f_dentry->d_inode;
+       struct inode *inode = file->f_path.dentry->d_inode;
        int dev = iminor(inode);
 
        DEB(printk("sound_poll(dev=%d)\n", dev));
@@ -417,7 +418,7 @@ static int sound_mmap(struct file *file, struct vm_area_struct *vma)
        int dev_class;
        unsigned long size;
        struct dma_buffparms *dmap = NULL;
-       int dev = iminor(file->f_dentry->d_inode);
+       int dev = iminor(file->f_path.dentry->d_inode);
 
        dev_class = dev & 0x0f;
        dev >>= 4;
@@ -462,9 +463,9 @@ static int sound_mmap(struct file *file, struct vm_area_struct *vma)
        if (size != dmap->bytes_in_use) {
                printk(KERN_WARNING "Sound: mmap() size = %ld. Should be %d\n", size, dmap->bytes_in_use);
        }
-       if (remap_page_range(vma, vma->vm_start, virt_to_phys(dmap->raw_buf),
-               vma->vm_end - vma->vm_start,
-               vma->vm_page_prot)) {
+       if (remap_pfn_range(vma, vma->vm_start,
+                       virt_to_phys(dmap->raw_buf) >> PAGE_SHIFT,
+                       vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
                unlock_kernel();
                return -EAGAIN;
        }
@@ -534,20 +535,14 @@ static const struct {
 static int dmabuf;
 static int dmabug;
 
-MODULE_PARM(dmabuf, "i");
-MODULE_PARM(dmabug, "i");
+module_param(dmabuf, int, 0444);
+module_param(dmabug, int, 0444);
 
 static int __init oss_init(void)
 {
        int             err;
        int i, j;
        
-       /* drag in sound_syms.o */
-       {
-               extern char sound_syms_symbol;
-               sound_syms_symbol = 0;
-       }
-
 #ifdef CONFIG_PCI
        if(dmabug)
                isa_dma_bridge_buggy = dmabug;
@@ -563,26 +558,17 @@ static int __init oss_init(void)
        sound_dmap_flag = (dmabuf > 0 ? 1 : 0);
 
        for (i = 0; i < sizeof (dev_list) / sizeof *dev_list; i++) {
-               devfs_mk_cdev(MKDEV(SOUND_MAJOR, dev_list[i].minor),
-                               S_IFCHR | dev_list[i].mode,
-                               "sound/%s", dev_list[i].name);
-               class_simple_device_add(sound_class, 
-                                       MKDEV(SOUND_MAJOR, dev_list[i].minor),
-                                       NULL, "%s", dev_list[i].name);
+               device_create(sound_class, NULL,
+                             MKDEV(SOUND_MAJOR, dev_list[i].minor),
+                             "%s", dev_list[i].name);
 
                if (!dev_list[i].num)
                        continue;
 
-               for (j = 1; j < *dev_list[i].num; j++) {
-                       devfs_mk_cdev(MKDEV(SOUND_MAJOR,
-                                               dev_list[i].minor + (j*0x10)),
-                                       S_IFCHR | dev_list[i].mode,
-                                       "sound/%s%d", dev_list[i].name, j);
-                       class_simple_device_add(sound_class,
-                                       MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)),
-                                       NULL,
-                                       "%s%d", dev_list[i].name, j);
-               }
+               for (j = 1; j < *dev_list[i].num; j++)
+                       device_create(sound_class, NULL,
+                                     MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)),
+                                     "%s%d", dev_list[i].name, j);
        }
 
        if (sound_nblocks >= 1024)
@@ -596,14 +582,11 @@ static void __exit oss_cleanup(void)
        int i, j;
 
        for (i = 0; i < sizeof (dev_list) / sizeof *dev_list; i++) {
-               devfs_remove("sound/%s", dev_list[i].name);
-               class_simple_device_remove(MKDEV(SOUND_MAJOR, dev_list[i].minor));
+               device_destroy(sound_class, MKDEV(SOUND_MAJOR, dev_list[i].minor));
                if (!dev_list[i].num)
                        continue;
-               for (j = 1; j < *dev_list[i].num; j++) {
-                       devfs_remove("sound/%s%d", dev_list[i].name, j);
-                       class_simple_device_remove(MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)));
-               }
+               for (j = 1; j < *dev_list[i].num; j++)
+                       device_destroy(sound_class, MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)));
        }
        
        unregister_sound_special(1);
@@ -627,6 +610,8 @@ static void __exit oss_cleanup(void)
 module_init(oss_init);
 module_exit(oss_cleanup);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("OSS Sound subsystem");
+MODULE_AUTHOR("Hannu Savolainen, et al.");
 
 
 int sound_alloc_dma(int chn, char *deviceID)
@@ -640,6 +625,7 @@ int sound_alloc_dma(int chn, char *deviceID)
 
        return 0;
 }
+EXPORT_SYMBOL(sound_alloc_dma);
 
 int sound_open_dma(int chn, char *deviceID)
 {
@@ -655,6 +641,7 @@ int sound_open_dma(int chn, char *deviceID)
        dma_alloc_map[chn] = DMA_MAP_BUSY;
        return 0;
 }
+EXPORT_SYMBOL(sound_open_dma);
 
 void sound_free_dma(int chn)
 {
@@ -665,6 +652,7 @@ void sound_free_dma(int chn)
        free_dma(chn);
        dma_alloc_map[chn] = DMA_MAP_UNAVAIL;
 }
+EXPORT_SYMBOL(sound_free_dma);
 
 void sound_close_dma(int chn)
 {
@@ -674,6 +662,7 @@ void sound_close_dma(int chn)
        }
        dma_alloc_map[chn] = DMA_MAP_FREE;
 }
+EXPORT_SYMBOL(sound_close_dma);
 
 static void do_sequencer_timer(unsigned long dummy)
 {
@@ -681,8 +670,7 @@ static void do_sequencer_timer(unsigned long dummy)
 }
 
 
-static struct timer_list seq_timer =
-               TIMER_INITIALIZER(do_sequencer_timer, 0, 0);
+static DEFINE_TIMER(seq_timer, do_sequencer_timer, 0, 0);
 
 void request_sound_timer(int count)
 {
@@ -728,6 +716,7 @@ void conf_printf(char *name, struct address_info *hw_config)
        printk("\n");
 #endif
 }
+EXPORT_SYMBOL(conf_printf);
 
 void conf_printf2(char *name, int base, int irq, int dma, int dma2)
 {
@@ -748,3 +737,5 @@ void conf_printf2(char *name, int base, int irq, int dma, int dma2)
        printk("\n");
 #endif
 }
+EXPORT_SYMBOL(conf_printf2);
+