]> git.karo-electronics.de Git - linux-beck.git/commitdiff
ACPICA: Invalidate DdbHandle after table unload
authorLin Ming <ming.m.lin@intel.com>
Thu, 21 May 2009 02:32:02 +0000 (10:32 +0800)
committerLen Brown <len.brown@intel.com>
Wed, 27 May 2009 04:35:51 +0000 (00:35 -0400)
Mark the DdbHandle as invalid after the table it refers to is
unloaded.  This is needed because the handle itself may not be
deleted after the table unload, depending on whether it has been
stored in a named object by the caller.

Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
drivers/acpi/acpica/exconfig.c

index c0348ff9a602c5cf06a5ff60583477c90ade4e8f..0731fd6bad6317feeb37dabbfc1fbdd0c324d24c 100644 (file)
@@ -91,6 +91,7 @@ acpi_ex_add_table(u32 table_index,
 
        /* Init the table handle */
 
+       obj_desc->common.flags |= AOPOBJ_DATA_VALID;
        obj_desc->reference.class = ACPI_REFCLASS_TABLE;
        *ddb_handle = obj_desc;
 
@@ -501,13 +502,18 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
 
        /*
         * Validate the handle
-        * Although the handle is partially validated in acpi_ex_reconfiguration(),
+        * Although the handle is partially validated in acpi_ex_reconfiguration()
         * when it calls acpi_ex_resolve_operands(), the handle is more completely
         * validated here.
+        *
+        * Handle must be a valid operand object of type reference. Also, the
+        * ddb_handle must still be marked valid (table has not been previously
+        * unloaded)
         */
        if ((!ddb_handle) ||
            (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
-           (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE)) {
+           (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE) ||
+           (!(ddb_handle->common.flags & AOPOBJ_DATA_VALID))) {
                return_ACPI_STATUS(AE_BAD_PARAMETER);
        }
 
@@ -515,6 +521,12 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
 
        table_index = table_desc->reference.value;
 
+       /* Ensure the table is still loaded */
+
+       if (!acpi_tb_is_table_loaded(table_index)) {
+               return_ACPI_STATUS(AE_NOT_EXIST);
+       }
+
        /* Invoke table handler if present */
 
        if (acpi_gbl_table_handler) {
@@ -536,5 +548,10 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
        (void)acpi_tb_release_owner_id(table_index);
        acpi_tb_set_table_loaded_flag(table_index, FALSE);
 
+       /*
+        * Invalidate the handle. We do this because the handle may be stored
+        * in a named object and may not be actually deleted until much later.
+        */
+       ddb_handle->common.flags &= ~AOPOBJ_DATA_VALID;
        return_ACPI_STATUS(AE_OK);
 }