X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Facpi%2Fparser%2Fpsxface.c;h=2dd48cbb7c0299c66e0606d8a8da9687eb35aa5c;hb=d8b3d7077d08311552643a220f21ce0d30130f59;hp=b318ad24726dc6c36db7af01722c2de6dde29372;hpb=207e0a826fdee4bfe853681aef2175a739c11286;p=linux-2.6.git diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c index b318ad247..2dd48cbb7 100644 --- a/drivers/acpi/parser/psxface.c +++ b/drivers/acpi/parser/psxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -41,188 +41,244 @@ * POSSIBILITY OF SUCH DAMAGES. */ - #include #include #include #include -#include - #define _COMPONENT ACPI_PARSER - ACPI_MODULE_NAME ("psxface") +ACPI_MODULE_NAME("psxface") + +/* Local Prototypes */ +static void acpi_ps_start_trace(struct acpi_parameter_info *info); + +static void acpi_ps_stop_trace(struct acpi_parameter_info *info); + +static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info); +static void +acpi_ps_update_parameter_list(struct acpi_parameter_info *info, u16 action); /******************************************************************************* * - * FUNCTION: acpi_psx_execute + * FUNCTION: acpi_debug_trace * - * PARAMETERS: Info->Node - A method object containing both the AML - * address and length. - * **Params - List of parameters to pass to method, - * terminated by NULL. Params itself may be - * NULL if no parameters are being passed. - * **return_obj_desc - Return object from execution of the - * method. + * PARAMETERS: method_name - Valid ACPI name string + * debug_level - Optional level mask. 0 to use default + * debug_layer - Optional layer mask. 0 to use default + * Flags - bit 1: one shot(1) or persistent(0) * * RETURN: Status * - * DESCRIPTION: Execute a control method + * DESCRIPTION: External interface to enable debug tracing during control + * method execution * ******************************************************************************/ acpi_status -acpi_psx_execute ( - struct acpi_parameter_info *info) +acpi_debug_trace(char *name, u32 debug_level, u32 debug_layer, u32 flags) { - acpi_status status; - union acpi_operand_object *obj_desc; - u32 i; - union acpi_parse_object *op; - struct acpi_walk_state *walk_state; - + acpi_status status; - ACPI_FUNCTION_TRACE ("psx_execute"); + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return (status); + } + /* TBDs: Validate name, allow full path or just nameseg */ - /* Validate the Node and get the attached object */ + acpi_gbl_trace_method_name = *ACPI_CAST_PTR(u32, name); + acpi_gbl_trace_flags = flags; - if (!info || !info->node) { - return_ACPI_STATUS (AE_NULL_ENTRY); + if (debug_level) { + acpi_gbl_trace_dbg_level = debug_level; } - - obj_desc = acpi_ns_get_attached_object (info->node); - if (!obj_desc) { - return_ACPI_STATUS (AE_NULL_OBJECT); + if (debug_layer) { + acpi_gbl_trace_dbg_layer = debug_layer; } - /* Init for new method, wait on concurrency semaphore */ + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + return (AE_OK); +} - status = acpi_ds_begin_method_execution (info->node, obj_desc, NULL); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); +/******************************************************************************* + * + * FUNCTION: acpi_ps_start_trace + * + * PARAMETERS: Info - Method info struct + * + * RETURN: None + * + * DESCRIPTION: Start control method execution trace + * + ******************************************************************************/ + +static void acpi_ps_start_trace(struct acpi_parameter_info *info) +{ + acpi_status status; + + ACPI_FUNCTION_ENTRY(); + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return; } - if ((info->parameter_type == ACPI_PARAM_ARGS) && - (info->parameters)) { - /* - * The caller "owns" the parameters, so give each one an extra - * reference - */ - for (i = 0; info->parameters[i]; i++) { - acpi_ut_add_reference (info->parameters[i]); - } + if ((!acpi_gbl_trace_method_name) || + (acpi_gbl_trace_method_name != info->node->name.integer)) { + goto exit; } - /* - * 1) Perform the first pass parse of the method to enter any - * named objects that it creates into the namespace - */ - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, - "**** Begin Method Parse **** Entry=%p obj=%p\n", - info->node, obj_desc)); + acpi_gbl_original_dbg_level = acpi_dbg_level; + acpi_gbl_original_dbg_layer = acpi_dbg_layer; - /* Create and init a Root Node */ + acpi_dbg_level = 0x00FFFFFF; + acpi_dbg_layer = ACPI_UINT32_MAX; - op = acpi_ps_create_scope_op (); - if (!op) { - status = AE_NO_MEMORY; - goto cleanup1; + if (acpi_gbl_trace_dbg_level) { + acpi_dbg_level = acpi_gbl_trace_dbg_level; + } + if (acpi_gbl_trace_dbg_layer) { + acpi_dbg_layer = acpi_gbl_trace_dbg_layer; } - /* - * Get a new owner_id for objects created by this method. Namespace - * objects (such as Operation Regions) can be created during the - * first pass parse. - */ - obj_desc->method.owning_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD); + exit: + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); +} - /* Create and initialize a new walk state */ +/******************************************************************************* + * + * FUNCTION: acpi_ps_stop_trace + * + * PARAMETERS: Info - Method info struct + * + * RETURN: None + * + * DESCRIPTION: Stop control method execution trace + * + ******************************************************************************/ - walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id, - NULL, NULL, NULL); - if (!walk_state) { - status = AE_NO_MEMORY; - goto cleanup2; +static void acpi_ps_stop_trace(struct acpi_parameter_info *info) +{ + acpi_status status; + + ACPI_FUNCTION_ENTRY(); + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return; } - status = acpi_ds_init_aml_walk (walk_state, op, info->node, - obj_desc->method.aml_start, - obj_desc->method.aml_length, NULL, 1); - if (ACPI_FAILURE (status)) { - goto cleanup3; + if ((!acpi_gbl_trace_method_name) || + (acpi_gbl_trace_method_name != info->node->name.integer)) { + goto exit; } - /* Parse the AML */ + /* Disable further tracing if type is one-shot */ - status = acpi_ps_parse_aml (walk_state); - acpi_ps_delete_parse_tree (op); - if (ACPI_FAILURE (status)) { - goto cleanup1; /* Walk state is already deleted */ + if (acpi_gbl_trace_flags & 1) { + acpi_gbl_trace_method_name = 0; + acpi_gbl_trace_dbg_level = 0; + acpi_gbl_trace_dbg_layer = 0; } - /* - * 2) Execute the method. Performs second pass parse simultaneously - */ - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, - "**** Begin Method Execution **** Entry=%p obj=%p\n", - info->node, obj_desc)); + acpi_dbg_level = acpi_gbl_original_dbg_level; + acpi_dbg_layer = acpi_gbl_original_dbg_layer; - /* Create and init a Root Node */ + exit: + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); +} - op = acpi_ps_create_scope_op (); - if (!op) { - status = AE_NO_MEMORY; - goto cleanup1; - } +/******************************************************************************* + * + * FUNCTION: acpi_ps_execute_method + * + * PARAMETERS: Info - Method info block, contains: + * Node - Method Node to execute + * obj_desc - Method object + * Parameters - List of parameters to pass to the method, + * terminated by NULL. Params itself may be + * NULL if no parameters are being passed. + * return_object - Where to put method's return value (if + * any). If NULL, no value is returned. + * parameter_type - Type of Parameter list + * return_object - Where to put method's return value (if + * any). If NULL, no value is returned. + * pass_number - Parse or execute pass + * + * RETURN: Status + * + * DESCRIPTION: Execute a control method + * + ******************************************************************************/ - /* Init new op with the method name and pointer back to the NS node */ +acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info) +{ + acpi_status status; - acpi_ps_set_name (op, info->node->name.integer); - op->common.node = info->node; + ACPI_FUNCTION_TRACE("ps_execute_method"); - /* Create and initialize a new walk state */ + /* Validate the Info and method Node */ - walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); - if (!walk_state) { - status = AE_NO_MEMORY; - goto cleanup2; + if (!info || !info->node) { + return_ACPI_STATUS(AE_NULL_ENTRY); } - status = acpi_ds_init_aml_walk (walk_state, op, info->node, - obj_desc->method.aml_start, - obj_desc->method.aml_length, info, 3); - if (ACPI_FAILURE (status)) { - goto cleanup3; + /* Init for new method, wait on concurrency semaphore */ + + status = + acpi_ds_begin_method_execution(info->node, info->obj_desc, NULL); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); } /* - * The walk of the parse tree is where we actually execute the method + * The caller "owns" the parameters, so give each one an extra + * reference */ - status = acpi_ps_parse_aml (walk_state); - goto cleanup2; /* Walk state already deleted */ + acpi_ps_update_parameter_list(info, REF_INCREMENT); + /* Begin tracing if requested */ -cleanup3: - acpi_ds_delete_walk_state (walk_state); + acpi_ps_start_trace(info); + + /* + * 1) Perform the first pass parse of the method to enter any + * named objects that it creates into the namespace + */ + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, + "**** Begin Method Parse **** Entry=%p obj=%p\n", + info->node, info->obj_desc)); + + info->pass_number = 1; + status = acpi_ps_execute_pass(info); + if (ACPI_FAILURE(status)) { + goto cleanup; + } -cleanup2: - acpi_ps_delete_parse_tree (op); + /* + * 2) Execute the method. Performs second pass parse simultaneously + */ + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, + "**** Begin Method Execution **** Entry=%p obj=%p\n", + info->node, info->obj_desc)); -cleanup1: - if ((info->parameter_type == ACPI_PARAM_ARGS) && - (info->parameters)) { - /* Take away the extra reference that we gave the parameters above */ + info->pass_number = 3; + status = acpi_ps_execute_pass(info); - for (i = 0; info->parameters[i]; i++) { - /* Ignore errors, just do them all */ + cleanup: + /* End optional tracing */ - (void) acpi_ut_update_object_reference (info->parameters[i], REF_DECREMENT); - } - } + acpi_ps_stop_trace(info); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + /* Take away the extra reference that we gave the parameters above */ + + acpi_ps_update_parameter_list(info, REF_DECREMENT); + + /* Exit now if error above */ + + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); } /* @@ -230,14 +286,104 @@ cleanup1: * a control exception code */ if (info->return_object) { - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned obj_desc=%p\n", - info->return_object)); - ACPI_DUMP_STACK_ENTRY (info->return_object); + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, + "Method returned obj_desc=%p\n", + info->return_object)); + ACPI_DUMP_STACK_ENTRY(info->return_object); status = AE_CTRL_RETURN_VALUE; } - return_ACPI_STATUS (status); + return_ACPI_STATUS(status); } +/******************************************************************************* + * + * FUNCTION: acpi_ps_update_parameter_list + * + * PARAMETERS: Info - See struct acpi_parameter_info + * (Used: parameter_type and Parameters) + * Action - Add or Remove reference + * + * RETURN: Status + * + * DESCRIPTION: Update reference count on all method parameter objects + * + ******************************************************************************/ + +static void +acpi_ps_update_parameter_list(struct acpi_parameter_info *info, u16 action) +{ + acpi_native_uint i; + + if ((info->parameter_type == ACPI_PARAM_ARGS) && (info->parameters)) { + /* Update reference count for each parameter */ + + for (i = 0; info->parameters[i]; i++) { + /* Ignore errors, just do them all */ + (void)acpi_ut_update_object_reference(info-> + parameters[i], + action); + } + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_ps_execute_pass + * + * PARAMETERS: Info - See struct acpi_parameter_info + * (Used: pass_number, Node, and obj_desc) + * + * RETURN: Status + * + * DESCRIPTION: Single AML pass: Parse or Execute a control method + * + ******************************************************************************/ + +static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info) +{ + acpi_status status; + union acpi_parse_object *op; + struct acpi_walk_state *walk_state; + + ACPI_FUNCTION_TRACE("ps_execute_pass"); + + /* Create and init a Root Node */ + + op = acpi_ps_create_scope_op(); + if (!op) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + /* Create and initialize a new walk state */ + + walk_state = + acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL, + NULL, NULL); + if (!walk_state) { + status = AE_NO_MEMORY; + goto cleanup; + } + + status = acpi_ds_init_aml_walk(walk_state, op, info->node, + info->obj_desc->method.aml_start, + info->obj_desc->method.aml_length, + info->pass_number == 1 ? NULL : info, + info->pass_number); + if (ACPI_FAILURE(status)) { + acpi_ds_delete_walk_state(walk_state); + goto cleanup; + } + + /* Parse the AML */ + + status = acpi_ps_parse_aml(walk_state); + + /* Walk state was deleted by parse_aml */ + + cleanup: + acpi_ps_delete_parse_tree(op); + return_ACPI_STATUS(status); +}