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

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)