Skip to content

Commit

Permalink
ACPI: ACPICA 20060512
Browse files Browse the repository at this point in the history
Replaced the acpi_os_queue_for_execution() with a new
interface named acpi_os_execute(). The major difference is
that the new interface does not have a Priority parameter,
this appeared to be useless and has been replaced by
a Type parameter. The Type tells the OS what type of
execution is being requested, such as global lock handler,
notify handler, GPE handler, etc. This allows the host
to queue and execute the request as appropriate for the
request type, possibly using different work queues and
different priorities for the various request types. This
enables fixes for multithreading deadlock problems such as
http://bugzilla.kernel.org/show_bug.cgi?id=5534
(Alexey Starikovskiy and Bob Moore)

Fixed a possible memory leak associated with the
support for the so-called "implicit return" ACPI
extension. Reported by FreeBSD  (Fiodor Suietov)
http://bugzilla.kernel.org/show_bug.cgi?id=6514

Fixed a problem with the Load() operator where a table
load from an operation region could overwrite an internal
table buffer by up to 7 bytes and cause alignment faults
on IPF systems. (With assistance from Luming Yu)

Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
  • Loading branch information
Bob Moore authored and Len Brown committed Jun 14, 2006
1 parent b229cf9 commit 958dd24
Show file tree
Hide file tree
Showing 28 changed files with 161 additions and 110 deletions.
23 changes: 17 additions & 6 deletions drivers/acpi/dispatcher/dsmethod.c
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ acpi_ds_restart_control_method(struct acpi_walk_state *walk_state,
union acpi_operand_object *return_desc)
{
acpi_status status;
int same_as_implicit_return;

ACPI_FUNCTION_TRACE_PTR(ds_restart_control_method, walk_state);

Expand All @@ -402,6 +403,11 @@ acpi_ds_restart_control_method(struct acpi_walk_state *walk_state,

if (return_desc) {

/* Is the implicit return object the same as the return desc? */

same_as_implicit_return =
(walk_state->implicit_return_obj == return_desc);

/* Are we actually going to use the return value? */

if (walk_state->return_used) {
Expand All @@ -422,18 +428,23 @@ acpi_ds_restart_control_method(struct acpi_walk_state *walk_state,
}

/*
* The following code is the
* optional support for a so-called "implicit return". Some AML code
* assumes that the last value of the method is "implicitly" returned
* to the caller. Just save the last result as the return value.
* The following code is the optional support for the so-called
* "implicit return". Some AML code assumes that the last value of the
* method is "implicitly" returned to the caller, in the absence of an
* explicit return value.
*
* Just save the last result of the method as the return value.
*
* NOTE: this is optional because the ASL language does not actually
* support this behavior.
*/
else if (!acpi_ds_do_implicit_return
(return_desc, walk_state, FALSE)) {
(return_desc, walk_state, FALSE)
|| same_as_implicit_return) {
/*
* Delete the return value if it will not be used by the
* calling method
* calling method or remove one reference if the explicit return
* is the same as the implicit return value.
*/
acpi_ut_remove_reference(return_desc);
}
Expand Down
6 changes: 3 additions & 3 deletions drivers/acpi/dispatcher/dsmthdat.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ acpi_ds_method_data_set_value(u16 opcode,
* Increment ref count so object can't be deleted while installed.
* NOTE: We do not copy the object in order to preserve the call by
* reference semantics of ACPI Control Method invocation.
* (See ACPI specification 2.0_c)
* (See ACPI Specification 2.0_c)
*/
acpi_ut_add_reference(object);

Expand All @@ -351,7 +351,7 @@ acpi_ds_method_data_set_value(u16 opcode,
* FUNCTION: acpi_ds_method_data_get_value
*
* PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP
* Index - which local_var or argument to get
* Index - Which local_var or argument to get
* walk_state - Current walk state object
* dest_desc - Where Arg or Local value is returned
*
Expand Down Expand Up @@ -459,7 +459,7 @@ acpi_ds_method_data_get_value(u16 opcode,
* FUNCTION: acpi_ds_method_data_delete_value
*
* PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP
* Index - which local_var or argument to delete
* Index - Which local_var or argument to delete
* walk_state - Current walk state object
*
* RETURN: None
Expand Down
41 changes: 36 additions & 5 deletions drivers/acpi/dispatcher/dswload.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,12 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
* Target of Scope() not found. Generate an External for it, and
* insert the name into the namespace.
*/
acpi_dm_add_to_external_list(path);
acpi_dm_add_to_external_list(path, ACPI_TYPE_DEVICE, 0);
status =
acpi_ns_lookup(walk_state->scope_info, path,
object_type, ACPI_IMODE_LOAD_PASS1,
ACPI_NS_SEARCH_PARENT, walk_state,
&(node));
&node);
}
#endif
if (ACPI_FAILURE(status)) {
Expand Down Expand Up @@ -301,10 +301,41 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
status =
acpi_ns_lookup(walk_state->scope_info, path, object_type,
ACPI_IMODE_LOAD_PASS1, flags, walk_state,
&(node));
&node);
if (ACPI_FAILURE(status)) {
ACPI_ERROR_NAMESPACE(path, status);
return_ACPI_STATUS(status);
if (status == AE_ALREADY_EXISTS) {

/* The name already exists in this scope */

if (node->flags & ANOBJ_IS_EXTERNAL) {
/*
* Allow one create on an object or segment that was
* previously declared External
*/
node->flags &= ~ANOBJ_IS_EXTERNAL;
node->type = (u8) object_type;

/* Just retyped a node, probably will need to open a scope */

if (acpi_ns_opens_scope(object_type)) {
status =
acpi_ds_scope_stack_push
(node, object_type,
walk_state);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS
(status);
}
}
status = AE_OK;
}
}

if (ACPI_FAILURE(status)) {

ACPI_ERROR_NAMESPACE(path, status);
return_ACPI_STATUS(status);
}
}
break;
}
Expand Down
8 changes: 4 additions & 4 deletions drivers/acpi/events/evgpe.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
* RETURN: None
*
* DESCRIPTION: Perform the actual execution of a GPE control method. This
* function is called from an invocation of acpi_os_queue_for_execution
* function is called from an invocation of acpi_os_exece
* (and therefore does NOT execute at interrupt level) so that
* the control method itself is not executed in the context of
* an interrupt handler.
Expand Down Expand Up @@ -674,9 +674,9 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
* Execute the method associated with the GPE
* NOTE: Level-triggered GPEs are cleared after the method completes.
*/
status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
acpi_ev_asynch_execute_gpe_method,
gpe_event_info);
status = acpi_os_execute(OSL_GPE_HANDLER,
acpi_ev_asynch_execute_gpe_method,
gpe_event_info);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"Unable to queue handler for GPE[%2X] - event disabled",
Expand Down
10 changes: 4 additions & 6 deletions drivers/acpi/events/evmisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,8 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
notify_info->notify.value = (u16) notify_value;
notify_info->notify.handler_obj = handler_obj;

status = acpi_os_queue_for_execution(OSD_PRIORITY_HIGH,
acpi_ev_notify_dispatch,
notify_info);
status = acpi_os_execute(OSL_NOTIFY_HANDLER,
acpi_ev_notify_dispatch, notify_info);
if (ACPI_FAILURE(status)) {
acpi_ut_delete_generic_state(notify_info);
}
Expand Down Expand Up @@ -346,9 +345,8 @@ static u32 acpi_ev_global_lock_handler(void *context)

/* Run the Global Lock thread which will signal all waiting threads */

status = acpi_os_queue_for_execution(OSD_PRIORITY_HIGH,
acpi_ev_global_lock_thread,
context);
status = acpi_os_execute(OSL_GLOBAL_LOCK_HANDLER,
acpi_ev_global_lock_thread, context);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"Could not queue Global Lock thread"));
Expand Down
7 changes: 4 additions & 3 deletions drivers/acpi/events/evregion.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,8 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
* Function - Read or Write operation
* Address - Where in the space to read or write
* bit_width - Field width in bits (8, 16, 32, or 64)
* Value - Pointer to in or out value
* Value - Pointer to in or out value, must be
* full 64-bit acpi_integer
*
* RETURN: Status
*
Expand All @@ -274,7 +275,7 @@ acpi_status
acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
u32 function,
acpi_physical_address address,
u32 bit_width, void *value)
u32 bit_width, acpi_integer * value)
{
acpi_status status;
acpi_status status2;
Expand Down Expand Up @@ -1007,7 +1008,7 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
*
* PARAMETERS: walk_namespace callback
*
* DESCRIPTION: Run _REg method for region objects of the requested space_iD
* DESCRIPTION: Run _REG method for region objects of the requested space_iD
*
******************************************************************************/

Expand Down
17 changes: 12 additions & 5 deletions drivers/acpi/executer/exconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
struct acpi_table_header *table_ptr = NULL;
acpi_physical_address address;
struct acpi_table_header table_header;
acpi_integer temp;
u32 i;

ACPI_FUNCTION_TRACE(ex_load_op);
Expand Down Expand Up @@ -326,19 +327,22 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,

address = obj_desc->region.address;

/* Get the table length from the table header */
/* Get part of the table header to get the table length */

table_header.length = 0;
for (i = 0; i < 8; i++) {
status =
acpi_ev_address_space_dispatch(obj_desc, ACPI_READ,
(acpi_physical_address)
(i + address), 8,
((u8 *) &
table_header) + i);
&temp);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}

/* Get the one valid byte of the returned 64-bit value */

ACPI_CAST_PTR(u8, &table_header)[i] = (u8) temp;
}

/* Sanity check the table length */
Expand All @@ -361,11 +365,14 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
acpi_ev_address_space_dispatch(obj_desc, ACPI_READ,
(acpi_physical_address)
(i + address), 8,
((u8 *) table_ptr +
i));
&temp);
if (ACPI_FAILURE(status)) {
goto cleanup;
}

/* Get the one valid byte of the returned 64-bit value */

ACPI_CAST_PTR(u8, table_ptr)[i] = (u8) temp;
}
break;

Expand Down
2 changes: 1 addition & 1 deletion drivers/acpi/executer/exstorob.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc,
* NOTE: ACPI versions up to 3.0 specified that the buffer must be
* truncated if the string is smaller than the buffer. However, "other"
* implementations of ACPI never did this and thus became the defacto
* standard. ACPi 3.0_a changes this behavior such that the buffer
* standard. ACPI 3.0_a changes this behavior such that the buffer
* is no longer truncated.
*/

Expand Down
8 changes: 4 additions & 4 deletions drivers/acpi/namespace/nsaccess.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ acpi_status acpi_ns_root_initialize(void)

#if defined (ACPI_ASL_COMPILER)

/* save the parameter count for the i_aSL compiler */
/* Save the parameter count for the i_aSL compiler */

new_node->value = obj_desc->method.param_count;
#else
Expand Down Expand Up @@ -311,17 +311,17 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
acpi_object_type type_to_check_for;
acpi_object_type this_search_type;
u32 search_parent_flag = ACPI_NS_SEARCH_PARENT;
u32 local_flags = flags & ~(ACPI_NS_ERROR_IF_FOUND |
ACPI_NS_SEARCH_PARENT);
u32 local_flags;

ACPI_FUNCTION_TRACE(ns_lookup);

if (!return_node) {
return_ACPI_STATUS(AE_BAD_PARAMETER);
}

acpi_gbl_ns_lookup_count++;
local_flags = flags & ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_SEARCH_PARENT);
*return_node = ACPI_ENTRY_NOT_FOUND;
acpi_gbl_ns_lookup_count++;

if (!acpi_gbl_root_node) {
return_ACPI_STATUS(AE_NO_NAMESPACE);
Expand Down
7 changes: 6 additions & 1 deletion drivers/acpi/namespace/nssearch.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ acpi_ns_search_and_enter(u32 target_name,

if (!node || !target_name || !return_node) {
ACPI_ERROR((AE_INFO,
"Null param: Node %p Name %X ReturnNode %p",
"Null parameter: Node %p Name %X ReturnNode %p",
node, target_name, return_node));
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
Expand Down Expand Up @@ -385,6 +385,11 @@ acpi_ns_search_and_enter(u32 target_name,
if (!new_node) {
return_ACPI_STATUS(AE_NO_MEMORY);
}
#ifdef ACPI_ASL_COMPILER
if (flags & ACPI_NS_EXTERNAL) {
new_node->flags |= ANOBJ_IS_EXTERNAL;
}
#endif

/* Install the new object into the parent's list of children */

Expand Down
4 changes: 2 additions & 2 deletions drivers/acpi/resources/rscalc.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ acpi_rs_get_list_length(u8 * aml_buffer,
*/
buffer_size = acpi_gbl_resource_struct_sizes[resource_index] +
extra_struct_bytes;
buffer_size = ACPI_ROUND_UP_TO_NATIVE_WORD(buffer_size);
buffer_size = (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(buffer_size);

*size_needed += buffer_size;

Expand Down Expand Up @@ -579,7 +579,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,

/* Round up the size since each element must be aligned */

temp_size_needed = ACPI_ROUND_UP_to_64_bIT(temp_size_needed);
temp_size_needed = ACPI_ROUND_UP_TO_64BIT(temp_size_needed);

/* Point to the next union acpi_operand_object */

Expand Down
2 changes: 1 addition & 1 deletion drivers/acpi/resources/rscreate.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* Now align the current length */

user_prt->length =
(u32) ACPI_ROUND_UP_to_64_bIT(user_prt->length);
(u32) ACPI_ROUND_UP_TO_64BIT(user_prt->length);

/* 4) Fourth subobject: Dereference the PRT.source_index */

Expand Down
5 changes: 3 additions & 2 deletions drivers/acpi/resources/rsutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ acpi_rs_get_resource_source(acpi_rs_length resource_length,
* Zero the entire area of the buffer.
*/
total_length =
(u32)
ACPI_STRLEN(ACPI_CAST_PTR(char, &aml_resource_source[1])) +
1;
total_length = (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(total_length);
Expand Down Expand Up @@ -528,7 +529,7 @@ acpi_rs_get_crs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer)
*/
status = acpi_rs_create_resource_list(obj_desc, ret_buffer);

/* on exit, we must delete the object returned by evaluate_object */
/* On exit, we must delete the object returned by evaluate_object */

acpi_ut_remove_reference(obj_desc);
return_ACPI_STATUS(status);
Expand Down Expand Up @@ -578,7 +579,7 @@ acpi_rs_get_prs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer)
*/
status = acpi_rs_create_resource_list(obj_desc, ret_buffer);

/* on exit, we must delete the object returned by evaluate_object */
/* On exit, we must delete the object returned by evaluate_object */

acpi_ut_remove_reference(obj_desc);
return_ACPI_STATUS(status);
Expand Down
6 changes: 2 additions & 4 deletions drivers/acpi/tables/tbrsdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,8 @@ acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr)
ACPI_DUMP_BUFFER(acpi_gbl_RSDP, 20);

ACPI_ERROR((AE_INFO,
"RSDT/XSDT signature at %X (%p) is invalid",
acpi_gbl_RSDP->rsdt_physical_address,
(void *)(acpi_native_uint) acpi_gbl_RSDP->
rsdt_physical_address));
"RSDT/XSDT signature at %X is invalid",
acpi_gbl_RSDP->rsdt_physical_address));

if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
ACPI_ERROR((AE_INFO, "Looking for RSDT"));
Expand Down
Loading

0 comments on commit 958dd24

Please sign in to comment.