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