[PATCH] opl3sa2 resource free on probe failure

From: Zwane Mwaikambo (zwane@linux.realnet.co.sz)
Date: Mon Apr 29 2002 - 08:31:26 EST


This patch is dependent on the ad1848 and mpu401 patches i sent earlier,
which are in 2.4-ac-current and 2.5-dj-current.

Please apply,
        Zwane Mwaikambo

--- linux-2.4.19-pre-ac/drivers/sound/opl3sa2.c.orig Mon Apr 29 15:14:17 2002
+++ linux-2.4.19-pre-ac/drivers/sound/opl3sa2.c Mon Apr 29 15:28:52 2002
@@ -57,6 +57,8 @@
  * (Jan 7, 2001)
  * Zwane Mwaikambo Added PM support. (Dec 4 2001)
  * Zwane Mwaikambo Code, data structure cleanups. (Feb 15 2002)
+ * Zwane Mwaikambo Free resources during auxiliary device probe
+ * failures (Apr 29 2002)
  *
  */
 
@@ -142,7 +144,7 @@
         unsigned int card;
         int chipset; /* What's my version(s)? */
         char *chipset_name;
-
+
         /* mixer data */
         int mixer;
         unsigned int volume_l;
@@ -236,7 +238,6 @@
         *data = inb(port + 1);
 }
 
-
 /*
  * All of the mixer functions...
  */
@@ -584,9 +585,9 @@
 }
 
 
-static inline void __init attach_opl3sa2_mpu(struct address_info* hw_config)
+static inline int __init attach_opl3sa2_mpu(struct address_info* hw_config)
 {
- attach_mpu401(hw_config, THIS_MODULE);
+ return attach_mpu401(hw_config, THIS_MODULE);
 }
 
 
@@ -641,7 +642,7 @@
         if(!request_region(hw_config->io_base, 2, OPL3SA2_MODULE_NAME)) {
                 printk(KERN_ERR PFX "Control I/O port %#x not free\n",
                        hw_config->io_base);
- return 0;
+ goto out_nodev;
         }
 
         /*
@@ -654,7 +655,7 @@
         if(tmp != misc) {
                 printk(KERN_ERR PFX "Control I/O port %#x is not a YMF7xx chipset!\n",
                        hw_config->io_base);
- return 0;
+ goto out_region;
         }
 
         /*
@@ -667,7 +668,7 @@
                 printk(KERN_ERR
                        PFX "Control I/O port %#x is not a YMF7xx chipset!\n",
                        hw_config->io_base);
- return 0;
+ goto out_region;
         }
         opl3sa2_write(hw_config->io_base, OPL3SA2_MIC, tmp);
 
@@ -714,9 +715,13 @@
         if(opl3sa2_state[card].chipset != CHIPSET_UNKNOWN) {
                 /* Generate a pretty name */
                 opl3sa2_state[card].chipset_name = (char *)CHIPSET_TABLE[opl3sa2_state[card].chipset];
- return 1;
+ return 0;
         }
- return 0;
+
+out_region:
+ release_region(hw_config->io_base, 2);
+out_nodev:
+ return -ENODEV;
 }
 
 
@@ -914,7 +919,7 @@
 
 #ifdef CONFIG_PM
 /* Power Management support functions */
-static int opl3sa2_suspend(struct pm_dev *pdev, unsigned char pm_mode)
+static int opl3sa2_suspend(struct pm_dev *pdev, unsigned int pm_mode)
 {
         unsigned long flags;
         opl3sa2_state_t *p;
@@ -975,11 +980,9 @@
 
 static int opl3sa2_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data)
 {
- unsigned char mode = (unsigned char)data;
-
         switch (rqst) {
                 case PM_SUSPEND:
- return opl3sa2_suspend(pdev, mode);
+ return opl3sa2_suspend(pdev, (unsigned int)data);
 
                 case PM_RESUME:
                         return opl3sa2_resume(pdev);
@@ -995,8 +998,7 @@
  */
 static int __init init_opl3sa2(void)
 {
- int card;
- int max;
+ int card, max;
 
         /* Sanitize isapnp and multiple settings */
         isapnp = isapnp != 0 ? 1 : 0;
@@ -1060,15 +1062,19 @@
                         opl3sa2_clear_slots(&opl3sa2_state[card].cfg_mss);
                         opl3sa2_clear_slots(&opl3sa2_state[card].cfg_mpu);
                 }
+
+ if (probe_opl3sa2(&opl3sa2_state[card].cfg, card))
+ return -ENODEV;
 
- if(!probe_opl3sa2(&opl3sa2_state[card].cfg, card) ||
- !probe_opl3sa2_mss(&opl3sa2_state[card].cfg_mss)) {
+ if(!probe_opl3sa2_mss(&opl3sa2_state[card].cfg_mss)) {
                         /*
                          * If one or more cards are already registered, don't
                          * return an error but print a warning. Note, this
                          * should never really happen unless the hardware or
                          * ISA PnP screwed up.
                          */
+ release_region(opl3sa2_state[card].cfg.io_base, 2);
+
                         if(opl3sa2_cards_num) {
                                 printk(KERN_WARNING
                                        PFX "There was a problem probing one "
@@ -1114,10 +1120,13 @@
                         opl3sa2_set_loopback(&opl3sa2_state[card].cfg, loopback);
                 }
                 
- /* Attach MPU if we've been asked to do so */
+ /* Attach MPU if we've been asked to do so, failure isn't fatal */
                 if(opl3sa2_state[card].cfg_mpu.io_base != -1) {
                         if(probe_opl3sa2_mpu(&opl3sa2_state[card].cfg_mpu)) {
- attach_opl3sa2_mpu(&opl3sa2_state[card].cfg_mpu);
+ if (attach_opl3sa2_mpu(&opl3sa2_state[card].cfg_mpu)) {
+ printk(KERN_ERR PFX "failed to attach MPU401\n");
+ opl3sa2_state[card].cfg_mpu.slots[1] = -1;
+ }
                         }
                 }
         }

-- 
http://function.linuxpower.ca
		

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue Apr 30 2002 - 22:00:17 EST