vserver 1.9.5.x5
[linux-2.6.git] / sound / oss / opl3sa2.c
index 6057e07..7b4996e 100644 (file)
@@ -177,9 +177,6 @@ static int __initdata loopback      = -1;
 static int __initdata isapnp = 1;
 static int __initdata multiple = 1;
 
-/* PnP devices */
-struct pnp_dev* opl3sa2_dev[OPL3SA2_CARDS_MAX];
-
 /* Whether said devices have been activated */
 static int opl3sa2_activated[OPL3SA2_CARDS_MAX];
 #else
@@ -192,35 +189,35 @@ MODULE_AUTHOR("Scott Murray <scott@spiteful.org>");
 MODULE_LICENSE("GPL");
 
 
-MODULE_PARM(io, "i");
+module_param(io, int, 0);
 MODULE_PARM_DESC(io, "Set I/O base of OPL3-SA2 or SA3 card (usually 0x370.  Address must be even and must be from 0x100 to 0xFFE)");
 
-MODULE_PARM(mss_io, "i");
+module_param(mss_io, int, 0);
 MODULE_PARM_DESC(mss_io, "Set MSS (audio) I/O base (0x530, 0xE80, or other. Address must end in 0 or 4 and must be from 0x530 to 0xF48)");
 
-MODULE_PARM(mpu_io, "i");
+module_param(mpu_io, int, 0);
 MODULE_PARM_DESC(mpu_io, "Set MIDI I/O base (0x330 or other. Address must be even and must be from 0x300 to 0x334)");
 
-MODULE_PARM(irq, "i");
+module_param(irq, int, 0);
 MODULE_PARM_DESC(mss_irq, "Set MSS (audio) IRQ (5, 7, 9, 10, 11, 12)");
 
-MODULE_PARM(dma, "i");
+module_param(dma, int, 0);
 MODULE_PARM_DESC(dma, "Set MSS (audio) first DMA channel (0, 1, 3)");
 
-MODULE_PARM(dma2, "i");
+module_param(dma2, int, 0);
 MODULE_PARM_DESC(dma2, "Set MSS (audio) second DMA channel (0, 1, 3)");
 
-MODULE_PARM(ymode, "i");
+module_param(ymode, int, 0);
 MODULE_PARM_DESC(ymode, "Set Yamaha 3D enhancement mode (0 = Desktop/Normal, 1 = Notebook PC (1), 2 = Notebook PC (2), 3 = Hi-Fi)");
 
-MODULE_PARM(loopback, "i");
+module_param(loopback, int, 0);
 MODULE_PARM_DESC(loopback, "Set A/D input source. Useful for echo cancellation (0 = Mic Rch (default), 1 = Mono output loopback)");
 
 #ifdef CONFIG_PNP
-MODULE_PARM(isapnp, "i");
+module_param(isapnp, bool, 0);
 MODULE_PARM_DESC(isapnp, "When set to 0, ISA PnP support will be disabled");
 
-MODULE_PARM(multiple, "i");
+module_param(multiple, bool, 0);
 MODULE_PARM_DESC(multiple, "When set to 0, will not search for multiple cards");
 #endif
 
@@ -389,9 +386,10 @@ static inline int ret_vol_stereo(int left, int right)
 }
 
 
-static int opl3sa2_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
+static int opl3sa2_mixer_ioctl(int dev, unsigned int cmd, void __user *arg)
 {
        int retval, value, cmdf = cmd & 0xff;
+       int __user *p = (int __user *)arg;
 
        opl3sa2_state_t* devc = &opl3sa2_state[dev];
        
@@ -416,23 +414,23 @@ static int opl3sa2_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
        if (_SIOC_DIR (cmd) & _SIOC_WRITE) {
                switch (cmdf) {
                        case SOUND_MIXER_VOLUME:
-                               retval = get_user(value, (unsigned int *) arg);
+                               retval = get_user(value, (unsigned __user *) arg);
                                if (retval)
                                        break;
                                arg_to_vol_stereo(value, &devc->volume_l, &devc->volume_r);
                                opl3sa2_set_volume(devc, devc->volume_l, devc->volume_r);
                                value = ret_vol_stereo(devc->volume_l, devc->volume_r);
-                               retval = put_user(value, (int *) arg);
+                               retval = put_user(value, p);
                                break;
                  
                        case SOUND_MIXER_MIC:
-                               retval = get_user(value, (unsigned int *) arg);
+                               retval = get_user(value, (unsigned __user *) arg);
                                if (retval)
                                        break;
                                arg_to_vol_mono(value, &devc->mic);
                                opl3sa2_set_mic(devc, devc->mic);
                                value = ret_vol_mono(devc->mic);
-                               retval = put_user(value, (int *) arg);
+                               retval = put_user(value, p);
                                break;
 
                        default:
@@ -445,35 +443,35 @@ static int opl3sa2_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
                 */
                switch (cmdf) {
                        case SOUND_MIXER_DEVMASK:
-                               retval = put_user(SOUND_MASK_VOLUME | SOUND_MASK_MIC, (int *) arg);
+                               retval = put_user(SOUND_MASK_VOLUME | SOUND_MASK_MIC, p);
                                break;
                  
                        case SOUND_MIXER_STEREODEVS:
-                               retval = put_user(SOUND_MASK_VOLUME, (int *) arg);
+                               retval = put_user(SOUND_MASK_VOLUME, p);
                                break;
                  
                        case SOUND_MIXER_RECMASK:
                                /* No recording devices */
-                               retval = put_user(0, (int *) arg);
+                               retval = put_user(0, p);
                                break;
 
                        case SOUND_MIXER_CAPS:
-                               retval = put_user(SOUND_CAP_EXCL_INPUT, (int *) arg);
+                               retval = put_user(SOUND_CAP_EXCL_INPUT, p);
                                break;
 
                        case SOUND_MIXER_RECSRC:
                                /* No recording source */
-                               retval = put_user(0, (int *) arg);
+                               retval = put_user(0, p);
                                break;
 
                        case SOUND_MIXER_VOLUME:
                                value = ret_vol_stereo(devc->volume_l, devc->volume_r);
-                               retval = put_user(value, (int *) arg);
+                               retval = put_user(value, p);
                                break;
                          
                        case SOUND_MIXER_MIC:
                                value = ret_vol_mono(devc->mic);
-                               put_user(value, (int *) arg);
+                               put_user(value, p);
                                break;
 
                        default:
@@ -485,7 +483,7 @@ static int opl3sa2_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
 /* opl3sa2_mixer_ioctl end */
 
 
-static int opl3sa3_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
+static int opl3sa3_mixer_ioctl(int dev, unsigned int cmd, void __user * arg)
 {
        int value, retval, cmdf = cmd & 0xff;
 
@@ -494,17 +492,17 @@ static int opl3sa3_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
        switch (cmdf) {
        case SOUND_MIXER_BASS:
                value = ret_vol_stereo(devc->bass_l, devc->bass_r);
-               retval = put_user(value, (int *) arg);
+               retval = put_user(value, (int __user *) arg);
                break;
                
        case SOUND_MIXER_TREBLE:
                value = ret_vol_stereo(devc->treble_l, devc->treble_r);
-               retval = put_user(value, (int *) arg);
+               retval = put_user(value, (int __user *) arg);
                break;
 
        case SOUND_MIXER_DIGITAL1:
                value = ret_vol_stereo(devc->wide_l, devc->wide_r);
-               retval = put_user(value, (int *) arg);
+               retval = put_user(value, (int __user *) arg);
                break;
 
        default:
@@ -538,36 +536,18 @@ static struct mixer_operations opl3sa3_mixer_operations =
  * Component probe, attach, unload functions
  */
 
-static inline int __init probe_opl3sa2_mpu(struct address_info* hw_config)
-{
-       return probe_mpu401(hw_config);
-}
-
-
-static inline int __init attach_opl3sa2_mpu(struct address_info* hw_config)
-{
-       return attach_mpu401(hw_config, THIS_MODULE);
-}
-
-
 static inline void __exit unload_opl3sa2_mpu(struct address_info *hw_config)
 {
        unload_mpu401(hw_config);
 }
 
 
-static inline int __init probe_opl3sa2_mss(struct address_info* hw_config)
-{
-       return probe_ms_sound(hw_config);
-}
-
-
-static void __init attach_opl3sa2_mss(struct address_info* hw_config)
+static void __init attach_opl3sa2_mss(struct address_info* hw_config, struct resource *ports)
 {
        int initial_mixers;
 
        initial_mixers = num_mixers;
-       attach_ms_sound(hw_config, THIS_MODULE);        /* Slot 0 */
+       attach_ms_sound(hw_config, ports, THIS_MODULE); /* Slot 0 */
        if (hw_config->slots[0] != -1) {
                /* Did the MSS driver install? */
                if(num_mixers == (initial_mixers + 1)) {
@@ -731,7 +711,7 @@ static void __init attach_opl3sa2_mixer(struct address_info *hw_config, int card
 }
 
 
-static void __init opl3sa2_clear_slots(struct address_info* hw_config)
+static void opl3sa2_clear_slots(struct address_info* hw_config)
 {
        int i;
 
@@ -792,7 +772,7 @@ static void __exit unload_opl3sa2(struct address_info* hw_config, int card)
 }
 
 #ifdef CONFIG_PNP
-struct pnp_device_id pnp_opl3sa2_list[] = {
+static struct pnp_device_id pnp_opl3sa2_list[] = {
        {.id = "YMH0021", .driver_data = 0},
        {.id = ""}
 };
@@ -852,7 +832,7 @@ static struct pnp_driver opl3sa2_driver = {
 /* End of component functions */
 
 #ifdef CONFIG_PM
-static spinlock_t opl3sa2_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(opl3sa2_lock);
 
 /* Power Management support functions */
 static int opl3sa2_suspend(struct pm_dev *pdev, unsigned int pm_mode)
@@ -956,6 +936,8 @@ static int __init init_opl3sa2(void)
 
        for (card = 0; card < max; card++) {
                /* If a user wants an I/O then assume they meant it */
+               struct resource *ports;
+               int base;
                
                if (!isapnp) {
                        if (io == -1 || irq == -1 || dma == -1 ||
@@ -994,17 +976,30 @@ static int __init init_opl3sa2(void)
                        opl3sa2_clear_slots(&opl3sa2_state[card].cfg_mpu);
                }
 
+               /* FIXME: leak */
                if (probe_opl3sa2(&opl3sa2_state[card].cfg, card))
                        return -ENODEV;
 
+               base = opl3sa2_state[card].cfg_mss.io_base;
+
+               if (!request_region(base, 4, "WSS config"))
+                       goto failed;
 
-               if (!probe_opl3sa2_mss(&opl3sa2_state[card].cfg_mss)) {
+               ports = request_region(base + 4, 4, "ad1848");
+               if (!ports)
+                       goto failed2;
+
+               if (!probe_ms_sound(&opl3sa2_state[card].cfg_mss, ports)) {
                        /*
                         * If one or more cards are already registered, don't
                         * return an error but print a warning.  Note, this
                         * should never really happen unless the hardware or
                         * ISA PnP screwed up.
                         */
+                       release_region(base + 4, 4);
+               failed2:
+                       release_region(base, 4);
+               failed:
                        release_region(opl3sa2_state[card].cfg.io_base, 2);
 
                        if (opl3sa2_cards_num) {
@@ -1020,7 +1015,7 @@ static int __init init_opl3sa2(void)
                attach_opl3sa2(&opl3sa2_state[card].cfg, card);
                conf_printf(opl3sa2_state[card].chipset_name, &opl3sa2_state[card].cfg);
                attach_opl3sa2_mixer(&opl3sa2_state[card].cfg, card);
-               attach_opl3sa2_mss(&opl3sa2_state[card].cfg_mss);
+               attach_opl3sa2_mss(&opl3sa2_state[card].cfg_mss, ports);
 
                /* ewww =) */
                opl3sa2_state[card].card = card;
@@ -1053,15 +1048,23 @@ static int __init init_opl3sa2(void)
                
                /* Attach MPU if we've been asked to do so, failure isn't fatal */
                if (opl3sa2_state[card].cfg_mpu.io_base != -1) {
-                       if (probe_opl3sa2_mpu(&opl3sa2_state[card].cfg_mpu)) {
-                               if (attach_opl3sa2_mpu(&opl3sa2_state[card].cfg_mpu)) {
-                                       printk(KERN_ERR PFX "failed to attach MPU401\n");
-                                       opl3sa2_state[card].cfg_mpu.slots[1] = -1;
-                               }
+                       int base = opl3sa2_state[card].cfg_mpu.io_base;
+                       struct resource *ports;
+                       ports = request_region(base, 2, "mpu401");
+                       if (!ports)
+                               goto out;
+                       if (!probe_mpu401(&opl3sa2_state[card].cfg_mpu, ports)) {
+                               release_region(base, 2);
+                               goto out;
+                       }
+                       if (attach_mpu401(&opl3sa2_state[card].cfg_mpu, THIS_MODULE)) {
+                               printk(KERN_ERR PFX "failed to attach MPU401\n");
+                               opl3sa2_state[card].cfg_mpu.slots[1] = -1;
                        }
                }
        }
 
+out:
        if (isapnp) {
                printk(KERN_NOTICE PFX "%d PnP card(s) found.\n", opl3sa2_cards_num);
        }