root/drivers/acpi/acpica/dswstate.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ds_result_push
  3. acpi_ds_result_stack_push
  4. acpi_ds_result_stack_pop
  5. acpi_ds_obj_stack_push
  6. acpi_ds_obj_stack_pop
  7. acpi_ds_obj_stack_pop_and_delete
  8. acpi_ds_get_current_walk_state
  9. acpi_ds_push_walk_state
  10. acpi_ds_pop_walk_state
  11. acpi_ds_create_walk_state
  12. acpi_ds_init_aml_walk
  13. acpi_ds_delete_walk_state

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Module Name: dswstate - Dispatcher parse tree walk management routines
   5  *
   6  * Copyright (C) 2000 - 2019, Intel Corp.
   7  *
   8  *****************************************************************************/
   9 
  10 #include <acpi/acpi.h>
  11 #include "accommon.h"
  12 #include "acparser.h"
  13 #include "acdispat.h"
  14 #include "acnamesp.h"
  15 
  16 #define _COMPONENT          ACPI_DISPATCHER
  17 ACPI_MODULE_NAME("dswstate")
  18 
  19   /* Local prototypes */
  20 static acpi_status
  21 acpi_ds_result_stack_push(struct acpi_walk_state *walk_state);
  22 static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *walk_state);
  23 
  24 /*******************************************************************************
  25  *
  26  * FUNCTION:    acpi_ds_result_pop
  27  *
  28  * PARAMETERS:  object              - Where to return the popped object
  29  *              walk_state          - Current Walk state
  30  *
  31  * RETURN:      Status
  32  *
  33  * DESCRIPTION: Pop an object off the top of this walk's result stack
  34  *
  35  ******************************************************************************/
  36 
  37 acpi_status
  38 acpi_ds_result_pop(union acpi_operand_object **object,
  39                    struct acpi_walk_state *walk_state)
  40 {
  41         u32 index;
  42         union acpi_generic_state *state;
  43         acpi_status status;
  44 
  45         ACPI_FUNCTION_NAME(ds_result_pop);
  46 
  47         state = walk_state->results;
  48 
  49         /* Incorrect state of result stack */
  50 
  51         if (state && !walk_state->result_count) {
  52                 ACPI_ERROR((AE_INFO, "No results on result stack"));
  53                 return (AE_AML_INTERNAL);
  54         }
  55 
  56         if (!state && walk_state->result_count) {
  57                 ACPI_ERROR((AE_INFO, "No result state for result stack"));
  58                 return (AE_AML_INTERNAL);
  59         }
  60 
  61         /* Empty result stack */
  62 
  63         if (!state) {
  64                 ACPI_ERROR((AE_INFO, "Result stack is empty! State=%p",
  65                             walk_state));
  66                 return (AE_AML_NO_RETURN_VALUE);
  67         }
  68 
  69         /* Return object of the top element and clean that top element result stack */
  70 
  71         walk_state->result_count--;
  72         index = (u32)walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
  73 
  74         *object = state->results.obj_desc[index];
  75         if (!*object) {
  76                 ACPI_ERROR((AE_INFO,
  77                             "No result objects on result stack, State=%p",
  78                             walk_state));
  79                 return (AE_AML_NO_RETURN_VALUE);
  80         }
  81 
  82         state->results.obj_desc[index] = NULL;
  83         if (index == 0) {
  84                 status = acpi_ds_result_stack_pop(walk_state);
  85                 if (ACPI_FAILURE(status)) {
  86                         return (status);
  87                 }
  88         }
  89 
  90         ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
  91                           "Obj=%p [%s] Index=%X State=%p Num=%X\n", *object,
  92                           acpi_ut_get_object_type_name(*object),
  93                           index, walk_state, walk_state->result_count));
  94 
  95         return (AE_OK);
  96 }
  97 
  98 /*******************************************************************************
  99  *
 100  * FUNCTION:    acpi_ds_result_push
 101  *
 102  * PARAMETERS:  object              - Where to return the popped object
 103  *              walk_state          - Current Walk state
 104  *
 105  * RETURN:      Status
 106  *
 107  * DESCRIPTION: Push an object onto the current result stack
 108  *
 109  ******************************************************************************/
 110 
 111 acpi_status
 112 acpi_ds_result_push(union acpi_operand_object *object,
 113                     struct acpi_walk_state *walk_state)
 114 {
 115         union acpi_generic_state *state;
 116         acpi_status status;
 117         u32 index;
 118 
 119         ACPI_FUNCTION_NAME(ds_result_push);
 120 
 121         if (walk_state->result_count > walk_state->result_size) {
 122                 ACPI_ERROR((AE_INFO, "Result stack is full"));
 123                 return (AE_AML_INTERNAL);
 124         } else if (walk_state->result_count == walk_state->result_size) {
 125 
 126                 /* Extend the result stack */
 127 
 128                 status = acpi_ds_result_stack_push(walk_state);
 129                 if (ACPI_FAILURE(status)) {
 130                         ACPI_ERROR((AE_INFO,
 131                                     "Failed to extend the result stack"));
 132                         return (status);
 133                 }
 134         }
 135 
 136         if (!(walk_state->result_count < walk_state->result_size)) {
 137                 ACPI_ERROR((AE_INFO, "No free elements in result stack"));
 138                 return (AE_AML_INTERNAL);
 139         }
 140 
 141         state = walk_state->results;
 142         if (!state) {
 143                 ACPI_ERROR((AE_INFO, "No result stack frame during push"));
 144                 return (AE_AML_INTERNAL);
 145         }
 146 
 147         if (!object) {
 148                 ACPI_ERROR((AE_INFO,
 149                             "Null Object! Obj=%p State=%p Num=%u",
 150                             object, walk_state, walk_state->result_count));
 151                 return (AE_BAD_PARAMETER);
 152         }
 153 
 154         /* Assign the address of object to the top free element of result stack */
 155 
 156         index = (u32)walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
 157         state->results.obj_desc[index] = object;
 158         walk_state->result_count++;
 159 
 160         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
 161                           object,
 162                           acpi_ut_get_object_type_name((union
 163                                                         acpi_operand_object *)
 164                                                        object), walk_state,
 165                           walk_state->result_count,
 166                           walk_state->current_result));
 167 
 168         return (AE_OK);
 169 }
 170 
 171 /*******************************************************************************
 172  *
 173  * FUNCTION:    acpi_ds_result_stack_push
 174  *
 175  * PARAMETERS:  walk_state          - Current Walk state
 176  *
 177  * RETURN:      Status
 178  *
 179  * DESCRIPTION: Push an object onto the walk_state result stack
 180  *
 181  ******************************************************************************/
 182 
 183 static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *walk_state)
 184 {
 185         union acpi_generic_state *state;
 186 
 187         ACPI_FUNCTION_NAME(ds_result_stack_push);
 188 
 189         /* Check for stack overflow */
 190 
 191         if (((u32) walk_state->result_size + ACPI_RESULTS_FRAME_OBJ_NUM) >
 192             ACPI_RESULTS_OBJ_NUM_MAX) {
 193                 ACPI_ERROR((AE_INFO, "Result stack overflow: State=%p Num=%u",
 194                             walk_state, walk_state->result_size));
 195                 return (AE_STACK_OVERFLOW);
 196         }
 197 
 198         state = acpi_ut_create_generic_state();
 199         if (!state) {
 200                 return (AE_NO_MEMORY);
 201         }
 202 
 203         state->common.descriptor_type = ACPI_DESC_TYPE_STATE_RESULT;
 204         acpi_ut_push_generic_state(&walk_state->results, state);
 205 
 206         /* Increase the length of the result stack by the length of frame */
 207 
 208         walk_state->result_size += ACPI_RESULTS_FRAME_OBJ_NUM;
 209 
 210         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Results=%p State=%p\n",
 211                           state, walk_state));
 212 
 213         return (AE_OK);
 214 }
 215 
 216 /*******************************************************************************
 217  *
 218  * FUNCTION:    acpi_ds_result_stack_pop
 219  *
 220  * PARAMETERS:  walk_state          - Current Walk state
 221  *
 222  * RETURN:      Status
 223  *
 224  * DESCRIPTION: Pop an object off of the walk_state result stack
 225  *
 226  ******************************************************************************/
 227 
 228 static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *walk_state)
 229 {
 230         union acpi_generic_state *state;
 231 
 232         ACPI_FUNCTION_NAME(ds_result_stack_pop);
 233 
 234         /* Check for stack underflow */
 235 
 236         if (walk_state->results == NULL) {
 237                 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 238                                   "Result stack underflow - State=%p\n",
 239                                   walk_state));
 240                 return (AE_AML_NO_OPERAND);
 241         }
 242 
 243         if (walk_state->result_size < ACPI_RESULTS_FRAME_OBJ_NUM) {
 244                 ACPI_ERROR((AE_INFO, "Insufficient result stack size"));
 245                 return (AE_AML_INTERNAL);
 246         }
 247 
 248         state = acpi_ut_pop_generic_state(&walk_state->results);
 249         acpi_ut_delete_generic_state(state);
 250 
 251         /* Decrease the length of result stack by the length of frame */
 252 
 253         walk_state->result_size -= ACPI_RESULTS_FRAME_OBJ_NUM;
 254 
 255         ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 256                           "Result=%p RemainingResults=%X State=%p\n",
 257                           state, walk_state->result_count, walk_state));
 258 
 259         return (AE_OK);
 260 }
 261 
 262 /*******************************************************************************
 263  *
 264  * FUNCTION:    acpi_ds_obj_stack_push
 265  *
 266  * PARAMETERS:  object              - Object to push
 267  *              walk_state          - Current Walk state
 268  *
 269  * RETURN:      Status
 270  *
 271  * DESCRIPTION: Push an object onto this walk's object/operand stack
 272  *
 273  ******************************************************************************/
 274 
 275 acpi_status
 276 acpi_ds_obj_stack_push(void *object, struct acpi_walk_state *walk_state)
 277 {
 278         ACPI_FUNCTION_NAME(ds_obj_stack_push);
 279 
 280         /* Check for stack overflow */
 281 
 282         if (walk_state->num_operands >= ACPI_OBJ_NUM_OPERANDS) {
 283                 ACPI_ERROR((AE_INFO,
 284                             "Object stack overflow! Obj=%p State=%p #Ops=%u",
 285                             object, walk_state, walk_state->num_operands));
 286                 return (AE_STACK_OVERFLOW);
 287         }
 288 
 289         /* Put the object onto the stack */
 290 
 291         walk_state->operands[walk_state->operand_index] = object;
 292         walk_state->num_operands++;
 293 
 294         /* For the usual order of filling the operand stack */
 295 
 296         walk_state->operand_index++;
 297 
 298         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
 299                           object,
 300                           acpi_ut_get_object_type_name((union
 301                                                         acpi_operand_object *)
 302                                                        object), walk_state,
 303                           walk_state->num_operands));
 304 
 305         return (AE_OK);
 306 }
 307 
 308 /*******************************************************************************
 309  *
 310  * FUNCTION:    acpi_ds_obj_stack_pop
 311  *
 312  * PARAMETERS:  pop_count           - Number of objects/entries to pop
 313  *              walk_state          - Current Walk state
 314  *
 315  * RETURN:      Status
 316  *
 317  * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT
 318  *              deleted by this routine.
 319  *
 320  ******************************************************************************/
 321 
 322 acpi_status
 323 acpi_ds_obj_stack_pop(u32 pop_count, struct acpi_walk_state *walk_state)
 324 {
 325         u32 i;
 326 
 327         ACPI_FUNCTION_NAME(ds_obj_stack_pop);
 328 
 329         for (i = 0; i < pop_count; i++) {
 330 
 331                 /* Check for stack underflow */
 332 
 333                 if (walk_state->num_operands == 0) {
 334                         ACPI_ERROR((AE_INFO,
 335                                     "Object stack underflow! Count=%X State=%p #Ops=%u",
 336                                     pop_count, walk_state,
 337                                     walk_state->num_operands));
 338                         return (AE_STACK_UNDERFLOW);
 339                 }
 340 
 341                 /* Just set the stack entry to null */
 342 
 343                 walk_state->num_operands--;
 344                 walk_state->operands[walk_state->num_operands] = NULL;
 345         }
 346 
 347         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%u\n",
 348                           pop_count, walk_state, walk_state->num_operands));
 349 
 350         return (AE_OK);
 351 }
 352 
 353 /*******************************************************************************
 354  *
 355  * FUNCTION:    acpi_ds_obj_stack_pop_and_delete
 356  *
 357  * PARAMETERS:  pop_count           - Number of objects/entries to pop
 358  *              walk_state          - Current Walk state
 359  *
 360  * RETURN:      Status
 361  *
 362  * DESCRIPTION: Pop this walk's object stack and delete each object that is
 363  *              popped off.
 364  *
 365  ******************************************************************************/
 366 
 367 void
 368 acpi_ds_obj_stack_pop_and_delete(u32 pop_count,
 369                                  struct acpi_walk_state *walk_state)
 370 {
 371         s32 i;
 372         union acpi_operand_object *obj_desc;
 373 
 374         ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete);
 375 
 376         if (pop_count == 0) {
 377                 return;
 378         }
 379 
 380         for (i = (s32)pop_count - 1; i >= 0; i--) {
 381                 if (walk_state->num_operands == 0) {
 382                         return;
 383                 }
 384 
 385                 /* Pop the stack and delete an object if present in this stack entry */
 386 
 387                 walk_state->num_operands--;
 388                 obj_desc = walk_state->operands[i];
 389                 if (obj_desc) {
 390                         acpi_ut_remove_reference(walk_state->operands[i]);
 391                         walk_state->operands[i] = NULL;
 392                 }
 393         }
 394 
 395         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
 396                           pop_count, walk_state, walk_state->num_operands));
 397 }
 398 
 399 /*******************************************************************************
 400  *
 401  * FUNCTION:    acpi_ds_get_current_walk_state
 402  *
 403  * PARAMETERS:  thread          - Get current active state for this Thread
 404  *
 405  * RETURN:      Pointer to the current walk state
 406  *
 407  * DESCRIPTION: Get the walk state that is at the head of the list (the "current"
 408  *              walk state.)
 409  *
 410  ******************************************************************************/
 411 
 412 struct acpi_walk_state *acpi_ds_get_current_walk_state(struct acpi_thread_state
 413                                                        *thread)
 414 {
 415         ACPI_FUNCTION_NAME(ds_get_current_walk_state);
 416 
 417         if (!thread) {
 418                 return (NULL);
 419         }
 420 
 421         ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Current WalkState %p\n",
 422                           thread->walk_state_list));
 423 
 424         return (thread->walk_state_list);
 425 }
 426 
 427 /*******************************************************************************
 428  *
 429  * FUNCTION:    acpi_ds_push_walk_state
 430  *
 431  * PARAMETERS:  walk_state      - State to push
 432  *              thread          - Thread state object
 433  *
 434  * RETURN:      None
 435  *
 436  * DESCRIPTION: Place the Thread state at the head of the state list
 437  *
 438  ******************************************************************************/
 439 
 440 void
 441 acpi_ds_push_walk_state(struct acpi_walk_state *walk_state,
 442                         struct acpi_thread_state *thread)
 443 {
 444         ACPI_FUNCTION_TRACE(ds_push_walk_state);
 445 
 446         walk_state->next = thread->walk_state_list;
 447         thread->walk_state_list = walk_state;
 448 
 449         return_VOID;
 450 }
 451 
 452 /*******************************************************************************
 453  *
 454  * FUNCTION:    acpi_ds_pop_walk_state
 455  *
 456  * PARAMETERS:  thread      - Current thread state
 457  *
 458  * RETURN:      A walk_state object popped from the thread's stack
 459  *
 460  * DESCRIPTION: Remove and return the walkstate object that is at the head of
 461  *              the walk stack for the given walk list. NULL indicates that
 462  *              the list is empty.
 463  *
 464  ******************************************************************************/
 465 
 466 struct acpi_walk_state *acpi_ds_pop_walk_state(struct acpi_thread_state *thread)
 467 {
 468         struct acpi_walk_state *walk_state;
 469 
 470         ACPI_FUNCTION_TRACE(ds_pop_walk_state);
 471 
 472         walk_state = thread->walk_state_list;
 473 
 474         if (walk_state) {
 475 
 476                 /* Next walk state becomes the current walk state */
 477 
 478                 thread->walk_state_list = walk_state->next;
 479 
 480                 /*
 481                  * Don't clear the NEXT field, this serves as an indicator
 482                  * that there is a parent WALK STATE
 483                  * Do Not: walk_state->Next = NULL;
 484                  */
 485         }
 486 
 487         return_PTR(walk_state);
 488 }
 489 
 490 /*******************************************************************************
 491  *
 492  * FUNCTION:    acpi_ds_create_walk_state
 493  *
 494  * PARAMETERS:  owner_id        - ID for object creation
 495  *              origin          - Starting point for this walk
 496  *              method_desc     - Method object
 497  *              thread          - Current thread state
 498  *
 499  * RETURN:      Pointer to the new walk state.
 500  *
 501  * DESCRIPTION: Allocate and initialize a new walk state. The current walk
 502  *              state is set to this new state.
 503  *
 504  ******************************************************************************/
 505 
 506 struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id,
 507                                                   union acpi_parse_object
 508                                                   *origin,
 509                                                   union acpi_operand_object
 510                                                   *method_desc,
 511                                                   struct acpi_thread_state
 512                                                   *thread)
 513 {
 514         struct acpi_walk_state *walk_state;
 515 
 516         ACPI_FUNCTION_TRACE(ds_create_walk_state);
 517 
 518         walk_state = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_walk_state));
 519         if (!walk_state) {
 520                 return_PTR(NULL);
 521         }
 522 
 523         walk_state->descriptor_type = ACPI_DESC_TYPE_WALK;
 524         walk_state->method_desc = method_desc;
 525         walk_state->owner_id = owner_id;
 526         walk_state->origin = origin;
 527         walk_state->thread = thread;
 528 
 529         walk_state->parser_state.start_op = origin;
 530 
 531         /* Init the method args/local */
 532 
 533 #ifndef ACPI_CONSTANT_EVAL_ONLY
 534         acpi_ds_method_data_init(walk_state);
 535 #endif
 536 
 537         /* Put the new state at the head of the walk list */
 538 
 539         if (thread) {
 540                 acpi_ds_push_walk_state(walk_state, thread);
 541         }
 542 
 543         return_PTR(walk_state);
 544 }
 545 
 546 /*******************************************************************************
 547  *
 548  * FUNCTION:    acpi_ds_init_aml_walk
 549  *
 550  * PARAMETERS:  walk_state      - New state to be initialized
 551  *              op              - Current parse op
 552  *              method_node     - Control method NS node, if any
 553  *              aml_start       - Start of AML
 554  *              aml_length      - Length of AML
 555  *              info            - Method info block (params, etc.)
 556  *              pass_number     - 1, 2, or 3
 557  *
 558  * RETURN:      Status
 559  *
 560  * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk
 561  *
 562  ******************************************************************************/
 563 
 564 acpi_status
 565 acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state,
 566                       union acpi_parse_object *op,
 567                       struct acpi_namespace_node *method_node,
 568                       u8 * aml_start,
 569                       u32 aml_length,
 570                       struct acpi_evaluate_info *info, u8 pass_number)
 571 {
 572         acpi_status status;
 573         struct acpi_parse_state *parser_state = &walk_state->parser_state;
 574         union acpi_parse_object *extra_op;
 575 
 576         ACPI_FUNCTION_TRACE(ds_init_aml_walk);
 577 
 578         walk_state->parser_state.aml =
 579             walk_state->parser_state.aml_start = aml_start;
 580         walk_state->parser_state.aml_end =
 581             walk_state->parser_state.pkg_end = aml_start + aml_length;
 582 
 583         /* The next_op of the next_walk will be the beginning of the method */
 584 
 585         walk_state->next_op = NULL;
 586         walk_state->pass_number = pass_number;
 587 
 588         if (info) {
 589                 walk_state->params = info->parameters;
 590                 walk_state->caller_return_desc = &info->return_object;
 591         }
 592 
 593         status = acpi_ps_init_scope(&walk_state->parser_state, op);
 594         if (ACPI_FAILURE(status)) {
 595                 return_ACPI_STATUS(status);
 596         }
 597 
 598         if (method_node) {
 599                 walk_state->parser_state.start_node = method_node;
 600                 walk_state->walk_type = ACPI_WALK_METHOD;
 601                 walk_state->method_node = method_node;
 602                 walk_state->method_desc =
 603                     acpi_ns_get_attached_object(method_node);
 604 
 605                 /* Push start scope on scope stack and make it current  */
 606 
 607                 status =
 608                     acpi_ds_scope_stack_push(method_node, ACPI_TYPE_METHOD,
 609                                              walk_state);
 610                 if (ACPI_FAILURE(status)) {
 611                         return_ACPI_STATUS(status);
 612                 }
 613 
 614                 /* Init the method arguments */
 615 
 616                 status = acpi_ds_method_data_init_args(walk_state->params,
 617                                                        ACPI_METHOD_NUM_ARGS,
 618                                                        walk_state);
 619                 if (ACPI_FAILURE(status)) {
 620                         return_ACPI_STATUS(status);
 621                 }
 622         } else {
 623                 /*
 624                  * Setup the current scope.
 625                  * Find a Named Op that has a namespace node associated with it.
 626                  * search upwards from this Op. Current scope is the first
 627                  * Op with a namespace node.
 628                  */
 629                 extra_op = parser_state->start_op;
 630                 while (extra_op && !extra_op->common.node) {
 631                         extra_op = extra_op->common.parent;
 632                 }
 633 
 634                 if (!extra_op) {
 635                         parser_state->start_node = NULL;
 636                 } else {
 637                         parser_state->start_node = extra_op->common.node;
 638                 }
 639 
 640                 if (parser_state->start_node) {
 641 
 642                         /* Push start scope on scope stack and make it current  */
 643 
 644                         status =
 645                             acpi_ds_scope_stack_push(parser_state->start_node,
 646                                                      parser_state->start_node->
 647                                                      type, walk_state);
 648                         if (ACPI_FAILURE(status)) {
 649                                 return_ACPI_STATUS(status);
 650                         }
 651                 }
 652         }
 653 
 654         status = acpi_ds_init_callbacks(walk_state, pass_number);
 655         return_ACPI_STATUS(status);
 656 }
 657 
 658 /*******************************************************************************
 659  *
 660  * FUNCTION:    acpi_ds_delete_walk_state
 661  *
 662  * PARAMETERS:  walk_state      - State to delete
 663  *
 664  * RETURN:      Status
 665  *
 666  * DESCRIPTION: Delete a walk state including all internal data structures
 667  *
 668  ******************************************************************************/
 669 
 670 void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state)
 671 {
 672         union acpi_generic_state *state;
 673 
 674         ACPI_FUNCTION_TRACE_PTR(ds_delete_walk_state, walk_state);
 675 
 676         if (!walk_state) {
 677                 return_VOID;
 678         }
 679 
 680         if (walk_state->descriptor_type != ACPI_DESC_TYPE_WALK) {
 681                 ACPI_ERROR((AE_INFO, "%p is not a valid walk state",
 682                             walk_state));
 683                 return_VOID;
 684         }
 685 
 686         /* There should not be any open scopes */
 687 
 688         if (walk_state->parser_state.scope) {
 689                 ACPI_ERROR((AE_INFO, "%p walk still has a scope list",
 690                             walk_state));
 691                 acpi_ps_cleanup_scope(&walk_state->parser_state);
 692         }
 693 
 694         /* Always must free any linked control states */
 695 
 696         while (walk_state->control_state) {
 697                 state = walk_state->control_state;
 698                 walk_state->control_state = state->common.next;
 699 
 700                 acpi_ut_delete_generic_state(state);
 701         }
 702 
 703         /* Always must free any linked parse states */
 704 
 705         while (walk_state->scope_info) {
 706                 state = walk_state->scope_info;
 707                 walk_state->scope_info = state->common.next;
 708 
 709                 acpi_ut_delete_generic_state(state);
 710         }
 711 
 712         /* Always must free any stacked result states */
 713 
 714         while (walk_state->results) {
 715                 state = walk_state->results;
 716                 walk_state->results = state->common.next;
 717 
 718                 acpi_ut_delete_generic_state(state);
 719         }
 720 
 721         ACPI_FREE(walk_state);
 722         return_VOID;
 723 }

/* [<][>][^][v][top][bottom][index][help] */