diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-20 16:45:38 (GMT) |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-20 16:45:38 (GMT) |
commit | 04afb40593f9a3007e5ea817d009529ef10fb685 (patch) | |
tree | de5a16c2b1e5f2d97a7c2eccea4677719817f282 /drivers/acpi/acpica/tbxface.c | |
parent | 7f06a8b26aba1dc03b42272dc0089a800372c575 (diff) | |
parent | cce4f632db200aef147c59084437168174b23f11 (diff) | |
download | linux-fsl-qoriq-04afb40593f9a3007e5ea817d009529ef10fb685.tar.xz |
Merge branch 'acpica' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'acpica' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (22 commits)
ACPI: fix early DSDT dmi check warnings on ia64
ACPICA: Update version to 20100428.
ACPICA: Update/clarify some parameter names associated with acpi_handle
ACPICA: Rename acpi_ex_system_do_suspend->acpi_ex_system_do_sleep
ACPICA: Prevent possible allocation overrun during object copy
ACPICA: Split large file, evgpeblk
ACPICA: Add GPE support for dynamically loaded ACPI tables
ACPICA: Clarify/rename some root table descriptor fields
ACPICA: Update version to 20100331.
ACPICA: Minimize the differences between linux GPE code and ACPICA code base
ACPI: add boot option acpi=copy_dsdt to fix corrupt DSDT
ACPICA: Update DSDT copy/detection.
ACPICA: Add subsystem option to force copy of DSDT to local memory
ACPICA: Add detection of corrupted/replaced DSDT
ACPICA: Add write support for DataTable operation regions
ACPICA: Fix for acpi_reallocate_root_table for incorrect root table copy
ACPICA: Update comments/headers, no functional change
ACPICA: Update version to 20100304
ACPICA: Fix for possible fault in acpi_ex_release_mutex
ACPICA: Standardize integer output for ACPICA warnings/errors
...
Diffstat (limited to 'drivers/acpi/acpica/tbxface.c')
-rw-r--r-- | drivers/acpi/acpica/tbxface.c | 80 |
1 files changed, 58 insertions, 22 deletions
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index 5217a61..4a8b9e6 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c @@ -72,7 +72,7 @@ static int no_auto_ssdt; acpi_status acpi_allocate_root_table(u32 initial_table_count) { - acpi_gbl_root_table_list.size = initial_table_count; + acpi_gbl_root_table_list.max_table_count = initial_table_count; acpi_gbl_root_table_list.flags = ACPI_ROOT_ALLOW_RESIZE; return (acpi_tb_resize_root_table_list()); @@ -130,7 +130,7 @@ acpi_initialize_tables(struct acpi_table_desc * initial_table_array, sizeof(struct acpi_table_desc)); acpi_gbl_root_table_list.tables = initial_table_array; - acpi_gbl_root_table_list.size = initial_table_count; + acpi_gbl_root_table_list.max_table_count = initial_table_count; acpi_gbl_root_table_list.flags = ACPI_ROOT_ORIGIN_UNKNOWN; if (allow_resize) { acpi_gbl_root_table_list.flags |= @@ -172,6 +172,7 @@ acpi_status acpi_reallocate_root_table(void) { struct acpi_table_desc *tables; acpi_size new_size; + acpi_size current_size; ACPI_FUNCTION_TRACE(acpi_reallocate_root_table); @@ -183,10 +184,17 @@ acpi_status acpi_reallocate_root_table(void) return_ACPI_STATUS(AE_SUPPORT); } - new_size = ((acpi_size) acpi_gbl_root_table_list.count + - ACPI_ROOT_TABLE_SIZE_INCREMENT) * + /* + * Get the current size of the root table and add the default + * increment to create the new table size. + */ + current_size = (acpi_size) + acpi_gbl_root_table_list.current_table_count * sizeof(struct acpi_table_desc); + new_size = current_size + + (ACPI_ROOT_TABLE_SIZE_INCREMENT * sizeof(struct acpi_table_desc)); + /* Create new array and copy the old array */ tables = ACPI_ALLOCATE_ZEROED(new_size); @@ -194,10 +202,17 @@ acpi_status acpi_reallocate_root_table(void) return_ACPI_STATUS(AE_NO_MEMORY); } - ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, new_size); + ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, current_size); - acpi_gbl_root_table_list.size = acpi_gbl_root_table_list.count; + /* + * Update the root table descriptor. The new size will be the current + * number of tables plus the increment, independent of the reserved + * size of the original table list. + */ acpi_gbl_root_table_list.tables = tables; + acpi_gbl_root_table_list.max_table_count = + acpi_gbl_root_table_list.current_table_count + + ACPI_ROOT_TABLE_SIZE_INCREMENT; acpi_gbl_root_table_list.flags = ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE; @@ -278,7 +293,8 @@ acpi_get_table_header(char *signature, /* Walk the root table list */ - for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) { + for (i = 0, j = 0; i < acpi_gbl_root_table_list.current_table_count; + i++) { if (!ACPI_COMPARE_NAME (&(acpi_gbl_root_table_list.tables[i].signature), signature)) { @@ -341,7 +357,7 @@ acpi_status acpi_unload_table_id(acpi_owner_id id) ACPI_FUNCTION_TRACE(acpi_unload_table_id); /* Find table in the global table list */ - for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { + for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { if (id != acpi_gbl_root_table_list.tables[i].owner_id) { continue; } @@ -391,7 +407,8 @@ acpi_get_table_with_size(char *signature, /* Walk the root table list */ - for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) { + for (i = 0, j = 0; i < acpi_gbl_root_table_list.current_table_count; + i++) { if (!ACPI_COMPARE_NAME (&(acpi_gbl_root_table_list.tables[i].signature), signature)) { @@ -459,7 +476,7 @@ acpi_get_table_by_index(u32 table_index, struct acpi_table_header **table) /* Validate index */ - if (table_index >= acpi_gbl_root_table_list.count) { + if (table_index >= acpi_gbl_root_table_list.current_table_count) { (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); return_ACPI_STATUS(AE_BAD_PARAMETER); } @@ -500,16 +517,17 @@ static acpi_status acpi_tb_load_namespace(void) { acpi_status status; u32 i; + struct acpi_table_header *new_dsdt; ACPI_FUNCTION_TRACE(tb_load_namespace); (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); /* - * Load the namespace. The DSDT is required, but any SSDT and PSDT tables - * are optional. + * Load the namespace. The DSDT is required, but any SSDT and + * PSDT tables are optional. Verify the DSDT. */ - if (!acpi_gbl_root_table_list.count || + if (!acpi_gbl_root_table_list.current_table_count || !ACPI_COMPARE_NAME(& (acpi_gbl_root_table_list. tables[ACPI_TABLE_INDEX_DSDT].signature), @@ -522,17 +540,35 @@ static acpi_status acpi_tb_load_namespace(void) goto unlock_and_exit; } - /* A valid DSDT is required */ - - status = - acpi_tb_verify_table(&acpi_gbl_root_table_list. - tables[ACPI_TABLE_INDEX_DSDT]); - if (ACPI_FAILURE(status)) { + /* + * Save the DSDT pointer for simple access. This is the mapped memory + * address. We must take care here because the address of the .Tables + * array can change dynamically as tables are loaded at run-time. Note: + * .Pointer field is not validated until after call to acpi_tb_verify_table. + */ + acpi_gbl_DSDT = + acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer; - status = AE_NO_ACPI_TABLES; - goto unlock_and_exit; + /* + * Optionally copy the entire DSDT to local memory (instead of simply + * mapping it.) There are some BIOSs that corrupt or replace the original + * DSDT, creating the need for this option. Default is FALSE, do not copy + * the DSDT. + */ + if (acpi_gbl_copy_dsdt_locally) { + new_dsdt = acpi_tb_copy_dsdt(ACPI_TABLE_INDEX_DSDT); + if (new_dsdt) { + acpi_gbl_DSDT = new_dsdt; + } } + /* + * Save the original DSDT header for detection of table corruption + * and/or replacement of the DSDT from outside the OS. + */ + ACPI_MEMCPY(&acpi_gbl_original_dsdt_header, acpi_gbl_DSDT, + sizeof(struct acpi_table_header)); + (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); /* Load and parse tables */ @@ -545,7 +581,7 @@ static acpi_status acpi_tb_load_namespace(void) /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */ (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); - for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { + for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { if ((!ACPI_COMPARE_NAME (&(acpi_gbl_root_table_list.tables[i].signature), ACPI_SIG_SSDT) |