aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/exconfig.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/exconfig.c')
-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}