X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Foss%2Fsb_card.c;h=8666291c00523fccca590df1d6a5fbedbf6c28c7;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=b5f5ecbf25a95d9de93052e904de489b761a35cc;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/sound/oss/sb_card.c b/sound/oss/sb_card.c index b5f5ecbf2..8666291c0 100644 --- a/sound/oss/sb_card.c +++ b/sound/oss/sb_card.c @@ -22,13 +22,9 @@ * 02-07-2003 Bug made it into first release. Take two. */ -#include #include #include #include -#ifdef CONFIG_MCA -#include -#endif /* CONFIG_MCA */ #include "sound_config.h" #include "sb_mixer.h" #include "sb.h" @@ -52,9 +48,10 @@ static int __initdata esstype = 0; /* ESS chip type */ static int __initdata acer = 0; /* Do acer notebook init? */ static int __initdata sm_games = 0; /* Logitech soundman games? */ -struct sb_card_config *legacy = NULL; +static struct sb_card_config *legacy = NULL; #ifdef CONFIG_PNP +static int pnp_registered; static int __initdata pnp = 1; /* static int __initdata uart401 = 0; @@ -100,7 +97,14 @@ MODULE_PARM_DESC(uart401, "When set to 1, will attempt to detect and enable"\ /* OSS subsystem card registration shared by PnP and legacy routines */ static int sb_register_oss(struct sb_card_config *scc, struct sb_module_options *sbmo) { - if(!sb_dsp_detect(&scc->conf, 0, 0, sbmo)) { + if (!request_region(scc->conf.io_base, 16, "soundblaster")) { + printk(KERN_ERR "sb: ports busy.\n"); + kfree(scc); + return -EBUSY; + } + + if (!sb_dsp_detect(&scc->conf, 0, 0, sbmo)) { + release_region(scc->conf.io_base, 16); printk(KERN_ERR "sb: Failed DSP Detect.\n"); kfree(scc); return -ENODEV; @@ -129,7 +133,7 @@ static void sb_unload(struct sb_card_config *scc) } /* Register legacy card with OSS subsystem */ -static int sb_init_legacy(void) +static int __init sb_init_legacy(void) { struct sb_module_options sbmo = {0}; @@ -230,6 +234,8 @@ static void sb_dev2cfg(struct pnp_dev *dev, struct sb_card_config *scc) } } +static unsigned int sb_pnp_devices; + /* Probe callback function for the PnP API */ static int sb_pnp_probe(struct pnp_card_link *card, const struct pnp_card_device_id *card_id) { @@ -260,6 +266,7 @@ static int sb_pnp_probe(struct pnp_card_link *card, const struct pnp_card_device scc->conf.dma, scc->conf.dma2); pnp_set_card_drvdata(card, scc); + sb_pnp_devices++; return sb_register_oss(scc, &sbmo); } @@ -282,8 +289,17 @@ static struct pnp_card_driver sb_pnp_driver = { .probe = sb_pnp_probe, .remove = sb_pnp_remove, }; +MODULE_DEVICE_TABLE(pnp_card, sb_pnp_card_table); #endif /* CONFIG_PNP */ +static void __init_or_module sb_unregister_all(void) +{ +#ifdef CONFIG_PNP + if (pnp_registered) + pnp_unregister_card_driver(&sb_pnp_driver); +#endif +} + static int __init sb_init(void) { int lres = 0; @@ -302,14 +318,21 @@ static int __init sb_init(void) #ifdef CONFIG_PNP if(pnp) { - pres = pnp_register_card_driver(&sb_pnp_driver); + int err = pnp_register_card_driver(&sb_pnp_driver); + if (!err) + pnp_registered = 1; + pres = sb_pnp_devices; } #endif printk(KERN_INFO "sb: Init: Done\n"); /* If either PnP or Legacy registered a card then return * success */ - return (pres > 0 || lres > 0) ? 0 : -ENODEV; + if (pres == 0 && lres <= 0) { + sb_unregister_all(); + return -ENODEV; + } + return 0; } static void __exit sb_exit(void) @@ -322,14 +345,10 @@ static void __exit sb_exit(void) sb_unload(legacy); } -#ifdef CONFIG_PNP - pnp_unregister_card_driver(&sb_pnp_driver); -#endif + sb_unregister_all(); - if (smw_free) { - vfree(smw_free); - smw_free = NULL; - } + vfree(smw_free); + smw_free = NULL; } module_init(sb_init);