Commit db1005ec authored by Takashi Iwai's avatar Takashi Iwai

ALSA: riptide - Fix joystick resource handling

The current code doesn't handle the multiple gameports properly,
and uses unnecessary global static variables to store the data.
This patch changes the probe / remove routines to use the driver
data assigned to the dedicated pci device, and adds the support of
multiple devices.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent a693a26f
...@@ -2014,14 +2014,12 @@ static int __devinit snd_riptide_mixer(struct snd_riptide *chip) ...@@ -2014,14 +2014,12 @@ static int __devinit snd_riptide_mixer(struct snd_riptide *chip)
} }
#ifdef SUPPORT_JOYSTICK #ifdef SUPPORT_JOYSTICK
static int have_joystick;
static struct pci_dev *riptide_gameport_pci;
static struct gameport *riptide_gameport;
static int __devinit static int __devinit
snd_riptide_joystick_probe(struct pci_dev *pci, const struct pci_device_id *id) snd_riptide_joystick_probe(struct pci_dev *pci, const struct pci_device_id *id)
{ {
static int dev; static int dev;
struct gameport *gameport;
if (dev >= SNDRV_CARDS) if (dev >= SNDRV_CARDS)
return -ENODEV; return -ENODEV;
...@@ -2030,36 +2028,33 @@ snd_riptide_joystick_probe(struct pci_dev *pci, const struct pci_device_id *id) ...@@ -2030,36 +2028,33 @@ snd_riptide_joystick_probe(struct pci_dev *pci, const struct pci_device_id *id)
return -ENOENT; return -ENOENT;
} }
if (joystick_port[dev]) { if (!joystick_port[dev++])
riptide_gameport = gameport_allocate_port(); return 0;
if (riptide_gameport) {
if (!request_region gameport = gameport_allocate_port();
(joystick_port[dev], 8, "Riptide gameport")) { if (!gameport)
return -ENOMEM;
if (!request_region(joystick_port[dev], 8, "Riptide gameport")) {
snd_printk(KERN_WARNING snd_printk(KERN_WARNING
"Riptide: cannot grab gameport 0x%x\n", "Riptide: cannot grab gameport 0x%x\n",
joystick_port[dev]); joystick_port[dev]);
gameport_free_port(riptide_gameport); gameport_free_port(gameport);
riptide_gameport = NULL; return -EBUSY;
} else {
riptide_gameport_pci = pci;
riptide_gameport->io = joystick_port[dev];
gameport_register_port(riptide_gameport);
}
}
} }
dev++;
gameport->io = joystick_port[dev];
gameport_register_port(gameport);
pci_set_drvdata(pci, gameport);
return 0; return 0;
} }
static void __devexit snd_riptide_joystick_remove(struct pci_dev *pci) static void __devexit snd_riptide_joystick_remove(struct pci_dev *pci)
{ {
if (riptide_gameport) { struct gameport *gameport = pci_get_drvdata(pci);
if (riptide_gameport_pci == pci) { if (gameport) {
release_region(riptide_gameport->io, 8); release_region(gameport->io, 8);
riptide_gameport_pci = NULL; gameport_unregister_port(gameport);
gameport_unregister_port(riptide_gameport); pci_set_drvdata(pci, NULL);
riptide_gameport = NULL;
}
} }
} }
#endif #endif
...@@ -2198,14 +2193,11 @@ static struct pci_driver joystick_driver = { ...@@ -2198,14 +2193,11 @@ static struct pci_driver joystick_driver = {
static int __init alsa_card_riptide_init(void) static int __init alsa_card_riptide_init(void)
{ {
int err; int err;
if ((err = pci_register_driver(&driver)) < 0) err = pci_register_driver(&driver);
if (err < 0)
return err; return err;
#if defined(SUPPORT_JOYSTICK) #if defined(SUPPORT_JOYSTICK)
if (pci_register_driver(&joystick_driver) < 0) { pci_register_driver(&joystick_driver);
have_joystick = 0;
snd_printk(KERN_INFO "no joystick found\n");
} else
have_joystick = 1;
#endif #endif
return 0; return 0;
} }
...@@ -2214,7 +2206,6 @@ static void __exit alsa_card_riptide_exit(void) ...@@ -2214,7 +2206,6 @@ static void __exit alsa_card_riptide_exit(void)
{ {
pci_unregister_driver(&driver); pci_unregister_driver(&driver);
#if defined(SUPPORT_JOYSTICK) #if defined(SUPPORT_JOYSTICK)
if (have_joystick)
pci_unregister_driver(&joystick_driver); pci_unregister_driver(&joystick_driver);
#endif #endif
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment