diff options
Diffstat (limited to 'drivers/acpi/acpica')
-rw-r--r-- | drivers/acpi/acpica/acevents.h | 4 | ||||
-rw-r--r-- | drivers/acpi/acpica/acglobal.h | 5 | ||||
-rw-r--r-- | drivers/acpi/acpica/aclocal.h | 19 | ||||
-rw-r--r-- | drivers/acpi/acpica/acnamesp.h | 3 | ||||
-rw-r--r-- | drivers/acpi/acpica/actables.h | 5 | ||||
-rw-r--r-- | drivers/acpi/acpica/acutils.h | 2 | ||||
-rw-r--r-- | drivers/acpi/acpica/amlcode.h | 1 | ||||
-rw-r--r-- | drivers/acpi/acpica/dsinit.c | 11 | ||||
-rw-r--r-- | drivers/acpi/acpica/dsmethod.c | 50 | ||||
-rw-r--r-- | drivers/acpi/acpica/dsopcode.c | 2 | ||||
-rw-r--r-- | drivers/acpi/acpica/dswload2.c | 15 | ||||
-rw-r--r-- | drivers/acpi/acpica/evrgnini.c | 62 | ||||
-rw-r--r-- | drivers/acpi/acpica/exconfig.c | 42 | ||||
-rw-r--r-- | drivers/acpi/acpica/nsload.c | 2 | ||||
-rw-r--r-- | drivers/acpi/acpica/nsnames.c | 45 | ||||
-rw-r--r-- | drivers/acpi/acpica/nsxfname.c | 43 | ||||
-rw-r--r-- | drivers/acpi/acpica/tbdata.c | 81 | ||||
-rw-r--r-- | drivers/acpi/acpica/tbfadt.c | 10 | ||||
-rw-r--r-- | drivers/acpi/acpica/tbxface.c | 16 | ||||
-rw-r--r-- | drivers/acpi/acpica/tbxfload.c | 44 | ||||
-rw-r--r-- | drivers/acpi/acpica/utdecode.c | 49 |
21 files changed, 262 insertions, 249 deletions
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 92fa47c6498c..8a0049d5cdf3 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -243,9 +243,7 @@ acpi_ev_default_region_setup(acpi_handle handle, u32 function, void *handler_context, void **region_context); -acpi_status -acpi_ev_initialize_region(union acpi_operand_object *region_obj, - u8 acpi_ns_locked); +acpi_status acpi_ev_initialize_region(union acpi_operand_object *region_obj); /* * evsci - SCI (System Control Interrupt) handling/dispatch diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 750fa824d42c..edbb42e251a6 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -240,10 +240,6 @@ ACPI_INIT_GLOBAL(u32, acpi_gbl_nesting_level, 0); ACPI_GLOBAL(struct acpi_thread_state *, acpi_gbl_current_walk_list); -/* Maximum number of While() loop iterations before forced abort */ - -ACPI_GLOBAL(u16, acpi_gbl_max_loop_iterations); - /* Control method single step flag */ ACPI_GLOBAL(u8, acpi_gbl_cm_single_step); @@ -318,6 +314,7 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_cstyle_disassembly, TRUE); ACPI_INIT_GLOBAL(u8, acpi_gbl_force_aml_disassembly, FALSE); ACPI_INIT_GLOBAL(u8, acpi_gbl_dm_opt_verbose, TRUE); ACPI_INIT_GLOBAL(u8, acpi_gbl_dm_emit_external_opcodes, FALSE); +ACPI_INIT_GLOBAL(u8, acpi_gbl_do_disassembler_optimizations, TRUE); ACPI_GLOBAL(u8, acpi_gbl_dm_opt_disasm); ACPI_GLOBAL(u8, acpi_gbl_dm_opt_listing); diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index dff1207a6078..792660054992 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -765,7 +765,7 @@ union acpi_parse_value { union acpi_parse_value value; /* Value or args associated with the opcode */\ u8 arg_list_length; /* Number of elements in the arg list */\ ACPI_DISASM_ONLY_MEMBERS (\ - u8 disasm_flags; /* Used during AML disassembly */\ + u16 disasm_flags; /* Used during AML disassembly */\ u8 disasm_opcode; /* Subtype used for disassembly */\ char *operator_symbol;/* Used for C-style operator name strings */\ char aml_op_name[16]) /* Op name (debug only) */ @@ -868,14 +868,15 @@ struct acpi_parse_state { /* Parse object disasm_flags */ -#define ACPI_PARSEOP_IGNORE 0x01 -#define ACPI_PARSEOP_PARAMETER_LIST 0x02 -#define ACPI_PARSEOP_EMPTY_TERMLIST 0x04 -#define ACPI_PARSEOP_PREDEFINED_CHECKED 0x08 -#define ACPI_PARSEOP_CLOSING_PAREN 0x10 -#define ACPI_PARSEOP_COMPOUND_ASSIGNMENT 0x20 -#define ACPI_PARSEOP_ASSIGNMENT 0x40 -#define ACPI_PARSEOP_ELSEIF 0x80 +#define ACPI_PARSEOP_IGNORE 0x0001 +#define ACPI_PARSEOP_PARAMETER_LIST 0x0002 +#define ACPI_PARSEOP_EMPTY_TERMLIST 0x0004 +#define ACPI_PARSEOP_PREDEFINED_CHECKED 0x0008 +#define ACPI_PARSEOP_CLOSING_PAREN 0x0010 +#define ACPI_PARSEOP_COMPOUND_ASSIGNMENT 0x0020 +#define ACPI_PARSEOP_ASSIGNMENT 0x0040 +#define ACPI_PARSEOP_ELSEIF 0x0080 +#define ACPI_PARSEOP_LEGACY_ASL_ONLY 0x0100 /***************************************************************************** * diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index bb7fca1c8ba3..7affdcdfcc81 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -292,6 +292,9 @@ char *acpi_ns_get_normalized_pathname(struct acpi_namespace_node *node, char *acpi_ns_name_of_current_scope(struct acpi_walk_state *walk_state); acpi_status +acpi_ns_handle_to_name(acpi_handle target_handle, struct acpi_buffer *buffer); + +acpi_status acpi_ns_handle_to_pathname(acpi_handle target_handle, struct acpi_buffer *buffer, u8 no_trailing); diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index e85953b6fa0e..7dd527f8ca1d 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h @@ -127,10 +127,11 @@ acpi_status acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node); acpi_status -acpi_tb_install_and_load_table(struct acpi_table_header *table, - acpi_physical_address address, +acpi_tb_install_and_load_table(acpi_physical_address address, u8 flags, u8 override, u32 *table_index); +acpi_status acpi_tb_unload_table(u32 table_index); + void acpi_tb_terminate(void); acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index); diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 0a1b53c9ee0e..845afb180a7e 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -232,6 +232,8 @@ const char *acpi_ut_get_region_name(u8 space_id); const char *acpi_ut_get_event_name(u32 event_id); +const char *acpi_ut_get_argument_type_name(u32 arg_type); + char acpi_ut_hex_to_ascii_char(u64 integer, u32 position); acpi_status acpi_ut_ascii_to_hex_byte(char *two_ascii_chars, u8 *return_byte); diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h index ceb4f7365f7f..6bd8d4bcff65 100644 --- a/drivers/acpi/acpica/amlcode.h +++ b/drivers/acpi/acpica/amlcode.h @@ -240,6 +240,7 @@ #define ARGP_QWORDDATA 0x11 #define ARGP_SIMPLENAME 0x12 /* name_string | local_term | arg_term */ #define ARGP_NAME_OR_REF 0x13 /* For object_type only */ +#define ARGP_MAX 0x13 /* * Resolved argument types for the AML Interpreter diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c index f1e6dcc7a827..5de3f10cab03 100644 --- a/drivers/acpi/acpica/dsinit.c +++ b/drivers/acpi/acpica/dsinit.c @@ -46,6 +46,7 @@ #include "acdispat.h" #include "acnamesp.h" #include "actables.h" +#include "acinterp.h" #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dsinit") @@ -214,23 +215,17 @@ acpi_ds_initialize_objects(u32 table_index, /* Walk entire namespace from the supplied root */ - status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - /* * We don't use acpi_walk_namespace since we do not want to acquire * the namespace reader lock. */ status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX, - ACPI_NS_WALK_UNLOCK, acpi_ds_init_one_object, - NULL, &info, NULL); + ACPI_NS_WALK_NO_UNLOCK, + acpi_ds_init_one_object, NULL, &info, NULL); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); } - (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); status = acpi_get_table_by_index(table_index, &table); if (ACPI_FAILURE(status)) { diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index 32e9ddc0cf2b..2b3210f42a46 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -99,14 +99,11 @@ acpi_ds_auto_serialize_method(struct acpi_namespace_node *node, "Method auto-serialization parse [%4.4s] %p\n", acpi_ut_get_node_name(node), node)); - acpi_ex_enter_interpreter(); - /* Create/Init a root op for the method parse tree */ op = acpi_ps_alloc_op(AML_METHOD_OP, obj_desc->method.aml_start); if (!op) { - status = AE_NO_MEMORY; - goto unlock; + return_ACPI_STATUS(AE_NO_MEMORY); } acpi_ps_set_name(op, node->name.integer); @@ -118,8 +115,7 @@ acpi_ds_auto_serialize_method(struct acpi_namespace_node *node, acpi_ds_create_walk_state(node->owner_id, NULL, NULL, NULL); if (!walk_state) { acpi_ps_free_op(op); - status = AE_NO_MEMORY; - goto unlock; + return_ACPI_STATUS(AE_NO_MEMORY); } status = acpi_ds_init_aml_walk(walk_state, op, node, @@ -138,8 +134,6 @@ acpi_ds_auto_serialize_method(struct acpi_namespace_node *node, status = acpi_ps_parse_aml(walk_state); acpi_ps_delete_parse_tree(op); -unlock: - acpi_ex_exit_interpreter(); return_ACPI_STATUS(status); } @@ -731,26 +725,6 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, acpi_ds_method_data_delete_all(walk_state); /* - * If method is serialized, release the mutex and restore the - * current sync level for this thread - */ - if (method_desc->method.mutex) { - - /* Acquisition Depth handles recursive calls */ - - method_desc->method.mutex->mutex.acquisition_depth--; - if (!method_desc->method.mutex->mutex.acquisition_depth) { - walk_state->thread->current_sync_level = - method_desc->method.mutex->mutex. - original_sync_level; - - acpi_os_release_mutex(method_desc->method. - mutex->mutex.os_mutex); - method_desc->method.mutex->mutex.thread_id = 0; - } - } - - /* * Delete any namespace objects created anywhere within the * namespace by the execution of this method. Unless: * 1) This method is a module-level executable code method, in which @@ -786,6 +760,26 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, ~ACPI_METHOD_MODIFIED_NAMESPACE; } } + + /* + * If method is serialized, release the mutex and restore the + * current sync level for this thread + */ + if (method_desc->method.mutex) { + + /* Acquisition Depth handles recursive calls */ + + method_desc->method.mutex->mutex.acquisition_depth--; + if (!method_desc->method.mutex->mutex.acquisition_depth) { + walk_state->thread->current_sync_level = + method_desc->method.mutex->mutex. + original_sync_level; + + acpi_os_release_mutex(method_desc->method. + mutex->mutex.os_mutex); + method_desc->method.mutex->mutex.thread_id = 0; + } + } } /* Decrement the thread count on the method */ diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index 4cc9d989a114..77fd7c84ec39 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c @@ -84,7 +84,7 @@ acpi_status acpi_ds_initialize_region(acpi_handle obj_handle) /* Namespace is NOT locked */ - status = acpi_ev_initialize_region(obj_desc, FALSE); + status = acpi_ev_initialize_region(obj_desc); return (status); } diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c index 028b22a3154e..651f35a66cc2 100644 --- a/drivers/acpi/acpica/dswload2.c +++ b/drivers/acpi/acpica/dswload2.c @@ -607,22 +607,9 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) } } - acpi_ex_exit_interpreter(); status = acpi_ev_initialize_region - (acpi_ns_get_attached_object(node), FALSE); - acpi_ex_enter_interpreter(); - - if (ACPI_FAILURE(status)) { - /* - * If AE_NOT_EXIST is returned, it is not fatal - * because many regions get created before a handler - * is installed for said region. - */ - if (AE_NOT_EXIST == status) { - status = AE_OK; - } - } + (acpi_ns_get_attached_object(node)); break; case AML_NAME_OP: diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index 3843f1fc5dbb..a9092251ce80 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c @@ -45,6 +45,7 @@ #include "accommon.h" #include "acevents.h" #include "acnamesp.h" +#include "acinterp.h" #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evrgnini") @@ -478,7 +479,6 @@ acpi_ev_default_region_setup(acpi_handle handle, * FUNCTION: acpi_ev_initialize_region * * PARAMETERS: region_obj - Region we are initializing - * acpi_ns_locked - Is namespace locked? * * RETURN: Status * @@ -496,19 +496,28 @@ acpi_ev_default_region_setup(acpi_handle handle, * MUTEX: Interpreter should be unlocked, because we may run the _REG * method for this region. * + * NOTE: Possible incompliance: + * There is a behavior conflict in automatic _REG execution: + * 1. When the interpreter is evaluating a method, we can only + * automatically run _REG for the following case: + * operation_region (OPR1, 0x80, 0x1000010, 0x4) + * 2. When the interpreter is loading a table, we can also + * automatically run _REG for the following case: + * operation_region (OPR1, 0x80, 0x1000010, 0x4) + * Though this may not be compliant to the de-facto standard, the + * logic is kept in order not to trigger regressions. And keeping + * this logic should be taken care by the caller of this function. + * ******************************************************************************/ -acpi_status -acpi_ev_initialize_region(union acpi_operand_object *region_obj, - u8 acpi_ns_locked) +acpi_status acpi_ev_initialize_region(union acpi_operand_object *region_obj) { union acpi_operand_object *handler_obj; union acpi_operand_object *obj_desc; acpi_adr_space_type space_id; struct acpi_namespace_node *node; - acpi_status status; - ACPI_FUNCTION_TRACE_U32(ev_initialize_region, acpi_ns_locked); + ACPI_FUNCTION_TRACE(ev_initialize_region); if (!region_obj) { return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -579,37 +588,17 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, handler_obj, region_obj, obj_desc)); - status = - acpi_ev_attach_region(handler_obj, - region_obj, - acpi_ns_locked); + (void)acpi_ev_attach_region(handler_obj, + region_obj, FALSE); /* * Tell all users that this region is usable by * running the _REG method */ - if (acpi_ns_locked) { - status = - acpi_ut_release_mutex - (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - } - - status = - acpi_ev_execute_reg_method(region_obj, - ACPI_REG_CONNECT); - - if (acpi_ns_locked) { - status = - acpi_ut_acquire_mutex - (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - } - + acpi_ex_exit_interpreter(); + (void)acpi_ev_execute_reg_method(region_obj, + ACPI_REG_CONNECT); + acpi_ex_enter_interpreter(); return_ACPI_STATUS(AE_OK); } } @@ -619,12 +608,15 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, node = node->parent; } - /* If we get here, there is no handler for this region */ - + /* + * If we get here, there is no handler for this region. This is not + * fatal because many regions get created before a handler is installed + * for said region. + */ ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, "No handler for RegionType %s(%X) (RegionObj %p)\n", acpi_ut_get_region_name(space_id), space_id, region_obj)); - return_ACPI_STATUS(AE_NOT_EXIST); + return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 718428ba0b89..c32c7829878a 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -437,10 +437,9 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, ACPI_INFO(("Dynamic OEM Table Load:")); acpi_ex_exit_interpreter(); - status = - acpi_tb_install_and_load_table(table, ACPI_PTR_TO_PHYSADDR(table), - ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, - TRUE, &table_index); + status = acpi_tb_install_and_load_table(ACPI_PTR_TO_PHYSADDR(table), + ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, + TRUE, &table_index); acpi_ex_enter_interpreter(); if (ACPI_FAILURE(status)) { @@ -500,7 +499,6 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) acpi_status status = AE_OK; union acpi_operand_object *table_desc = ddb_handle; u32 table_index; - struct acpi_table_header *table; ACPI_FUNCTION_TRACE(ex_unload_table); @@ -537,39 +535,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) * strict order requirement against it. */ acpi_ex_exit_interpreter(); - - /* Ensure the table is still loaded */ - - if (!acpi_tb_is_table_loaded(table_index)) { - status = AE_NOT_EXIST; - goto lock_and_exit; - } - - /* Invoke table handler if present */ - - if (acpi_gbl_table_handler) { - status = acpi_get_table_by_index(table_index, &table); - if (ACPI_SUCCESS(status)) { - (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD, - table, - acpi_gbl_table_handler_context); - } - } - - /* Delete the portion of the namespace owned by this table */ - - status = acpi_tb_delete_namespace_by_owner(table_index); - if (ACPI_FAILURE(status)) { - goto lock_and_exit; - } - - (void)acpi_tb_release_owner_id(table_index); - acpi_tb_set_table_loaded_flag(table_index, FALSE); - -lock_and_exit: - - /* Re-acquire the interpreter lock */ - + status = acpi_tb_unload_table(table_index); acpi_ex_enter_interpreter(); /* diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c index 334d3c5ba617..d1f20143bb11 100644 --- a/drivers/acpi/acpica/nsload.c +++ b/drivers/acpi/acpica/nsload.c @@ -137,7 +137,9 @@ unlock: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Begin Table Object Initialization\n")); + acpi_ex_enter_interpreter(); status = acpi_ds_initialize_objects(table_index, node); + acpi_ex_exit_interpreter(); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Completed Table Object Initialization\n")); diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c index f03dd41e86d0..94d5d3339845 100644 --- a/drivers/acpi/acpica/nsnames.c +++ b/drivers/acpi/acpica/nsnames.c @@ -97,6 +97,51 @@ acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node) /******************************************************************************* * + * FUNCTION: acpi_ns_handle_to_name + * + * PARAMETERS: target_handle - Handle of named object whose name is + * to be found + * buffer - Where the name is returned + * + * RETURN: Status, Buffer is filled with name if status is AE_OK + * + * DESCRIPTION: Build and return a full namespace name + * + ******************************************************************************/ + +acpi_status +acpi_ns_handle_to_name(acpi_handle target_handle, struct acpi_buffer *buffer) +{ + acpi_status status; + struct acpi_namespace_node *node; + const char *node_name; + + ACPI_FUNCTION_TRACE_PTR(ns_handle_to_name, target_handle); + + node = acpi_ns_validate_handle(target_handle); + if (!node) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + /* Validate/Allocate/Clear caller buffer */ + + status = acpi_ut_initialize_buffer(buffer, ACPI_PATH_SEGMENT_LENGTH); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Just copy the ACPI name from the Node and zero terminate it */ + + node_name = acpi_ut_get_node_name(node); + ACPI_MOVE_NAME(buffer->pointer, node_name); + ((char *)buffer->pointer)[ACPI_NAME_SIZE] = 0; + + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%4.4s\n", (char *)buffer->pointer)); + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * * FUNCTION: acpi_ns_handle_to_pathname * * PARAMETERS: target_handle - Handle of named object whose name is diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index 76a1bd4bb070..e525cbe7d83b 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c @@ -158,8 +158,6 @@ acpi_status acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer *buffer) { acpi_status status; - struct acpi_namespace_node *node; - const char *node_name; /* Parameter validation */ @@ -172,18 +170,6 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer *buffer) return (status); } - if (name_type == ACPI_FULL_PATHNAME || - name_type == ACPI_FULL_PATHNAME_NO_TRAILING) { - - /* Get the full pathname (From the namespace root) */ - - status = acpi_ns_handle_to_pathname(handle, buffer, - name_type == - ACPI_FULL_PATHNAME ? FALSE : - TRUE); - return (status); - } - /* * Wants the single segment ACPI name. * Validate handle and convert to a namespace Node @@ -193,27 +179,20 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer *buffer) return (status); } - node = acpi_ns_validate_handle(handle); - if (!node) { - status = AE_BAD_PARAMETER; - goto unlock_and_exit; - } - - /* Validate/Allocate/Clear caller buffer */ - - status = acpi_ut_initialize_buffer(buffer, ACPI_PATH_SEGMENT_LENGTH); - if (ACPI_FAILURE(status)) { - goto unlock_and_exit; - } + if (name_type == ACPI_FULL_PATHNAME || + name_type == ACPI_FULL_PATHNAME_NO_TRAILING) { - /* Just copy the ACPI name from the Node and zero terminate it */ + /* Get the full pathname (From the namespace root) */ - node_name = acpi_ut_get_node_name(node); - ACPI_MOVE_NAME(buffer->pointer, node_name); - ((char *)buffer->pointer)[ACPI_NAME_SIZE] = 0; - status = AE_OK; + status = acpi_ns_handle_to_pathname(handle, buffer, + name_type == + ACPI_FULL_PATHNAME ? FALSE : + TRUE); + } else { + /* Get the single name */ -unlock_and_exit: + status = acpi_ns_handle_to_name(handle, buffer); + } (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); return (status); diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c index d9ca8c2aa2d3..82b0b5710979 100644 --- a/drivers/acpi/acpica/tbdata.c +++ b/drivers/acpi/acpica/tbdata.c @@ -832,9 +832,9 @@ acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node) * * FUNCTION: acpi_tb_install_and_load_table * - * PARAMETERS: table - Pointer to the table - * address - Physical address of the table + * PARAMETERS: address - Physical address of the table * flags - Allocation flags of the table + * override - Whether override should be performed * table_index - Where table index is returned * * RETURN: Status @@ -844,15 +844,13 @@ acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node) ******************************************************************************/ acpi_status -acpi_tb_install_and_load_table(struct acpi_table_header *table, - acpi_physical_address address, +acpi_tb_install_and_load_table(acpi_physical_address address, u8 flags, u8 override, u32 *table_index) { acpi_status status; u32 i; - acpi_owner_id owner_id; - ACPI_FUNCTION_TRACE(acpi_load_table); + ACPI_FUNCTION_TRACE(tb_install_and_load_table); (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); @@ -864,45 +862,60 @@ acpi_tb_install_and_load_table(struct acpi_table_header *table, goto unlock_and_exit; } - /* - * Note: Now table is "INSTALLED", it must be validated before - * using. - */ - status = acpi_tb_validate_table(&acpi_gbl_root_table_list.tables[i]); - if (ACPI_FAILURE(status)) { - goto unlock_and_exit; - } + (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); + status = acpi_tb_load_table(i, acpi_gbl_root_node); + (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); +unlock_and_exit: + *table_index = i; (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - status = acpi_ns_load_table(i, acpi_gbl_root_node); + return_ACPI_STATUS(status); +} - /* Execute any module-level code that was found in the table */ +/******************************************************************************* + * + * FUNCTION: acpi_tb_unload_table + * + * PARAMETERS: table_index - Table index + * + * RETURN: Status + * + * DESCRIPTION: Unload an ACPI table + * + ******************************************************************************/ - if (!acpi_gbl_parse_table_as_term_list - && acpi_gbl_group_module_level_code) { - acpi_ns_exec_module_code_list(); - } +acpi_status acpi_tb_unload_table(u32 table_index) +{ + acpi_status status = AE_OK; + struct acpi_table_header *table; - /* - * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is - * responsible for discovering any new wake GPEs by running _PRW methods - * that may have been loaded by this table. - */ - status = acpi_tb_get_owner_id(i, &owner_id); - if (ACPI_SUCCESS(status)) { - acpi_ev_update_gpes(owner_id); + ACPI_FUNCTION_TRACE(tb_unload_table); + + /* 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) { - (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, - acpi_gbl_table_handler_context); + status = acpi_get_table_by_index(table_index, &table); + if (ACPI_SUCCESS(status)) { + (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD, + table, + acpi_gbl_table_handler_context); + } } - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); -unlock_and_exit: - *table_index = i; - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); + /* Delete the portion of the namespace owned by this table */ + + status = acpi_tb_delete_namespace_by_owner(table_index); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + (void)acpi_tb_release_owner_id(table_index); + acpi_tb_set_table_loaded_flag(table_index, FALSE); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 046c4d0394ee..5fb838e592dc 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -480,19 +480,17 @@ static void acpi_tb_convert_fadt(void) u32 i; /* - * For ACPI 1.0 FADTs (revision 1), ensure that reserved fields which + * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which * should be zero are indeed zero. This will workaround BIOSs that * inadvertently place values in these fields. * * The ACPI 1.0 reserved fields that will be zeroed are the bytes located * at offset 45, 55, 95, and the word located at offset 109, 110. * - * Note: The FADT revision value is unreliable because of BIOS errors. - * The table length is instead used as the final word on the version. - * - * Note: FADT revision 3 is the ACPI 2.0 version of the FADT. + * Note: The FADT revision value is unreliable. Only the length can be + * trusted. */ - if (acpi_gbl_FADT.header.length <= ACPI_FADT_V3_SIZE) { + if (acpi_gbl_FADT.header.length <= ACPI_FADT_V2_SIZE) { acpi_gbl_FADT.preferred_profile = 0; acpi_gbl_FADT.pstate_control = 0; acpi_gbl_FADT.cst_control = 0; diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index 4ab6b9cd0aec..d5adb7ac4684 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c @@ -167,6 +167,7 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_initialize_tables) acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void) { acpi_status status; + u32 i; ACPI_FUNCTION_TRACE(acpi_reallocate_root_table); @@ -178,6 +179,21 @@ acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void) return_ACPI_STATUS(AE_SUPPORT); } + /* + * Ensure OS early boot logic, which is required by some hosts. If the + * table state is reported to be wrong, developers should fix the + * issue by invoking acpi_put_table() for the reported table during the + * early stage. + */ + for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { + if (acpi_gbl_root_table_list.tables[i].pointer) { + ACPI_ERROR((AE_INFO, + "Table [%4.4s] is not invalidated during early boot stage", + acpi_gbl_root_table_list.tables[i]. + signature.ascii)); + } + } + acpi_gbl_root_table_list.flags |= ACPI_ROOT_ALLOW_RESIZE; status = acpi_tb_resize_root_table_list(); diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c index 5569f637f669..82019c01a0e5 100644 --- a/drivers/acpi/acpica/tbxfload.c +++ b/drivers/acpi/acpica/tbxfload.c @@ -239,7 +239,7 @@ acpi_status acpi_tb_load_namespace(void) } if (!tables_failed) { - ACPI_INFO(("%u ACPI AML tables successfully acquired and loaded\n", tables_loaded)); + ACPI_INFO(("%u ACPI AML tables successfully acquired and loaded", tables_loaded)); } else { ACPI_ERROR((AE_INFO, "%u table load failures, %u successful", @@ -250,6 +250,10 @@ acpi_status acpi_tb_load_namespace(void) status = AE_CTRL_TERMINATE; } +#ifdef ACPI_APPLICATION + ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "\n")); +#endif + unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); return_ACPI_STATUS(status); @@ -326,10 +330,9 @@ acpi_status acpi_load_table(struct acpi_table_header *table) /* Install the table and load it into the namespace */ ACPI_INFO(("Host-directed Dynamic ACPI Table Load:")); - status = - acpi_tb_install_and_load_table(table, ACPI_PTR_TO_PHYSADDR(table), - ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, - FALSE, &table_index); + status = acpi_tb_install_and_load_table(ACPI_PTR_TO_PHYSADDR(table), + ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, + FALSE, &table_index); return_ACPI_STATUS(status); } @@ -405,37 +408,8 @@ acpi_status acpi_unload_parent_table(acpi_handle object) break; } - /* Ensure the table is actually loaded */ - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - if (!acpi_tb_is_table_loaded(i)) { - status = AE_NOT_EXIST; - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); - break; - } - - /* Invoke table handler if present */ - - if (acpi_gbl_table_handler) { - (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD, - acpi_gbl_root_table_list. - tables[i].pointer, - acpi_gbl_table_handler_context); - } - - /* - * Delete all namespace objects owned by this table. Note that - * these objects can appear anywhere in the namespace by virtue - * of the AML "Scope" operator. Thus, we need to track ownership - * by an ID, not simply a position within the hierarchy. - */ - status = acpi_tb_delete_namespace_by_owner(i); - if (ACPI_FAILURE(status)) { - break; - } - - status = acpi_tb_release_owner_id(i); - acpi_tb_set_table_loaded_flag(i, FALSE); + status = acpi_tb_unload_table(i); (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); break; } diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c index 15728ad8356b..b3d8421cfb80 100644 --- a/drivers/acpi/acpica/utdecode.c +++ b/drivers/acpi/acpica/utdecode.c @@ -44,6 +44,7 @@ #include <acpi/acpi.h> #include "accommon.h" #include "acnamesp.h" +#include "amlcode.h" #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utdecode") @@ -532,6 +533,54 @@ const char *acpi_ut_get_notify_name(u32 notify_value, acpi_object_type type) return ("Hardware-Specific"); } + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_argument_type_name + * + * PARAMETERS: arg_type - an ARGP_* parser argument type + * + * RETURN: Decoded ARGP_* type + * + * DESCRIPTION: Decode an ARGP_* parser type, as defined in the amlcode.h file, + * and used in the acopcode.h file. For example, ARGP_TERMARG. + * Used for debug only. + * + ******************************************************************************/ + +static const char *acpi_gbl_argument_type[20] = { + /* 00 */ "Unknown ARGP", + /* 01 */ "ByteData", + /* 02 */ "ByteList", + /* 03 */ "CharList", + /* 04 */ "DataObject", + /* 05 */ "DataObjectList", + /* 06 */ "DWordData", + /* 07 */ "FieldList", + /* 08 */ "Name", + /* 09 */ "NameString", + /* 0A */ "ObjectList", + /* 0B */ "PackageLength", + /* 0C */ "SuperName", + /* 0D */ "Target", + /* 0E */ "TermArg", + /* 0F */ "TermList", + /* 10 */ "WordData", + /* 11 */ "QWordData", + /* 12 */ "SimpleName", + /* 13 */ "NameOrRef" +}; + +const char *acpi_ut_get_argument_type_name(u32 arg_type) +{ + + if (arg_type > ARGP_MAX) { + return ("Unknown ARGP"); + } + + return (acpi_gbl_argument_type[arg_type]); +} + #endif /******************************************************************************* |