From b74be6119e9e38390395f08767b7c84de9023b38 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 22 Apr 2009 10:20:23 +0800 Subject: ACPICA: Update error/warning interfaces Moved the module name and line number to the end of the message. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index 1c9e250..fbe7823 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -1033,11 +1033,12 @@ acpi_error(const char *module_name, u32 line_number, const char *format, ...) { va_list args; - acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); + acpi_os_printf("ACPI Error: "); va_start(args, format); acpi_os_vprintf(format, args); - acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); + acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, + line_number); va_end(args); } @@ -1047,12 +1048,12 @@ acpi_exception(const char *module_name, { va_list args; - acpi_os_printf("ACPI Exception (%s-%04d): %s, ", module_name, - line_number, acpi_format_exception(status)); + acpi_os_printf("ACPI Exception: %s, ", acpi_format_exception(status)); va_start(args, format); acpi_os_vprintf(format, args); - acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); + acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, + line_number); va_end(args); } @@ -1061,11 +1062,12 @@ acpi_warning(const char *module_name, u32 line_number, const char *format, ...) { va_list args; - acpi_os_printf("ACPI Warning (%s-%04d): ", module_name, line_number); + acpi_os_printf("ACPI Warning: "); va_start(args, format); acpi_os_vprintf(format, args); - acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); + acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, + line_number); va_end(args); } @@ -1074,10 +1076,6 @@ acpi_info(const char *module_name, u32 line_number, const char *format, ...) { va_list args; - /* - * Removed module_name, line_number, and acpica version, not needed - * for info output - */ acpi_os_printf("ACPI: "); va_start(args, format); diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 4db89e9..a868df6 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -375,7 +375,7 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state); acpi_status acpi_leave_sleep_state(u8 sleep_state); /* - * Debug output + * Error/Warning output */ void ACPI_INTERNAL_VAR_XFACE acpi_error(const char *module_name, @@ -394,6 +394,9 @@ void ACPI_INTERNAL_VAR_XFACE acpi_info(const char *module_name, u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3); +/* + * Debug output + */ #ifdef ACPI_DEBUG_OUTPUT void ACPI_INTERNAL_VAR_XFACE -- cgit v0.10.2 From 8eb7b2477c4e4fec4788605e4edb5f7acafb59ff Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 22 Apr 2009 10:28:22 +0800 Subject: ACPICA: Fix a few warnings for gcc 3.4.4 Mostly for acpiexec, one in the core subsystem. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 7b2fb60..23d5505 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c @@ -81,9 +81,9 @@ acpi_status acpi_hw_clear_acpi_status(void) ACPI_FUNCTION_TRACE(hw_clear_acpi_status); - ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %0llX\n", + ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n", ACPI_BITMASK_ALL_FIXED_STATUS, - acpi_gbl_xpm1a_status.address)); + ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address))); lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); diff --git a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h index 8e2cdc5..935c5d7 100644 --- a/include/acpi/platform/acgcc.h +++ b/include/acpi/platform/acgcc.h @@ -62,4 +62,8 @@ */ #define ACPI_UNUSED_VAR __attribute__ ((unused)) +#ifdef _ANSI +#define inline +#endif + #endif /* __ACGCC_H__ */ -- cgit v0.10.2 From 33a1d461d294722dd15ffe17651bdd48b5763883 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 22 Apr 2009 10:48:57 +0800 Subject: ACPICA: Change behavior of object copy for mutex/event objects When copying these internal objects, cannot simply copy the underlying OS object. A new OS object must be created. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c index 919624f..0f0c64b 100644 --- a/drivers/acpi/acpica/utcopy.c +++ b/drivers/acpi/acpica/utcopy.c @@ -676,6 +676,7 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, { u16 reference_count; union acpi_operand_object *next_object; + acpi_status status; /* Save fields from destination that we don't want to overwrite */ @@ -768,6 +769,28 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, } break; + /* + * For Mutex and Event objects, we cannot simply copy the underlying + * OS object. We must create a new one. + */ + case ACPI_TYPE_MUTEX: + + status = acpi_os_create_mutex(&dest_desc->mutex.os_mutex); + if (ACPI_FAILURE(status)) { + return status; + } + break; + + case ACPI_TYPE_EVENT: + + status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0, + &dest_desc->event. + os_semaphore); + if (ACPI_FAILURE(status)) { + return status; + } + break; + default: /* Nothing to do for other simple objects */ break; -- cgit v0.10.2 From 41bdd8e9809665d6a13e49137661a8f2e5a7dc51 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 22 Apr 2009 10:51:06 +0800 Subject: ACPICA: Remove unused global variables Remove two unused/obsolete variables. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 16e5210..3d87362 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -362,9 +362,6 @@ extern u8 acpi_gbl_method_executing; extern u8 acpi_gbl_abort_method; extern u8 acpi_gbl_db_terminate_threads; -ACPI_EXTERN int optind; -ACPI_EXTERN char *optarg; - ACPI_EXTERN u8 acpi_gbl_db_opt_tables; ACPI_EXTERN u8 acpi_gbl_db_opt_stats; ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods; -- cgit v0.10.2 From 10b6575b5d84d21e2eab01df2284288e5fdf7887 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 22 Apr 2009 11:39:10 +0800 Subject: ACPICA: Fix possible warnings for ACPI_THREAD_ID on 64-bit build Warnings can be generated for printf-like statements that output the ACPI_THREAD_ID on 64-bit builds, since this type can expand to 64-bits depending on how it is defined. Use the %p format specifier to allow the output to automatically expand to 64 bits. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c index d301c1f..d7cb030 100644 --- a/drivers/acpi/acpica/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c @@ -373,11 +373,12 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, walk_state->thread->thread_id) && (obj_desc != acpi_gbl_global_lock_mutex)) { ACPI_ERROR((AE_INFO, - "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX", - (unsigned long)walk_state->thread->thread_id, + "Thread %p cannot release Mutex [%4.4s] acquired by thread %p", + ACPI_CAST_PTR(void, walk_state->thread->thread_id), acpi_ut_get_node_name(obj_desc->mutex.node), - (unsigned long)obj_desc->mutex.owner_thread-> - thread_id)); + ACPI_CAST_PTR(void, + obj_desc->mutex.owner_thread-> + thread_id))); return_ACPI_STATUS(AE_AML_NOT_OWNER); } diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index 38821f5..527d729 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c @@ -179,9 +179,9 @@ acpi_debug_print(u32 requested_debug_level, if (thread_id != acpi_gbl_prev_thread_id) { if (ACPI_LV_THREADS & acpi_dbg_level) { acpi_os_printf - ("\n**** Context Switch from TID %lX to TID %lX ****\n\n", - (unsigned long)acpi_gbl_prev_thread_id, - (unsigned long)thread_id); + ("\n**** Context Switch from TID %p to TID %p ****\n\n", + ACPI_CAST_PTR(void, acpi_gbl_prev_thread_id), + ACPI_CAST_PTR(void, thread_id)); } acpi_gbl_prev_thread_id = thread_id; @@ -194,7 +194,7 @@ acpi_debug_print(u32 requested_debug_level, acpi_os_printf("%8s-%04ld ", module_name, line_number); if (ACPI_LV_THREADS & acpi_dbg_level) { - acpi_os_printf("[%04lX] ", (unsigned long)thread_id); + acpi_os_printf("[%p] ", ACPI_CAST_PTR(void, thread_id)); } acpi_os_printf("[%02ld] %-22.22s: ", diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index 26c93a7..80bb651 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c @@ -230,17 +230,18 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { if (i == mutex_id) { ACPI_ERROR((AE_INFO, - "Mutex [%s] already acquired by this thread [%X]", + "Mutex [%s] already acquired by this thread [%p]", acpi_ut_get_mutex_name (mutex_id), - this_thread_id)); + ACPI_CAST_PTR(void, + this_thread_id))); return (AE_ALREADY_ACQUIRED); } ACPI_ERROR((AE_INFO, - "Invalid acquire order: Thread %X owns [%s], wants [%s]", - this_thread_id, + "Invalid acquire order: Thread %p owns [%s], wants [%s]", + ACPI_CAST_PTR(void, this_thread_id), acpi_ut_get_mutex_name(i), acpi_ut_get_mutex_name(mutex_id))); @@ -251,24 +252,24 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) #endif ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, - "Thread %lX attempting to acquire Mutex [%s]\n", - (unsigned long)this_thread_id, + "Thread %p attempting to acquire Mutex [%s]\n", + ACPI_CAST_PTR(void, this_thread_id), acpi_ut_get_mutex_name(mutex_id))); status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex, ACPI_WAIT_FOREVER); if (ACPI_SUCCESS(status)) { ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, - "Thread %lX acquired Mutex [%s]\n", - (unsigned long)this_thread_id, + "Thread %p acquired Mutex [%s]\n", + ACPI_CAST_PTR(void, this_thread_id), acpi_ut_get_mutex_name(mutex_id))); acpi_gbl_mutex_info[mutex_id].use_count++; acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; } else { ACPI_EXCEPTION((AE_INFO, status, - "Thread %lX could not acquire Mutex [%X]", - (unsigned long)this_thread_id, mutex_id)); + "Thread %p could not acquire Mutex [%X]", + ACPI_CAST_PTR(void, this_thread_id), mutex_id)); } return (status); @@ -293,9 +294,8 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) ACPI_FUNCTION_NAME(ut_release_mutex); this_thread_id = acpi_os_get_thread_id(); - ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, - "Thread %lX releasing Mutex [%s]\n", - (unsigned long)this_thread_id, + ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n", + ACPI_CAST_PTR(void, this_thread_id), acpi_ut_get_mutex_name(mutex_id))); if (mutex_id > ACPI_MAX_MUTEX) { -- cgit v0.10.2 From 35d7c1cfe5262480d3d8e6ccd7e4caf3a9c8ab39 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 22 Apr 2009 12:41:27 +0800 Subject: ACPICA: Cleanup byte/word/dword extraction macros, fix possible warnings Removed unnecessary masking. For the 64-bit macros, removed the structure overlay. Fixes aliasing warnings seen with gcc 4+ compilers. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index f555d927..37ba576 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -429,20 +429,12 @@ typedef unsigned long long acpi_integer; /* Data manipulation */ -#define ACPI_LOWORD(l) ((u16)(u32)(l)) -#define ACPI_HIWORD(l) ((u16)((((u32)(l)) >> 16) & 0xFFFF)) -#define ACPI_LOBYTE(l) ((u8)(u16)(l)) -#define ACPI_HIBYTE(l) ((u8)((((u16)(l)) >> 8) & 0xFF)) - -/* Full 64-bit integer must be available on both 32-bit and 64-bit platforms */ - -struct acpi_integer_overlay { - u32 lo_dword; - u32 hi_dword; -}; - -#define ACPI_LODWORD(integer) (ACPI_CAST_PTR (struct acpi_integer_overlay, &integer)->lo_dword) -#define ACPI_HIDWORD(integer) (ACPI_CAST_PTR (struct acpi_integer_overlay, &integer)->hi_dword) +#define ACPI_LOBYTE(integer) ((u8) (u16)(integer)) +#define ACPI_HIBYTE(integer) ((u8) (((u16)(integer)) >> 8)) +#define ACPI_LOWORD(integer) ((u16) (u32)(integer)) +#define ACPI_HIWORD(integer) ((u16)(((u32)(integer)) >> 16)) +#define ACPI_LODWORD(integer64) ((u32) (u64)(integer64)) +#define ACPI_HIDWORD(integer64) ((u32)(((u64)(integer64)) >> 32)) #define ACPI_SET_BIT(target,bit) ((target) |= (bit)) #define ACPI_CLEAR_BIT(target,bit) ((target) &= ~(bit)) -- cgit v0.10.2 From b21245a85e62ea7eeb5b7562ce98cf8b0aecbd26 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 22 Apr 2009 12:52:51 +0800 Subject: ACPICA: Fix printf format warnings for 64-bit build Fix warnings caused by size_t and ACPI_SIZE changing to 64 bits. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c index ae3dc10..af8e6bc 100644 --- a/drivers/acpi/acpica/nsnames.c +++ b/drivers/acpi/acpica/nsnames.c @@ -149,7 +149,7 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) name_buffer = ACPI_ALLOCATE_ZEROED(size); if (!name_buffer) { - ACPI_ERROR((AE_INFO, "Allocation failure")); + ACPI_ERROR((AE_INFO, "Could not allocate %u bytes", (u32)size)); return_PTR(NULL); } diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 71e655d..e5fe7c8 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -284,9 +284,9 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) if (length > sizeof(struct acpi_table_fadt)) { ACPI_WARNING((AE_INFO, "FADT (revision %u) is longer than ACPI 2.0 version, " - "truncating length 0x%X to 0x%zX", - table->revision, (unsigned)length, - sizeof(struct acpi_table_fadt))); + "truncating length 0x%X to 0x%X", + table->revision, length, + (u32)sizeof(struct acpi_table_fadt))); } /* Clear the entire local FADT */ -- cgit v0.10.2 From 65259094c3e038519a2d8fa6fbc6256f04ad6535 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 22 Apr 2009 12:57:40 +0800 Subject: ACPICA: Fix possible dereference of null pointer Fix dereference of possibly null pointer "Predefined" in the case where the method is not one of the predefined methods. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index d9e8cbc..7f8e066 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -144,7 +144,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, pathname = acpi_ns_get_external_pathname(node); if (!pathname) { - pathname = ACPI_CAST_PTR(char, predefined->info.name); + return AE_OK; /* Could not get pathname, ignore */ } /* @@ -230,10 +230,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, } exit: - if (pathname != predefined->info.name) { - ACPI_FREE(pathname); - } - + ACPI_FREE(pathname); return (status); } -- cgit v0.10.2 From e4c1ebfc65c125b1289144f5815715f238367683 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 22 Apr 2009 13:02:06 +0800 Subject: ACPICA: Miscellaneous lint changes Unused variables/headers, casting, etc. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index d0a0807..4721f58 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -51,7 +51,7 @@ ACPI_MODULE_NAME("evxfevnt") /* Local prototypes */ -acpi_status +static acpi_status acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, struct acpi_gpe_block_info *gpe_block, void *context); @@ -785,7 +785,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_gpe_device) * block device. NULL if the GPE is one of the FADT-defined GPEs. * ******************************************************************************/ -acpi_status +static acpi_status acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, struct acpi_gpe_block_info *gpe_block, void *context) { diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c index f9b4f51..7e86563 100644 --- a/drivers/acpi/acpica/nssearch.c +++ b/drivers/acpi/acpica/nssearch.c @@ -45,6 +45,10 @@ #include "accommon.h" #include "acnamesp.h" +#ifdef ACPI_ASL_COMPILER +#include "amlcode.h" +#endif + #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nssearch") diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c index 88b5a2c..d3f77a5 100644 --- a/drivers/acpi/acpica/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c @@ -593,9 +593,6 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, } else { temp_size_needed += acpi_ns_get_pathname_length((*sub_object_list)->reference.node); - if (!temp_size_needed) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } } } else { /* diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index e5fe7c8..82b02dc 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -441,7 +441,7 @@ static void acpi_tb_convert_fadt(void) &acpi_gbl_FADT, fadt_info_table [i].length), - address32); + (u64) address32); } } } @@ -469,7 +469,6 @@ static void acpi_tb_convert_fadt(void) static void acpi_tb_validate_fadt(void) { char *name; - u32 *address32; struct acpi_generic_address *address64; u8 length; u32 i; @@ -505,15 +504,12 @@ static void acpi_tb_validate_fadt(void) for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { /* - * Generate pointers to the 32-bit and 64-bit addresses, get the - * register length (width), and the register name + * Generate pointer to the 64-bit address, get the register + * length (width) and the register name */ address64 = ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT, fadt_info_table[i].address64); - address32 = - ACPI_ADD_PTR(u32, &acpi_gbl_FADT, - fadt_info_table[i].address32); length = *ACPI_ADD_PTR(u8, &acpi_gbl_FADT, fadt_info_table[i].length); diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index f865d5a..63e8232 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c @@ -472,7 +472,7 @@ acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index) * lock may block, and also since the execution of a namespace walk * must be allowed to use the interpreter. */ - acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); + (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); acpi_ns_delete_namespace_by_owner(owner_id); -- cgit v0.10.2 From ba9c3f550e5792fbce2bbd7a429bf6f6d1f45fda Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 22 Apr 2009 13:13:48 +0800 Subject: ACPICA: Fix miscellaneous warnings under gcc 4+ Some possible warnings with gcc 4+, especially with extended warnings enabled Signed-off-by: Bob Moore Signed-off-by: Lin Ming diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c index dab3f48..02e6caa 100644 --- a/drivers/acpi/acpica/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c @@ -734,7 +734,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */ - obj_desc->reference.value = opcode - AML_LOCAL_OP; + obj_desc->reference.value = + ((u32)opcode) - AML_LOCAL_OP; obj_desc->reference.class = ACPI_REFCLASS_LOCAL; #ifndef ACPI_NO_METHOD_EXECUTION @@ -754,7 +755,7 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */ - obj_desc->reference.value = opcode - AML_ARG_OP; + obj_desc->reference.value = ((u32)opcode) - AML_ARG_OP; obj_desc->reference.class = ACPI_REFCLASS_ARG; #ifndef ACPI_NO_METHOD_EXECUTION diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c index 40f92bf..e46c821 100644 --- a/drivers/acpi/acpica/dswstate.c +++ b/drivers/acpi/acpica/dswstate.c @@ -102,7 +102,7 @@ acpi_ds_result_pop(union acpi_operand_object **object, /* Return object of the top element and clean that top element result stack */ walk_state->result_count--; - index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; + index = (u32)walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; *object = state->results.obj_desc[index]; if (!*object) { @@ -186,7 +186,7 @@ acpi_ds_result_push(union acpi_operand_object * object, /* Assign the address of object to the top free element of result stack */ - index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; + index = (u32)walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; state->results.obj_desc[index] = object; walk_state->result_count++; diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c index 69a2aa5..395212b 100644 --- a/drivers/acpi/acpica/rsxface.c +++ b/drivers/acpi/acpica/rsxface.c @@ -338,13 +338,17 @@ acpi_resource_to_address64(struct acpi_resource *resource, switch (resource->type) { case ACPI_RESOURCE_TYPE_ADDRESS16: - address16 = (struct acpi_resource_address16 *)&resource->data; + address16 = + ACPI_CAST_PTR(struct acpi_resource_address16, + &resource->data); ACPI_COPY_ADDRESS(out, address16); break; case ACPI_RESOURCE_TYPE_ADDRESS32: - address32 = (struct acpi_resource_address32 *)&resource->data; + address32 = + ACPI_CAST_PTR(struct acpi_resource_address32, + &resource->data); ACPI_COPY_ADDRESS(out, address32); break; -- cgit v0.10.2 From 2b09ce98a25e467455ecd81354cc18381628be75 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 22 Apr 2009 13:22:38 +0800 Subject: ACPICA: Fix implementation of AML BreakPoint operator (break to debugger) The AML BreakPoint opcode will now cause a break into the AML debugger if it is present/configured. This matches the expected behavior per the ACPI specification. Previously, only a message was output. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index b4c87b5..584d766 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c @@ -1386,14 +1386,19 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, case AML_BREAK_POINT_OP: - /* Call up to the OS service layer to handle this */ - - status = - acpi_os_signal(ACPI_SIGNAL_BREAKPOINT, - "Executed AML Breakpoint opcode"); + /* + * Set the single-step flag. This will cause the debugger (if present) + * to break to the console within the AML debugger at the start of the + * next AML instruction. + */ + ACPI_DEBUGGER_EXEC(acpi_gbl_cm_single_step = TRUE); + ACPI_DEBUGGER_EXEC(acpi_os_printf + ("**break** Executed AML BreakPoint opcode\n")); - /* If and when it returns, all done. */ + /* Call to the OSL in case OS wants a piece of the action */ + status = acpi_os_signal(ACPI_SIGNAL_BREAKPOINT, + "Executed AML Breakpoint opcode"); break; case AML_BREAK_OP: -- cgit v0.10.2 From e0c437bcca6926b541c738b5c64445654750b365 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 22 Apr 2009 13:39:47 +0800 Subject: ACPICA: Linux OSL: cleanup/update/merge Merge the OSL with the actual file used by Linux, so that the file does not require patching when integrated with Linux. General cleanup and some restructuring. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index 6d49b2a..fcb8e4b 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h @@ -1,11 +1,11 @@ /****************************************************************************** * - * Name: aclinux.h - OS specific defines, etc. + * Name: aclinux.h - OS specific defines, etc. for Linux * *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2009, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,10 +44,13 @@ #ifndef __ACLINUX_H__ #define __ACLINUX_H__ +/* Common (in-kernel/user-space) ACPICA configuration */ + #define ACPI_USE_SYSTEM_CLIBRARY #define ACPI_USE_DO_WHILE_0 #define ACPI_MUTEX_TYPE ACPI_BINARY_SEMAPHORE + #ifdef __KERNEL__ #include @@ -63,15 +66,18 @@ #include #include -/* Host-dependent types and defines */ +/* Host-dependent types and defines for in-kernel ACPICA */ #define ACPI_MACHINE_WIDTH BITS_PER_LONG -#define acpi_cache_t struct kmem_cache -#define acpi_spinlock spinlock_t * #define ACPI_EXPORT_SYMBOL(symbol) EXPORT_SYMBOL(symbol); #define strtoul simple_strtoul -#else /* !__KERNEL__ */ +#define acpi_cache_t struct kmem_cache +#define acpi_spinlock spinlock_t * +#define acpi_cpu_flags unsigned long +#define acpi_thread_id struct task_struct * + +#else /* !__KERNEL__ */ #include #include @@ -79,6 +85,11 @@ #include #include +/* Host-dependent types and defines for user-space ACPICA */ + +#define ACPI_FLUSH_CPU_CACHE() +#define acpi_thread_id pthread_t + #if defined(__ia64__) || defined(__x86_64__) #define ACPI_MACHINE_WIDTH 64 #define COMPILER_DEPENDENT_INT64 long @@ -94,17 +105,17 @@ #define __cdecl #endif -#define ACPI_FLUSH_CPU_CACHE() -#endif /* __KERNEL__ */ +#endif /* __KERNEL__ */ /* Linux uses GCC */ #include "acgcc.h" -#define acpi_cpu_flags unsigned long - -#define acpi_thread_id struct task_struct * +#ifdef __KERNEL__ +/* + * Overrides for in-kernel ACPICA + */ static inline acpi_thread_id acpi_os_get_thread_id(void) { return current; @@ -119,30 +130,32 @@ static inline acpi_thread_id acpi_os_get_thread_id(void) #include static inline void *acpi_os_allocate(acpi_size size) { - return kmalloc(size, irqs_disabled()? GFP_ATOMIC : GFP_KERNEL); + return kmalloc(size, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL); } + static inline void *acpi_os_allocate_zeroed(acpi_size size) { - return kzalloc(size, irqs_disabled()? GFP_ATOMIC : GFP_KERNEL); + return kzalloc(size, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL); } static inline void *acpi_os_acquire_object(acpi_cache_t * cache) { return kmem_cache_zalloc(cache, - irqs_disabled()? GFP_ATOMIC : GFP_KERNEL); + irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL); } -#define ACPI_ALLOCATE(a) acpi_os_allocate(a) -#define ACPI_ALLOCATE_ZEROED(a) acpi_os_allocate_zeroed(a) -#define ACPI_FREE(a) kfree(a) +#define ACPI_ALLOCATE(a) acpi_os_allocate(a) +#define ACPI_ALLOCATE_ZEROED(a) acpi_os_allocate_zeroed(a) +#define ACPI_FREE(a) kfree(a) -/* - * We need to show where it is safe to preempt execution of ACPICA - */ -#define ACPI_PREEMPTION_POINT() \ - do { \ - if (!irqs_disabled()) \ - cond_resched(); \ +/* Used within ACPICA to show where it is safe to preempt execution */ + +#define ACPI_PREEMPTION_POINT() \ + do { \ + if (!irqs_disabled()) \ + cond_resched(); \ } while (0) -#endif /* __ACLINUX_H__ */ +#endif /* __KERNEL__ */ + +#endif /* __ACLINUX_H__ */ -- cgit v0.10.2 From ba9e2ae443feb7231d9631ea0f62b63e26cfb9b1 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 24 Apr 2009 10:43:43 +0800 Subject: ACPICA: Update version to 20090422. Version 20090422. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index a868df6..60b76a3 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -47,7 +47,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20090320 +#define ACPI_CA_VERSION 0x20090422 #include "actypes.h" #include "actbl.h" -- cgit v0.10.2 From 10a3b461a258f52b17fb8e35edf3625726eca9a8 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 21 May 2009 10:02:34 +0800 Subject: ACPICA: Mutex support: Fix release ordering issue and current sync level Fixes a problem where if multiple mutexes of the same sync level are acquired but then not released in strict opposite order, the current sync level becomes confused and can cause errors. ACPICA BZ 471. http://acpica.org/bugzilla/show_bug.cgi?id=471 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c index d7cb030..77a592a 100644 --- a/drivers/acpi/acpica/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c @@ -83,6 +83,15 @@ void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc) if (obj_desc->mutex.prev) { (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. + */ + (obj_desc->mutex.prev)->mutex.original_sync_level = + obj_desc->mutex.original_sync_level; } else { thread->acquired_mutex_list = obj_desc->mutex.next; } @@ -349,6 +358,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, struct acpi_walk_state *walk_state) { acpi_status status = AE_OK; + u8 previous_sync_level; ACPI_FUNCTION_TRACE(ex_release_mutex); @@ -404,14 +414,21 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, return_ACPI_STATUS(AE_AML_MUTEX_ORDER); } + /* + * Get the previous sync_level from the head of the acquired mutex list. + * This handles the case where several mutexes at the same level have been + * acquired, but are not released in reverse order. + */ + previous_sync_level = + walk_state->thread->acquired_mutex_list->mutex.original_sync_level; + status = acpi_ex_release_mutex_object(obj_desc); if (obj_desc->mutex.acquisition_depth == 0) { /* Restore the original sync_level */ - walk_state->thread->current_sync_level = - obj_desc->mutex.original_sync_level; + walk_state->thread->current_sync_level = previous_sync_level; } return_ACPI_STATUS(status); } -- cgit v0.10.2 From 315c728887f198d12eb6ec7ef9d88483018c11cb Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 21 May 2009 10:04:33 +0800 Subject: ACPICA: Fix allowable release order for ASL mutex objects The ACPI 4.0 specification has been changed to make the SyncLevel for mutex objects more useful. When releasing a mutex, the synclevel of the mutex must now be the same as the current sync level. This makes more sense. This change updates the code to match the spec. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c index 77a592a..2f01142 100644 --- a/drivers/acpi/acpica/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c @@ -402,10 +402,14 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, } /* - * The sync level of the mutex must be less than or equal to the current - * sync level + * The sync level of the mutex must be equal to the current sync level. In + * other words, the current level means that at least one mutex at that + * level is currently being held. Attempting to release a mutex of a + * different level can only mean that the mutex ordering rule is being + * violated. This behavior is clarified in ACPI 4.0 specification. */ - if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) { + if (obj_desc->mutex.sync_level != + walk_state->thread->current_sync_level) { ACPI_ERROR((AE_INFO, "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d", acpi_ut_get_node_name(obj_desc->mutex.node), @@ -423,10 +427,13 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, walk_state->thread->acquired_mutex_list->mutex.original_sync_level; status = acpi_ex_release_mutex_object(obj_desc); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } if (obj_desc->mutex.acquisition_depth == 0) { - /* Restore the original sync_level */ + /* Restore the previous sync_level */ walk_state->thread->current_sync_level = previous_sync_level; } -- cgit v0.10.2 From a76b7727364ebb77b25983427623757d2c99bbc3 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 21 May 2009 10:06:19 +0800 Subject: ACPICA: Fix DebugObject output for DdbHandle objects Was putting several extra spaces on the next line. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c index 90d6061..6efd07a 100644 --- a/drivers/acpi/acpica/exstore.c +++ b/drivers/acpi/acpica/exstore.c @@ -193,10 +193,12 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, case ACPI_REFCLASS_TABLE: + /* Case for ddb_handle */ + ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "Table Index 0x%X\n", source_desc->reference.value)); - break; + return; default: break; -- cgit v0.10.2 From 474caffdc1ab35e9bcb1f88768442e3a4079a10d Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 21 May 2009 10:10:16 +0800 Subject: ACPICA: Additional validation of _PRT packages (resource mgr) Fixes a possible fault when parsing an ill-formed _PRT package. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c index d3f77a5..3c4dcc3 100644 --- a/drivers/acpi/acpica/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c @@ -547,7 +547,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, if (!package_element || (package_element->common.type != ACPI_TYPE_PACKAGE)) { - return_ACPI_STATUS (AE_AML_OPERAND_TYPE); + return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } /* -- cgit v0.10.2 From 8c725bf93706db976e9de495579ca625d493e809 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 21 May 2009 10:27:51 +0800 Subject: ACPICA: Simplify and optimize NsGetNextNode function Reduced parameter count and reduced code for this frequently used function. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 46cb5b4..94cdc2b 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -99,10 +99,19 @@ acpi_ns_walk_namespace(acpi_object_type type, acpi_walk_callback user_function, void *context, void **return_value); -struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct acpi_namespace_node - *parent, struct acpi_namespace_node +struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node + *parent, + struct acpi_namespace_node *child); +struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type, + struct + acpi_namespace_node + *parent, + struct + acpi_namespace_node + *child); + /* * nsparse - table parsing */ diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index aceb931..efc971a 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c @@ -334,9 +334,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) /* Get the next node in this scope (NULL if none) */ - child_node = - acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, - child_node); + child_node = acpi_ns_get_next_node(parent_node, child_node); if (child_node) { /* Found a child node - detach any attached object */ @@ -345,8 +343,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) /* Check if this node has any children */ - if (acpi_ns_get_next_node - (ACPI_TYPE_ANY, child_node, NULL)) { + if (child_node->child) { /* * There is at least one child of this node, * visit the node @@ -432,9 +429,7 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id) * Get the next child of this parent node. When child_node is NULL, * the first child of the parent is returned */ - child_node = - acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, - child_node); + child_node = acpi_ns_get_next_node(parent_node, child_node); if (deletion_node) { acpi_ns_delete_children(deletion_node); @@ -452,8 +447,7 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id) /* Check if this node has any children */ - if (acpi_ns_get_next_node - (ACPI_TYPE_ANY, child_node, NULL)) { + if (child_node->child) { /* * There is at least one child of this node, * visit the node diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c index 83e3aa6..35539df 100644 --- a/drivers/acpi/acpica/nswalk.c +++ b/drivers/acpi/acpica/nswalk.c @@ -52,8 +52,7 @@ ACPI_MODULE_NAME("nswalk") * * FUNCTION: acpi_ns_get_next_node * - * PARAMETERS: Type - Type of node to be searched for - * parent_node - Parent node whose children we are + * PARAMETERS: parent_node - Parent node whose children we are * getting * child_node - Previous child that was found. * The NEXT child will be returned @@ -66,27 +65,68 @@ ACPI_MODULE_NAME("nswalk") * within Scope is returned. * ******************************************************************************/ -struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct acpi_namespace_node - *parent_node, struct acpi_namespace_node +struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node + *parent_node, + struct acpi_namespace_node *child_node) { - struct acpi_namespace_node *next_node = NULL; - ACPI_FUNCTION_ENTRY(); if (!child_node) { /* It's really the parent's _scope_ that we want */ - next_node = parent_node->child; + return parent_node->child; } - else { - /* Start search at the NEXT node */ - - next_node = acpi_ns_get_next_valid_node(child_node); + /* + * Get the next node. + * + * If we are at the end of this peer list, return NULL + */ + if (child_node->flags & ANOBJ_END_OF_PEER_LIST) { + return NULL; } + /* Otherwise just return the next peer */ + + return child_node->peer; +} + +/******************************************************************************* + * + * FUNCTION: acpi_ns_get_next_node_typed + * + * PARAMETERS: Type - Type of node to be searched for + * parent_node - Parent node whose children we are + * getting + * child_node - Previous child that was found. + * The NEXT child will be returned + * + * RETURN: struct acpi_namespace_node - Pointer to the NEXT child or NULL if + * none is found. + * + * DESCRIPTION: Return the next peer node within the namespace. If Handle + * is valid, Scope is ignored. Otherwise, the first node + * within Scope is returned. + * + ******************************************************************************/ + +struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type, + struct + acpi_namespace_node + *parent_node, + struct + acpi_namespace_node + *child_node) +{ + struct acpi_namespace_node *next_node = NULL; + + ACPI_FUNCTION_ENTRY(); + + next_node = acpi_ns_get_next_node(parent_node, child_node); + + /* If any type is OK, we are done */ if (type == ACPI_TYPE_ANY) { @@ -186,9 +226,7 @@ acpi_ns_walk_namespace(acpi_object_type type, /* Get the next node in this scope. Null if not found */ status = AE_OK; - child_node = - acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, - child_node); + child_node = acpi_ns_get_next_node(parent_node, child_node); if (child_node) { /* Found next child, get the type if we are not searching for ANY */ @@ -269,8 +307,7 @@ acpi_ns_walk_namespace(acpi_object_type type, * function has specified that the maximum depth has been reached. */ if ((level < max_depth) && (status != AE_CTRL_DEPTH)) { - if (acpi_ns_get_next_node - (ACPI_TYPE_ANY, child_node, NULL)) { + if (child_node->child) { /* There is at least one child of this node, visit it */ diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c index 1c7efc1..dd33d8b 100644 --- a/drivers/acpi/acpica/nsxfobj.c +++ b/drivers/acpi/acpica/nsxfobj.c @@ -268,7 +268,7 @@ acpi_get_next_object(acpi_object_type type, /* Internal function does the real work */ - node = acpi_ns_get_next_node(type, parent_node, child_node); + node = acpi_ns_get_next_node_typed(type, parent_node, child_node); if (!node) { status = AE_NOT_FOUND; goto unlock_and_exit; -- cgit v0.10.2 From 06366c149232f64c89f513f188ccc6783d0e444f Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Thu, 21 May 2009 10:29:28 +0800 Subject: ACPICA: Fix reference count issues for DdbHandle object Fix a problem where the DdbHandle could be prematurely deleted, possibly causing a fault. Signed-off-by: Lin Ming Signed-off-by: Bob Moore Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 3deb20a..c0348ff 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -229,6 +229,8 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, walk_state); if (ACPI_FAILURE(status)) { (void)acpi_ex_unload_table(ddb_handle); + + acpi_ut_remove_reference(ddb_handle); return_ACPI_STATUS(status); } } @@ -454,6 +456,10 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, return_ACPI_STATUS(status); } + /* Remove the reference by added by acpi_ex_store above */ + + acpi_ut_remove_reference(ddb_handle); + /* Invoke table handler if present */ if (acpi_gbl_table_handler) { @@ -530,8 +536,5 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) (void)acpi_tb_release_owner_id(table_index); acpi_tb_set_table_loaded_flag(table_index, FALSE); - /* Table unloaded, remove a reference to the ddb_handle object */ - - acpi_ut_remove_reference(ddb_handle); return_ACPI_STATUS(AE_OK); } -- cgit v0.10.2 From e0be6f5a9863b626c19f0be04946c6285cc9db56 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Thu, 21 May 2009 10:32:02 +0800 Subject: ACPICA: Invalidate DdbHandle after table unload Mark the DdbHandle as invalid after the table it refers to is unloaded. This is needed because the handle itself may not be deleted after the table unload, depending on whether it has been stored in a named object by the caller. Signed-off-by: Lin Ming Signed-off-by: Bob Moore Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index c0348ff..0731fd6 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -91,6 +91,7 @@ acpi_ex_add_table(u32 table_index, /* Init the table handle */ + obj_desc->common.flags |= AOPOBJ_DATA_VALID; obj_desc->reference.class = ACPI_REFCLASS_TABLE; *ddb_handle = obj_desc; @@ -501,13 +502,18 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) /* * Validate the handle - * Although the handle is partially validated in acpi_ex_reconfiguration(), + * Although the handle is partially validated in acpi_ex_reconfiguration() * when it calls acpi_ex_resolve_operands(), the handle is more completely * validated here. + * + * Handle must be a valid operand object of type reference. Also, the + * ddb_handle must still be marked valid (table has not been previously + * unloaded) */ if ((!ddb_handle) || (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) || - (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE)) { + (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE) || + (!(ddb_handle->common.flags & AOPOBJ_DATA_VALID))) { return_ACPI_STATUS(AE_BAD_PARAMETER); } @@ -515,6 +521,12 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) table_index = table_desc->reference.value; + /* Ensure the table is still loaded */ + + if (!acpi_tb_is_table_loaded(table_index)) { + return_ACPI_STATUS(AE_NOT_EXIST); + } + /* Invoke table handler if present */ if (acpi_gbl_table_handler) { @@ -536,5 +548,10 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) (void)acpi_tb_release_owner_id(table_index); acpi_tb_set_table_loaded_flag(table_index, FALSE); + /* + * Invalidate the handle. We do this because the handle may be stored + * in a named object and may not be actually deleted until much later. + */ + ddb_handle->common.flags &= ~AOPOBJ_DATA_VALID; return_ACPI_STATUS(AE_OK); } -- cgit v0.10.2 From b2f7ddcfcb9c2436896cb339a7ff70245648f033 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Thu, 21 May 2009 10:42:09 +0800 Subject: ACPICA: New: AcpiInstallMethod - install a single control method This interface enables the override or creation of a single control method. Useful to repair a bug or install a missing method. Signed-off-by: Lin Ming Signed-off-by: Bob Moore Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 2ec394a..882b4b5 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -205,6 +205,7 @@ struct acpi_namespace_node { #define ANOBJ_METHOD_LOCAL 0x08 /* Node is a method local */ #define ANOBJ_SUBTREE_HAS_INI 0x10 /* Used to optimize device initialization */ #define ANOBJ_EVALUATED 0x20 /* Set on first evaluation of node */ +#define ANOBJ_ALLOCATED_BUFFER 0x40 /* Method AML buffer is dynamic (install_method) */ #define ANOBJ_IS_EXTERNAL 0x08 /* i_aSL only: This object created via External() */ #define ANOBJ_METHOD_NO_RETVAL 0x10 /* i_aSL only: Method has no return value */ diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h index ff851c5..067f967 100644 --- a/drivers/acpi/acpica/amlcode.h +++ b/drivers/acpi/acpica/amlcode.h @@ -483,7 +483,7 @@ typedef enum { #define AML_METHOD_ARG_COUNT 0x07 #define AML_METHOD_SERIALIZED 0x08 -#define AML_METHOD_SYNCH_LEVEL 0xF0 +#define AML_METHOD_SYNC_LEVEL 0xF0 /* METHOD_FLAGS_ARG_COUNT is not used internally, define additional flags */ diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c index a57ad25..02b25d2 100644 --- a/drivers/acpi/acpica/excreate.c +++ b/drivers/acpi/acpica/excreate.c @@ -502,7 +502,7 @@ acpi_ex_create_method(u8 * aml_start, * ACPI 2.0: sync_level = sync_level in method declaration */ obj_desc->method.sync_level = (u8) - ((method_flags & AML_METHOD_SYNCH_LEVEL) >> 4); + ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4); } /* Attach the new object to the method Node */ diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index 89d141f..ec52461 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c @@ -120,9 +120,11 @@ static struct acpi_exdump_info acpi_ex_dump_event[2] = { {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(event.os_semaphore), "OsSemaphore"} }; -static struct acpi_exdump_info acpi_ex_dump_method[8] = { +static struct acpi_exdump_info acpi_ex_dump_method[9] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL}, - {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), "ParamCount"}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.method_flags), "Method Flags"}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), + "Parameter Count"}, {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.sync_level), "Sync Level"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.mutex), "Mutex"}, {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.owner_id), "Owner Id"}, diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c index 3eb20bf..60f3af0 100644 --- a/drivers/acpi/acpica/nsobject.c +++ b/drivers/acpi/acpica/nsobject.c @@ -213,6 +213,15 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node) return_VOID; } + if (node->flags & ANOBJ_ALLOCATED_BUFFER) { + + /* Free the dynamic aml buffer */ + + if (obj_desc->common.type == ACPI_TYPE_METHOD) { + ACPI_FREE(obj_desc->method.aml_start); + } + } + /* Clear the entry in all cases */ node->object = NULL; diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index 9589fea..f23593d 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c @@ -45,6 +45,8 @@ #include #include "accommon.h" #include "acnamesp.h" +#include "acparser.h" +#include "amlcode.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsxfname") @@ -358,3 +360,151 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) } ACPI_EXPORT_SYMBOL(acpi_get_object_info) + +/****************************************************************************** + * + * FUNCTION: acpi_install_method + * + * PARAMETERS: Buffer - An ACPI table containing one control method + * + * RETURN: Status + * + * DESCRIPTION: Install a control method into the namespace. If the method + * name already exists in the namespace, it is overwritten. The + * input buffer must contain a valid DSDT or SSDT containing a + * single control method. + * + ******************************************************************************/ +acpi_status acpi_install_method(u8 *buffer) +{ + struct acpi_table_header *table = + ACPI_CAST_PTR(struct acpi_table_header, buffer); + u8 *aml_buffer; + u8 *aml_start; + char *path; + struct acpi_namespace_node *node; + union acpi_operand_object *method_obj; + struct acpi_parse_state parser_state; + u32 aml_length; + u16 opcode; + u8 method_flags; + acpi_status status; + + /* Parameter validation */ + + if (!buffer) { + return AE_BAD_PARAMETER; + } + + /* Table must be a DSDT or SSDT */ + + if (!ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) && + !ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT)) { + return AE_BAD_HEADER; + } + + /* First AML opcode in the table must be a control method */ + + parser_state.aml = buffer + sizeof(struct acpi_table_header); + opcode = acpi_ps_peek_opcode(&parser_state); + if (opcode != AML_METHOD_OP) { + return AE_BAD_PARAMETER; + } + + /* Extract method information from the raw AML */ + + parser_state.aml += acpi_ps_get_opcode_size(opcode); + parser_state.pkg_end = acpi_ps_get_next_package_end(&parser_state); + path = acpi_ps_get_next_namestring(&parser_state); + method_flags = *parser_state.aml++; + aml_start = parser_state.aml; + aml_length = ACPI_PTR_DIFF(parser_state.pkg_end, aml_start); + + /* + * Allocate resources up-front. We don't want to have to delete a new + * node from the namespace if we cannot allocate memory. + */ + aml_buffer = ACPI_ALLOCATE(aml_length); + if (!aml_buffer) { + return AE_NO_MEMORY; + } + + method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD); + if (!method_obj) { + ACPI_FREE(aml_buffer); + return AE_NO_MEMORY; + } + + /* Lock namespace for acpi_ns_lookup, we may be creating a new node */ + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + goto error_exit; + } + + /* The lookup either returns an existing node or creates a new one */ + + status = + acpi_ns_lookup(NULL, path, ACPI_TYPE_METHOD, ACPI_IMODE_LOAD_PASS1, + ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND, + NULL, &node); + + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + + if (ACPI_FAILURE(status)) { /* ns_lookup */ + if (status != AE_ALREADY_EXISTS) { + goto error_exit; + } + + /* Node existed previously, make sure it is a method node */ + + if (node->type != ACPI_TYPE_METHOD) { + status = AE_TYPE; + goto error_exit; + } + } + + /* Copy the method AML to the local buffer */ + + ACPI_MEMCPY(aml_buffer, aml_start, aml_length); + + /* Initialize the method object with the new method's information */ + + method_obj->method.aml_start = aml_buffer; + method_obj->method.aml_length = aml_length; + + method_obj->method.param_count = (u8) + (method_flags & AML_METHOD_ARG_COUNT); + + method_obj->method.method_flags = (u8) + (method_flags & ~AML_METHOD_ARG_COUNT); + + if (method_flags & AML_METHOD_SERIALIZED) { + method_obj->method.sync_level = (u8) + ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4); + } + + /* + * Now that it is complete, we can attach the new method object to + * the method Node (detaches/deletes any existing object) + */ + status = acpi_ns_attach_object(node, method_obj, ACPI_TYPE_METHOD); + + /* + * Flag indicates AML buffer is dynamic, must be deleted later. + * Must be set only after attach above. + */ + node->flags |= ANOBJ_ALLOCATED_BUFFER; + + /* Remove local reference to the method object */ + + acpi_ut_remove_reference(method_obj); + return status; + +error_exit: + + ACPI_FREE(aml_buffer); + ACPI_FREE(method_obj); + return status; +} +ACPI_EXPORT_SYMBOL(acpi_install_method) diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 60b76a3..c3b08d3 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -201,6 +201,8 @@ acpi_evaluate_object_typed(acpi_handle object, acpi_status acpi_get_object_info(acpi_handle handle, struct acpi_buffer *return_buffer); +acpi_status acpi_install_method(u8 *buffer); + acpi_status acpi_get_next_object(acpi_object_type type, acpi_handle parent, -- cgit v0.10.2 From 3c59f96081259358d9d5d677f4839c36391806b6 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 21 May 2009 10:51:53 +0800 Subject: ACPICA: Update Load() to use operation region interfaces Replace memory mapping with region access calls. Now, all region accesses go through the region handler as they should. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 0731fd6..eca6f63 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -47,6 +47,7 @@ #include "acnamesp.h" #include "actables.h" #include "acdispat.h" +#include "acevents.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exconfig") @@ -57,6 +58,10 @@ acpi_ex_add_table(u32 table_index, struct acpi_namespace_node *parent_node, union acpi_operand_object **ddb_handle); +static acpi_status +acpi_ex_region_read(union acpi_operand_object *obj_desc, + u32 length, u8 *buffer); + /******************************************************************************* * * FUNCTION: acpi_ex_add_table @@ -257,6 +262,48 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, /******************************************************************************* * + * FUNCTION: acpi_ex_region_read + * + * PARAMETERS: obj_desc - Region descriptor + * Length - Number of bytes to read + * Buffer - Pointer to where to put the data + * + * RETURN: Status + * + * DESCRIPTION: Read data from an operation region. The read starts from the + * beginning of the region. + * + ******************************************************************************/ + +static acpi_status +acpi_ex_region_read(union acpi_operand_object *obj_desc, u32 length, u8 *buffer) +{ + acpi_status status; + acpi_integer value; + acpi_physical_address address; + u32 i; + + address = obj_desc->region.address; + + /* Bytewise reads */ + + for (i = 0; i < length; i++) { + status = acpi_ev_address_space_dispatch(obj_desc, ACPI_READ, + address, 8, &value); + if (ACPI_FAILURE(status)) { + return status; + } + + *buffer = (u8)value; + buffer++; + address++; + } + + return AE_OK; +} + +/******************************************************************************* + * * FUNCTION: acpi_ex_load_op * * PARAMETERS: obj_desc - Region or Buffer/Field where the table will be @@ -317,18 +364,23 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, } } - /* - * Map the table header and get the actual table length. The region - * length is not guaranteed to be the same as the table length. - */ - table = acpi_os_map_memory(obj_desc->region.address, - sizeof(struct acpi_table_header)); + /* Get the table header first so we can get the table length */ + + table = ACPI_ALLOCATE(sizeof(struct acpi_table_header)); if (!table) { return_ACPI_STATUS(AE_NO_MEMORY); } + status = + acpi_ex_region_read(obj_desc, + sizeof(struct acpi_table_header), + ACPI_CAST_PTR(u8, table)); length = table->length; - acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); + ACPI_FREE(table); + + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } /* Must have at least an ACPI table header */ @@ -337,10 +389,19 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, } /* - * The memory region is not guaranteed to remain stable and we must - * copy the table to a local buffer. For example, the memory region - * is corrupted after suspend on some machines. Dynamically loaded - * tables are usually small, so this overhead is minimal. + * The original implementation simply mapped the table, with no copy. + * However, the memory region is not guaranteed to remain stable and + * we must copy the table to a local buffer. For example, the memory + * region is corrupted after suspend on some machines. Dynamically + * loaded tables are usually small, so this overhead is minimal. + * + * The latest implementation (5/2009) does not use a mapping at all. + * We use the low-level operation region interface to read the table + * instead of the obvious optimization of using a direct mapping. + * This maintains a consistent use of operation regions across the + * entire subsystem. This is important if additional processing must + * be performed in the (possibly user-installed) operation region + * handler. For example, acpi_exec and ASLTS depend on this. */ /* Allocate a buffer for the table */ @@ -350,17 +411,16 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, return_ACPI_STATUS(AE_NO_MEMORY); } - /* Map the entire table and copy it */ + /* Read the entire table */ - table = acpi_os_map_memory(obj_desc->region.address, length); - if (!table) { + status = acpi_ex_region_read(obj_desc, length, + ACPI_CAST_PTR(u8, + table_desc.pointer)); + if (ACPI_FAILURE(status)) { ACPI_FREE(table_desc.pointer); - return_ACPI_STATUS(AE_NO_MEMORY); + return_ACPI_STATUS(status); } - ACPI_MEMCPY(table_desc.pointer, table, length); - acpi_os_unmap_memory(table, length); - table_desc.address = obj_desc->region.address; break; -- cgit v0.10.2 From f5407af3f271ed4cd6655cf30d419d77e0f8bfaa Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 21 May 2009 10:56:52 +0800 Subject: ACPICA: Simplify internal operation region interface Changed address parameter to a simple offset. This removes the need for the caller to access the region object to obtain the physical address. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 07e2013..0bba148 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -139,7 +139,7 @@ acpi_status acpi_ev_initialize_op_regions(void); acpi_status acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, u32 function, - acpi_physical_address address, + u32 region_offset, u32 bit_width, acpi_integer * value); acpi_status diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 538d632..98c7f9c 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c @@ -275,7 +275,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) * * PARAMETERS: region_obj - Internal region object * Function - Read or Write operation - * Address - Where in the space to read or write + * region_offset - Where in the region to read or write * bit_width - Field width in bits (8, 16, 32, or 64) * Value - Pointer to in or out value, must be * full 64-bit acpi_integer @@ -290,7 +290,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) acpi_status acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, u32 function, - acpi_physical_address address, + u32 region_offset, u32 bit_width, acpi_integer * value) { acpi_status status; @@ -396,7 +396,8 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", ®ion_obj->region.handler->address_space, handler, - ACPI_FORMAT_NATIVE_UINT(address), + ACPI_FORMAT_NATIVE_UINT(region_obj->region.address + + region_offset), acpi_ut_get_region_name(region_obj->region. space_id))); @@ -412,8 +413,9 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, /* Call the handler */ - status = handler(function, address, bit_width, value, - handler_desc->address_space.context, + status = handler(function, + (region_obj->region.address + region_offset), + bit_width, value, handler_desc->address_space.context, region_obj2->extra.region_context); if (ACPI_FAILURE(status)) { diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index eca6f63..277fd60 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -280,23 +280,22 @@ acpi_ex_region_read(union acpi_operand_object *obj_desc, u32 length, u8 *buffer) { acpi_status status; acpi_integer value; - acpi_physical_address address; + u32 region_offset = 0; u32 i; - address = obj_desc->region.address; - /* Bytewise reads */ for (i = 0; i < length; i++) { status = acpi_ev_address_space_dispatch(obj_desc, ACPI_READ, - address, 8, &value); + region_offset, 8, + &value); if (ACPI_FAILURE(status)) { return status; } *buffer = (u8)value; buffer++; - address++; + region_offset++; } return AE_OK; diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index 99cee61..d4075b8 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c @@ -222,7 +222,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, { acpi_status status; union acpi_operand_object *rgn_desc; - acpi_physical_address address; + u32 region_offset; ACPI_FUNCTION_TRACE(ex_access_region); @@ -243,7 +243,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, * 3) The current offset into the field */ rgn_desc = obj_desc->common_field.region_obj; - address = rgn_desc->region.address + + region_offset = obj_desc->common_field.base_byte_offset + field_datum_byte_offset; if ((function & ACPI_IO_MASK) == ACPI_READ) { @@ -260,16 +260,18 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, obj_desc->common_field.access_byte_width, obj_desc->common_field.base_byte_offset, field_datum_byte_offset, ACPI_CAST_PTR(void, - address))); + (rgn_desc-> + region. + address + + region_offset)))); /* Invoke the appropriate address_space/op_region handler */ - status = acpi_ev_address_space_dispatch(rgn_desc, function, - address, - ACPI_MUL_8(obj_desc-> - common_field. - access_byte_width), - value); + status = + acpi_ev_address_space_dispatch(rgn_desc, function, region_offset, + ACPI_MUL_8(obj_desc->common_field. + access_byte_width), + value); if (ACPI_FAILURE(status)) { if (status == AE_NOT_IMPLEMENTED) { -- cgit v0.10.2 From c446eed6187addf9f76ee0028abed32393aef27e Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Thu, 21 May 2009 10:59:15 +0800 Subject: ACPICA: Eliminate extra call to NsGetParentNode Was called twice in the same function with the same parameter. Alex Chiang. Signed-off-by: Alex Chiang Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c index dd33d8b..4071bad 100644 --- a/drivers/acpi/acpica/nsxfobj.c +++ b/drivers/acpi/acpica/nsxfobj.c @@ -162,6 +162,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_type) acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle) { struct acpi_namespace_node *node; + struct acpi_namespace_node *parent_node; acpi_status status; if (!ret_handle) { @@ -189,12 +190,12 @@ acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle) /* Get the parent entry */ - *ret_handle = - acpi_ns_convert_entry_to_handle(acpi_ns_get_parent_node(node)); + parent_node = acpi_ns_get_parent_node(node); + *ret_handle = acpi_ns_convert_entry_to_handle(parent_node); /* Return exception if parent is null */ - if (!acpi_ns_get_parent_node(node)) { + if (!parent_node) { status = AE_NULL_ENTRY; } -- cgit v0.10.2 From 3362a6badb4fe75e198885b125b21ccf846861b4 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Thu, 21 May 2009 11:03:29 +0800 Subject: ACPICA: Region deletion: Ensure region object is removed from handler list Prevents a possible fault when a dynamic operation region is deleted. ACPICA BZ 507. http://acpica.org/bugzilla/show_bug.cgi?id=507 Signed-off-by: Lin Ming Signed-off-by: Bob Moore Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c index a5ee23b..bc17103 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c @@ -75,6 +75,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) union acpi_operand_object *handler_desc; union acpi_operand_object *second_desc; union acpi_operand_object *next_desc; + union acpi_operand_object **last_obj_ptr; ACPI_FUNCTION_TRACE_PTR(ut_delete_internal_obj, object); @@ -223,6 +224,26 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) */ handler_desc = object->region.handler; if (handler_desc) { + next_desc = + handler_desc->address_space.region_list; + last_obj_ptr = + &handler_desc->address_space.region_list; + + /* Remove the region object from the handler's list */ + + while (next_desc) { + if (next_desc == object) { + *last_obj_ptr = + next_desc->region.next; + break; + } + + /* Walk the linked list of handler */ + + last_obj_ptr = &next_desc->region.next; + next_desc = next_desc->region.next; + } + if (handler_desc->address_space.handler_flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) { -- cgit v0.10.2 From b1cd843be74ba0dcc6c42db7b11b76d63be149f6 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 21 May 2009 11:05:03 +0800 Subject: ACPICA: Disable preservation of SCI enable bit (SCI_EN) Preserving this bit breaks some machines. Not preserving this bit seems to work OK in all cases, even though this goes against the ACPI spec. http://bugzilla.kernel.org/show_bug.cgi?id=13289 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 882b4b5..ee986ed 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -789,11 +789,14 @@ struct acpi_bit_register_info { /* For control registers, both ignored and reserved bits must be preserved */ /* - * The ACPI spec says to ignore PM1_CTL.SCI_EN (bit 0) - * but we need to be able to write ACPI_BITREG_SCI_ENABLE directly - * as a BIOS workaround on some machines. + * For PM1 control, the SCI enable bit (bit 0, SCI_EN) is defined by the + * ACPI specification to be a "preserved" bit - "OSPM always preserves this + * bit position", section 4.7.3.2.1. However, on some machines the OS must + * write a one to this bit after resume for the machine to work properly. + * To enable this, we no longer attempt to preserve this bit. No machines + * are known to fail if the bit is not preserved. (May 2009) */ -#define ACPI_PM1_CONTROL_IGNORED_BITS 0x0200 /* Bits 9 */ +#define ACPI_PM1_CONTROL_IGNORED_BITS 0x0200 /* Bit 9 */ #define ACPI_PM1_CONTROL_RESERVED_BITS 0xC1F8 /* Bits 14-15, 3-8 */ #define ACPI_PM1_CONTROL_PRESERVED_BITS \ (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS) -- cgit v0.10.2 From d6a1cd4975a5ffaa21a961be04a469519edf50d6 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 21 May 2009 11:06:53 +0800 Subject: ACPICA: Update version to 20090521. Update version number. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index c3b08d3..82ec6a3 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -47,7 +47,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20090422 +#define ACPI_CA_VERSION 0x20090521 #include "actypes.h" #include "actbl.h" -- cgit v0.10.2