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 c0348ff..0731fd6 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);
 }