Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / sound / oss / btaudio.c
index c8866da..324a81f 100644 (file)
@@ -32,6 +32,8 @@
 #include <linux/soundcard.h>
 #include <linux/slab.h>
 #include <linux/kdev_t.h>
+#include <linux/mutex.h>
+
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
@@ -104,11 +106,11 @@ struct btaudio {
        struct pci_dev *pci;
        unsigned int   irq;
        unsigned long  mem;
-       unsigned long  *mmio;
+       unsigned long  __iomem *mmio;
 
        /* locking */
        int            users;
-       struct semaphore lock;
+       struct mutex lock;
 
        /* risc instructions */
        unsigned int   risc_size;
@@ -327,6 +329,7 @@ static int btaudio_mixer_ioctl(struct inode *inode, struct file *file,
 {
        struct btaudio *bta = file->private_data;
        int ret,val=0,i=0;
+       void __user *argp = (void __user *)arg;
 
        if (cmd == SOUND_MIXER_INFO) {
                mixer_info info;
@@ -334,7 +337,7 @@ static int btaudio_mixer_ioctl(struct inode *inode, struct file *file,
                 strlcpy(info.id,"bt878",sizeof(info.id));
                 strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name));
                 info.modify_counter = bta->mixcount;
-                if (copy_to_user((void *)arg, &info, sizeof(info)))
+                if (copy_to_user(argp, &info, sizeof(info)))
                         return -EFAULT;
                return 0;
        }
@@ -343,16 +346,16 @@ static int btaudio_mixer_ioctl(struct inode *inode, struct file *file,
                memset(&info,0,sizeof(info));
                 strlcpy(info.id,"bt878",sizeof(info.id)-1);
                 strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name));
-                if (copy_to_user((void *)arg, &info, sizeof(info)))
+                if (copy_to_user(argp, &info, sizeof(info)))
                         return -EFAULT;
                return 0;
        }
        if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, (int *)arg);
+               return put_user(SOUND_VERSION, (int __user *)argp);
 
        /* read */
        if (_SIOC_DIR(cmd) & _SIOC_WRITE)
-               if (get_user(val, (int *)arg))
+               if (get_user(val, (int __user *)argp))
                        return -EFAULT;
 
        switch (cmd) {
@@ -421,7 +424,7 @@ static int btaudio_mixer_ioctl(struct inode *inode, struct file *file,
        default:
                return -EINVAL;
        }
-       if (put_user(ret, (int *)arg))
+       if (put_user(ret, (int __user *)argp))
                return -EFAULT;
        return 0;
 }
@@ -439,7 +442,7 @@ static struct file_operations btaudio_mixer_fops = {
 static int btaudio_dsp_open(struct inode *inode, struct file *file,
                            struct btaudio *bta, int analog)
 {
-       down(&bta->lock);
+       mutex_lock(&bta->lock);
        if (bta->users)
                goto busy;
        bta->users++;
@@ -451,11 +454,11 @@ static int btaudio_dsp_open(struct inode *inode, struct file *file,
        bta->read_count = 0;
        bta->sampleshift = 0;
 
-       up(&bta->lock);
+       mutex_unlock(&bta->lock);
        return 0;
 
  busy:
-       up(&bta->lock);
+       mutex_unlock(&bta->lock);
        return -EBUSY;
 }
 
@@ -495,15 +498,15 @@ static int btaudio_dsp_release(struct inode *inode, struct file *file)
 {
        struct btaudio *bta = file->private_data;
 
-       down(&bta->lock);
+       mutex_lock(&bta->lock);
        if (bta->recording)
                stop_recording(bta);
        bta->users--;
-       up(&bta->lock);
+       mutex_unlock(&bta->lock);
        return 0;
 }
 
-static ssize_t btaudio_dsp_read(struct file *file, char *buffer,
+static ssize_t btaudio_dsp_read(struct file *file, char __user *buffer,
                                size_t swcount, loff_t *ppos)
 {
        struct btaudio *bta = file->private_data;
@@ -512,7 +515,7 @@ static ssize_t btaudio_dsp_read(struct file *file, char *buffer,
        DECLARE_WAITQUEUE(wait, current);
 
        add_wait_queue(&bta->readq, &wait);
-       down(&bta->lock);
+       mutex_lock(&bta->lock);
        while (swcount > 0) {
                if (0 == bta->read_count) {
                        if (!bta->recording) {
@@ -527,10 +530,10 @@ static ssize_t btaudio_dsp_read(struct file *file, char *buffer,
                                        ret = -EAGAIN;
                                break;
                        }
-                       up(&bta->lock);
+                       mutex_unlock(&bta->lock);
                        current->state = TASK_INTERRUPTIBLE;
                        schedule();
-                       down(&bta->lock);
+                       mutex_lock(&bta->lock);
                        if(signal_pending(current)) {
                                if (0 == ret)
                                        ret = -EINTR;
@@ -554,10 +557,10 @@ static ssize_t btaudio_dsp_read(struct file *file, char *buffer,
                } else if (!bta->analog) {
                        /* stereo => mono (digital audio) */
                        __s16 *src = (__s16*)(bta->buf_cpu + bta->read_offset);
-                       __s16 *dst = (__s16*)(buffer + ret);
+                       __s16 __user *dst = (__s16 __user *)(buffer + ret);
                        __s16 avg;
                        int n = ndst>>1;
-                       if (0 != verify_area(VERIFY_WRITE,dst,ndst)) {
+                       if (!access_ok(VERIFY_WRITE, dst, ndst)) {
                                if (0 == ret)
                                        ret = -EFAULT;
                                break;
@@ -565,34 +568,34 @@ static ssize_t btaudio_dsp_read(struct file *file, char *buffer,
                        for (; n; n--, dst++) {
                                avg  = (__s16)le16_to_cpu(*src) / 2; src++;
                                avg += (__s16)le16_to_cpu(*src) / 2; src++;
-                               __put_user(cpu_to_le16(avg),(__u16*)(dst));
+                               __put_user(cpu_to_le16(avg),dst);
                        }
 
                } else if (8 == bta->bits) {
                        /* copy + byte downsampling (audio A/D) */
                        __u8 *src = bta->buf_cpu + bta->read_offset;
-                       __u8 *dst = buffer + ret;
+                       __u8 __user *dst = buffer + ret;
                        int n = ndst;
-                       if (0 != verify_area(VERIFY_WRITE,dst,ndst)) {
+                       if (!access_ok(VERIFY_WRITE, dst, ndst)) {
                                if (0 == ret)
                                        ret = -EFAULT;
                                break;
                        }
                        for (; n; n--, src += (1 << bta->sampleshift), dst++)
-                               __put_user(*src,(__u8*)(dst));
+                               __put_user(*src, dst);
 
                } else {
                        /* copy + word downsampling (audio A/D) */
                        __u16 *src = (__u16*)(bta->buf_cpu + bta->read_offset);
-                       __u16 *dst = (__u16*)(buffer + ret);
+                       __u16 __user *dst = (__u16 __user *)(buffer + ret);
                        int n = ndst>>1;
-                       if (0 != verify_area(VERIFY_WRITE,dst,ndst)) {
+                       if (!access_ok(VERIFY_WRITE,dst,ndst)) {
                                if (0 == ret)
                                        ret = -EFAULT;
                                break;
                        }
                        for (; n; n--, src += (1 << bta->sampleshift), dst++)
-                               __put_user(*src,(__u16*)(dst));
+                               __put_user(*src, dst);
                }
 
                ret     += ndst;
@@ -603,13 +606,13 @@ static ssize_t btaudio_dsp_read(struct file *file, char *buffer,
                if (bta->read_offset == bta->buf_size)
                        bta->read_offset = 0;
        }
-       up(&bta->lock);
+       mutex_unlock(&bta->lock);
        remove_wait_queue(&bta->readq, &wait);
        current->state = TASK_RUNNING;
        return ret;
 }
 
-static ssize_t btaudio_dsp_write(struct file *file, const char *buffer,
+static ssize_t btaudio_dsp_write(struct file *file, const char __user *buffer,
                                 size_t count, loff_t *ppos)
 {
        return -EINVAL;
@@ -620,15 +623,17 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
 {
        struct btaudio *bta = file->private_data;
        int s, i, ret, val = 0;
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        
         switch (cmd) {
         case OSS_GETVERSION:
-                return put_user(SOUND_VERSION, (int *)arg);
+                return put_user(SOUND_VERSION, p);
         case SNDCTL_DSP_GETCAPS:
                return 0;
 
         case SNDCTL_DSP_SPEED:
-               if (get_user(val, (int*)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (bta->analog) {
                        for (s = 0; s < 16; s++)
@@ -648,22 +653,22 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
                        bta->decimation  = 0;
                }
                if (bta->recording) {
-                       down(&bta->lock);
+                       mutex_lock(&bta->lock);
                        stop_recording(bta);
                        start_recording(bta);
-                       up(&bta->lock);
+                       mutex_unlock(&bta->lock);
                }
                /* fall through */
         case SOUND_PCM_READ_RATE:
                if (bta->analog) {
-                       return put_user(HWBASE_AD*4/bta->decimation>>bta->sampleshift, (int*)arg);
+                       return put_user(HWBASE_AD*4/bta->decimation>>bta->sampleshift, p);
                } else {
-                       return put_user(bta->rate, (int*)arg);
+                       return put_user(bta->rate, p);
                }
 
         case SNDCTL_DSP_STEREO:
                if (!bta->analog) {
-                       if (get_user(val, (int*)arg))
+                       if (get_user(val, p))
                                return -EFAULT;
                        bta->channels    = (val > 0) ? 2 : 1;
                        bta->sampleshift = (bta->channels == 2) ? 0 : 1;
@@ -681,11 +686,11 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
                                               "btaudio: stereo=0 channels=1\n");
                        }
                }
-               return put_user((bta->channels)-1, (int *)arg);
+               return put_user((bta->channels)-1, p);
 
         case SNDCTL_DSP_CHANNELS:
                if (!bta->analog) {
-                       if (get_user(val, (int*)arg))
+                       if (get_user(val, p))
                                return -EFAULT;
                        bta->channels    = (val > 1) ? 2 : 1;
                        bta->sampleshift = (bta->channels == 2) ? 0 : 1;
@@ -696,16 +701,16 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
                }
                /* fall through */
         case SOUND_PCM_READ_CHANNELS:
-               return put_user(bta->channels, (int *)arg);
+               return put_user(bta->channels, p);
                
         case SNDCTL_DSP_GETFMTS: /* Returns a mask */
                if (bta->analog)
-                       return put_user(AFMT_S16_LE|AFMT_S8, (int*)arg);
+                       return put_user(AFMT_S16_LE|AFMT_S8, p);
                else
-                       return put_user(AFMT_S16_LE, (int*)arg);
+                       return put_user(AFMT_S16_LE, p);
 
         case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, (int*)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                 if (val != AFMT_QUERY) {
                        if (bta->analog)
@@ -713,19 +718,19 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
                        else
                                bta->bits = 16;
                        if (bta->recording) {
-                               down(&bta->lock);
+                               mutex_lock(&bta->lock);
                                stop_recording(bta);
                                start_recording(bta);
-                               up(&bta->lock);
+                               mutex_unlock(&bta->lock);
                        }
                }
                if (debug)
                        printk(KERN_DEBUG "btaudio: fmt: bits=%d\n",bta->bits);
                 return put_user((bta->bits==16) ? AFMT_S16_LE : AFMT_S8,
-                               (int*)arg);
+                               p);
                break;
         case SOUND_PCM_READ_BITS:
-               return put_user(bta->bits, (int*)arg);
+               return put_user(bta->bits, p);
 
         case SNDCTL_DSP_NONBLOCK:
                 file->f_flags |= O_NONBLOCK;
@@ -733,9 +738,9 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
 
         case SNDCTL_DSP_RESET:
                if (bta->recording) {
-                       down(&bta->lock);
+                       mutex_lock(&bta->lock);
                        stop_recording(bta);
-                       up(&bta->lock);
+                       mutex_unlock(&bta->lock);
                }
                return 0;
         case SNDCTL_DSP_GETBLKSIZE:
@@ -745,7 +750,7 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
                        if (0 != (ret = make_risc(bta)))
                                return ret;
                }
-               return put_user(bta->block_bytes>>bta->sampleshift,(int*)arg);
+               return put_user(bta->block_bytes>>bta->sampleshift,p);
 
         case SNDCTL_DSP_SYNC:
                /* NOP */
@@ -764,7 +769,7 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
                               "returns %d/%d/%d/%d\n",
                               info.fragsize, info.fragstotal,
                               info.bytes, info.fragments);
-               if (copy_to_user((void *)arg, &info, sizeof(info)))
+               if (copy_to_user(argp, &info, sizeof(info)))
                        return -EFAULT;
                return 0;
        }
@@ -938,7 +943,7 @@ static int __devinit btaudio_probe(struct pci_dev *pci_dev,
        if (rate)
                bta->rate = rate;
        
-       init_MUTEX(&bta->lock);
+       mutex_init(&bta->lock);
         init_waitqueue_head(&bta->readq);
 
        if (-1 != latency) {
@@ -958,10 +963,10 @@ static int __devinit btaudio_probe(struct pci_dev *pci_dev,
        /* init hw */
         btwrite(0, REG_GPIO_DMA_CTL);
         btwrite(0, REG_INT_MASK);
-        btwrite(~0x0UL, REG_INT_STAT);
+        btwrite(~0U, REG_INT_STAT);
        pci_set_master(pci_dev);
 
-       if ((rc = request_irq(bta->irq, btaudio_irq, SA_SHIRQ|SA_INTERRUPT,
+       if ((rc = request_irq(bta->irq, btaudio_irq, IRQF_SHARED|IRQF_DISABLED,
                              "btaudio",(void *)bta)) < 0) {
                printk(KERN_WARNING
                       "btaudio: can't request irq (rc=%d)\n",rc);
@@ -1030,7 +1035,7 @@ static void __devexit btaudio_remove(struct pci_dev *pci_dev)
        /* turn off all DMA / IRQs */
         btand(~15, REG_GPIO_DMA_CTL);
         btwrite(0, REG_INT_MASK);
-        btwrite(~0x0UL, REG_INT_STAT);
+        btwrite(~0U, REG_INT_STAT);
 
        /* unregister devices */
        if (digital) {
@@ -1098,7 +1103,7 @@ static int btaudio_init_module(void)
               digital ? "digital" : "",
               analog && digital ? "+" : "",
               analog ? "analog" : "");
-       return pci_module_init(&btaudio_pci_driver);
+       return pci_register_driver(&btaudio_pci_driver);
 }
 
 static void btaudio_cleanup_module(void)
@@ -1110,15 +1115,15 @@ static void btaudio_cleanup_module(void)
 module_init(btaudio_init_module);
 module_exit(btaudio_cleanup_module);
 
-MODULE_PARM(dsp1,"i");
-MODULE_PARM(dsp2,"i");
-MODULE_PARM(mixer,"i");
-MODULE_PARM(debug,"i");
-MODULE_PARM(irq_debug,"i");
-MODULE_PARM(digital,"i");
-MODULE_PARM(analog,"i");
-MODULE_PARM(rate,"i");
-MODULE_PARM(latency,"i");
+module_param(dsp1, int, S_IRUGO);
+module_param(dsp2, int, S_IRUGO);
+module_param(mixer, int, S_IRUGO);
+module_param(debug, int, S_IRUGO | S_IWUSR);
+module_param(irq_debug, int, S_IRUGO | S_IWUSR);
+module_param(digital, int, S_IRUGO);
+module_param(analog, int, S_IRUGO);
+module_param(rate, int, S_IRUGO);
+module_param(latency, int, S_IRUGO);
 MODULE_PARM_DESC(latency,"pci latency timer");
 
 MODULE_DEVICE_TABLE(pci, btaudio_pci_tbl);