diff -urpN --exclude-from=/home/davej/.exclude bk-linus/sound/oss/mpu401.c linux-2.5/sound/oss/mpu401.c --- bk-linus/sound/oss/mpu401.c 2002-11-21 02:26:07.000000000 +0000 +++ linux-2.5/sound/oss/mpu401.c 2002-11-21 18:06:20.000000000 +0000 @@ -15,6 +15,7 @@ * Alan Cox modularisation, use normal request_irq, use dev_id * Bartlomiej Zolnierkiewicz removed some __init to allow using many drivers * Chris Rankin Update the module-usage counter for the coprocessor + * Zwane Mwaikambo Changed attach/unload resource freeing */ #include @@ -79,7 +80,7 @@ struct mpu_config static void mpu401_close(int dev); -static int mpu401_status(struct mpu_config *devc) +static inline int mpu401_status(struct mpu_config *devc) { return inb(STATPORT(devc->base)); } @@ -87,17 +88,17 @@ static int mpu401_status(struct mpu_conf #define input_avail(devc) (!(mpu401_status(devc)&INPUT_AVAIL)) #define output_ready(devc) (!(mpu401_status(devc)&OUTPUT_READY)) -static void write_command(struct mpu_config *devc, unsigned char cmd) +static inline void write_command(struct mpu_config *devc, unsigned char cmd) { outb(cmd, COMDPORT(devc->base)); } -static int read_data(struct mpu_config *devc) +static inline int read_data(struct mpu_config *devc) { return inb(DATAPORT(devc->base)); } -static void write_data(struct mpu_config *devc, unsigned char byte) +static inline void write_data(struct mpu_config *devc, unsigned char byte) { outb(byte, DATAPORT(devc->base)); } @@ -962,12 +963,12 @@ static void mpu401_chk_version(int n, st spin_unlock_irqrestore(&devc->lock,flags); } -void attach_mpu401(struct address_info *hw_config, struct module *owner) +int attach_mpu401(struct address_info *hw_config, struct module *owner) { unsigned long flags; char revision_char; - int m; + int m, ret; struct mpu_config *devc; hw_config->slots[1] = -1; @@ -975,7 +976,8 @@ void attach_mpu401(struct address_info * if (m == -1) { printk(KERN_WARNING "MPU-401: Too many midi devices detected\n"); - return; + ret = -ENOMEM; + goto out_err; } devc = &dev_conf[m]; devc->base = hw_config->io_base; @@ -1006,16 +1008,16 @@ void attach_mpu401(struct address_info * if (!reset_mpu401(devc)) { printk(KERN_WARNING "mpu401: Device didn't respond\n"); - sound_unload_mididev(m); - return; + ret = -ENODEV; + goto out_mididev; } if (!devc->shared_irq) { if (request_irq(devc->irq, mpuintr, 0, "mpu401", (void *)m) < 0) { printk(KERN_WARNING "mpu401: Failed to allocate IRQ%d\n", devc->irq); - sound_unload_mididev(m); - return; + ret = -ENOMEM; + goto out_mididev; } } spin_lock_irqsave(&devc->lock,flags); @@ -1024,7 +1026,12 @@ void attach_mpu401(struct address_info * mpu401_chk_version(m, devc); spin_unlock_irqrestore(&devc->lock,flags); } - request_region(hw_config->io_base, 2, "mpu401"); + + 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 */ @@ -1036,9 +1043,9 @@ void attach_mpu401(struct address_info * if (mpu401_synth_operations[m] == NULL) { - sound_unload_mididev(m); printk(KERN_ERR "mpu401: Can't allocate memory\n"); - return; + ret = -ENOMEM; + goto out_resource; } if (!(devc->capabilities & MPU_CAP_INTLG)) /* No intelligent mode */ { @@ -1117,6 +1124,17 @@ void attach_mpu401(struct address_info * hw_config->slots[1] = m; sequencer_init(); + + 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: + return ret; } static int reset_mpu401(struct mpu_config *devc) @@ -1227,15 +1245,17 @@ void unload_mpu401(struct address_info * { void *p; int n=hw_config->slots[1]; - - release_region(hw_config->io_base, 2); - if (hw_config->always_detect == 0 && hw_config->irq > 0) - free_irq(hw_config->irq, (void *)n); - p=mpu401_synth_operations[n]; - sound_unload_mididev(n); - sound_unload_timerdev(hw_config->slots[2]); - if(p) - kfree(p); + + if (n != -1) { + release_region(hw_config->io_base, 2); + if (hw_config->always_detect == 0 && hw_config->irq > 0) + free_irq(hw_config->irq, (void *)n); + p=mpu401_synth_operations[n]; + sound_unload_mididev(n); + sound_unload_timerdev(hw_config->slots[2]); + if(p) + kfree(p); + } } /***************************************************** @@ -1752,6 +1772,7 @@ MODULE_PARM(io, "i"); int __init init_mpu401(void) { + int ret; /* Can be loaded either for module use or to provide functions to others */ if (io != -1 && irq != -1) { @@ -1759,7 +1780,8 @@ int __init init_mpu401(void) cfg.io_base = io; if (probe_mpu401(&cfg) == 0) return -ENODEV; - attach_mpu401(&cfg, THIS_MODULE); + if ((ret = attach_mpu401(&cfg, THIS_MODULE))) + return ret; } return 0;