]> err.no Git - linux-2.6/blobdiff - sound/isa/opl3sa2.c
[PATCH] Update libata DMA blacklist to cover versions, and resync with IDE layer
[linux-2.6] / sound / isa / opl3sa2.c
index b923de9b321df2eca1c006947e53bc42df50c355..56fcd8a946a485822539099505e9bc41043e66fe 100644 (file)
@@ -90,6 +90,12 @@ MODULE_PARM_DESC(dma2, "DMA2 # for OPL3-SA driver.");
 module_param_array(opl3sa3_ymode, int, NULL, 0444);
 MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi.");
 
+static struct platform_device *platform_devices[SNDRV_CARDS];
+#ifdef CONFIG_PNP
+static int pnp_registered;
+static int pnpc_registered;
+#endif
+
 /* control ports */
 #define OPL3SA2_PM_CTRL                0x01
 #define OPL3SA2_SYS_CTRL               0x02
@@ -496,21 +502,29 @@ static int __init snd_opl3sa2_mixer(struct snd_opl3sa2 *chip)
        /* reassign AUX0 to CD */
         strcpy(id1.name, "Aux Playback Switch");
         strcpy(id2.name, "CD Playback Switch");
-        if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+        if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
+               snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n");
                 return err;
+       }
         strcpy(id1.name, "Aux Playback Volume");
         strcpy(id2.name, "CD Playback Volume");
-        if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+        if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
+               snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n");
                 return err;
+       }
        /* reassign AUX1 to FM */
         strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
         strcpy(id2.name, "FM Playback Switch");
-        if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+        if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
+               snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n");
                 return err;
+       }
         strcpy(id1.name, "Aux Playback Volume");
         strcpy(id2.name, "FM Playback Volume");
-        if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+        if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
+               snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n");
                 return err;
+       }
        /* add OPL3SA2 controls */
        for (idx = 0; idx < ARRAY_SIZE(snd_opl3sa2_controls); idx++) {
                if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_opl3sa2_controls[idx], chip))) < 0)
@@ -575,8 +589,10 @@ static int __init snd_opl3sa2_pnp(int dev, struct snd_opl3sa2 *chip,
        int err;
 
        cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
-       if (!cfg)
+       if (!cfg) {
+               snd_printk(KERN_ERR PFX "cannot allocate pnp cfg\n");
                return -ENOMEM;
+       }
        /* PnP initialization */
        pnp_init_resource_table(cfg);
        if (sb_port[dev] != SNDRV_AUTO_PORT)
@@ -597,7 +613,7 @@ static int __init snd_opl3sa2_pnp(int dev, struct snd_opl3sa2 *chip,
                pnp_resource_change(&cfg->irq_resource[0], irq[dev], 1);
        err = pnp_manual_config_dev(pdev, cfg, 0);
        if (err < 0)
-               snd_printk(KERN_ERR "PnP manual resources are invalid, using auto config\n");
+               snd_printk(KERN_WARNING "PnP manual resources are invalid, using auto config\n");
        err = pnp_activate_dev(pdev);
        if (err < 0) {
                kfree(cfg);
@@ -707,7 +723,7 @@ static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev)
        }
        sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
                card->shortname, chip->port, xirq, xdma1);
-       if (dma2 >= 0)
+       if (xdma2 >= 0)
                sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
 
        return snd_card_register(card);
@@ -765,7 +781,7 @@ static int snd_opl3sa2_pnp_resume(struct pnp_dev *pdev)
 #endif
 
 static struct pnp_driver opl3sa2_pnp_driver = {
-       .name = "opl3sa2-pnpbios",
+       .name = "snd-opl3sa2-pnpbios",
        .id_table = snd_opl3sa2_pnpbiosids,
        .probe = snd_opl3sa2_pnp_detect,
        .remove = __devexit_p(snd_opl3sa2_pnp_remove),
@@ -784,8 +800,11 @@ static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard,
        struct snd_card *card;
 
        pdev = pnp_request_card_device(pcard, id->devs[0].id, NULL);
-       if (pdev == NULL)
+       if (pdev == NULL) {
+               snd_printk(KERN_ERR PFX "can't get pnp device from id '%s'\n",
+                          id->devs[0].id);
                return -EBUSY;
+       }
        for (; dev < SNDRV_CARDS; dev++) {
                if (enable[dev] && isapnp[dev])
                        break;
@@ -829,7 +848,7 @@ static int snd_opl3sa2_pnp_cresume(struct pnp_card_link *pcard)
 
 static struct pnp_card_driver opl3sa2_pnpc_driver = {
        .flags = PNP_DRIVER_RES_DISABLE,
-       .name = "opl3sa2",
+       .name = "snd-opl3sa2-cpnp",
        .id_table = snd_opl3sa2_pnpids,
        .probe = snd_opl3sa2_pnp_cdetect,
        .remove = __devexit_p(snd_opl3sa2_pnp_cremove),
@@ -908,6 +927,21 @@ static struct platform_driver snd_opl3sa2_nonpnp_driver = {
        },
 };
 
+static void __init_or_module snd_opl3sa2_unregister_all(void)
+{
+       int i;
+
+#ifdef CONFIG_PNP
+       if (pnpc_registered)
+               pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
+       if (pnp_registered)
+               pnp_unregister_driver(&opl3sa2_pnp_driver);
+#endif
+       for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
+               platform_device_unregister(platform_devices[i]);
+       platform_driver_unregister(&snd_opl3sa2_nonpnp_driver);
+}
+
 static int __init alsa_card_opl3sa2_init(void)
 {
        int i, err, cards = 0;
@@ -915,8 +949,10 @@ static int __init alsa_card_opl3sa2_init(void)
        if ((err = platform_driver_register(&snd_opl3sa2_nonpnp_driver)) < 0)
                return err;
 
-       for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+       for (i = 0; i < SNDRV_CARDS; i++) {
                struct platform_device *device;
+               if (! enable[i])
+                       continue;
 #ifdef CONFIG_PNP
                if (isapnp[i])
                        continue;
@@ -925,36 +961,42 @@ static int __init alsa_card_opl3sa2_init(void)
                                                         i, NULL, 0);
                if (IS_ERR(device)) {
                        err = PTR_ERR(device);
-                       platform_driver_unregister(&snd_opl3sa2_nonpnp_driver);
-                       return err;
+                       goto errout;
                }
+               platform_devices[i] = device;
                cards++;
        }
 
+#ifdef CONFIG_PNP
        err = pnp_register_driver(&opl3sa2_pnp_driver);
-       if (err > 0)
+       if (err >= 0) {
+               pnp_registered = 1;
                cards += err;
+       }
        err = pnp_register_card_driver(&opl3sa2_pnpc_driver);
-       if (err > 0)
+       if (err >= 0) {
+               pnpc_registered = 1;
                cards += err;
+       }
+#endif
 
        if (!cards) {
 #ifdef MODULE
                snd_printk(KERN_ERR "Yamaha OPL3-SA soundcard not found or device busy\n");
 #endif
-               pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
-               pnp_unregister_driver(&opl3sa2_pnp_driver);
-               platform_driver_unregister(&snd_opl3sa2_nonpnp_driver);
-               return -ENODEV;
+               err = -ENODEV;
+               goto errout;
        }
        return 0;
+
+ errout:
+       snd_opl3sa2_unregister_all();
+       return err;
 }
 
 static void __exit alsa_card_opl3sa2_exit(void)
 {
-       pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
-       pnp_unregister_driver(&opl3sa2_pnp_driver);
-       platform_driver_unregister(&snd_opl3sa2_nonpnp_driver);
+       snd_opl3sa2_unregister_all();
 }
 
 module_init(alsa_card_opl3sa2_init)