vserver 1.9.3
[linux-2.6.git] / sound / oss / mpu401.c
index 0059ee0..73c3ce3 100644 (file)
@@ -728,7 +728,7 @@ static int mpu401_end_read(int dev)
        return 0;
 }
 
-static int mpu401_ioctl(int dev, unsigned cmd, caddr_t arg)
+static int mpu401_ioctl(int dev, unsigned cmd, void __user *arg)
 {
        struct mpu_config *devc;
        mpu_command_rec rec;
@@ -742,7 +742,7 @@ static int mpu401_ioctl(int dev, unsigned cmd, caddr_t arg)
                                printk(KERN_WARNING "mpu401: Intelligent mode not supported by the HW\n");
                                return -EINVAL;
                        }
-                       if (get_user(val, (int *)arg))
+                       if (get_user(val, (int __user *)arg))
                                return -EFAULT;
                        set_uart_mode(dev, devc, !val);
                        return 0;
@@ -772,8 +772,7 @@ static int mpu401_buffer_status(int dev)
                                 */
 }
 
-static int mpu_synth_ioctl(int dev,
-               unsigned int cmd, caddr_t arg)
+static int mpu_synth_ioctl(int dev, unsigned int cmd, void __user *arg)
 {
        int midi_dev;
        struct mpu_config *devc;
@@ -789,8 +788,7 @@ static int mpu_synth_ioctl(int dev,
        {
 
                case SNDCTL_SYNTH_INFO:
-                       if (copy_to_user((&((char *) arg)[0]),
-                                       (char *) &mpu_synth_info[midi_dev],
+                       if (copy_to_user(arg, &mpu_synth_info[midi_dev],
                                        sizeof(struct synth_info)))
                                return -EFAULT;
                        return 0;
@@ -1028,12 +1026,6 @@ int attach_mpu401(struct address_info *hw_config, struct module *owner)
                        spin_unlock_irqrestore(&devc->lock,flags);
        }
 
-       if (!request_region(hw_config->io_base, 2, "mpu401"))
-       {
-               ret = -ENOMEM;
-               goto out_irq;
-       }       
-
        if (devc->version != 0)
                if (mpu_cmd(m, 0xC5, 0) >= 0)   /* Set timebase OK */
                        if (mpu_cmd(m, 0xE0, 120) >= 0)         /* Set tempo OK */
@@ -1046,7 +1038,7 @@ int attach_mpu401(struct address_info *hw_config, struct module *owner)
        {
                printk(KERN_ERR "mpu401: Can't allocate memory\n");
                ret = -ENOMEM;
-               goto out_resource;
+               goto out_irq;
        }
        if (!(devc->capabilities & MPU_CAP_INTLG))      /* No intelligent mode */
        {
@@ -1128,13 +1120,12 @@ int attach_mpu401(struct address_info *hw_config, struct module *owner)
        
        return 0;
 
-out_resource:
-       release_region(hw_config->io_base, 2);
 out_irq:
        free_irq(devc->irq, (void *)m);
 out_mididev:
        sound_unload_mididev(m);
 out_err:
+       release_region(hw_config->io_base, 2);
        return ret;
 }
 
@@ -1209,16 +1200,11 @@ static void set_uart_mode(int dev, struct mpu_config *devc, int arg)
 
 }
 
-int probe_mpu401(struct address_info *hw_config)
+int probe_mpu401(struct address_info *hw_config, struct resource *ports)
 {
        int ok = 0;
        struct mpu_config tmp_devc;
 
-       if (check_region(hw_config->io_base, 2))
-       {
-               printk(KERN_ERR "mpu401: I/O port %x already in use\n\n", hw_config->io_base);
-               return 0;
-       }
        tmp_devc.base = hw_config->io_base;
        tmp_devc.irq = hw_config->irq;
        tmp_devc.initialized = 0;
@@ -1508,17 +1494,19 @@ static unsigned long mpu_timer_get_time(int dev)
        return curr_ticks;
 }
 
-static int mpu_timer_ioctl(int dev, unsigned int command, caddr_t arg)
+static int mpu_timer_ioctl(int dev, unsigned int command, void __user *arg)
 {
        int midi_dev = sound_timer_devs[dev]->devlink;
+       int __user *p = (int __user *)arg;
 
        switch (command)
        {
                case SNDCTL_TMR_SOURCE:
                        {
                                int parm;
-       
-                               parm = *(int *) arg;
+
+                               if (get_user(parm, p))
+                                       return -EFAULT;
                                parm &= timer_caps;
 
                                if (parm != 0)
@@ -1530,7 +1518,9 @@ static int mpu_timer_ioctl(int dev, unsigned int command, caddr_t arg)
                                        else if (timer_mode & TMR_MODE_SMPTE)
                                                mpu_cmd(midi_dev, 0x3d, 0);             /* Use SMPTE sync */
                                }
-                               return (*(int *) arg = timer_mode);
+                               if (put_user(timer_mode, p))
+                                       return -EFAULT;
+                               return timer_mode;
                        }
                        break;
 
@@ -1554,11 +1544,13 @@ static int mpu_timer_ioctl(int dev, unsigned int command, caddr_t arg)
                case SNDCTL_TMR_TIMEBASE:
                        {
                                int val;
-
-                               val = *(int *) arg;
+                               if (get_user(val, p))
+                                       return -EFAULT;
                                if (val)
                                        set_timebase(midi_dev, val);
-                               return (*(int *) arg = curr_timebase);
+                               if (put_user(curr_timebase, p))
+                                       return -EFAULT;
+                               return curr_timebase;
                        }
                        break;
 
@@ -1567,7 +1559,8 @@ static int mpu_timer_ioctl(int dev, unsigned int command, caddr_t arg)
                                int val;
                                int ret;
 
-                               val = *(int *) arg;
+                               if (get_user(val, p))
+                                       return -EFAULT;
 
                                if (val)
                                {
@@ -1582,26 +1575,35 @@ static int mpu_timer_ioctl(int dev, unsigned int command, caddr_t arg)
                                        }
                                        curr_tempo = val;
                                }
-                               return (*(int *) arg = curr_tempo);
+                               if (put_user(curr_tempo, p))
+                                       return -EFAULT;
+                               return curr_tempo;
                        }
                        break;
 
                case SNDCTL_SEQ_CTRLRATE:
                        {
                                int val;
+                               if (get_user(val, p))
+                                       return -EFAULT;
 
-                               val = *(int *) arg;
                                if (val != 0)           /* Can't change */
                                        return -EINVAL;
-                               return (*(int *) arg = ((curr_tempo * curr_timebase) + 30) / 60);
+                               val = ((curr_tempo * curr_timebase) + 30)/60;
+                               if (put_user(val, p))
+                                       return -EFAULT;
+                               return val;
                        }
                        break;
 
                case SNDCTL_SEQ_GETTIME:
-                       return (*(int *) arg = curr_ticks);
+                       if (put_user(curr_ticks, p))
+                               return -EFAULT;
+                       return curr_ticks;
 
                case SNDCTL_TMR_METRONOME:
-                       metronome_mode = *(int *) arg;
+                       if (get_user(metronome_mode, p))
+                               return -EFAULT;
                        setup_metronome(midi_dev);
                        return 0;
 
@@ -1777,10 +1779,16 @@ static int __init init_mpu401(void)
        /* Can be loaded either for module use or to provide functions
           to others */
        if (io != -1 && irq != -1) {
+               struct resource *ports;
                cfg.irq = irq;
                cfg.io_base = io;
-               if (probe_mpu401(&cfg) == 0)
+               ports = request_region(io, 2, "mpu401");
+               if (!ports)
+                       return -EBUSY;
+               if (probe_mpu401(&cfg, ports) == 0) {
+                       release_region(io, 2);
                        return -ENODEV;
+               }
                if ((ret = attach_mpu401(&cfg, THIS_MODULE)))
                        return ret;
        }