diff options
author | Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> | 2007-02-02 19:48:22 +0300 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-02-02 21:14:29 -0500 |
commit | 428f211297bc95fd41f23830eab4180339020dd0 (patch) | |
tree | 81537f25f9add9e727e9d764fdcb333a1af07528 /drivers/acpi/tables/tbinstal.c | |
parent | 77f6a9fca39f4f19d2d9d5fff1ff5c2ccf20629c (diff) |
ACPICA: Miscellaneous table manager updates and optimizations
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/tables/tbinstal.c')
-rw-r--r-- | drivers/acpi/tables/tbinstal.c | 91 |
1 files changed, 54 insertions, 37 deletions
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index 9e0b3ce0d8e5..b07d9c8330b3 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c @@ -61,16 +61,19 @@ ACPI_MODULE_NAME("tbinstal") *****************************************************************************/ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) { - acpi_status status; + acpi_status status = AE_OK; ACPI_FUNCTION_TRACE(tb_verify_table); /* Map the table if necessary */ if (!table_desc->pointer) { - table_desc->pointer = - acpi_tb_map(table_desc->address, table_desc->length, - table_desc->flags & ACPI_TABLE_ORIGIN_MASK); + if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) == + ACPI_TABLE_ORIGIN_MAPPED) { + table_desc->pointer = + acpi_os_map_memory(table_desc->address, + table_desc->length); + } if (!table_desc->pointer) { return_ACPI_STATUS(AE_NO_MEMORY); } @@ -78,14 +81,15 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) /* FACS is the odd table, has no standard ACPI header and no checksum */ - if (ACPI_COMPARE_NAME(&(table_desc->signature), ACPI_SIG_FACS)) { - return_ACPI_STATUS(AE_OK); - } + if (!ACPI_COMPARE_NAME(&table_desc->signature, ACPI_SIG_FACS)) { - /* Always calculate checksum, ignore bad checksum if requested */ + /* Always calculate checksum, ignore bad checksum if requested */ + + status = + acpi_tb_verify_checksum(table_desc->pointer, + table_desc->length); + } - status = - acpi_tb_verify_checksum(table_desc->pointer, table_desc->length); return_ACPI_STATUS(status); } @@ -93,7 +97,7 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) * * FUNCTION: acpi_tb_add_table * - * PARAMETERS: Table - Pointer to the table header + * PARAMETERS: table_desc - Table descriptor * table_index - Where the table index is returned * * RETURN: Status @@ -103,7 +107,7 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) ******************************************************************************/ acpi_status -acpi_tb_add_table(struct acpi_table_header *table, +acpi_tb_add_table(struct acpi_table_desc *table_desc, acpi_native_uint * table_index) { acpi_native_uint i; @@ -112,6 +116,25 @@ acpi_tb_add_table(struct acpi_table_header *table, ACPI_FUNCTION_TRACE(tb_add_table); + if (!table_desc->pointer) { + status = acpi_tb_verify_table(table_desc); + if (ACPI_FAILURE(status) || !table_desc->pointer) { + return_ACPI_STATUS(status); + } + } + + /* The table must be either an SSDT or a PSDT */ + + if ((!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT)) + && + (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT))) + { + ACPI_ERROR((AE_INFO, + "Table has invalid signature [%4.4s], must be SSDT or PSDT", + table_desc->pointer->signature)); + return_ACPI_STATUS(AE_BAD_SIGNATURE); + } + (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); /* Check if table is already registered */ @@ -127,18 +150,17 @@ acpi_tb_add_table(struct acpi_table_header *table, } } - length = ACPI_MIN(table->length, - acpi_gbl_root_table_list.tables[i].pointer-> - length); - if (ACPI_MEMCMP - (table, acpi_gbl_root_table_list.tables[i].pointer, - length)) { + length = ACPI_MIN(table_desc->length, + acpi_gbl_root_table_list.tables[i].length); + if (ACPI_MEMCMP(table_desc->pointer, + acpi_gbl_root_table_list.tables[i].pointer, + length)) { continue; } /* Table is already registered */ - ACPI_FREE(table); + acpi_tb_delete_table(table_desc); *table_index = i; goto release; } @@ -146,14 +168,14 @@ acpi_tb_add_table(struct acpi_table_header *table, /* * Add the table to the global table list */ - status = acpi_tb_store_table(ACPI_TO_INTEGER(table), - table, table->length, - ACPI_TABLE_ORIGIN_ALLOCATED, table_index); + status = acpi_tb_store_table(table_desc->address, table_desc->pointer, + table_desc->length, table_desc->flags, + table_index); if (ACPI_FAILURE(status)) { goto release; } - acpi_tb_print_table_header(0, table); + acpi_tb_print_table_header(table_desc->address, table_desc->pointer); release: (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); @@ -282,25 +304,20 @@ acpi_tb_store_table(acpi_physical_address address, * ******************************************************************************/ -void acpi_tb_delete_table(acpi_native_uint table_index) +void acpi_tb_delete_table(struct acpi_table_desc *table_desc) { - struct acpi_table_desc *table_desc; - - /* table_index assumed valid */ - - table_desc = &acpi_gbl_root_table_list.tables[table_index]; - /* Table must be mapped or allocated */ - if (!table_desc->pointer) { return; } - - if (table_desc->flags & ACPI_TABLE_ORIGIN_MAPPED) { - acpi_tb_unmap(table_desc->pointer, table_desc->length, - table_desc->flags & ACPI_TABLE_ORIGIN_MASK); - } else if (table_desc->flags & ACPI_TABLE_ORIGIN_ALLOCATED) { + switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { + case ACPI_TABLE_ORIGIN_MAPPED: + acpi_os_unmap_memory(table_desc->pointer, table_desc->length); + break; + case ACPI_TABLE_ORIGIN_ALLOCATED: ACPI_FREE(table_desc->pointer); + break; + default:; } table_desc->pointer = NULL; @@ -329,7 +346,7 @@ void acpi_tb_terminate(void) /* Delete the individual tables */ for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { - acpi_tb_delete_table(i); + acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]); } /* |