X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Foss%2Fmpu401.c;h=73c3ce32a69def591fd1fa2f9fa65ceb838f21cf;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=0059ee08d3b0b4a6047c472ce46605f00315cb94;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/sound/oss/mpu401.c b/sound/oss/mpu401.c index 0059ee08d..73c3ce32a 100644 --- a/sound/oss/mpu401.c +++ b/sound/oss/mpu401.c @@ -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; }