dswstate.c revision 1.1.1.2 1 /******************************************************************************
2 *
3 * Module Name: dswstate - Dispatcher parse tree walk management routines
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2011, 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
45 #define __DSWSTATE_C__
46
47 #include "acpi.h"
48 #include "accommon.h"
49 #include "acparser.h"
50 #include "acdispat.h"
51 #include "acnamesp.h"
52
53 #define _COMPONENT ACPI_DISPATCHER
54 ACPI_MODULE_NAME ("dswstate")
55
56 /* Local prototypes */
57
58 static ACPI_STATUS
59 AcpiDsResultStackPush (
60 ACPI_WALK_STATE *WalkState);
61
62 static ACPI_STATUS
63 AcpiDsResultStackPop (
64 ACPI_WALK_STATE *WalkState);
65
66
67 /*******************************************************************************
68 *
69 * FUNCTION: AcpiDsResultPop
70 *
71 * PARAMETERS: Object - Where to return the popped object
72 * WalkState - Current Walk state
73 *
74 * RETURN: Status
75 *
76 * DESCRIPTION: Pop an object off the top of this walk's result stack
77 *
78 ******************************************************************************/
79
80 ACPI_STATUS
81 AcpiDsResultPop (
82 ACPI_OPERAND_OBJECT **Object,
83 ACPI_WALK_STATE *WalkState)
84 {
85 UINT32 Index;
86 ACPI_GENERIC_STATE *State;
87 ACPI_STATUS Status;
88
89
90 ACPI_FUNCTION_NAME (DsResultPop);
91
92
93 State = WalkState->Results;
94
95 /* Incorrect state of result stack */
96
97 if (State && !WalkState->ResultCount)
98 {
99 ACPI_ERROR ((AE_INFO, "No results on result stack"));
100 return (AE_AML_INTERNAL);
101 }
102
103 if (!State && WalkState->ResultCount)
104 {
105 ACPI_ERROR ((AE_INFO, "No result state for result stack"));
106 return (AE_AML_INTERNAL);
107 }
108
109 /* Empty result stack */
110
111 if (!State)
112 {
113 ACPI_ERROR ((AE_INFO, "Result stack is empty! State=%p", WalkState));
114 return (AE_AML_NO_RETURN_VALUE);
115 }
116
117 /* Return object of the top element and clean that top element result stack */
118
119 WalkState->ResultCount--;
120 Index = (UINT32) WalkState->ResultCount % ACPI_RESULTS_FRAME_OBJ_NUM;
121
122 *Object = State->Results.ObjDesc [Index];
123 if (!*Object)
124 {
125 ACPI_ERROR ((AE_INFO, "No result objects on result stack, State=%p",
126 WalkState));
127 return (AE_AML_NO_RETURN_VALUE);
128 }
129
130 State->Results.ObjDesc [Index] = NULL;
131 if (Index == 0)
132 {
133 Status = AcpiDsResultStackPop (WalkState);
134 if (ACPI_FAILURE (Status))
135 {
136 return (Status);
137 }
138 }
139
140 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
141 "Obj=%p [%s] Index=%X State=%p Num=%X\n", *Object,
142 AcpiUtGetObjectTypeName (*Object),
143 Index, WalkState, WalkState->ResultCount));
144
145 return (AE_OK);
146 }
147
148
149 /*******************************************************************************
150 *
151 * FUNCTION: AcpiDsResultPush
152 *
153 * PARAMETERS: Object - Where to return the popped object
154 * WalkState - Current Walk state
155 *
156 * RETURN: Status
157 *
158 * DESCRIPTION: Push an object onto the current result stack
159 *
160 ******************************************************************************/
161
162 ACPI_STATUS
163 AcpiDsResultPush (
164 ACPI_OPERAND_OBJECT *Object,
165 ACPI_WALK_STATE *WalkState)
166 {
167 ACPI_GENERIC_STATE *State;
168 ACPI_STATUS Status;
169 UINT32 Index;
170
171
172 ACPI_FUNCTION_NAME (DsResultPush);
173
174
175 if (WalkState->ResultCount > WalkState->ResultSize)
176 {
177 ACPI_ERROR ((AE_INFO, "Result stack is full"));
178 return (AE_AML_INTERNAL);
179 }
180 else if (WalkState->ResultCount == WalkState->ResultSize)
181 {
182 /* Extend the result stack */
183
184 Status = AcpiDsResultStackPush (WalkState);
185 if (ACPI_FAILURE (Status))
186 {
187 ACPI_ERROR ((AE_INFO, "Failed to extend the result stack"));
188 return (Status);
189 }
190 }
191
192 if (!(WalkState->ResultCount < WalkState->ResultSize))
193 {
194 ACPI_ERROR ((AE_INFO, "No free elements in result stack"));
195 return (AE_AML_INTERNAL);
196 }
197
198 State = WalkState->Results;
199 if (!State)
200 {
201 ACPI_ERROR ((AE_INFO, "No result stack frame during push"));
202 return (AE_AML_INTERNAL);
203 }
204
205 if (!Object)
206 {
207 ACPI_ERROR ((AE_INFO,
208 "Null Object! Obj=%p State=%p Num=%u",
209 Object, WalkState, WalkState->ResultCount));
210 return (AE_BAD_PARAMETER);
211 }
212
213 /* Assign the address of object to the top free element of result stack */
214
215 Index = (UINT32) WalkState->ResultCount % ACPI_RESULTS_FRAME_OBJ_NUM;
216 State->Results.ObjDesc [Index] = Object;
217 WalkState->ResultCount++;
218
219 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
220 Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object),
221 WalkState, WalkState->ResultCount, WalkState->CurrentResult));
222
223 return (AE_OK);
224 }
225
226
227 /*******************************************************************************
228 *
229 * FUNCTION: AcpiDsResultStackPush
230 *
231 * PARAMETERS: WalkState - Current Walk state
232 *
233 * RETURN: Status
234 *
235 * DESCRIPTION: Push an object onto the WalkState result stack
236 *
237 ******************************************************************************/
238
239 static ACPI_STATUS
240 AcpiDsResultStackPush (
241 ACPI_WALK_STATE *WalkState)
242 {
243 ACPI_GENERIC_STATE *State;
244
245
246 ACPI_FUNCTION_NAME (DsResultStackPush);
247
248
249 /* Check for stack overflow */
250
251 if (((UINT32) WalkState->ResultSize + ACPI_RESULTS_FRAME_OBJ_NUM) >
252 ACPI_RESULTS_OBJ_NUM_MAX)
253 {
254 ACPI_ERROR ((AE_INFO, "Result stack overflow: State=%p Num=%u",
255 WalkState, WalkState->ResultSize));
256 return (AE_STACK_OVERFLOW);
257 }
258
259 State = AcpiUtCreateGenericState ();
260 if (!State)
261 {
262 return (AE_NO_MEMORY);
263 }
264
265 State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_RESULT;
266 AcpiUtPushGenericState (&WalkState->Results, State);
267
268 /* Increase the length of the result stack by the length of frame */
269
270 WalkState->ResultSize += ACPI_RESULTS_FRAME_OBJ_NUM;
271
272 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Results=%p State=%p\n",
273 State, WalkState));
274
275 return (AE_OK);
276 }
277
278
279 /*******************************************************************************
280 *
281 * FUNCTION: AcpiDsResultStackPop
282 *
283 * PARAMETERS: WalkState - Current Walk state
284 *
285 * RETURN: Status
286 *
287 * DESCRIPTION: Pop an object off of the WalkState result stack
288 *
289 ******************************************************************************/
290
291 static ACPI_STATUS
292 AcpiDsResultStackPop (
293 ACPI_WALK_STATE *WalkState)
294 {
295 ACPI_GENERIC_STATE *State;
296
297
298 ACPI_FUNCTION_NAME (DsResultStackPop);
299
300
301 /* Check for stack underflow */
302
303 if (WalkState->Results == NULL)
304 {
305 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Result stack underflow - State=%p\n",
306 WalkState));
307 return (AE_AML_NO_OPERAND);
308 }
309
310 if (WalkState->ResultSize < ACPI_RESULTS_FRAME_OBJ_NUM)
311 {
312 ACPI_ERROR ((AE_INFO, "Insufficient result stack size"));
313 return (AE_AML_INTERNAL);
314 }
315
316 State = AcpiUtPopGenericState (&WalkState->Results);
317 AcpiUtDeleteGenericState (State);
318
319 /* Decrease the length of result stack by the length of frame */
320
321 WalkState->ResultSize -= ACPI_RESULTS_FRAME_OBJ_NUM;
322
323 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
324 "Result=%p RemainingResults=%X State=%p\n",
325 State, WalkState->ResultCount, WalkState));
326
327 return (AE_OK);
328 }
329
330
331 /*******************************************************************************
332 *
333 * FUNCTION: AcpiDsObjStackPush
334 *
335 * PARAMETERS: Object - Object to push
336 * WalkState - Current Walk state
337 *
338 * RETURN: Status
339 *
340 * DESCRIPTION: Push an object onto this walk's object/operand stack
341 *
342 ******************************************************************************/
343
344 ACPI_STATUS
345 AcpiDsObjStackPush (
346 void *Object,
347 ACPI_WALK_STATE *WalkState)
348 {
349 ACPI_FUNCTION_NAME (DsObjStackPush);
350
351
352 /* Check for stack overflow */
353
354 if (WalkState->NumOperands >= ACPI_OBJ_NUM_OPERANDS)
355 {
356 ACPI_ERROR ((AE_INFO,
357 "Object stack overflow! Obj=%p State=%p #Ops=%u",
358 Object, WalkState, WalkState->NumOperands));
359 return (AE_STACK_OVERFLOW);
360 }
361
362 /* Put the object onto the stack */
363
364 WalkState->Operands [WalkState->OperandIndex] = Object;
365 WalkState->NumOperands++;
366
367 /* For the usual order of filling the operand stack */
368
369 WalkState->OperandIndex++;
370
371 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
372 Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object),
373 WalkState, WalkState->NumOperands));
374
375 return (AE_OK);
376 }
377
378
379 /*******************************************************************************
380 *
381 * FUNCTION: AcpiDsObjStackPop
382 *
383 * PARAMETERS: PopCount - Number of objects/entries to pop
384 * WalkState - Current Walk state
385 *
386 * RETURN: Status
387 *
388 * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT
389 * deleted by this routine.
390 *
391 ******************************************************************************/
392
393 ACPI_STATUS
394 AcpiDsObjStackPop (
395 UINT32 PopCount,
396 ACPI_WALK_STATE *WalkState)
397 {
398 UINT32 i;
399
400
401 ACPI_FUNCTION_NAME (DsObjStackPop);
402
403
404 for (i = 0; i < PopCount; i++)
405 {
406 /* Check for stack underflow */
407
408 if (WalkState->NumOperands == 0)
409 {
410 ACPI_ERROR ((AE_INFO,
411 "Object stack underflow! Count=%X State=%p #Ops=%u",
412 PopCount, WalkState, WalkState->NumOperands));
413 return (AE_STACK_UNDERFLOW);
414 }
415
416 /* Just set the stack entry to null */
417
418 WalkState->NumOperands--;
419 WalkState->Operands [WalkState->NumOperands] = NULL;
420 }
421
422 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%u\n",
423 PopCount, WalkState, WalkState->NumOperands));
424
425 return (AE_OK);
426 }
427
428
429 /*******************************************************************************
430 *
431 * FUNCTION: AcpiDsObjStackPopAndDelete
432 *
433 * PARAMETERS: PopCount - Number of objects/entries to pop
434 * WalkState - Current Walk state
435 *
436 * RETURN: Status
437 *
438 * DESCRIPTION: Pop this walk's object stack and delete each object that is
439 * popped off.
440 *
441 ******************************************************************************/
442
443 void
444 AcpiDsObjStackPopAndDelete (
445 UINT32 PopCount,
446 ACPI_WALK_STATE *WalkState)
447 {
448 INT32 i;
449 ACPI_OPERAND_OBJECT *ObjDesc;
450
451
452 ACPI_FUNCTION_NAME (DsObjStackPopAndDelete);
453
454
455 if (PopCount == 0)
456 {
457 return;
458 }
459
460 for (i = (INT32) PopCount - 1; i >= 0; i--)
461 {
462 if (WalkState->NumOperands == 0)
463 {
464 return;
465 }
466
467 /* Pop the stack and delete an object if present in this stack entry */
468
469 WalkState->NumOperands--;
470 ObjDesc = WalkState->Operands [i];
471 if (ObjDesc)
472 {
473 AcpiUtRemoveReference (WalkState->Operands [i]);
474 WalkState->Operands [i] = NULL;
475 }
476 }
477
478 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
479 PopCount, WalkState, WalkState->NumOperands));
480 }
481
482
483 /*******************************************************************************
484 *
485 * FUNCTION: AcpiDsGetCurrentWalkState
486 *
487 * PARAMETERS: Thread - Get current active state for this Thread
488 *
489 * RETURN: Pointer to the current walk state
490 *
491 * DESCRIPTION: Get the walk state that is at the head of the list (the "current"
492 * walk state.)
493 *
494 ******************************************************************************/
495
496 ACPI_WALK_STATE *
497 AcpiDsGetCurrentWalkState (
498 ACPI_THREAD_STATE *Thread)
499 {
500 ACPI_FUNCTION_NAME (DsGetCurrentWalkState);
501
502
503 if (!Thread)
504 {
505 return (NULL);
506 }
507
508 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Current WalkState %p\n",
509 Thread->WalkStateList));
510
511 return (Thread->WalkStateList);
512 }
513
514
515 /*******************************************************************************
516 *
517 * FUNCTION: AcpiDsPushWalkState
518 *
519 * PARAMETERS: WalkState - State to push
520 * Thread - Thread state object
521 *
522 * RETURN: None
523 *
524 * DESCRIPTION: Place the Thread state at the head of the state list
525 *
526 ******************************************************************************/
527
528 void
529 AcpiDsPushWalkState (
530 ACPI_WALK_STATE *WalkState,
531 ACPI_THREAD_STATE *Thread)
532 {
533 ACPI_FUNCTION_TRACE (DsPushWalkState);
534
535
536 WalkState->Next = Thread->WalkStateList;
537 Thread->WalkStateList = WalkState;
538
539 return_VOID;
540 }
541
542
543 /*******************************************************************************
544 *
545 * FUNCTION: AcpiDsPopWalkState
546 *
547 * PARAMETERS: Thread - Current thread state
548 *
549 * RETURN: A WalkState object popped from the thread's stack
550 *
551 * DESCRIPTION: Remove and return the walkstate object that is at the head of
552 * the walk stack for the given walk list. NULL indicates that
553 * the list is empty.
554 *
555 ******************************************************************************/
556
557 ACPI_WALK_STATE *
558 AcpiDsPopWalkState (
559 ACPI_THREAD_STATE *Thread)
560 {
561 ACPI_WALK_STATE *WalkState;
562
563
564 ACPI_FUNCTION_TRACE (DsPopWalkState);
565
566
567 WalkState = Thread->WalkStateList;
568
569 if (WalkState)
570 {
571 /* Next walk state becomes the current walk state */
572
573 Thread->WalkStateList = WalkState->Next;
574
575 /*
576 * Don't clear the NEXT field, this serves as an indicator
577 * that there is a parent WALK STATE
578 * Do Not: WalkState->Next = NULL;
579 */
580 }
581
582 return_PTR (WalkState);
583 }
584
585
586 /*******************************************************************************
587 *
588 * FUNCTION: AcpiDsCreateWalkState
589 *
590 * PARAMETERS: OwnerId - ID for object creation
591 * Origin - Starting point for this walk
592 * MethodDesc - Method object
593 * Thread - Current thread state
594 *
595 * RETURN: Pointer to the new walk state.
596 *
597 * DESCRIPTION: Allocate and initialize a new walk state. The current walk
598 * state is set to this new state.
599 *
600 ******************************************************************************/
601
602 ACPI_WALK_STATE *
603 AcpiDsCreateWalkState (
604 ACPI_OWNER_ID OwnerId,
605 ACPI_PARSE_OBJECT *Origin,
606 ACPI_OPERAND_OBJECT *MethodDesc,
607 ACPI_THREAD_STATE *Thread)
608 {
609 ACPI_WALK_STATE *WalkState;
610
611
612 ACPI_FUNCTION_TRACE (DsCreateWalkState);
613
614
615 WalkState = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_WALK_STATE));
616 if (!WalkState)
617 {
618 return_PTR (NULL);
619 }
620
621 WalkState->DescriptorType = ACPI_DESC_TYPE_WALK;
622 WalkState->MethodDesc = MethodDesc;
623 WalkState->OwnerId = OwnerId;
624 WalkState->Origin = Origin;
625 WalkState->Thread = Thread;
626
627 WalkState->ParserState.StartOp = Origin;
628
629 /* Init the method args/local */
630
631 #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
632 AcpiDsMethodDataInit (WalkState);
633 #endif
634
635 /* Put the new state at the head of the walk list */
636
637 if (Thread)
638 {
639 AcpiDsPushWalkState (WalkState, Thread);
640 }
641
642 return_PTR (WalkState);
643 }
644
645
646 /*******************************************************************************
647 *
648 * FUNCTION: AcpiDsInitAmlWalk
649 *
650 * PARAMETERS: WalkState - New state to be initialized
651 * Op - Current parse op
652 * MethodNode - Control method NS node, if any
653 * AmlStart - Start of AML
654 * AmlLength - Length of AML
655 * Info - Method info block (params, etc.)
656 * PassNumber - 1, 2, or 3
657 *
658 * RETURN: Status
659 *
660 * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk
661 *
662 ******************************************************************************/
663
664 ACPI_STATUS
665 AcpiDsInitAmlWalk (
666 ACPI_WALK_STATE *WalkState,
667 ACPI_PARSE_OBJECT *Op,
668 ACPI_NAMESPACE_NODE *MethodNode,
669 UINT8 *AmlStart,
670 UINT32 AmlLength,
671 ACPI_EVALUATE_INFO *Info,
672 UINT8 PassNumber)
673 {
674 ACPI_STATUS Status;
675 ACPI_PARSE_STATE *ParserState = &WalkState->ParserState;
676 ACPI_PARSE_OBJECT *ExtraOp;
677
678
679 ACPI_FUNCTION_TRACE (DsInitAmlWalk);
680
681
682 WalkState->ParserState.Aml =
683 WalkState->ParserState.AmlStart = AmlStart;
684 WalkState->ParserState.AmlEnd =
685 WalkState->ParserState.PkgEnd = AmlStart + AmlLength;
686
687 /* The NextOp of the NextWalk will be the beginning of the method */
688
689 WalkState->NextOp = NULL;
690 WalkState->PassNumber = PassNumber;
691
692 if (Info)
693 {
694 WalkState->Params = Info->Parameters;
695 WalkState->CallerReturnDesc = &Info->ReturnObject;
696 }
697
698 Status = AcpiPsInitScope (&WalkState->ParserState, Op);
699 if (ACPI_FAILURE (Status))
700 {
701 return_ACPI_STATUS (Status);
702 }
703
704 if (MethodNode)
705 {
706 WalkState->ParserState.StartNode = MethodNode;
707 WalkState->WalkType = ACPI_WALK_METHOD;
708 WalkState->MethodNode = MethodNode;
709 WalkState->MethodDesc = AcpiNsGetAttachedObject (MethodNode);
710
711 /* Push start scope on scope stack and make it current */
712
713 Status = AcpiDsScopeStackPush (MethodNode, ACPI_TYPE_METHOD, WalkState);
714 if (ACPI_FAILURE (Status))
715 {
716 return_ACPI_STATUS (Status);
717 }
718
719 /* Init the method arguments */
720
721 Status = AcpiDsMethodDataInitArgs (WalkState->Params,
722 ACPI_METHOD_NUM_ARGS, WalkState);
723 if (ACPI_FAILURE (Status))
724 {
725 return_ACPI_STATUS (Status);
726 }
727 }
728 else
729 {
730 /*
731 * Setup the current scope.
732 * Find a Named Op that has a namespace node associated with it.
733 * search upwards from this Op. Current scope is the first
734 * Op with a namespace node.
735 */
736 ExtraOp = ParserState->StartOp;
737 while (ExtraOp && !ExtraOp->Common.Node)
738 {
739 ExtraOp = ExtraOp->Common.Parent;
740 }
741
742 if (!ExtraOp)
743 {
744 ParserState->StartNode = NULL;
745 }
746 else
747 {
748 ParserState->StartNode = ExtraOp->Common.Node;
749 }
750
751 if (ParserState->StartNode)
752 {
753 /* Push start scope on scope stack and make it current */
754
755 Status = AcpiDsScopeStackPush (ParserState->StartNode,
756 ParserState->StartNode->Type, WalkState);
757 if (ACPI_FAILURE (Status))
758 {
759 return_ACPI_STATUS (Status);
760 }
761 }
762 }
763
764 Status = AcpiDsInitCallbacks (WalkState, PassNumber);
765 return_ACPI_STATUS (Status);
766 }
767
768
769 /*******************************************************************************
770 *
771 * FUNCTION: AcpiDsDeleteWalkState
772 *
773 * PARAMETERS: WalkState - State to delete
774 *
775 * RETURN: Status
776 *
777 * DESCRIPTION: Delete a walk state including all internal data structures
778 *
779 ******************************************************************************/
780
781 void
782 AcpiDsDeleteWalkState (
783 ACPI_WALK_STATE *WalkState)
784 {
785 ACPI_GENERIC_STATE *State;
786
787
788 ACPI_FUNCTION_TRACE_PTR (DsDeleteWalkState, WalkState);
789
790
791 if (!WalkState)
792 {
793 return;
794 }
795
796 if (WalkState->DescriptorType != ACPI_DESC_TYPE_WALK)
797 {
798 ACPI_ERROR ((AE_INFO, "%p is not a valid walk state",
799 WalkState));
800 return;
801 }
802
803 /* There should not be any open scopes */
804
805 if (WalkState->ParserState.Scope)
806 {
807 ACPI_ERROR ((AE_INFO, "%p walk still has a scope list",
808 WalkState));
809 AcpiPsCleanupScope (&WalkState->ParserState);
810 }
811
812 /* Always must free any linked control states */
813
814 while (WalkState->ControlState)
815 {
816 State = WalkState->ControlState;
817 WalkState->ControlState = State->Common.Next;
818
819 AcpiUtDeleteGenericState (State);
820 }
821
822 /* Always must free any linked parse states */
823
824 while (WalkState->ScopeInfo)
825 {
826 State = WalkState->ScopeInfo;
827 WalkState->ScopeInfo = State->Common.Next;
828
829 AcpiUtDeleteGenericState (State);
830 }
831
832 /* Always must free any stacked result states */
833
834 while (WalkState->Results)
835 {
836 State = WalkState->Results;
837 WalkState->Results = State->Common.Next;
838
839 AcpiUtDeleteGenericState (State);
840 }
841
842 ACPI_FREE (WalkState);
843 return_VOID;
844 }
845
846
847