patch-2.4.0-prerelease linux/drivers/acpi/parser/pswalk.c
Next file: linux/drivers/acpi/parser/psxface.c
Previous file: linux/drivers/acpi/parser/psutils.c
Back to the patch index
Back to the overall index
- Lines: 544
- Date:
Fri Dec 29 14:07:21 2000
- Orig file:
v2.4.0-test12/linux/drivers/acpi/parser/pswalk.c
- Orig date:
Sun Oct 8 10:50:15 2000
diff -u --recursive --new-file v2.4.0-test12/linux/drivers/acpi/parser/pswalk.c linux/drivers/acpi/parser/pswalk.c
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: pswalk - Parser routines to walk parsed op tree(s)
- * $Revision: 45 $
+ * $Revision: 50 $
*
*****************************************************************************/
@@ -42,8 +42,6 @@
* PARAMETERS: Walk_state - Current state of the walk
* Op - Current Op to be walked
* Ascending_callback - Procedure called when Op is complete
- * Prev_op - Where the previous Op is stored
- * Next_op - Where the next Op in the walk is stored
*
* RETURN: Status
*
@@ -90,112 +88,40 @@
status = ascending_callback (walk_state, op);
- switch (status)
- {
- case AE_CTRL_TERMINATE:
-
- /*
- * A control method was terminated via a RETURN statement.
- * The walk of this method is complete.
- */
- walk_state->prev_op = walk_state->origin;
- walk_state->next_op = NULL;
-
- return (AE_OK);
- break;
-
-
- case AE_CTRL_FALSE:
-
- /*
- * Either an IF/WHILE Predicate was false or we encountered a BREAK
- * opcode. In both cases, we do not execute the rest of the
- * package; We simply close out the parent (finishing the walk of
- * this branch of the tree) and continue execution at the parent
- * level.
- */
-
- next = parent->next;
- status = AE_OK;
-
- /*
- * If there is a sibling to the parent, we must close out the
- * parent now, because we are going to continue to go downward (to
- * the sibling) in the parse tree.
- */
- if (next) {
- status = ascending_callback (walk_state, parent);
-
- /* The parent sibling will be next */
-
- walk_state->prev_op = op;
- walk_state->next_op = next;
- walk_state->next_op_info = NEXT_OP_DOWNWARD;
-
- /* Continue downward */
-
- return (AE_OK);
- }
-
- /*
- * Drop into the loop below because we are moving upwards in
- * the tree
- */
-
- break;
-
-
- default:
- /*
- * If we are back to the starting point, the walk is complete.
- */
- if (op == walk_state->origin) {
- /* Reached the point of origin, the walk is complete */
-
- walk_state->prev_op = op;
- walk_state->next_op = NULL;
-
- return (status);
- }
-
- /*
- * Check for a sibling to the current op. A sibling means
- * we are still going "downward" in the tree.
- */
+ /*
+ * If we are back to the starting point, the walk is complete.
+ */
+ if (op == walk_state->origin) {
+ /* Reached the point of origin, the walk is complete */
- if (next) {
- /* There is a sibling, it will be next */
+ walk_state->prev_op = op;
+ walk_state->next_op = NULL;
- walk_state->prev_op = op;
- walk_state->next_op = next;
- walk_state->next_op_info = NEXT_OP_DOWNWARD;
+ return (status);
+ }
- /* Continue downward */
+ /*
+ * Check for a sibling to the current op. A sibling means
+ * we are still going "downward" in the tree.
+ */
- return (status);
- }
+ if (next) {
+ /* There is a sibling, it will be next */
- /*
- * No sibling, but check status.
- * Abort on error from callback routine
- */
- if (ACPI_FAILURE (status)) {
- /* Next op will be the parent */
+ walk_state->prev_op = op;
+ walk_state->next_op = next;
+ walk_state->next_op_info = NEXT_OP_DOWNWARD;
- walk_state->prev_op = op;
- walk_state->next_op = parent;
- walk_state->next_op_info = NEXT_OP_UPWARD;
+ /* Continue downward */
- return (status);
- }
+ return (status);
+ }
- /*
- * Drop into the loop below because we are moving upwards in
- * the tree
- */
- break;
- }
+ /*
+ * Drop into the loop below because we are moving upwards in
+ * the tree
+ */
}
else {
@@ -221,69 +147,6 @@
status = ascending_callback (walk_state, parent);
-
- switch (status)
- {
- case AE_CTRL_FALSE:
-
- /*
- * Either an IF/WHILE Predicate was false or we encountered a
- * BREAK opcode. In both cases, we do not execute the rest of the
- * package; We simply close out the parent (finishing the walk of
- * this branch of the tree) and continue execution at the parent
- * level.
- */
-
- parent = grand_parent;
- next = grand_parent->next;
- grand_parent = grand_parent->parent;
-
- status = ascending_callback (walk_state, parent);
-
- /* Now continue to the next node in the tree */
-
- break;
-
-
- case AE_CTRL_TRUE:
-
- /*
- * Predicate of a WHILE was true and the loop just completed an
- * execution. Go back to the start of the loop and reevaluate the
- * predicate.
- */
-
- op = walk_state->control_state->control.predicate_op;
-
- walk_state->control_state->common.state = CONTROL_PREDICATE_EXECUTING;
-
- /*
- * Acpi_evaluate the predicate again (next)
- * Because we will traverse WHILE tree again
- */
-
- walk_state->prev_op = op->parent;
- walk_state->next_op = op;
- walk_state->next_op_info = NEXT_OP_DOWNWARD;
-
- return (AE_OK);
- break;
-
-
- case AE_CTRL_TERMINATE:
-
- /*
- * A control method was terminated via a RETURN statement.
- * The walk of this method is complete.
- */
- walk_state->prev_op = walk_state->origin;
- walk_state->next_op = NULL;
-
- return (AE_OK);
- break;
- }
-
-
/*
* If we are back to the starting point, the walk is complete.
*/
@@ -296,7 +159,6 @@
return (status);
}
-
/*
* If there is a sibling to this parent (it is not the starting point
* Op), then we will visit it.
@@ -311,18 +173,6 @@
return (status);
}
- /*
- * No sibling, check for an error from closing the parent
- * (Also, AE_PENDING if a method call was encountered)
- */
- if (ACPI_FAILURE (status)) {
- walk_state->prev_op = parent;
- walk_state->next_op = grand_parent;
- walk_state->next_op_info = NEXT_OP_UPWARD;
-
- return (status);
- }
-
/* No siblings, no errors, just move up one more level in the tree */
op = parent;
@@ -342,251 +192,88 @@
/*******************************************************************************
*
- * FUNCTION: Acpi_ps_walk_loop
+ * FUNCTION: Acpi_ps_delete_completed_op
*
- * PARAMETERS: Walk_list - State of the walk
- * Start_op - Starting Op of the subtree to be walked
- * Descending_callback - Procedure called when a new Op is
- * encountered
- * Ascending_callback - Procedure called when Op is complete
+ * PARAMETERS: State - Walk state
+ * Op - Completed op
*
- * RETURN: Status
+ * RETURN: AE_OK
*
- * DESCRIPTION: Perform a walk of the parsed AML tree. Begins and terminates at
- * the Start_op.
+ * DESCRIPTION: Callback function for Acpi_ps_get_next_walk_op(). Used during
+ * Acpi_ps_delete_parse tree to delete Op objects when all sub-objects
+ * have been visited (and deleted.)
*
******************************************************************************/
-ACPI_STATUS
-acpi_ps_walk_loop (
- ACPI_WALK_LIST *walk_list,
- ACPI_PARSE_OBJECT *start_op,
- ACPI_PARSE_DOWNWARDS descending_callback,
- ACPI_PARSE_UPWARDS ascending_callback)
+static ACPI_STATUS
+acpi_ps_delete_completed_op (
+ ACPI_WALK_STATE *state,
+ ACPI_PARSE_OBJECT *op)
{
- ACPI_STATUS status = AE_OK;
- ACPI_WALK_STATE *walk_state;
- ACPI_PARSE_OBJECT *op = start_op;
-
-
- walk_state = acpi_ds_get_current_walk_state (walk_list);
-
-
- /* Walk entire subtree, visiting all nodes depth-first */
-
- while (op) {
- if (walk_state->next_op_info != NEXT_OP_UPWARD) {
- status = descending_callback (op->opcode, op, walk_state, NULL);
- }
-
- /*
- * A TRUE exception means that an ELSE was detected, but the IF
- * predicate evaluated TRUE.
- */
- if (status == AE_CTRL_TRUE) {
- /*
- * Ignore the entire ELSE block by moving on to the the next opcode.
- * And we do that by simply going up in the tree (either to the next
- * sibling or to the parent) from here.
- */
-
- walk_state->next_op_info = NEXT_OP_UPWARD;
- }
-
- /* Get the next node (op) in the depth-first walk */
-
- status = acpi_ps_get_next_walk_op (walk_state, op, ascending_callback);
-
- /*
- * A PENDING exception means that a control method invocation has been
- * detected
- */
-
- if (status == AE_CTRL_PENDING) {
- /* Transfer control to the called control method */
-
- status = acpi_ds_call_control_method (walk_list, walk_state, op);
-
- /*
- * If the transfer to the new method method call worked, a new walk
- * state was created -- get it
- */
-
- walk_state = acpi_ds_get_current_walk_state (walk_list);
- }
-
- /* Abort the walk on any exception */
-
- if (ACPI_FAILURE (status)) {
- return (status);
- }
-
- op = walk_state->next_op;
- }
+ acpi_ps_free_op (op);
return (AE_OK);
}
/*******************************************************************************
*
- * FUNCTION: Acpi_ps_walk_parsed_aml
+ * FUNCTION: Acpi_ps_delete_parse_tree
*
- * PARAMETERS: Start_op - Starting Op of the subtree to be walked
- * End_op - Where to terminate the walk
- * Descending_callback - Procedure called when a new Op is
- * encountered
- * Ascending_callback - Procedure called when Op is complete
+ * PARAMETERS: Subtree_root - Root of tree (or subtree) to delete
*
- * RETURN: Status
- *
- * DESCRIPTION: Top level interface to walk the parsed AML tree. Handles
- * preemption of executing control methods.
+ * RETURN: None
*
- * NOTE: The End_op is usually only different from the Start_op if
- * we don't want to visit the Start_op during the tree descent.
+ * DESCRIPTION: Delete a portion of or an entire parse tree.
*
******************************************************************************/
-ACPI_STATUS
-acpi_ps_walk_parsed_aml (
- ACPI_PARSE_OBJECT *start_op,
- ACPI_PARSE_OBJECT *end_op,
- ACPI_OPERAND_OBJECT *mth_desc,
- ACPI_NAMESPACE_NODE *start_node,
- ACPI_OPERAND_OBJECT **params,
- ACPI_OPERAND_OBJECT **caller_return_desc,
- ACPI_OWNER_ID owner_id,
- ACPI_PARSE_DOWNWARDS descending_callback,
- ACPI_PARSE_UPWARDS ascending_callback)
+void
+acpi_ps_delete_parse_tree (
+ ACPI_PARSE_OBJECT *subtree_root)
{
- ACPI_PARSE_OBJECT *op;
ACPI_WALK_STATE *walk_state;
- ACPI_OPERAND_OBJECT *return_desc;
- ACPI_STATUS status;
ACPI_WALK_LIST walk_list;
- ACPI_WALK_LIST *prev_walk_list;
- /* Parameter Validation */
-
- if (!start_op || !end_op) {
- return (AE_BAD_PARAMETER);
+ if (!subtree_root) {
+ return;
}
- /* Initialize a new walk list */
+ /* Create and initialize a new walk list */
walk_list.walk_state = NULL;
-
- walk_state = acpi_ds_create_walk_state (owner_id, end_op, mth_desc, &walk_list);
+ walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, &walk_list);
if (!walk_state) {
- return (AE_NO_MEMORY);
+ return;
}
- /* TBD: [Restructure] TEMP until we pass Walk_state to the interpreter
- */
- prev_walk_list = acpi_gbl_current_walk_list;
- acpi_gbl_current_walk_list = &walk_list;
+ walk_state->parser_state = NULL;
+ walk_state->parse_flags = 0;
+ walk_state->descending_callback = NULL;
+ walk_state->ascending_callback = NULL;
- if (start_node) {
- /* Push start scope on scope stack and make it current */
- status = acpi_ds_scope_stack_push (start_node, ACPI_TYPE_METHOD, walk_state);
- if (ACPI_FAILURE (status)) {
- return (status);
- }
-
- }
-
- if (mth_desc) {
- /* Init arguments if this is a control method */
- /* TBD: [Restructure] add walkstate as a param */
-
- acpi_ds_method_data_init_args (params, MTH_NUM_ARGS, walk_state);
- }
+ walk_state->origin = subtree_root;
+ walk_state->next_op = subtree_root;
- op = start_op;
- status = AE_OK;
+ /* Head downward in the tree */
- /*
- * Execute the walk loop as long as there is a valid Walk State. This
- * handles nested control method invocations without recursion.
- */
-
- while (walk_state) {
- if (ACPI_SUCCESS (status)) {
- status = acpi_ps_walk_loop (&walk_list, op, descending_callback,
- ascending_callback);
- }
+ walk_state->next_op_info = NEXT_OP_DOWNWARD;
- /* We are done with this walk, move on to the parent if any */
-
- BREAKPOINT3;
-
- walk_state = acpi_ds_pop_walk_state (&walk_list);
-
- /* Extract return value before we delete Walk_state */
-
- return_desc = walk_state->return_desc;
-
- /* Reset the current scope to the beginning of scope stack */
-
- acpi_ds_scope_stack_clear (walk_state);
-
- /*
- * If we just returned from the execution of a control method,
- * there's lots of cleanup to do
- */
+ /* Visit all nodes in the subtree */
- if (walk_state->method_desc) {
- acpi_ds_terminate_control_method (walk_state);
- }
-
- /* Delete this walk state and all linked control states */
-
- acpi_ds_delete_walk_state (walk_state);
-
- /* Check if we have restarted a preempted walk */
-
- walk_state = acpi_ds_get_current_walk_state (&walk_list);
- if (walk_state &&
- ACPI_SUCCESS (status))
- {
- /* There is another walk state, restart it */
-
- /*
- * If the method returned value is not used by the parent,
- * The object is deleted
- */
-
- acpi_ds_restart_control_method (walk_state, return_desc);
-
- /* Get the next Op to process */
-
- op = walk_state->next_op;
- }
-
- /*
- * Just completed a 1st-level method, save the final internal return
- * value (if any)
- */
-
- else if (caller_return_desc) {
- *caller_return_desc = return_desc; /* NULL if no return value */
- }
-
- else if (return_desc) {
- /* Caller doesn't want it, must delete it */
-
- acpi_cm_remove_reference (return_desc);
- }
+ while (walk_state->next_op) {
+ acpi_ps_get_next_walk_op (walk_state, walk_state->next_op,
+ acpi_ps_delete_completed_op);
}
+ /* We are done with this walk */
- acpi_gbl_current_walk_list = prev_walk_list;
+ acpi_ds_delete_walk_state (walk_state);
- return (status);
+ return;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)