aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLin Ming <ming.m.lin@intel.com>2009-05-20 22:32:02 -0400
committerLen Brown <len.brown@intel.com>2009-05-27 00:35:51 -0400
commite0be6f5a9863b626c19f0be04946c6285cc9db56 (patch)
treeca2fb2a68d8a58101a27810d108a6965af04b602
parent06366c149232f64c89f513f188ccc6783d0e444f (diff)
ACPICA: Invalidate DdbHandle after table unload
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>
-rw-r--r--drivers/acpi/acpica/exconfig.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c
index c0348ff9a602..0731fd6bad63 100644
--- a/drivers/acpi/acpica/exconfig.c
+++ b/drivers/acpi/acpica/exconfig.c
@@ -91,6 +91,7 @@ acpi_ex_add_table(u32 table_index,
91 91
92 /* Init the table handle */ 92 /* Init the table handle */
93 93
94 obj_desc->common.flags |= AOPOBJ_DATA_VALID;
94 obj_desc->reference.class = ACPI_REFCLASS_TABLE; 95 obj_desc->reference.class = ACPI_REFCLASS_TABLE;
95 *ddb_handle = obj_desc; 96 *ddb_handle = obj_desc;
96 97
@@ -501,13 +502,18 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
501 502
502 /* 503 /*
503 * Validate the handle 504 * Validate the handle
504 * Although the handle is partially validated in acpi_ex_reconfiguration(), 505 * Although the handle is partially validated in acpi_ex_reconfiguration()
505 * when it calls acpi_ex_resolve_operands(), the handle is more completely 506 * when it calls acpi_ex_resolve_operands(), the handle is more completely
506 * validated here. 507 * validated here.
508 *
509 * Handle must be a valid operand object of type reference. Also, the
510 * ddb_handle must still be marked valid (table has not been previously
511 * unloaded)
507 */ 512 */
508 if ((!ddb_handle) || 513 if ((!ddb_handle) ||
509 (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) || 514 (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
510 (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE)) { 515 (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE) ||
516 (!(ddb_handle->common.flags & AOPOBJ_DATA_VALID))) {
511 return_ACPI_STATUS(AE_BAD_PARAMETER); 517 return_ACPI_STATUS(AE_BAD_PARAMETER);
512 } 518 }
513 519
@@ -515,6 +521,12 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
515 521
516 table_index = table_desc->reference.value; 522 table_index = table_desc->reference.value;
517 523
524 /* Ensure the table is still loaded */
525
526 if (!acpi_tb_is_table_loaded(table_index)) {
527 return_ACPI_STATUS(AE_NOT_EXIST);
528 }
529
518 /* Invoke table handler if present */ 530 /* Invoke table handler if present */
519 531
520 if (acpi_gbl_table_handler) { 532 if (acpi_gbl_table_handler) {
@@ -536,5 +548,10 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
536 (void)acpi_tb_release_owner_id(table_index); 548 (void)acpi_tb_release_owner_id(table_index);
537 acpi_tb_set_table_loaded_flag(table_index, FALSE); 549 acpi_tb_set_table_loaded_flag(table_index, FALSE);
538 550
551 /*
552 * Invalidate the handle. We do this because the handle may be stored
553 * in a named object and may not be actually deleted until much later.
554 */
555 ddb_handle->common.flags &= ~AOPOBJ_DATA_VALID;
539 return_ACPI_STATUS(AE_OK); 556 return_ACPI_STATUS(AE_OK);
540} 557}