dswstate.c revision 306536
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 <contrib/dev/acpica/include/acpi.h>
45#include <contrib/dev/acpica/include/accommon.h>
46#include <contrib/dev/acpica/include/acparser.h>
47#include <contrib/dev/acpica/include/acdispat.h>
48#include <contrib/dev/acpica/include/acnamesp.h>
49
50#define _COMPONENT          ACPI_DISPATCHER
51        ACPI_MODULE_NAME    ("dswstate")
52
53/* Local prototypes */
54
55static ACPI_STATUS
56AcpiDsResultStackPush (
57    ACPI_WALK_STATE         *WalkState);
58
59static ACPI_STATUS
60AcpiDsResultStackPop (
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
77ACPI_STATUS
78AcpiDsResultPop (
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
159ACPI_STATUS
160AcpiDsResultPush (
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
236static ACPI_STATUS
237AcpiDsResultStackPush (
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
288static ACPI_STATUS
289AcpiDsResultStackPop (
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
341ACPI_STATUS
342AcpiDsObjStackPush (
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
390ACPI_STATUS
391AcpiDsObjStackPop (
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
440void
441AcpiDsObjStackPopAndDelete (
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
493ACPI_WALK_STATE *
494AcpiDsGetCurrentWalkState (
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
525void
526AcpiDsPushWalkState (
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
554ACPI_WALK_STATE *
555AcpiDsPopWalkState (
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
599ACPI_WALK_STATE *
600AcpiDsCreateWalkState (
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
661ACPI_STATUS
662AcpiDsInitAmlWalk (
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
779void
780AcpiDsDeleteWalkState (
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