Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /******************************************************************************
0003  *
0004  * Module Name: dswstate - Dispatcher parse tree walk management routines
0005  *
0006  * Copyright (C) 2000 - 2022, Intel Corp.
0007  *
0008  *****************************************************************************/
0009 
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acparser.h"
0013 #include "acdispat.h"
0014 #include "acnamesp.h"
0015 
0016 #define _COMPONENT          ACPI_DISPATCHER
0017 ACPI_MODULE_NAME("dswstate")
0018 
0019   /* Local prototypes */
0020 static acpi_status
0021 acpi_ds_result_stack_push(struct acpi_walk_state *walk_state);
0022 static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *walk_state);
0023 
0024 /*******************************************************************************
0025  *
0026  * FUNCTION:    acpi_ds_result_pop
0027  *
0028  * PARAMETERS:  object              - Where to return the popped object
0029  *              walk_state          - Current Walk state
0030  *
0031  * RETURN:      Status
0032  *
0033  * DESCRIPTION: Pop an object off the top of this walk's result stack
0034  *
0035  ******************************************************************************/
0036 
0037 acpi_status
0038 acpi_ds_result_pop(union acpi_operand_object **object,
0039            struct acpi_walk_state *walk_state)
0040 {
0041     u32 index;
0042     union acpi_generic_state *state;
0043     acpi_status status;
0044 
0045     ACPI_FUNCTION_NAME(ds_result_pop);
0046 
0047     state = walk_state->results;
0048 
0049     /* Incorrect state of result stack */
0050 
0051     if (state && !walk_state->result_count) {
0052         ACPI_ERROR((AE_INFO, "No results on result stack"));
0053         return (AE_AML_INTERNAL);
0054     }
0055 
0056     if (!state && walk_state->result_count) {
0057         ACPI_ERROR((AE_INFO, "No result state for result stack"));
0058         return (AE_AML_INTERNAL);
0059     }
0060 
0061     /* Empty result stack */
0062 
0063     if (!state) {
0064         ACPI_ERROR((AE_INFO, "Result stack is empty! State=%p",
0065                 walk_state));
0066         return (AE_AML_NO_RETURN_VALUE);
0067     }
0068 
0069     /* Return object of the top element and clean that top element result stack */
0070 
0071     walk_state->result_count--;
0072     index = (u32)walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
0073 
0074     *object = state->results.obj_desc[index];
0075     if (!*object) {
0076         ACPI_ERROR((AE_INFO,
0077                 "No result objects on result stack, State=%p",
0078                 walk_state));
0079         return (AE_AML_NO_RETURN_VALUE);
0080     }
0081 
0082     state->results.obj_desc[index] = NULL;
0083     if (index == 0) {
0084         status = acpi_ds_result_stack_pop(walk_state);
0085         if (ACPI_FAILURE(status)) {
0086             return (status);
0087         }
0088     }
0089 
0090     ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0091               "Obj=%p [%s] Index=%X State=%p Num=%X\n", *object,
0092               acpi_ut_get_object_type_name(*object),
0093               index, walk_state, walk_state->result_count));
0094 
0095     return (AE_OK);
0096 }
0097 
0098 /*******************************************************************************
0099  *
0100  * FUNCTION:    acpi_ds_result_push
0101  *
0102  * PARAMETERS:  object              - Where to return the popped object
0103  *              walk_state          - Current Walk state
0104  *
0105  * RETURN:      Status
0106  *
0107  * DESCRIPTION: Push an object onto the current result stack
0108  *
0109  ******************************************************************************/
0110 
0111 acpi_status
0112 acpi_ds_result_push(union acpi_operand_object *object,
0113             struct acpi_walk_state *walk_state)
0114 {
0115     union acpi_generic_state *state;
0116     acpi_status status;
0117     u32 index;
0118 
0119     ACPI_FUNCTION_NAME(ds_result_push);
0120 
0121     if (walk_state->result_count > walk_state->result_size) {
0122         ACPI_ERROR((AE_INFO, "Result stack is full"));
0123         return (AE_AML_INTERNAL);
0124     } else if (walk_state->result_count == walk_state->result_size) {
0125 
0126         /* Extend the result stack */
0127 
0128         status = acpi_ds_result_stack_push(walk_state);
0129         if (ACPI_FAILURE(status)) {
0130             ACPI_ERROR((AE_INFO,
0131                     "Failed to extend the result stack"));
0132             return (status);
0133         }
0134     }
0135 
0136     if (!(walk_state->result_count < walk_state->result_size)) {
0137         ACPI_ERROR((AE_INFO, "No free elements in result stack"));
0138         return (AE_AML_INTERNAL);
0139     }
0140 
0141     state = walk_state->results;
0142     if (!state) {
0143         ACPI_ERROR((AE_INFO, "No result stack frame during push"));
0144         return (AE_AML_INTERNAL);
0145     }
0146 
0147     if (!object) {
0148         ACPI_ERROR((AE_INFO,
0149                 "Null Object! Obj=%p State=%p Num=%u",
0150                 object, walk_state, walk_state->result_count));
0151         return (AE_BAD_PARAMETER);
0152     }
0153 
0154     /* Assign the address of object to the top free element of result stack */
0155 
0156     index = (u32)walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
0157     state->results.obj_desc[index] = object;
0158     walk_state->result_count++;
0159 
0160     ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
0161               object,
0162               acpi_ut_get_object_type_name((union
0163                             acpi_operand_object *)
0164                                object), walk_state,
0165               walk_state->result_count,
0166               walk_state->current_result));
0167 
0168     return (AE_OK);
0169 }
0170 
0171 /*******************************************************************************
0172  *
0173  * FUNCTION:    acpi_ds_result_stack_push
0174  *
0175  * PARAMETERS:  walk_state          - Current Walk state
0176  *
0177  * RETURN:      Status
0178  *
0179  * DESCRIPTION: Push an object onto the walk_state result stack
0180  *
0181  ******************************************************************************/
0182 
0183 static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *walk_state)
0184 {
0185     union acpi_generic_state *state;
0186 
0187     ACPI_FUNCTION_NAME(ds_result_stack_push);
0188 
0189     /* Check for stack overflow */
0190 
0191     if (((u32) walk_state->result_size + ACPI_RESULTS_FRAME_OBJ_NUM) >
0192         ACPI_RESULTS_OBJ_NUM_MAX) {
0193         ACPI_ERROR((AE_INFO, "Result stack overflow: State=%p Num=%u",
0194                 walk_state, walk_state->result_size));
0195         return (AE_STACK_OVERFLOW);
0196     }
0197 
0198     state = acpi_ut_create_generic_state();
0199     if (!state) {
0200         return (AE_NO_MEMORY);
0201     }
0202 
0203     state->common.descriptor_type = ACPI_DESC_TYPE_STATE_RESULT;
0204     acpi_ut_push_generic_state(&walk_state->results, state);
0205 
0206     /* Increase the length of the result stack by the length of frame */
0207 
0208     walk_state->result_size += ACPI_RESULTS_FRAME_OBJ_NUM;
0209 
0210     ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Results=%p State=%p\n",
0211               state, walk_state));
0212 
0213     return (AE_OK);
0214 }
0215 
0216 /*******************************************************************************
0217  *
0218  * FUNCTION:    acpi_ds_result_stack_pop
0219  *
0220  * PARAMETERS:  walk_state          - Current Walk state
0221  *
0222  * RETURN:      Status
0223  *
0224  * DESCRIPTION: Pop an object off of the walk_state result stack
0225  *
0226  ******************************************************************************/
0227 
0228 static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *walk_state)
0229 {
0230     union acpi_generic_state *state;
0231 
0232     ACPI_FUNCTION_NAME(ds_result_stack_pop);
0233 
0234     /* Check for stack underflow */
0235 
0236     if (walk_state->results == NULL) {
0237         ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0238                   "Result stack underflow - State=%p\n",
0239                   walk_state));
0240         return (AE_AML_NO_OPERAND);
0241     }
0242 
0243     if (walk_state->result_size < ACPI_RESULTS_FRAME_OBJ_NUM) {
0244         ACPI_ERROR((AE_INFO, "Insufficient result stack size"));
0245         return (AE_AML_INTERNAL);
0246     }
0247 
0248     state = acpi_ut_pop_generic_state(&walk_state->results);
0249     acpi_ut_delete_generic_state(state);
0250 
0251     /* Decrease the length of result stack by the length of frame */
0252 
0253     walk_state->result_size -= ACPI_RESULTS_FRAME_OBJ_NUM;
0254 
0255     ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0256               "Result=%p RemainingResults=%X State=%p\n",
0257               state, walk_state->result_count, walk_state));
0258 
0259     return (AE_OK);
0260 }
0261 
0262 /*******************************************************************************
0263  *
0264  * FUNCTION:    acpi_ds_obj_stack_push
0265  *
0266  * PARAMETERS:  object              - Object to push
0267  *              walk_state          - Current Walk state
0268  *
0269  * RETURN:      Status
0270  *
0271  * DESCRIPTION: Push an object onto this walk's object/operand stack
0272  *
0273  ******************************************************************************/
0274 
0275 acpi_status
0276 acpi_ds_obj_stack_push(void *object, struct acpi_walk_state *walk_state)
0277 {
0278     ACPI_FUNCTION_NAME(ds_obj_stack_push);
0279 
0280     /* Check for stack overflow */
0281 
0282     if (walk_state->num_operands >= ACPI_OBJ_NUM_OPERANDS) {
0283         ACPI_ERROR((AE_INFO,
0284                 "Object stack overflow! Obj=%p State=%p #Ops=%u",
0285                 object, walk_state, walk_state->num_operands));
0286         return (AE_STACK_OVERFLOW);
0287     }
0288 
0289     /* Put the object onto the stack */
0290 
0291     walk_state->operands[walk_state->operand_index] = object;
0292     walk_state->num_operands++;
0293 
0294     /* For the usual order of filling the operand stack */
0295 
0296     walk_state->operand_index++;
0297 
0298     ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
0299               object,
0300               acpi_ut_get_object_type_name((union
0301                             acpi_operand_object *)
0302                                object), walk_state,
0303               walk_state->num_operands));
0304 
0305     return (AE_OK);
0306 }
0307 
0308 /*******************************************************************************
0309  *
0310  * FUNCTION:    acpi_ds_obj_stack_pop
0311  *
0312  * PARAMETERS:  pop_count           - Number of objects/entries to pop
0313  *              walk_state          - Current Walk state
0314  *
0315  * RETURN:      Status
0316  *
0317  * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT
0318  *              deleted by this routine.
0319  *
0320  ******************************************************************************/
0321 
0322 acpi_status
0323 acpi_ds_obj_stack_pop(u32 pop_count, struct acpi_walk_state *walk_state)
0324 {
0325     u32 i;
0326 
0327     ACPI_FUNCTION_NAME(ds_obj_stack_pop);
0328 
0329     for (i = 0; i < pop_count; i++) {
0330 
0331         /* Check for stack underflow */
0332 
0333         if (walk_state->num_operands == 0) {
0334             ACPI_ERROR((AE_INFO,
0335                     "Object stack underflow! Count=%X State=%p #Ops=%u",
0336                     pop_count, walk_state,
0337                     walk_state->num_operands));
0338             return (AE_STACK_UNDERFLOW);
0339         }
0340 
0341         /* Just set the stack entry to null */
0342 
0343         walk_state->num_operands--;
0344         walk_state->operands[walk_state->num_operands] = NULL;
0345     }
0346 
0347     ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%u\n",
0348               pop_count, walk_state, walk_state->num_operands));
0349 
0350     return (AE_OK);
0351 }
0352 
0353 /*******************************************************************************
0354  *
0355  * FUNCTION:    acpi_ds_obj_stack_pop_and_delete
0356  *
0357  * PARAMETERS:  pop_count           - Number of objects/entries to pop
0358  *              walk_state          - Current Walk state
0359  *
0360  * RETURN:      Status
0361  *
0362  * DESCRIPTION: Pop this walk's object stack and delete each object that is
0363  *              popped off.
0364  *
0365  ******************************************************************************/
0366 
0367 void
0368 acpi_ds_obj_stack_pop_and_delete(u32 pop_count,
0369                  struct acpi_walk_state *walk_state)
0370 {
0371     s32 i;
0372     union acpi_operand_object *obj_desc;
0373 
0374     ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete);
0375 
0376     if (pop_count == 0) {
0377         return;
0378     }
0379 
0380     for (i = (s32)pop_count - 1; i >= 0; i--) {
0381         if (walk_state->num_operands == 0) {
0382             return;
0383         }
0384 
0385         /* Pop the stack and delete an object if present in this stack entry */
0386 
0387         walk_state->num_operands--;
0388         obj_desc = walk_state->operands[i];
0389         if (obj_desc) {
0390             acpi_ut_remove_reference(walk_state->operands[i]);
0391             walk_state->operands[i] = NULL;
0392         }
0393     }
0394 
0395     ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
0396               pop_count, walk_state, walk_state->num_operands));
0397 }
0398 
0399 /*******************************************************************************
0400  *
0401  * FUNCTION:    acpi_ds_get_current_walk_state
0402  *
0403  * PARAMETERS:  thread          - Get current active state for this Thread
0404  *
0405  * RETURN:      Pointer to the current walk state
0406  *
0407  * DESCRIPTION: Get the walk state that is at the head of the list (the "current"
0408  *              walk state.)
0409  *
0410  ******************************************************************************/
0411 
0412 struct acpi_walk_state *acpi_ds_get_current_walk_state(struct acpi_thread_state
0413                                *thread)
0414 {
0415     ACPI_FUNCTION_NAME(ds_get_current_walk_state);
0416 
0417     if (!thread) {
0418         return (NULL);
0419     }
0420 
0421     ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Current WalkState %p\n",
0422               thread->walk_state_list));
0423 
0424     return (thread->walk_state_list);
0425 }
0426 
0427 /*******************************************************************************
0428  *
0429  * FUNCTION:    acpi_ds_push_walk_state
0430  *
0431  * PARAMETERS:  walk_state      - State to push
0432  *              thread          - Thread state object
0433  *
0434  * RETURN:      None
0435  *
0436  * DESCRIPTION: Place the Thread state at the head of the state list
0437  *
0438  ******************************************************************************/
0439 
0440 void
0441 acpi_ds_push_walk_state(struct acpi_walk_state *walk_state,
0442             struct acpi_thread_state *thread)
0443 {
0444     ACPI_FUNCTION_TRACE(ds_push_walk_state);
0445 
0446     walk_state->next = thread->walk_state_list;
0447     thread->walk_state_list = walk_state;
0448 
0449     return_VOID;
0450 }
0451 
0452 /*******************************************************************************
0453  *
0454  * FUNCTION:    acpi_ds_pop_walk_state
0455  *
0456  * PARAMETERS:  thread      - Current thread state
0457  *
0458  * RETURN:      A walk_state object popped from the thread's stack
0459  *
0460  * DESCRIPTION: Remove and return the walkstate object that is at the head of
0461  *              the walk stack for the given walk list. NULL indicates that
0462  *              the list is empty.
0463  *
0464  ******************************************************************************/
0465 
0466 struct acpi_walk_state *acpi_ds_pop_walk_state(struct acpi_thread_state *thread)
0467 {
0468     struct acpi_walk_state *walk_state;
0469 
0470     ACPI_FUNCTION_TRACE(ds_pop_walk_state);
0471 
0472     walk_state = thread->walk_state_list;
0473 
0474     if (walk_state) {
0475 
0476         /* Next walk state becomes the current walk state */
0477 
0478         thread->walk_state_list = walk_state->next;
0479 
0480         /*
0481          * Don't clear the NEXT field, this serves as an indicator
0482          * that there is a parent WALK STATE
0483          * Do Not: walk_state->Next = NULL;
0484          */
0485     }
0486 
0487     return_PTR(walk_state);
0488 }
0489 
0490 /*******************************************************************************
0491  *
0492  * FUNCTION:    acpi_ds_create_walk_state
0493  *
0494  * PARAMETERS:  owner_id        - ID for object creation
0495  *              origin          - Starting point for this walk
0496  *              method_desc     - Method object
0497  *              thread          - Current thread state
0498  *
0499  * RETURN:      Pointer to the new walk state.
0500  *
0501  * DESCRIPTION: Allocate and initialize a new walk state. The current walk
0502  *              state is set to this new state.
0503  *
0504  ******************************************************************************/
0505 
0506 struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id,
0507                           union acpi_parse_object
0508                           *origin,
0509                           union acpi_operand_object
0510                           *method_desc,
0511                           struct acpi_thread_state
0512                           *thread)
0513 {
0514     struct acpi_walk_state *walk_state;
0515 
0516     ACPI_FUNCTION_TRACE(ds_create_walk_state);
0517 
0518     walk_state = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_walk_state));
0519     if (!walk_state) {
0520         return_PTR(NULL);
0521     }
0522 
0523     walk_state->descriptor_type = ACPI_DESC_TYPE_WALK;
0524     walk_state->method_desc = method_desc;
0525     walk_state->owner_id = owner_id;
0526     walk_state->origin = origin;
0527     walk_state->thread = thread;
0528 
0529     walk_state->parser_state.start_op = origin;
0530 
0531     /* Init the method args/local */
0532 
0533 #ifndef ACPI_CONSTANT_EVAL_ONLY
0534     acpi_ds_method_data_init(walk_state);
0535 #endif
0536 
0537     /* Put the new state at the head of the walk list */
0538 
0539     if (thread) {
0540         acpi_ds_push_walk_state(walk_state, thread);
0541     }
0542 
0543     return_PTR(walk_state);
0544 }
0545 
0546 /*******************************************************************************
0547  *
0548  * FUNCTION:    acpi_ds_init_aml_walk
0549  *
0550  * PARAMETERS:  walk_state      - New state to be initialized
0551  *              op              - Current parse op
0552  *              method_node     - Control method NS node, if any
0553  *              aml_start       - Start of AML
0554  *              aml_length      - Length of AML
0555  *              info            - Method info block (params, etc.)
0556  *              pass_number     - 1, 2, or 3
0557  *
0558  * RETURN:      Status
0559  *
0560  * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk
0561  *
0562  ******************************************************************************/
0563 
0564 acpi_status
0565 acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state,
0566               union acpi_parse_object *op,
0567               struct acpi_namespace_node *method_node,
0568               u8 * aml_start,
0569               u32 aml_length,
0570               struct acpi_evaluate_info *info, u8 pass_number)
0571 {
0572     acpi_status status;
0573     struct acpi_parse_state *parser_state = &walk_state->parser_state;
0574     union acpi_parse_object *extra_op;
0575 
0576     ACPI_FUNCTION_TRACE(ds_init_aml_walk);
0577 
0578     walk_state->parser_state.aml =
0579         walk_state->parser_state.aml_start = aml_start;
0580     walk_state->parser_state.aml_end =
0581         walk_state->parser_state.pkg_end = aml_start + aml_length;
0582 
0583     /* The next_op of the next_walk will be the beginning of the method */
0584 
0585     walk_state->next_op = NULL;
0586     walk_state->pass_number = pass_number;
0587 
0588     if (info) {
0589         walk_state->params = info->parameters;
0590         walk_state->caller_return_desc = &info->return_object;
0591     }
0592 
0593     status = acpi_ps_init_scope(&walk_state->parser_state, op);
0594     if (ACPI_FAILURE(status)) {
0595         return_ACPI_STATUS(status);
0596     }
0597 
0598     if (method_node) {
0599         walk_state->parser_state.start_node = method_node;
0600         walk_state->walk_type = ACPI_WALK_METHOD;
0601         walk_state->method_node = method_node;
0602         walk_state->method_desc =
0603             acpi_ns_get_attached_object(method_node);
0604 
0605         /* Push start scope on scope stack and make it current  */
0606 
0607         status =
0608             acpi_ds_scope_stack_push(method_node, ACPI_TYPE_METHOD,
0609                          walk_state);
0610         if (ACPI_FAILURE(status)) {
0611             return_ACPI_STATUS(status);
0612         }
0613 
0614         /* Init the method arguments */
0615 
0616         status = acpi_ds_method_data_init_args(walk_state->params,
0617                                ACPI_METHOD_NUM_ARGS,
0618                                walk_state);
0619         if (ACPI_FAILURE(status)) {
0620             return_ACPI_STATUS(status);
0621         }
0622     } else {
0623         /*
0624          * Setup the current scope.
0625          * Find a Named Op that has a namespace node associated with it.
0626          * search upwards from this Op. Current scope is the first
0627          * Op with a namespace node.
0628          */
0629         extra_op = parser_state->start_op;
0630         while (extra_op && !extra_op->common.node) {
0631             extra_op = extra_op->common.parent;
0632         }
0633 
0634         if (!extra_op) {
0635             parser_state->start_node = NULL;
0636         } else {
0637             parser_state->start_node = extra_op->common.node;
0638         }
0639 
0640         if (parser_state->start_node) {
0641 
0642             /* Push start scope on scope stack and make it current  */
0643 
0644             status =
0645                 acpi_ds_scope_stack_push(parser_state->start_node,
0646                              parser_state->start_node->
0647                              type, walk_state);
0648             if (ACPI_FAILURE(status)) {
0649                 return_ACPI_STATUS(status);
0650             }
0651         }
0652     }
0653 
0654     status = acpi_ds_init_callbacks(walk_state, pass_number);
0655     return_ACPI_STATUS(status);
0656 }
0657 
0658 /*******************************************************************************
0659  *
0660  * FUNCTION:    acpi_ds_delete_walk_state
0661  *
0662  * PARAMETERS:  walk_state      - State to delete
0663  *
0664  * RETURN:      Status
0665  *
0666  * DESCRIPTION: Delete a walk state including all internal data structures
0667  *
0668  ******************************************************************************/
0669 
0670 void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state)
0671 {
0672     union acpi_generic_state *state;
0673 
0674     ACPI_FUNCTION_TRACE_PTR(ds_delete_walk_state, walk_state);
0675 
0676     if (!walk_state) {
0677         return_VOID;
0678     }
0679 
0680     if (walk_state->descriptor_type != ACPI_DESC_TYPE_WALK) {
0681         ACPI_ERROR((AE_INFO, "%p is not a valid walk state",
0682                 walk_state));
0683         return_VOID;
0684     }
0685 
0686     /* There should not be any open scopes */
0687 
0688     if (walk_state->parser_state.scope) {
0689         ACPI_ERROR((AE_INFO, "%p walk still has a scope list",
0690                 walk_state));
0691         acpi_ps_cleanup_scope(&walk_state->parser_state);
0692     }
0693 
0694     /* Always must free any linked control states */
0695 
0696     while (walk_state->control_state) {
0697         state = walk_state->control_state;
0698         walk_state->control_state = state->common.next;
0699 
0700         acpi_ut_delete_generic_state(state);
0701     }
0702 
0703     /* Always must free any linked parse states */
0704 
0705     while (walk_state->scope_info) {
0706         state = walk_state->scope_info;
0707         walk_state->scope_info = state->common.next;
0708 
0709         acpi_ut_delete_generic_state(state);
0710     }
0711 
0712     /* Always must free any stacked result states */
0713 
0714     while (walk_state->results) {
0715         state = walk_state->results;
0716         walk_state->results = state->common.next;
0717 
0718         acpi_ut_delete_generic_state(state);
0719     }
0720 
0721     ACPI_FREE(walk_state);
0722     return_VOID;
0723 }