diff options
Diffstat (limited to 'drivers/acpi/acpica/exconfig.c')
-rw-r--r-- | drivers/acpi/acpica/exconfig.c | 21 |
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 | } |