[PATCH] acpi: release on failure

From: Arnaldo Carvalho de Melo (acme@conectiva.com.br)
Date: Wed Oct 04 2000 - 11:21:44 EST


Hi,

        Please consider applying. Jeff, if you think something is missing, please
tell me.

                        - Arnaldo

--- linux-2.4.0-test9/arch/i386/kernel/acpi.c Tue Oct 3 12:38:06 2000
+++ linux-2.4.0-test9.acme/arch/i386/kernel/acpi.c Wed Oct 4 09:48:59 2000
@@ -27,6 +27,8 @@
  * - check copy*user return
  * - get rid of check_region
  * - get rid of verify_area
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 2000/09/28
+ * - do proper release on failure in acpi_claim_ioports and acpi_init
  */
 
 #include <linux/config.h>
@@ -81,6 +83,7 @@
                          struct file *file,
                          void *buffer,
                          size_t *len);
+static void acpi_release(unsigned long start, unsigned long size);
 
 static struct ctl_table_header *acpi_sysctl = NULL;
 
@@ -1300,15 +1303,28 @@
 static int acpi_claim_ioports(struct acpi_facp *facp)
 {
         // we don't get a guarantee of contiguity for any of the ACPI registers
- if (acpi_claim(facp->pm1a_evt, facp->pm1_evt_len)
- || acpi_claim(facp->pm1b_evt, facp->pm1_evt_len)
- || acpi_claim(facp->pm1a_cnt, facp->pm1_cnt_len)
- || acpi_claim(facp->pm1b_cnt, facp->pm1_cnt_len)
- || acpi_claim(facp->pm_tmr, facp->pm_tm_len)
- || acpi_claim(facp->gpe0, facp->gpe0_len)
- || acpi_claim(facp->gpe1, facp->gpe1_len))
- return -EBUSY;
+ if (acpi_claim(facp->pm1a_evt, facp->pm1_evt_len))
+ goto return_ebusy;
+ if (acpi_claim(facp->pm1b_evt, facp->pm1_evt_len))
+ goto release_pm1a_evt;
+ if (acpi_claim(facp->pm1a_cnt, facp->pm1_cnt_len))
+ goto release_pm1b_evt;
+ if (acpi_claim(facp->pm1b_cnt, facp->pm1_cnt_len))
+ goto release_pm1a_cnt;
+ if (acpi_claim(facp->pm_tmr, facp->pm_tm_len))
+ goto release_pm1b_cnt;
+ if (acpi_claim(facp->gpe0, facp->gpe0_len))
+ goto release_pm_tmr;
+ if (acpi_claim(facp->gpe1, facp->gpe1_len))
+ goto release_gpe0;
         return 0;
+release_gpe0: acpi_release(facp->gpe0, facp->gpe0_len);
+release_pm_tmr: acpi_release(facp->pm_tmr, facp->pm_tm_len);
+release_pm1b_cnt: acpi_release(facp->pm1b_cnt, facp->pm1_cnt_len);
+release_pm1a_cnt: acpi_release(facp->pm1a_cnt, facp->pm1_cnt_len);
+release_pm1b_evt: acpi_release(facp->pm1b_evt, facp->pm1_evt_len);
+release_pm1a_evt: acpi_release(facp->pm1a_evt, facp->pm1_evt_len);
+return_ebusy: return -EBUSY;
 }
 
 /*
@@ -1523,8 +1539,10 @@
                                 error = -ENOMEM;
                 }
                 if (data)
- if (copy_from_user(data, buffer, size))
+ if (copy_from_user(data, buffer, size)) {
+ acpi_destroy_table(info);
                                 error = -EFAULT;
+ }
                 
                 write_unlock(&acpi_do_table_lock);
         }
@@ -1838,7 +1856,7 @@
                            &acpi_facp)) {
                 printk(KERN_ERR "ACPI: SCI (IRQ%d) allocation failed\n",
                        facp->sci_int);
- goto err_out;
+ goto cleanup_ioports;
         }
 
 #ifndef CONFIG_ACPI_S1_SLEEP
@@ -1846,6 +1864,8 @@
 #endif
 
         acpi_sysctl = register_sysctl_table(acpi_dir_table, 1);
+ if (!acpi_sysctl)
+ goto cleanup_irq;
 
         pm_power_off = acpi_power_off;
 
@@ -1863,7 +1883,10 @@
                 pm_idle = acpi_idle;
 
         return 0;
-
+cleanup_irq:
+ free_irq(facp->sci_int, &acpi_facp);
+cleanup_ioports:
+ acpi_release_ioports(facp);
 err_out:
         if (pci_driver_registered)
                 pci_unregister_driver(&acpi_driver);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sat Oct 07 2000 - 21:00:14 EST