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