ACPICA Release 20100331 linuxized patches
Subsystems (4)
Hi, Len
This patch series applied cleanly on top of your acpi/test branch. Build and test on my machine and it works well.
[PATCH 1/9] ACPICA: Update comments/headers, no functional change
[PATCH 2/9] ACPICA: Fix for acpi_reallocate_root_table for incorrect root table copy [PATCH 3/9] ACPICA: Add write support for DataTable operation regions [PATCH 4/9] ACPICA: Add detection of corrupted/replaced DSDT
[PATCH 5/9] ACPICA: Add subsystem option to force copy of DSDT to local memory [PATCH 6/9] ACPICA: Update DSDT copy/detection.
[PATCH 7/9] ACPI: add boot option acpi=copy_dsdt to fix corrupt DSDT [PATCH 8/9] ACPICA: Minimize the differences between linux GPE code and ACPICA code base [PATCH 9/9] ACPICA: Update version to 20100331.
Patch 7 includes the acpi=copy_dsdt option, DMI backlist and customized ACPICA warning message for corrupt DSDT workaround (bug 14679).
Lin Ming
Quoted 1 line
From
d900de0dfc3822022aa68ad1f9d33fe99c75b86aMon Sep 17 00:00:00 2001
From: Bob Moore <[email protected]>
Date: Thu, 1 Apr 2010 11:04:54 +0800
Subject: [PATCH 1/9] ACPICA: Update comments/headers, no functional change
Also split some long lines.
--- drivers/acpi/acpica/exmutex.c | 21 +++++++++++---------- 1 files changed, 11 insertions(+), 10 deletions(-)
drivers/acpi/acpica/exmutex.c +11 -10
@@ -85,10 +85,10 @@ void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc) (obj_desc->mutex.prev)->mutex.next = obj_desc->mutex.next;/* -* Migrate the previous sync level associated with this mutex to the -* previous mutex on the list so that it may be preserved. This handles -* the case where several mutexes have been acquired at the same level, -* but are not released in opposite order. +* Migrate the previous sync level associated with this mutex to +* the previous mutex on the list so that it may be preserved. +* This handles the case where several mutexes have been acquired +* at the same level, but are not released in opposite order. */ (obj_desc->mutex.prev)->mutex.original_sync_level = obj_desc->mutex.original_sync_level;
@@ -101,8 +101,8 @@ void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc)* * FUNCTION: acpi_ex_link_mutex * -* PARAMETERS: obj_desc - The mutex to be linked -* Thread - Current executing thread object +* PARAMETERS: obj_desc - The mutex to be linked +* Thread - Current executing thread object * * RETURN: None *
@@ -138,9 +138,9 @@ acpi_ex_link_mutex(union acpi_operand_object *obj_desc,* * FUNCTION: acpi_ex_acquire_mutex_object * -* PARAMETERS: time_desc - Timeout in milliseconds +* PARAMETERS: Timeout - Timeout in milliseconds * obj_desc - Mutex object -* Thread - Current thread state +* thread_id - Current thread state * * RETURN: Status *
@@ -234,7 +234,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,return_ACPI_STATUS (AE_BAD_PARAMETER ); } -/* Must have a valid thread ID */ +/* Must have a valid thread state struct */ if (!walk_state->thread) { ACPI_ERROR((AE_INFO,
@@ -435,6 +435,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, owner_thread->current_sync_level = previous_sync_level; } +return_ACPI_STATUS (status); }
@@ -442,7 +443,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,* * FUNCTION: acpi_ex_release_all_mutexes * -* PARAMETERS: Thread - Current executing thread object +* PARAMETERS: Thread - Current executing thread object * * RETURN: Status *
Quoted 1 line
From
50ec566ee569d9890b47de5bf17b27f208eaa647Mon Sep 17 00:00:00 2001
From: Alexey Starikovskiy <[email protected]>
Date: Thu, 1 Apr 2010 11:06:34 +0800
Subject: [PATCH 2/9] ACPICA: Fix for acpi_reallocate_root_table for incorrect root table copy
When copying the root table to the new allocation, the length used was incorrect. The new size was used instead of the current table size, meaning too much data was copied.
--- drivers/acpi/acpica/tbxface.c | 23 ++++++++++++++++++----- 1 files changed, 18 insertions(+), 5 deletions(-)
drivers/acpi/acpica/tbxface.c +18 -5
@@ -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,9 +184,15 @@ 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 ) * -sizeof (struct acpi_table_desc ); +/* +* 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.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 */
@@ -194,10 +201,16 @@ 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.size = + acpi_gbl_root_table_list.count +ACPI_ROOT_TABLE_SIZE_INCREMENT ; acpi_gbl_root_table_list.flags =ACPI_ROOT_ORIGIN_ALLOCATED |ACPI_ROOT_ALLOW_RESIZE ;
Quoted 1 line
From
0b13a3dbf1d38e4d4cb2b5b6a3073db0059302bdMon Sep 17 00:00:00 2001
From: Bob Moore <[email protected]>
Date: Thu, 1 Apr 2010 11:09:00 +0800
Subject: [PATCH 3/9] ACPICA: Add write support for DataTable operation regions
The original implementation only supported reading from a DataTable region. However, some machines have been seen that actually write to the ACPI table contained in such a region. This change adds support for writing to a DataTable region.
--- drivers/acpi/acpica/exregion.c | 13 ++++++++++--- 1 files changed, 10 insertions(+), 3 deletions(-)
drivers/acpi/acpica/exregion.c +10 -3
@@ -491,8 +491,10 @@ acpi_ex_data_table_space_handler(u32 function, {ACPI_FUNCTION_TRACE (ex_data_table_space_handler); -/* Perform the memory read or write */ - +/* +* Perform the memory read or write. The bit_width was already +* validated. +*/ switch (function) {case ACPI_READ :
@@ -502,9 +504,14 @@ acpi_ex_data_table_space_handler(u32 function,break ;case ACPI_WRITE : + +ACPI_MEMCPY (ACPI_PHYSADDR_TO_PTR (address), +ACPI_CAST_PTR (char, value),ACPI_DIV_8 (bit_width)); +break ; +default : -return_ACPI_STATUS (AE_SUPPORT ); +return_ACPI_STATUS (AE_BAD_PARAMETER ); }return_ACPI_STATUS (AE_OK );
Quoted 1 line
From
b435982a224b79470f05348d7e8f59f1c277e828Mon Sep 17 00:00:00 2001
From: Lin Ming <[email protected]>
Date: Thu, 1 Apr 2010 10:47:56 +0800
Subject: [PATCH 4/9] ACPICA: Add detection of corrupted/replaced DSDT
This change adds support to detect a DSDT that has been corrupted and/or replaced from outside the OS (by firmware). This is typically catastrophic for the system, but has been seen on some machines.
https://bugzilla.kernel.org/show_bug.cgi?id=14679
--- drivers/acpi/acpica/acglobal.h | 5 +++++ drivers/acpi/acpica/actables.h | 2 ++ drivers/acpi/acpica/psxface.c | 4 ++++ drivers/acpi/acpica/tbutils.c | 38 ++++++++++++++++++++++++++++++++++++++ drivers/acpi/acpica/tbxface.c | 32 ++++++++++++-------------------- 5 files changed, 61 insertions(+), 20 deletions(-)
drivers/acpi/acpica/acglobal.h +5 -0
@@ -165,6 +165,11 @@ ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable; ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_status; ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable; +/* DSDT information. Used to check for DSDT corruption */ + +ACPI_EXTERN struct acpi_table_desc *acpi_gbl_DSDT; +ACPI_EXTERN struct acpi_table_header acpi_gbl_original_dsdt_header; +/* * Handle both ACPI 1.0 and ACPI 2.0 Integer widths. The integer width is * determined by the revision of the DSDT: If the DSDT revision is less than
drivers/acpi/acpica/actables.h +2 -0
@@ -107,6 +107,8 @@ u8 acpi_tb_checksum(u8 *buffer, u32 length);acpi_status acpi_tb_verify_checksum (struct acpi_table_header *table,u32 length); +void acpi_tb_check_dsdt_header (void ); +void acpi_tb_install_table (acpi_physical_address address,char *signature,u32 table_index);
drivers/acpi/acpica/psxface.c +4 -0
@@ -220,6 +220,10 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)ACPI_FUNCTION_TRACE (ps_execute_method); +/* Quick validation of DSDT header */ + +acpi_tb_check_dsdt_header (); +/* Validate the Info and method Node */ if (!info || !info->resolved_node) {
drivers/acpi/acpica/tbutils.c +38 -0
@@ -349,6 +349,44 @@ u8 acpi_tb_checksum(u8 *buffer, u32 length)/******************************************************************************* * +* FUNCTION: acpi_tb_check_dsdt_header +* +* PARAMETERS: None +* +* RETURN: None +* +* DESCRIPTION: Quick compare to check validity of the DSDT. This will detect +* if the DSDT has been replaced from outside the OS and/or if +* the DSDT header has been corrupted. +* +******************************************************************************/ + +void acpi_tb_check_dsdt_header (void ) +{ + +/* Compare original length and checksum to current values */ + +if (acpi_gbl_original_dsdt_header.length != + acpi_gbl_DSDT->pointer->length + || acpi_gbl_original_dsdt_header.checksum != + acpi_gbl_DSDT->pointer->checksum) { +ACPI_ERROR ((AE_INFO , +"The DSDT has been corrupted or replaced - old, new headers below" )); +acpi_tb_print_table_header (0 , &acpi_gbl_original_dsdt_header); +acpi_tb_print_table_header (acpi_gbl_DSDT->address, + acpi_gbl_DSDT->pointer); + +/* Disable further error messages */ + + acpi_gbl_original_dsdt_header.length = + acpi_gbl_DSDT->pointer->length; + acpi_gbl_original_dsdt_header.checksum = + acpi_gbl_DSDT->pointer->checksum; + } +} + +/******************************************************************************* +* * FUNCTION: acpi_tb_install_table * * PARAMETERS: Address - Physical address of DSDT or FACS
drivers/acpi/acpica/tbxface.c +12 -20
@@ -518,33 +518,25 @@ static acpi_status acpi_tb_load_namespace(void) (void )acpi_ut_acquire_mutex (ACPI_MTX_TABLES ); + acpi_gbl_DSDT = &acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT ]; +/* -* 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 || - !ACPI_COMPARE_NAME (& - (acpi_gbl_root_table_list. - tables[ACPI_TABLE_INDEX_DSDT ].signature), -ACPI_SIG_DSDT ) - || -ACPI_FAILURE (acpi_tb_verify_table - (&acpi_gbl_root_table_list. - tables[ACPI_TABLE_INDEX_DSDT ]))) { + !ACPI_COMPARE_NAME (&acpi_gbl_DSDT->signature,ACPI_SIG_DSDT ) || +ACPI_FAILURE (acpi_tb_verify_table (acpi_gbl_DSDT))) { status =AE_NO_ACPI_TABLES ; 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)) { - - status =AE_NO_ACPI_TABLES ; - goto unlock_and_exit; - } +/* +* 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->pointer, +sizeof (struct acpi_table_header )); (void )acpi_ut_release_mutex (ACPI_MTX_TABLES );
Quoted 1 line
From
0412c9ab3d792c0c6c5ab641c811e45acfe61cd2Mon Sep 17 00:00:00 2001
From: Lin Ming <[email protected]>
Date: Thu, 1 Apr 2010 11:14:12 +0800
Subject: [PATCH 5/9] ACPICA: Add subsystem option to force copy of DSDT to local memory
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.
https://bugzilla.kernel.org/show_bug.cgi?id=14679
--- drivers/acpi/acpica/acglobal.h | 8 ++++++++ drivers/acpi/acpica/actables.h | 2 ++ drivers/acpi/acpica/psxface.c | 1 + drivers/acpi/acpica/tbutils.c | 35 +++++++++++++++++++++++++++++++++++ drivers/acpi/acpica/tbxface.c | 10 ++++++++++ include/acpi/acpixf.h | 1 + 6 files changed, 57 insertions(+), 0 deletions(-)
drivers/acpi/acpica/acglobal.h +8 -0
@@ -117,6 +117,14 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_use_default_register_widths, TRUE);*/ u8 ACPI_INIT_GLOBAL (acpi_gbl_enable_aml_debug_object ,FALSE ); +/* +* 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. +*/ +u8 ACPI_INIT_GLOBAL (acpi_gbl_copy_dsdt_locally ,FALSE ); +/* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */ struct acpi_table_fadt acpi_gbl_FADT;
drivers/acpi/acpica/actables.h +2 -0
@@ -109,6 +109,8 @@ acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length);void acpi_tb_check_dsdt_header (void ); +void acpi_tb_copy_dsdt (struct acpi_table_desc *table_desc); +void acpi_tb_install_table (acpi_physical_address address,char *signature,u32 table_index);
drivers/acpi/acpica/psxface.c +1 -0
@@ -46,6 +46,7 @@#include "acparser.h" #include "acdispat.h" #include "acinterp.h" +#include "actables.h" #include "amlcode.h" #define _COMPONENT ACPI_PARSER
drivers/acpi/acpica/tbutils.c +35 -0
@@ -387,6 +387,41 @@ void acpi_tb_check_dsdt_header(void)/******************************************************************************* * +* FUNCTION: acpi_tb_copy_dsdt +* +* PARAMETERS: table_desc - Installed table to copy +* +* RETURN: None +* +* DESCRIPTION: Implements a subsystem option to copy the DSDT to local memory. +* Some very bad BIOSs are known to either corrupt the DSDT or +* install a new, bad DSDT. This copy works around the problem. +* +******************************************************************************/ + +void acpi_tb_copy_dsdt (struct acpi_table_desc *table_desc) +{ +struct acpi_table_header *new_table; + + new_table =ACPI_ALLOCATE (table_desc->length); +if (!new_table) { +ACPI_ERROR ((AE_INFO ,"Could not copy DSDT of length 0x%X" , + table_desc->length)); +return ; + } + +ACPI_MEMCPY (new_table, table_desc->pointer, table_desc->length); +acpi_tb_delete_table (table_desc); + table_desc->pointer = new_table; + table_desc->flags =ACPI_TABLE_ORIGIN_ALLOCATED ; + +ACPI_INFO ((AE_INFO , +"Forced DSDT copy: length 0x%05X copied locally, original unmapped" , + new_table->length)); +} + +/******************************************************************************* +* * FUNCTION: acpi_tb_install_table * * PARAMETERS: Address - Physical address of DSDT or FACS
drivers/acpi/acpica/tbxface.c +10 -0
@@ -532,6 +532,16 @@ static acpi_status acpi_tb_load_namespace(void) }/* +* 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) { +acpi_tb_copy_dsdt (acpi_gbl_DSDT); + } + +/* * Save the original DSDT header for detection of table corruption * and/or replacement of the DSDT from outside the OS. */
include/acpi/acpixf.h +1 -0
@@ -68,6 +68,7 @@ extern u8 acpi_gbl_use_default_register_widths;extern acpi_name acpi_gbl_trace_method_name;extern u32 acpi_gbl_trace_flags;extern u8 acpi_gbl_enable_aml_debug_object; +extern u8 acpi_gbl_copy_dsdt_locally;extern u32 acpi_current_gpe_count;extern struct acpi_table_fadt acpi_gbl_FADT;
Quoted 1 line
From
39de59b737a3cc09e125f5a11decc08fc5f0884eMon Sep 17 00:00:00 2001
From: Bob Moore <[email protected]>
Date: Wed, 7 Apr 2010 11:05:11 +0800
Subject: [PATCH 6/9] ACPICA: Update DSDT copy/detection.
Move initialization of DSDT pointer. Emit address of DSDT in the dump of both table headers (good/bad DSDT). Now handles the case where the root table can be reallocated, which would invalidate the original pointer.
--- drivers/acpi/acpica/acglobal.h | 2 +- drivers/acpi/acpica/actables.h | 2 +- drivers/acpi/acpica/tbutils.c | 23 ++++++++++++----------- drivers/acpi/acpica/tbxface.c | 29 +++++++++++++++++++++++------ drivers/acpi/acpica/utglobal.c | 1 + 5 files changed, 38 insertions(+), 19 deletions(-)
drivers/acpi/acpica/acglobal.h +1 -1
@@ -175,7 +175,7 @@ ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable;/* DSDT information. Used to check for DSDT corruption */ -ACPI_EXTERN struct acpi_table_desc *acpi_gbl_DSDT; +ACPI_EXTERN struct acpi_table_header *acpi_gbl_DSDT; ACPI_EXTERN struct acpi_table_header acpi_gbl_original_dsdt_header;/*
drivers/acpi/acpica/actables.h +1 -1
@@ -109,7 +109,7 @@ acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length);void acpi_tb_check_dsdt_header (void ); -void acpi_tb_copy_dsdt (struct acpi_table_desc *table_desc); +struct acpi_table_header *acpi_tb_copy_dsdt (u32 table_index); void acpi_tb_install_table(acpi_physical_address address,
drivers/acpi/acpica/tbutils.c +12 -11
@@ -366,22 +366,18 @@ void acpi_tb_check_dsdt_header(void)/* Compare original length and checksum to current values */ -if (acpi_gbl_original_dsdt_header.length != - acpi_gbl_DSDT->pointer->length - || acpi_gbl_original_dsdt_header.checksum != - acpi_gbl_DSDT->pointer->checksum) { +if (acpi_gbl_original_dsdt_header.length != acpi_gbl_DSDT->length || + acpi_gbl_original_dsdt_header.checksum != acpi_gbl_DSDT->checksum) {ACPI_ERROR ((AE_INFO ,"The DSDT has been corrupted or replaced - old, new headers below" ));acpi_tb_print_table_header (0 , &acpi_gbl_original_dsdt_header); -acpi_tb_print_table_header (acpi_gbl_DSDT->address, - acpi_gbl_DSDT->pointer); +acpi_tb_print_table_header (0 , acpi_gbl_DSDT);/* Disable further error messages */ - acpi_gbl_original_dsdt_header.length = - acpi_gbl_DSDT->pointer->length; + acpi_gbl_original_dsdt_header.length = acpi_gbl_DSDT->length; acpi_gbl_original_dsdt_header.checksum = - acpi_gbl_DSDT->pointer->checksum; + acpi_gbl_DSDT->checksum; } }
@@ -399,15 +395,18 @@ void acpi_tb_check_dsdt_header(void)* ******************************************************************************/ -void acpi_tb_copy_dsdt (struct acpi_table_desc *table_desc) +struct acpi_table_header *acpi_tb_copy_dsdt (u32 table_index) {struct acpi_table_header *new_table; +struct acpi_table_desc *table_desc; + + table_desc = &acpi_gbl_root_table_list.tables[table_index]; new_table =ACPI_ALLOCATE (table_desc->length);if (!new_table) {ACPI_ERROR ((AE_INFO ,"Could not copy DSDT of length 0x%X" , table_desc->length)); -return ; +return (NULL ); }ACPI_MEMCPY (new_table, table_desc->pointer, table_desc->length);
@@ -418,6 +417,8 @@ void acpi_tb_copy_dsdt(struct acpi_table_desc *table_desc)ACPI_INFO ((AE_INFO ,"Forced DSDT copy: length 0x%05X copied locally, original unmapped" , new_table->length)); + +return (new_table); }/*******************************************************************************
drivers/acpi/acpica/tbxface.c +23 -6
@@ -513,39 +513,56 @@ 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 ); - acpi_gbl_DSDT = &acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT ]; -/* * 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 || - !ACPI_COMPARE_NAME (&acpi_gbl_DSDT->signature,ACPI_SIG_DSDT ) || -ACPI_FAILURE (acpi_tb_verify_table (acpi_gbl_DSDT))) { + !ACPI_COMPARE_NAME (& + (acpi_gbl_root_table_list. + tables[ACPI_TABLE_INDEX_DSDT ].signature), +ACPI_SIG_DSDT ) + || +ACPI_FAILURE (acpi_tb_verify_table + (&acpi_gbl_root_table_list. + tables[ACPI_TABLE_INDEX_DSDT ]))) { status =AE_NO_ACPI_TABLES ; goto unlock_and_exit; }/* +* 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; + +/* * 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) { -acpi_tb_copy_dsdt (acpi_gbl_DSDT); + 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->pointer, +ACPI_MEMCPY (&acpi_gbl_original_dsdt_header, acpi_gbl_DSDT,sizeof (struct acpi_table_header )); (void )acpi_ut_release_mutex (ACPI_MTX_TABLES );
drivers/acpi/acpica/utglobal.c +1 -0
@@ -785,6 +785,7 @@ acpi_status acpi_ut_init_globals(void)/* Miscellaneous variables */ + acpi_gbl_DSDT =NULL ; acpi_gbl_cm_single_step = FALSE; acpi_gbl_db_terminate_threads = FALSE; acpi_gbl_shutdown = FALSE;
Quoted 1 line
From
7e8098683e5b7375862d454fa05687270e509683Mon Sep 17 00:00:00 2001
From: Lin Ming <[email protected]>
Date: Thu, 8 Apr 2010 14:34:27 +0800
Subject: [PATCH 7/9] ACPI: add boot option acpi=copy_dsdt to fix corrupt DSDT
Some BIOS on Toshiba machines corrupt the DSDT, so add a new
boot option acpi=copy_dsdt to workaround it.
Add warning message to ask users to use this option if corrupt DSDT detected.
Also build a DMI blacklist to check it and automatically copy DSDT.
https://bugzilla.kernel.org/show_bug.cgi?id=14679
--- Documentation/kernel-parameters.txt | 1 + arch/x86/kernel/acpi/boot.c | 4 +++ drivers/acpi/acpica/tbutils.c | 4 +++ drivers/acpi/bus.c | 37 +++++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 0 deletions(-)
Documentation/kernel-parameters.txt +1 -0
@@ -150,6 +150,7 @@ and is between 256 and 4096 characters. It is defined in the file strict -- Be less tolerant of platforms that are not strictly ACPI specification compliant. rsdt -- prefer RSDT over (default) XSDT + copy_dsdt -- copy DSDT to memory See also Documentation/power/pm.txt, pci=noacpi
arch/x86/kernel/acpi/boot.c +4 -0
@@ -1563,6 +1563,10 @@ static int __init parse_acpi(char *arg)/* "acpi=noirq" disables ACPI interrupt routing */ else if (strcmp(arg, "noirq") == 0) { acpi_noirq_set(); + } + /* "acpi=copy_dsdt" copys DSDT */ + else if (strcmp(arg, "copy_dsdt") == 0) { + acpi_gbl_copy_dsdt_locally = 1; } else { /* Core will printk when we return error. */ return -EINVAL;
drivers/acpi/acpica/tbutils.c +4 -0
@@ -373,6 +373,10 @@ void acpi_tb_check_dsdt_header(void)acpi_tb_print_table_header (0 , &acpi_gbl_original_dsdt_header);acpi_tb_print_table_header (0 , acpi_gbl_DSDT); +ACPI_ERROR ((AE_INFO , +"Please send DMI info to [email protected]\n" +"If system does not work as expected, please boot with acpi=copy_dsdt" )); +/* Disable further error messages */ acpi_gbl_original_dsdt_header.length = acpi_gbl_DSDT->length;
drivers/acpi/bus.c +37 -0
@@ -69,6 +69,37 @@ static struct dmi_system_id __cpuinitdata power_nocheck_dmi_table[] = { }; +static int set_copy_dsdt (const struct dmi_system_id *id) +{ +printk (KERN_NOTICE "%s detected - " +"force copy of DSDT to local memory\n" , id->ident); + acpi_gbl_copy_dsdt_locally =1 ; +return 0 ; +} + +static struct dmi_system_id dsdt_dmi_table[]__initdata = { +/* +* Insyde BIOS on some TOSHIBA machines corrupt the DSDT. +* https://bugzilla.kernel.org/show_bug.cgi?id=14679 +*/ + { + .callback = set_copy_dsdt, + .ident ="TOSHIBA Satellite A505" , + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"TOSHIBA" ), +DMI_MATCH (DMI_PRODUCT_NAME ,"Satellite A505" ), + }, + }, + { + .callback = set_copy_dsdt, + .ident ="TOSHIBA Satellite L505D" , + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"TOSHIBA" ), +DMI_MATCH (DMI_PRODUCT_NAME ,"Satellite L505D" ), + }, + } +}; +/* -------------------------------------------------------------------------- Device Management -------------------------------------------------------------------------- */
@@ -813,6 +844,12 @@ void __init acpi_early_init(void) acpi_gbl_permanent_mmap =1 ; +/* +* If the machine falls into the DMI check table, +* DSDT will be copied to memory +*/ +dmi_check_system (dsdt_dmi_table); + status =acpi_reallocate_root_table ();if (ACPI_FAILURE (status)) { printk(KERN_ERR PREFIX
Quoted 1 line
From
a3a65368d88237d7c45bc6578b9cf7a07caa56fcMon Sep 17 00:00:00 2001
From: Lin Ming <[email protected]>
Date: Tue, 6 Apr 2010 14:52:37 +0800
Subject: [PATCH 8/9] ACPICA: Minimize the differences between linux GPE code and ACPICA code base
We have ported Rafael's major GPE changes
(ACPI: Use GPE reference counting to support shared GPEs) into ACPICA code base. But the port and Rafael's original patch have some differences, so we made below patch to make linux GPE code consistent with ACPICA code base.
Most changes are about comments and coding styles. Other noticeable changes are based on:
Rafael: Reduce code duplication related to GPE lookup
https://patchwork.kernel.org/patch/86237/
Rafeal: Always use the same lock for GPE locking
https://patchwork.kernel.org/patch/90471/
A new field gpe_count in struct acpi_gpe_block_info to record the number of individual GPEs in block.
Rename acpi_ev_save_method_info to acpi_ev_match_gpe_method.
--- drivers/acpi/acpica/acevents.h | 7 +- drivers/acpi/acpica/aclocal.h | 5 +- drivers/acpi/acpica/evgpe.c | 153 +++++++++++++++++++++++--------- drivers/acpi/acpica/evgpeblk.c | 143 ++++++++++++++++-------------- drivers/acpi/acpica/evxface.c | 20 +++-- drivers/acpi/acpica/evxfevnt.c | 191 +++++++++++++++++++++++---------------- drivers/acpi/acpica/exoparg2.c | 27 ------ drivers/acpi/scan.c | 2 +- drivers/acpi/system.c | 5 +- include/acpi/acexcep.h | 2 +- include/acpi/acpixf.h | 11 ++- include/acpi/actypes.h | 42 ++++----- 12 files changed, 346 insertions(+), 262 deletions(-)
drivers/acpi/acpica/acevents.h +4 -3
@@ -85,6 +85,10 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info (acpi_handle gpe_device,u32 gpe_number); +struct acpi_gpe_event_info *acpi_ev_low_get_gpe_info (u32 gpe_number, +struct acpi_gpe_block_info + *gpe_block); +/* * evgpeblk */
@@ -118,9 +122,6 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info,u32 acpi_ev_gpe_detect (struct acpi_gpe_xrupt_info *gpe_xrupt_list); -acpi_status -acpi_ev_check_for_wake_only_gpe (struct acpi_gpe_event_info *gpe_event_info); -acpi_status acpi_ev_gpe_initialize (void );/*
drivers/acpi/acpica/aclocal.h +3 -2
@@ -427,8 +427,8 @@ struct acpi_gpe_event_info {struct acpi_gpe_register_info *register_info;/* Backpointer to register info */ u8 flags;/* Misc info about this GPE */ u8 gpe_number;/* This GPE */ -u8 runtime_count; -u8 wakeup_count; +u8 runtime_count;/* References to a run GPE */ +u8 wakeup_count;/* References to a wake GPE */ };/* Information about a GPE register pair, one per each status/enable pair in an array */
@@ -454,6 +454,7 @@ struct acpi_gpe_block_info {struct acpi_gpe_event_info *event_info;/* One for each GPE */ struct acpi_generic_address block_address;/* Base address of the block */ u32 register_count;/* Number of register pairs in block */ +u16 gpe_count;/* Number of individual GPEs in block */ u8 block_base_number;/* Base GPE number for this block */ };
drivers/acpi/acpica/evgpe.c +109 -44
250 lines not on this page · raw message
drivers/acpi/acpica/evgpeblk.c +76 -67
310 lines not on this page · raw message
drivers/acpi/acpica/evxface.c +11 -9
@@ -682,14 +682,13 @@ acpi_install_gpe_handler(acpi_handle gpe_device,/* Parameter validation */ -if ((!address) || (type >ACPI_GPE_XRUPT_TYPE_MASK )) { - status =AE_BAD_PARAMETER ; - goto exit; +if ((!address) || (type & ~ACPI_GPE_XRUPT_TYPE_MASK )) { +return_ACPI_STATUS (AE_BAD_PARAMETER ); } status =acpi_ut_acquire_mutex (ACPI_MTX_EVENTS );if (ACPI_FAILURE (status)) { - goto exit; +return_ACPI_STATUS (status); }/* Ensure that we have a valid GPE number */
@@ -720,6 +719,13 @@ acpi_install_gpe_handler(acpi_handle gpe_device, handler->context = context; handler->method_node = gpe_event_info->dispatch.method_node; +/* Disable the GPE before installing the handler */ + + status =acpi_ev_disable_gpe (gpe_event_info); +if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } +/* Install the handler */ flags =acpi_os_acquire_lock (acpi_gbl_gpe_lock);
@@ -733,12 +739,8 @@ acpi_install_gpe_handler(acpi_handle gpe_device,acpi_os_release_lock (acpi_gbl_gpe_lock, flags); - unlock_and_exit: +unlock_and_exit: (void )acpi_ut_release_mutex (ACPI_MTX_EVENTS ); - exit: -if (ACPI_FAILURE (status)) -ACPI_EXCEPTION ((AE_INFO , status, -"Installing notify handler failed" ));return_ACPI_STATUS (status); }
drivers/acpi/acpica/evxfevnt.c +113 -78
353 lines not on this page · raw message
drivers/acpi/acpica/exoparg2.c +0 -27
@@ -119,33 +119,6 @@ acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state) status =AE_AML_OPERAND_TYPE ;break ; } -#ifdef ACPI_GPE_NOTIFY_CHECK -/* -* GPE method wake/notify check. Here, we want to ensure that we -* don't receive any "DeviceWake" Notifies from a GPE _Lxx or _Exx -* GPE method during system runtime. If we do, the GPE is marked -* as "wake-only" and disabled. -* -* 1) Is the Notify() value == device_wake? -* 2) Is this a GPE deferred method? (An _Lxx or _Exx method) -* 3) Did the original GPE happen at system runtime? -* (versus during wake) -* -* If all three cases are true, this is a wake-only GPE that should -* be disabled at runtime. -*/ -if (value ==2 ) {/* device_wake */ - status = -acpi_ev_check_for_wake_only_gpe (walk_state-> - gpe_event_info); -if (ACPI_FAILURE (status)) { - -/* AE_WAKE_ONLY_GPE only error, means ignore this notify */ - - return_ACPI_STATUS(AE_OK) - } - } -#endif /* * Dispatch the notify to the appropriate handler
drivers/acpi/scan.c +1 -1
@@ -765,7 +765,7 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) } status =acpi_get_gpe_status (NULL , device->wakeup.gpe_number, -ACPI_NOT_ISR , &event_status); + &event_status);if (status ==AE_OK ) device->wakeup.flags.run_wake = !!(event_status &ACPI_EVENT_FLAG_HANDLE );
drivers/acpi/system.c +2 -3
@@ -303,8 +303,7 @@ static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle) "Invalid GPE 0x%x\n", index)); goto end; } - result =acpi_get_gpe_status (*handle, index, -ACPI_NOT_ISR , status); + result =acpi_get_gpe_status (*handle, index, status); }else if (index < (num_gpes +ACPI_NUM_FIXED_EVENTS )) result =acpi_get_event_status (index - num_gpes, status);
@@ -395,7 +394,7 @@ static ssize_t counter_set(struct kobject *kobj, result =acpi_set_gpe (handle, index,ACPI_GPE_ENABLE ); else if (!strcmp(buf, "clear\n") && (status & ACPI_EVENT_FLAG_SET)) - result =acpi_clear_gpe (handle, index,ACPI_NOT_ISR ); + result =acpi_clear_gpe (handle, index); else all_counters[index].count = strtoul(buf, NULL, 0); }else if (index < num_gpes +ACPI_NUM_FIXED_EVENTS ) {
include/acpi/acexcep.h +1 -1
@@ -87,7 +87,7 @@#define AE_NO_GLOBAL_LOCK (acpi_status) (0x0017 | AE_CODE_ENVIRONMENTAL)#define AE_ABORT_METHOD (acpi_status) (0x0018 | AE_CODE_ENVIRONMENTAL)#define AE_SAME_HANDLER (acpi_status) (0x0019 | AE_CODE_ENVIRONMENTAL) -#define AE_WAKE_ONLY_GPE (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL) +#define AE_NO_HANDLER (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL)#define AE_OWNER_ID_LIMIT (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL)#define AE_CODE_ENV_MAX 0x001B
include/acpi/acpixf.h +6 -5
@@ -285,16 +285,17 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status);*/ acpi_status acpi_set_gpe (acpi_handle gpe_device,u32 gpe_number,u8 action); -acpi_status acpi_enable_gpe (acpi_handle gpe_device,u32 gpe_number,u8 type); +acpi_status +acpi_enable_gpe (acpi_handle gpe_device,u32 gpe_number,u8 gpe_type); -acpi_status acpi_disable_gpe (acpi_handle gpe_device,u32 gpe_number,u8 type); +acpi_status +acpi_disable_gpe (acpi_handle gpe_device,u32 gpe_number,u8 gpe_type); -acpi_status acpi_clear_gpe (acpi_handle gpe_device,u32 gpe_number,u32 flags); +acpi_status acpi_clear_gpe (acpi_handle gpe_device,u32 gpe_number);acpi_status acpi_get_gpe_status (acpi_handle gpe_device, -u32 gpe_number, -u32 flags,acpi_event_status * event_status); +u32 gpe_number,acpi_event_status *event_status);acpi_status acpi_disable_all_gpes (void );
include/acpi/actypes.h +20 -22
64 lines not on this page · raw message
Quoted 1 line
From
881a682a278c7b9d956c3dc36581210880d109f5Mon Sep 17 00:00:00 2001
From: Robert Moore <[email protected]>
Date: Thu, 8 Apr 2010 14:57:43 +0800
Subject: [PATCH 9/9] ACPICA: Update version to 20100331.
Version 20100331.
--- include/acpi/acpixf.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
include/acpi/acpixf.h +1 -1
@@ -47,7 +47,7 @@/* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20100304 +#define ACPI_CA_VERSION 0x20100331#include "actypes.h" #include "actbl.h"
Len Brown
reviewerapplied to acpi-test
(and acpica branch re-based to 2.6.34-rc5 to allow 8/9 to apply)
thanks,
Len Brown, Intel Open Source Technology Center
Quoted 21 lines · Lin Ming
Hi, Len
This patch series applied cleanly on top of your acpi/test branch. Build and test on my machine and it works well.
[PATCH 1/9] ACPICA: Update comments/headers, no functional change
[PATCH 2/9] ACPICA: Fix foracpi_reallocate_root_tablefor incorrect root table copy [PATCH 3/9] ACPICA: Add write support for DataTable operation regions [PATCH 4/9] ACPICA: Add detection of corrupted/replaced DSDT
[PATCH 5/9] ACPICA: Add subsystem option to force copy of DSDT to local memory [PATCH 6/9] ACPICA: Update DSDT copy/detection.
[PATCH 7/9] ACPI: add boot option acpi=copy_dsdt to fix corrupt DSDT [PATCH 8/9] ACPICA: Minimize the differences between linux GPE code and ACPICA code base [PATCH 9/9] ACPICA: Update version to 20100331.Patch 7 includes the acpi=copy_dsdt option, DMI backlist and customized ACPICA warning message for corrupt DSDT workaround (bug 14679).
Lin Ming