X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Facpi%2Fparser%2Fpsxface.c;h=5d996c1140af39ac64b1e30d2a8ba711a7a34f23;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=b7917cfdcf8fdd1b84e502fcb188df616da653ac;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c index b7917cfdc..5d996c114 100644 --- a/drivers/acpi/parser/psxface.c +++ b/drivers/acpi/parser/psxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2004, 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,202 +41,351 @@ * 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_evaluate_info *info); + +static void acpi_ps_stop_trace(struct acpi_evaluate_info *info); + +static acpi_status acpi_ps_execute_pass(struct acpi_evaluate_info *info); +static void +acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action); /******************************************************************************* * - * FUNCTION: acpi_psx_execute + * FUNCTION: acpi_debug_trace * - * PARAMETERS: method_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_namespace_node *method_node, - union acpi_operand_object **params, - union acpi_operand_object **return_obj_desc) +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; + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return (status); + } - ACPI_FUNCTION_TRACE ("psx_execute"); + /* TBDs: Validate name, allow full path or just nameseg */ + + acpi_gbl_trace_method_name = *ACPI_CAST_PTR(u32, name); + acpi_gbl_trace_flags = flags; + + if (debug_level) { + acpi_gbl_trace_dbg_level = debug_level; + } + if (debug_layer) { + acpi_gbl_trace_dbg_layer = debug_layer; + } + + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + return (AE_OK); +} + +/******************************************************************************* + * + * 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_evaluate_info *info) +{ + acpi_status status; - /* Validate the Node and get the attached object */ + ACPI_FUNCTION_ENTRY(); - if (!method_node) { - return_ACPI_STATUS (AE_NULL_ENTRY); + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return; } - obj_desc = acpi_ns_get_attached_object (method_node); - if (!obj_desc) { - return_ACPI_STATUS (AE_NULL_OBJECT); + if ((!acpi_gbl_trace_method_name) || + (acpi_gbl_trace_method_name != info->resolved_node->name.integer)) { + goto exit; } - /* Init for new method, wait on concurrency semaphore */ + acpi_gbl_original_dbg_level = acpi_dbg_level; + acpi_gbl_original_dbg_layer = acpi_dbg_layer; + + acpi_dbg_level = 0x00FFFFFF; + acpi_dbg_layer = ACPI_UINT32_MAX; - status = acpi_ds_begin_method_execution (method_node, obj_desc, NULL); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + 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; } - if (params) { - /* - * The caller "owns" the parameters, so give each one an extra - * reference - */ - for (i = 0; params[i]; i++) { - acpi_ut_add_reference (params[i]); - } + exit: + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ps_stop_trace + * + * PARAMETERS: Info - Method info struct + * + * RETURN: None + * + * DESCRIPTION: Stop control method execution trace + * + ******************************************************************************/ + +static void acpi_ps_stop_trace(struct acpi_evaluate_info *info) +{ + acpi_status status; + + ACPI_FUNCTION_ENTRY(); + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return; } - /* - * 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", - method_node, obj_desc)); + if ((!acpi_gbl_trace_method_name) || + (acpi_gbl_trace_method_name != info->resolved_node->name.integer)) { + goto exit; + } - /* Create and init a Root Node */ + /* Disable further tracing if type is one-shot */ - op = acpi_ps_create_scope_op (); - if (!op) { - status = AE_NO_MEMORY; - goto cleanup1; + if (acpi_gbl_trace_flags & 1) { + acpi_gbl_trace_method_name = 0; + acpi_gbl_trace_dbg_level = 0; + acpi_gbl_trace_dbg_layer = 0; } - /* - * 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); + acpi_dbg_level = acpi_gbl_original_dbg_level; + acpi_dbg_layer = acpi_gbl_original_dbg_layer; - /* Create and initialize a new walk state */ + exit: + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); +} - walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id, - NULL, NULL, NULL); - if (!walk_state) { - status = AE_NO_MEMORY; - goto cleanup2; +/******************************************************************************* + * + * 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 + * + ******************************************************************************/ + +acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE(ps_execute_method); + + /* Validate the Info and method Node */ + + if (!info || !info->resolved_node) { + return_ACPI_STATUS(AE_NULL_ENTRY); } - status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start, - obj_desc->method.aml_length, NULL, NULL, 1); - if (ACPI_FAILURE (status)) { - goto cleanup3; + /* Init for new method, wait on concurrency semaphore */ + + status = + acpi_ds_begin_method_execution(info->resolved_node, info->obj_desc, + NULL); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); } - /* Parse the AML */ + /* + * The caller "owns" the parameters, so give each one an extra + * reference + */ + acpi_ps_update_parameter_list(info, REF_INCREMENT); + + /* Begin tracing if requested */ - status = acpi_ps_parse_aml (walk_state); - acpi_ps_delete_parse_tree (op); - if (ACPI_FAILURE (status)) { - goto cleanup1; /* Walk state is already deleted */ + 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->resolved_node, info->obj_desc)); + + info->pass_number = 1; + status = acpi_ps_execute_pass(info); + if (ACPI_FAILURE(status)) { + goto cleanup; } /* - * 2) Execute the method. Performs second pass parse simultaneously + * 2) Execute the method. Performs second pass parse simultaneously */ - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, - "**** Begin Method Execution **** Entry=%p obj=%p\n", - method_node, obj_desc)); + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, + "**** Begin Method Execution **** Entry=%p obj=%p\n", + info->resolved_node, info->obj_desc)); - /* Create and init a Root Node */ + info->pass_number = 3; + status = acpi_ps_execute_pass(info); - op = acpi_ps_create_scope_op (); - if (!op) { - status = AE_NO_MEMORY; - goto cleanup1; - } + cleanup: + /* End optional tracing */ - /* Init new op with the method name and pointer back to the NS node */ + acpi_ps_stop_trace(info); - acpi_ps_set_name (op, method_node->name.integer); - op->common.node = method_node; + /* Take away the extra reference that we gave the parameters above */ - /* Create and initialize a new walk state */ + acpi_ps_update_parameter_list(info, REF_DECREMENT); - walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); - if (!walk_state) { - status = AE_NO_MEMORY; - goto cleanup2; - } + /* Exit now if error above */ - status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start, - obj_desc->method.aml_length, params, return_obj_desc, 3); - if (ACPI_FAILURE (status)) { - goto cleanup3; + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); } /* - * The walk of the parse tree is where we actually execute the method + * If the method has returned an object, signal this to the caller with + * a control exception code */ - status = acpi_ps_parse_aml (walk_state); - goto cleanup2; /* Walk state already deleted */ + if (info->return_object) { + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Method returned ObjDesc=%p\n", + info->return_object)); + ACPI_DUMP_STACK_ENTRY(info->return_object); + status = AE_CTRL_RETURN_VALUE; + } -cleanup3: - acpi_ds_delete_walk_state (walk_state); + return_ACPI_STATUS(status); +} -cleanup2: - acpi_ps_delete_parse_tree (op); +/******************************************************************************* + * + * FUNCTION: acpi_ps_update_parameter_list + * + * PARAMETERS: Info - See struct acpi_evaluate_info + * (Used: parameter_type and Parameters) + * Action - Add or Remove reference + * + * RETURN: Status + * + * DESCRIPTION: Update reference count on all method parameter objects + * + ******************************************************************************/ -cleanup1: - if (params) { - /* Take away the extra reference that we gave the parameters above */ +static void +acpi_ps_update_parameter_list(struct acpi_evaluate_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++) { - for (i = 0; params[i]; i++) { /* Ignore errors, just do them all */ - (void) acpi_ut_update_object_reference (params[i], REF_DECREMENT); + (void)acpi_ut_update_object_reference(info-> + parameters[i], + action); } } +} - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); +/******************************************************************************* + * + * FUNCTION: acpi_ps_execute_pass + * + * PARAMETERS: Info - See struct acpi_evaluate_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_evaluate_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); } - /* - * If the method has returned an object, signal this to the caller with - * a control exception code - */ - if (*return_obj_desc) { - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned obj_desc=%p\n", - *return_obj_desc)); - ACPI_DUMP_STACK_ENTRY (*return_obj_desc); + /* Create and initialize a new walk state */ - status = AE_CTRL_RETURN_VALUE; + 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; } - return_ACPI_STATUS (status); -} + status = acpi_ds_init_aml_walk(walk_state, op, info->resolved_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); +}