summaryrefslogtreecommitdiffstats
path: root/drivers/acpi/dispatcher/dswstate.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/dispatcher/dswstate.c')
-rw-r--r--drivers/acpi/dispatcher/dswstate.c288
1 files changed, 265 insertions, 23 deletions
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c
index cc2088492..a15a6f5f7 100644
--- a/drivers/acpi/dispatcher/dswstate.c
+++ b/drivers/acpi/dispatcher/dswstate.c
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: dswstate - Dispatcher parse tree walk management routines
- * $Revision: 31 $
+ * $Revision: 36 $
*
*****************************************************************************/
@@ -49,20 +49,20 @@
******************************************************************************/
ACPI_STATUS
-acpi_ds_result_stack_clear (
+xxx_acpi_ds_result_stack_clear (
ACPI_WALK_STATE *walk_state)
{
-
- walk_state->num_results = 0;
- walk_state->current_result = 0;
-
+/*
+ Walk_state->Num_results = 0;
+ Walk_state->Current_result = 0;
+*/
return (AE_OK);
}
/*******************************************************************************
*
- * FUNCTION: Acpi_ds_result_stack_push
+ * FUNCTION: Acpi_ds_result_insert
*
* PARAMETERS: Object - Object to push
* Walk_state - Current Walk state
@@ -74,18 +74,29 @@ acpi_ds_result_stack_clear (
******************************************************************************/
ACPI_STATUS
-acpi_ds_result_stack_push (
+acpi_ds_result_insert (
void *object,
+ u32 index,
ACPI_WALK_STATE *walk_state)
{
+ ACPI_GENERIC_STATE *state;
- if (walk_state->num_results >= OBJ_NUM_OPERANDS) {
- return (AE_STACK_OVERFLOW);
+ state = walk_state->results;
+ if (!state) {
+ return (AE_NOT_EXIST);
+ }
+
+ if (index >= OBJ_NUM_OPERANDS) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ if (!object) {
+ return (AE_BAD_PARAMETER);
}
- walk_state->results [walk_state->num_results] = object;
- walk_state->num_results++;
+ state->results.obj_desc [index] = object;
+ state->results.num_results++;
return (AE_OK);
}
@@ -93,7 +104,7 @@ acpi_ds_result_stack_push (
/*******************************************************************************
*
- * FUNCTION: Acpi_ds_result_stack_pop
+ * FUNCTION: Acpi_ds_result_remove
*
* PARAMETERS: Object - Where to return the popped object
* Walk_state - Current Walk state
@@ -106,31 +117,250 @@ acpi_ds_result_stack_push (
******************************************************************************/
ACPI_STATUS
-acpi_ds_result_stack_pop (
+acpi_ds_result_remove (
ACPI_OPERAND_OBJECT **object,
+ u32 index,
ACPI_WALK_STATE *walk_state)
{
+ ACPI_GENERIC_STATE *state;
- /* Check for stack underflow */
+ state = walk_state->results;
+ if (!state) {
+ return (AE_NOT_EXIST);
+ }
- if (walk_state->num_results == 0) {
+
+
+ /* Check for a valid result object */
+
+ if (!state->results.obj_desc [index]) {
return (AE_AML_NO_OPERAND);
}
+ /* Remove the object */
+
+ state->results.num_results--;
+
+ *object = state->results.obj_desc [index];
+ state->results.obj_desc [index] = NULL;
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_ds_result_pop
+ *
+ * PARAMETERS: Object - Where to return the popped object
+ * Walk_state - Current Walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In
+ * other words, this is a FIFO.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ds_result_pop (
+ ACPI_OPERAND_OBJECT **object,
+ ACPI_WALK_STATE *walk_state)
+{
+ u32 index;
+ ACPI_GENERIC_STATE *state;
- /* Pop the stack */
- walk_state->num_results--;
+ state = walk_state->results;
+ if (!state) {
+ return (AE_OK);
+ }
+
+
+ if (!state->results.num_results) {
+ return (AE_STACK_UNDERFLOW);
+ }
+
+ /* Remove top element */
+
+ state->results.num_results--;
+
+ for (index = OBJ_NUM_OPERANDS; index; index--) {
+ /* Check for a valid result object */
+
+ if (state->results.obj_desc [index -1]) {
+ *object = state->results.obj_desc [index -1];
+ state->results.obj_desc [index -1] = NULL;
+
+ return (AE_OK);
+ }
+ }
+
+
+ return (AE_STACK_UNDERFLOW);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_ds_result_pop
+ *
+ * PARAMETERS: Object - Where to return the popped object
+ * Walk_state - Current Walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In
+ * other words, this is a FIFO.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ds_result_pop_from_bottom (
+ ACPI_OPERAND_OBJECT **object,
+ ACPI_WALK_STATE *walk_state)
+{
+ u32 index;
+ ACPI_GENERIC_STATE *state;
+
+
+ state = walk_state->results;
+ if (!state) {
+ return (AE_NOT_EXIST);
+ }
+
+
+ if (!state->results.num_results) {
+ return (AE_STACK_UNDERFLOW);
+ }
+
+ /* Remove Bottom element */
+
+ *object = state->results.obj_desc [0];
+
+
+ /* Push entire stack down one element */
+
+ for (index = 0; index < state->results.num_results; index++) {
+ state->results.obj_desc [index] = state->results.obj_desc [index + 1];
+ }
+
+ state->results.num_results--;
/* Check for a valid result object */
- if (!walk_state->results [walk_state->num_results]) {
+ if (!*object) {
return (AE_AML_NO_OPERAND);
}
- *object = walk_state->results [walk_state->num_results];
- walk_state->results [walk_state->num_results] = NULL;
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_ds_result_pop
+ *
+ * PARAMETERS: Object - Where to return the popped object
+ * Walk_state - Current Walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In
+ * other words, this is a FIFO.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ds_result_push (
+ ACPI_OPERAND_OBJECT *object,
+ ACPI_WALK_STATE *walk_state)
+{
+ ACPI_GENERIC_STATE *state;
+
+
+ state = walk_state->results;
+ if (!state) {
+ return (AE_OK);
+ }
+
+ if (state->results.num_results == OBJ_NUM_OPERANDS) {
+ return (AE_STACK_OVERFLOW);
+ }
+
+ if (!object) {
+ return (AE_BAD_PARAMETER);
+ }
+
+
+ state->results.obj_desc [state->results.num_results] = object;
+ state->results.num_results++;
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_ds_result_stack_push
+ *
+ * PARAMETERS: Object - Object to push
+ * Walk_state - Current Walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION:
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ds_result_stack_push (
+ ACPI_WALK_STATE *walk_state)
+{
+ ACPI_GENERIC_STATE *state;
+
+
+ state = acpi_cm_create_generic_state ();
+ if (!state) {
+ return (AE_NO_MEMORY);
+ }
+
+ acpi_cm_push_generic_state (&walk_state->results, state);
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_ds_result_stack_pop
+ *
+ * PARAMETERS: Walk_state - Current Walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION:
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ds_result_stack_pop (
+ ACPI_WALK_STATE *walk_state)
+{
+ ACPI_GENERIC_STATE *state;
+
+
+ /* Check for stack underflow */
+
+ if (walk_state->results == NULL) {
+ return (AE_AML_NO_OPERAND);
+ }
+
+
+ state = acpi_cm_pop_generic_state (&walk_state->results);
+
+ acpi_cm_delete_generic_state (state);
return (AE_OK);
}
@@ -414,7 +644,7 @@ acpi_ds_get_current_walk_state (
*
******************************************************************************/
-void
+static void
acpi_ds_push_walk_state (
ACPI_WALK_STATE *walk_state,
ACPI_WALK_LIST *walk_list)
@@ -528,7 +758,9 @@ acpi_ds_create_walk_state (
/* Init the method args/local */
+#ifndef _ACPI_ASL_COMPILER
acpi_ds_method_data_init (walk_state);
+#endif
/* Put the new state at the head of the walk list */
@@ -565,6 +797,7 @@ acpi_ds_delete_walk_state (
return;
}
+
/* Always must free any linked control states */
while (walk_state->control_state) {
@@ -574,7 +807,6 @@ acpi_ds_delete_walk_state (
acpi_cm_delete_generic_state (state);
}
-
/* Always must free any linked parse states */
while (walk_state->scope_info) {
@@ -584,6 +816,16 @@ acpi_ds_delete_walk_state (
acpi_cm_delete_generic_state (state);
}
+ /* Always must free any stacked result states */
+
+ while (walk_state->results) {
+ state = walk_state->results;
+ walk_state->results = state->common.next;
+
+ acpi_cm_delete_generic_state (state);
+ }
+
+
/* If walk cache is full, just free this wallkstate object */
if (acpi_gbl_walk_state_cache_depth >= MAX_WALK_CACHE_DEPTH) {