Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / sound / oss / mad16.c
index 4c5db81..aa3c50d 100644 (file)
 #include "sb.h"
 #include "mpu401.h"
 
+#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
+#define SUPPORT_JOYSTICK 1
+#endif
+
 static int      mad16_conf;
 static int      mad16_cdsel;
-static struct gameport gameport;
-static spinlock_t lock=SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(lock);
 
 #define C928   1
 #define MOZART 2
@@ -874,19 +877,19 @@ static int __initdata cddma = -1;
 static int __initdata opl4 = 0;
 static int __initdata joystick = 0;
 
-MODULE_PARM(mpu_io, "i");
-MODULE_PARM(mpu_irq, "i");
-MODULE_PARM(io,"i");
-MODULE_PARM(dma,"i");
-MODULE_PARM(dma16,"i");
-MODULE_PARM(irq,"i");
-MODULE_PARM(cdtype,"i");
-MODULE_PARM(cdirq,"i");
-MODULE_PARM(cdport,"i");
-MODULE_PARM(cddma,"i");
-MODULE_PARM(opl4,"i");
-MODULE_PARM(joystick,"i");
-MODULE_PARM(debug,"i");
+module_param(mpu_io, int, 0);
+module_param(mpu_irq, int, 0);
+module_param(io, int, 0);
+module_param(dma, int, 0);
+module_param(dma16, int, 0);
+module_param(irq, int, 0);
+module_param(cdtype, int, 0);
+module_param(cdirq, int, 0);
+module_param(cdport, int, 0);
+module_param(cddma, int, 0);
+module_param(opl4, int, 0);
+module_param(joystick, bool, 0);
+module_param(debug, bool, 0644);
 
 static int __initdata dma_map[2][8] =
 {
@@ -902,7 +905,48 @@ static int __initdata irq_map[16] =
        -1, -1, -1, -1
 };
 
-static int __init init_mad16(void)
+#ifdef SUPPORT_JOYSTICK
+
+static struct gameport *gameport;
+
+static int __devinit mad16_register_gameport(int io_port)
+{
+       if (!request_region(io_port, 1, "mad16 gameport")) {
+               printk(KERN_ERR "mad16: gameport address 0x%#x already in use\n", io_port);
+               return -EBUSY;
+       }
+
+       gameport = gameport_allocate_port();
+       if (!gameport) {
+               printk(KERN_ERR "mad16: can not allocate memory for gameport\n");
+               release_region(io_port, 1);
+               return -ENOMEM;
+       }
+
+       gameport_set_name(gameport, "MAD16 Gameport");
+       gameport_set_phys(gameport, "isa%04x/gameport0", io_port);
+       gameport->io = io_port;
+
+       gameport_register_port(gameport);
+
+       return 0;
+}
+
+static inline void mad16_unregister_gameport(void)
+{
+       if (gameport) {
+               /* the gameport was initialized so we must free it up */
+               gameport_unregister_port(gameport);
+               gameport = NULL;
+               release_region(0x201, 1);
+       }
+}
+#else
+static inline int mad16_register_gameport(int io_port) { return -ENOSYS; }
+static inline void mad16_unregister_gameport(void) { }
+#endif
+
+static int __devinit init_mad16(void)
 {
        int dmatype = 0;
 
@@ -1027,17 +1071,9 @@ static int __init init_mad16(void)
 
        found_mpu = probe_mad16_mpu(&cfg_mpu);
 
-       if (joystick == 1) {
-               /* register gameport */
-               if (!request_region(0x201, 1, "mad16 gameport"))
-                       printk(KERN_ERR "mad16: gameport address 0x201 already in use\n");
-               else {
-                       printk(KERN_ERR "mad16: gameport enabled at 0x201\n");
-                       gameport.io = 0x201;
-                       gameport_register_port(&gameport);
-               }
-       }
-       else printk(KERN_ERR "mad16: gameport disabled.\n");
+       if (joystick)
+               mad16_register_gameport(0x201);
+
        return 0;
 }
 
@@ -1045,12 +1081,7 @@ static void __exit cleanup_mad16(void)
 {
        if (found_mpu)
                unload_mad16_mpu(&cfg_mpu);
-       if (gameport.io) {
-               /* the gameport was initialized so we must free it up */
-               gameport_unregister_port(&gameport);
-               gameport.io = 0;
-               release_region(0x201, 1);
-       }
+       mad16_unregister_gameport();
        unload_mad16(&cfg);
        release_region(MC0_PORT, 12);
 }