vserver 1.9.5.x5
[linux-2.6.git] / sound / oss / gus_wave.c
index 1aadc7e..b1f5c8c 100644 (file)
@@ -94,7 +94,7 @@ static int      recording_active;
 static int      only_read_access;
 static int      only_8_bits;
 
-int             iw_mode = 0;
+static int      iw_mode = 0;
 int             gus_wave_volume = 60;
 int             gus_pcm_volume = 80;
 int             have_gus_max = 0;
@@ -139,7 +139,7 @@ static int      pcm_current_block;
 static unsigned long pcm_current_buf;
 static int      pcm_current_count;
 static int      pcm_current_intrflag;
-spinlock_t gus_lock=SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(gus_lock);
 
 extern int     *gus_osp;
 
@@ -978,6 +978,13 @@ int __init gus_wave_detect(int baseaddr)
        unsigned long   loc;
        unsigned char   val;
 
+       if (!request_region(baseaddr, 16, "GUS"))
+               return 0;
+       if (!request_region(baseaddr + 0x100, 12, "GUS")) { /* 0x10c-> is MAX */
+               release_region(baseaddr, 16);
+               return 0;
+       }
+
        gus_base = baseaddr;
 
        gus_write8(0x4c, 0);    /* Reset GF1 */
@@ -1015,8 +1022,11 @@ int __init gus_wave_detect(int baseaddr)
 
        /* See if there is first block there.... */
        gus_poke(0L, 0xaa);
-       if (gus_peek(0L) != 0xaa)
-               return (0);
+       if (gus_peek(0L) != 0xaa) {
+               release_region(baseaddr + 0x100, 12);
+               release_region(baseaddr, 16);
+               return 0;
+       }
 
        /* Now zero it out so that I can check for mirroring .. */
        gus_poke(0L, 0x00);
@@ -1045,7 +1055,7 @@ int __init gus_wave_detect(int baseaddr)
        return 1;
 }
 
-static int guswave_ioctl(int dev, unsigned int cmd, caddr_t arg)
+static int guswave_ioctl(int dev, unsigned int cmd, void __user *arg)
 {
 
        switch (cmd) 
@@ -1622,7 +1632,7 @@ static void guswave_close(int dev)
                DMAbuf_close_dma(gus_devnum);
 }
 
-static int guswave_load_patch(int dev, int format, const char *addr,
+static int guswave_load_patch(int dev, int format, const char __user *addr,
                   int offs, int count, int pmgr_flag)
 {
        struct patch_info patch;
@@ -1780,7 +1790,7 @@ static int guswave_load_patch(int dev, int format, const char *addr,
 
                        for (i = 0; i < blk_sz; i++)
                        {
-                               get_user(*(unsigned char *) &data, (unsigned char *) &((addr)[sizeof_patch + i]));
+                               get_user(*(unsigned char *) &data, (unsigned char __user *) &((addr)[sizeof_patch + i]));
                                if (patch.mode & WAVE_UNSIGNED)
                                        if (!(patch.mode & WAVE_16_BITS) || (i & 0x01))
                                                data ^= 0x80;   /* Convert to signed */
@@ -2082,14 +2092,14 @@ static int gus_audio_set_bits(int bits)
        return bits;
 }
 
-static int gus_audio_ioctl(int dev, unsigned int cmd, caddr_t arg)
+static int gus_audio_ioctl(int dev, unsigned int cmd, void __user *arg)
 {
        int val;
 
        switch (cmd) 
        {
                case SOUND_PCM_WRITE_RATE:
-                       if (get_user(val, (int *)arg))
+                       if (get_user(val, (int __user*)arg))
                                return -EFAULT;
                        val = gus_audio_set_speed(val);
                        break;
@@ -2099,13 +2109,13 @@ static int gus_audio_ioctl(int dev, unsigned int cmd, caddr_t arg)
                        break;
 
                case SNDCTL_DSP_STEREO:
-                       if (get_user(val, (int *)arg))
+                       if (get_user(val, (int __user *)arg))
                                return -EFAULT;
                        val = gus_audio_set_channels(val + 1) - 1;
                        break;
 
                case SOUND_PCM_WRITE_CHANNELS:
-                       if (get_user(val, (int *)arg))
+                       if (get_user(val, (int __user *)arg))
                                return -EFAULT;
                        val = gus_audio_set_channels(val);
                        break;
@@ -2115,7 +2125,7 @@ static int gus_audio_ioctl(int dev, unsigned int cmd, caddr_t arg)
                        break;
                
                case SNDCTL_DSP_SETFMT:
-                       if (get_user(val, (int *)arg))
+                       if (get_user(val, (int __user *)arg))
                                return -EFAULT;
                        val = gus_audio_set_bits(val);
                        break;
@@ -2131,7 +2141,7 @@ static int gus_audio_ioctl(int dev, unsigned int cmd, caddr_t arg)
                default:
                        return -EINVAL;
        }
-       return put_user(val, (int *)arg);
+       return put_user(val, (int __user *)arg);
 }
 
 static void gus_audio_reset(int dev)
@@ -2687,19 +2697,19 @@ static void set_input_volumes(void)
 #define MIX_DEVS       (SOUND_MASK_MIC|SOUND_MASK_LINE| \
                         SOUND_MASK_SYNTH|SOUND_MASK_PCM)
 
-int gus_default_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
+int gus_default_mixer_ioctl(int dev, unsigned int cmd, void __user *arg)
 {
        int vol, val;
 
        if (((cmd >> 8) & 0xff) != 'M')
                return -EINVAL;
 
-       if (!access_ok(VERIFY_WRITE, (int *)arg, sizeof(int)))
+       if (!access_ok(VERIFY_WRITE, arg, sizeof(int)))
                return -EFAULT;
 
        if (_SIOC_DIR(cmd) & _SIOC_WRITE) 
        {
-               if (__get_user(val, (int *) arg))
+               if (__get_user(val, (int __user *) arg))
                        return -EFAULT;
 
                switch (cmd & 0xff) 
@@ -2810,7 +2820,7 @@ int gus_default_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
                                return -EINVAL;
                }
        }
-       return __put_user(val, (int *)arg);
+       return __put_user(val, (int __user *)arg);
 }
 
 static struct mixer_operations gus_mixer_operations =
@@ -2932,6 +2942,8 @@ void __init gus_wave_init(struct address_info *hw_config)
                }
                else
                {
+                       struct resource *ports;
+                       ports = request_region(gus_base + 0x10c, 4, "ad1848");
                        model_num = "MAX";
                        gus_type = 0x40;
                        mixer_type = CS4231;
@@ -2953,7 +2965,10 @@ void __init gus_wave_init(struct address_info *hw_config)
                                outb((max_config), gus_base + 0x106);   /* UltraMax control */
                        }
 
-                       if (ad1848_detect(gus_base + 0x10c, &ad_flags, hw_config->osp))
+                       if (!ports)
+                               goto no_cs4231;
+
+                       if (ad1848_detect(ports, &ad_flags, hw_config->osp))
                        {
                                char           *name = "GUS MAX";
                                int             old_num_mixers = num_mixers;
@@ -2967,7 +2982,7 @@ void __init gus_wave_init(struct address_info *hw_config)
                                if (hw_config->name)
                                        name = hw_config->name;
 
-                               hw_config->slots[1] = ad1848_init(name, gus_base + 0x10c,
+                               hw_config->slots[1] = ad1848_init(name, ports,
                                                        -irq, gus_dma2, /* Playback DMA */
                                                        gus_dma,        /* Capture DMA */
                                                        1,              /* Share DMA channels with GF1 */
@@ -2982,8 +2997,11 @@ void __init gus_wave_init(struct address_info *hw_config)
                                        AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE);
                                }
                        }
-                       else
+                       else {
+                               release_region(gus_base + 0x10c, 4);
+                       no_cs4231:
                                printk(KERN_WARNING "GUS: No CS4231 ??");
+                       }
 #else
                        printk(KERN_ERR "GUS MAX found, but not compiled in\n");
 #endif