psargs.c revision 217365
1/******************************************************************************
2 *
3 * Module Name: psargs - Parse AML opcode arguments
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#define __PSARGS_C__
45
46#include <contrib/dev/acpica/include/acpi.h>
47#include <contrib/dev/acpica/include/accommon.h>
48#include <contrib/dev/acpica/include/acparser.h>
49#include <contrib/dev/acpica/include/amlcode.h>
50#include <contrib/dev/acpica/include/acnamesp.h>
51#include <contrib/dev/acpica/include/acdispat.h>
52
53#define _COMPONENT          ACPI_PARSER
54        ACPI_MODULE_NAME    ("psargs")
55
56/* Local prototypes */
57
58static UINT32
59AcpiPsGetNextPackageLength (
60    ACPI_PARSE_STATE        *ParserState);
61
62static ACPI_PARSE_OBJECT *
63AcpiPsGetNextField (
64    ACPI_PARSE_STATE        *ParserState);
65
66
67/*******************************************************************************
68 *
69 * FUNCTION:    AcpiPsGetNextPackageLength
70 *
71 * PARAMETERS:  ParserState         - Current parser state object
72 *
73 * RETURN:      Decoded package length. On completion, the AML pointer points
74 *              past the length byte or bytes.
75 *
76 * DESCRIPTION: Decode and return a package length field.
77 *              Note: Largest package length is 28 bits, from ACPI specification
78 *
79 ******************************************************************************/
80
81static UINT32
82AcpiPsGetNextPackageLength (
83    ACPI_PARSE_STATE        *ParserState)
84{
85    UINT8                   *Aml = ParserState->Aml;
86    UINT32                  PackageLength = 0;
87    UINT32                  ByteCount;
88    UINT8                   ByteZeroMask = 0x3F; /* Default [0:5] */
89
90
91    ACPI_FUNCTION_TRACE (PsGetNextPackageLength);
92
93
94    /*
95     * Byte 0 bits [6:7] contain the number of additional bytes
96     * used to encode the package length, either 0,1,2, or 3
97     */
98    ByteCount = (Aml[0] >> 6);
99    ParserState->Aml += ((ACPI_SIZE) ByteCount + 1);
100
101    /* Get bytes 3, 2, 1 as needed */
102
103    while (ByteCount)
104    {
105        /*
106         * Final bit positions for the package length bytes:
107         *      Byte3->[20:27]
108         *      Byte2->[12:19]
109         *      Byte1->[04:11]
110         *      Byte0->[00:03]
111         */
112        PackageLength |= (Aml[ByteCount] << ((ByteCount << 3) - 4));
113
114        ByteZeroMask = 0x0F; /* Use bits [0:3] of byte 0 */
115        ByteCount--;
116    }
117
118    /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
119
120    PackageLength |= (Aml[0] & ByteZeroMask);
121    return_UINT32 (PackageLength);
122}
123
124
125/*******************************************************************************
126 *
127 * FUNCTION:    AcpiPsGetNextPackageEnd
128 *
129 * PARAMETERS:  ParserState         - Current parser state object
130 *
131 * RETURN:      Pointer to end-of-package +1
132 *
133 * DESCRIPTION: Get next package length and return a pointer past the end of
134 *              the package.  Consumes the package length field
135 *
136 ******************************************************************************/
137
138UINT8 *
139AcpiPsGetNextPackageEnd (
140    ACPI_PARSE_STATE        *ParserState)
141{
142    UINT8                   *Start = ParserState->Aml;
143    UINT32                  PackageLength;
144
145
146    ACPI_FUNCTION_TRACE (PsGetNextPackageEnd);
147
148
149    /* Function below updates ParserState->Aml */
150
151    PackageLength = AcpiPsGetNextPackageLength (ParserState);
152
153    return_PTR (Start + PackageLength); /* end of package */
154}
155
156
157/*******************************************************************************
158 *
159 * FUNCTION:    AcpiPsGetNextNamestring
160 *
161 * PARAMETERS:  ParserState         - Current parser state object
162 *
163 * RETURN:      Pointer to the start of the name string (pointer points into
164 *              the AML.
165 *
166 * DESCRIPTION: Get next raw namestring within the AML stream.  Handles all name
167 *              prefix characters.  Set parser state to point past the string.
168 *              (Name is consumed from the AML.)
169 *
170 ******************************************************************************/
171
172char *
173AcpiPsGetNextNamestring (
174    ACPI_PARSE_STATE        *ParserState)
175{
176    UINT8                   *Start = ParserState->Aml;
177    UINT8                   *End = ParserState->Aml;
178
179
180    ACPI_FUNCTION_TRACE (PsGetNextNamestring);
181
182
183    /* Point past any namestring prefix characters (backslash or carat) */
184
185    while (AcpiPsIsPrefixChar (*End))
186    {
187        End++;
188    }
189
190    /* Decode the path prefix character */
191
192    switch (*End)
193    {
194    case 0:
195
196        /* NullName */
197
198        if (End == Start)
199        {
200            Start = NULL;
201        }
202        End++;
203        break;
204
205    case AML_DUAL_NAME_PREFIX:
206
207        /* Two name segments */
208
209        End += 1 + (2 * ACPI_NAME_SIZE);
210        break;
211
212    case AML_MULTI_NAME_PREFIX_OP:
213
214        /* Multiple name segments, 4 chars each, count in next byte */
215
216        End += 2 + (*(End + 1) * ACPI_NAME_SIZE);
217        break;
218
219    default:
220
221        /* Single name segment */
222
223        End += ACPI_NAME_SIZE;
224        break;
225    }
226
227    ParserState->Aml = End;
228    return_PTR ((char *) Start);
229}
230
231
232/*******************************************************************************
233 *
234 * FUNCTION:    AcpiPsGetNextNamepath
235 *
236 * PARAMETERS:  ParserState         - Current parser state object
237 *              Arg                 - Where the namepath will be stored
238 *              ArgCount            - If the namepath points to a control method
239 *                                    the method's argument is returned here.
240 *              PossibleMethodCall  - Whether the namepath can possibly be the
241 *                                    start of a method call
242 *
243 * RETURN:      Status
244 *
245 * DESCRIPTION: Get next name (if method call, return # of required args).
246 *              Names are looked up in the internal namespace to determine
247 *              if the name represents a control method.  If a method
248 *              is found, the number of arguments to the method is returned.
249 *              This information is critical for parsing to continue correctly.
250 *
251 ******************************************************************************/
252
253ACPI_STATUS
254AcpiPsGetNextNamepath (
255    ACPI_WALK_STATE         *WalkState,
256    ACPI_PARSE_STATE        *ParserState,
257    ACPI_PARSE_OBJECT       *Arg,
258    BOOLEAN                 PossibleMethodCall)
259{
260    ACPI_STATUS             Status;
261    char                    *Path;
262    ACPI_PARSE_OBJECT       *NameOp;
263    ACPI_OPERAND_OBJECT     *MethodDesc;
264    ACPI_NAMESPACE_NODE     *Node;
265    UINT8                   *Start = ParserState->Aml;
266
267
268    ACPI_FUNCTION_TRACE (PsGetNextNamepath);
269
270
271    Path = AcpiPsGetNextNamestring (ParserState);
272    AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
273
274    /* Null path case is allowed, just exit */
275
276    if (!Path)
277    {
278        Arg->Common.Value.Name = Path;
279        return_ACPI_STATUS (AE_OK);
280    }
281
282    /*
283     * Lookup the name in the internal namespace, starting with the current
284     * scope. We don't want to add anything new to the namespace here,
285     * however, so we use MODE_EXECUTE.
286     * Allow searching of the parent tree, but don't open a new scope -
287     * we just want to lookup the object (must be mode EXECUTE to perform
288     * the upsearch)
289     */
290    Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
291                ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
292                ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
293
294    /*
295     * If this name is a control method invocation, we must
296     * setup the method call
297     */
298    if (ACPI_SUCCESS (Status) &&
299        PossibleMethodCall &&
300        (Node->Type == ACPI_TYPE_METHOD))
301    {
302        if (WalkState->Opcode == AML_UNLOAD_OP)
303        {
304            /*
305             * AcpiPsGetNextNamestring has increased the AML pointer,
306             * so we need to restore the saved AML pointer for method call.
307             */
308            WalkState->ParserState.Aml = Start;
309            WalkState->ArgCount = 1;
310            AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
311            return_ACPI_STATUS (AE_OK);
312        }
313
314        /* This name is actually a control method invocation */
315
316        MethodDesc = AcpiNsGetAttachedObject (Node);
317        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
318            "Control Method - %p Desc %p Path=%p\n", Node, MethodDesc, Path));
319
320        NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
321        if (!NameOp)
322        {
323            return_ACPI_STATUS (AE_NO_MEMORY);
324        }
325
326        /* Change Arg into a METHOD CALL and attach name to it */
327
328        AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
329        NameOp->Common.Value.Name = Path;
330
331        /* Point METHODCALL/NAME to the METHOD Node */
332
333        NameOp->Common.Node = Node;
334        AcpiPsAppendArg (Arg, NameOp);
335
336        if (!MethodDesc)
337        {
338            ACPI_ERROR ((AE_INFO,
339                "Control Method %p has no attached object",
340                Node));
341            return_ACPI_STATUS (AE_AML_INTERNAL);
342        }
343
344        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
345            "Control Method - %p Args %X\n",
346            Node, MethodDesc->Method.ParamCount));
347
348        /* Get the number of arguments to expect */
349
350        WalkState->ArgCount = MethodDesc->Method.ParamCount;
351        return_ACPI_STATUS (AE_OK);
352    }
353
354    /*
355     * Special handling if the name was not found during the lookup -
356     * some NotFound cases are allowed
357     */
358    if (Status == AE_NOT_FOUND)
359    {
360        /* 1) NotFound is ok during load pass 1/2 (allow forward references) */
361
362        if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) !=
363                ACPI_PARSE_EXECUTE)
364        {
365            Status = AE_OK;
366        }
367
368        /* 2) NotFound during a CondRefOf(x) is ok by definition */
369
370        else if (WalkState->Op->Common.AmlOpcode == AML_COND_REF_OF_OP)
371        {
372            Status = AE_OK;
373        }
374
375        /*
376         * 3) NotFound while building a Package is ok at this point, we
377         * may flag as an error later if slack mode is not enabled.
378         * (Some ASL code depends on allowing this behavior)
379         */
380        else if ((Arg->Common.Parent) &&
381            ((Arg->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
382             (Arg->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)))
383        {
384            Status = AE_OK;
385        }
386    }
387
388    /* Final exception check (may have been changed from code above) */
389
390    if (ACPI_FAILURE (Status))
391    {
392        ACPI_ERROR_NAMESPACE (Path, Status);
393
394        if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) ==
395                ACPI_PARSE_EXECUTE)
396        {
397            /* Report a control method execution error */
398
399            Status = AcpiDsMethodError (Status, WalkState);
400        }
401    }
402
403    /* Save the namepath */
404
405    Arg->Common.Value.Name = Path;
406    return_ACPI_STATUS (Status);
407}
408
409
410/*******************************************************************************
411 *
412 * FUNCTION:    AcpiPsGetNextSimpleArg
413 *
414 * PARAMETERS:  ParserState         - Current parser state object
415 *              ArgType             - The argument type (AML_*_ARG)
416 *              Arg                 - Where the argument is returned
417 *
418 * RETURN:      None
419 *
420 * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
421 *
422 ******************************************************************************/
423
424void
425AcpiPsGetNextSimpleArg (
426    ACPI_PARSE_STATE        *ParserState,
427    UINT32                  ArgType,
428    ACPI_PARSE_OBJECT       *Arg)
429{
430    UINT32                  Length;
431    UINT16                  Opcode;
432    UINT8                   *Aml = ParserState->Aml;
433
434
435    ACPI_FUNCTION_TRACE_U32 (PsGetNextSimpleArg, ArgType);
436
437
438    switch (ArgType)
439    {
440    case ARGP_BYTEDATA:
441
442        /* Get 1 byte from the AML stream */
443
444        Opcode = AML_BYTE_OP;
445        Arg->Common.Value.Integer = (UINT64) *Aml;
446        Length = 1;
447        break;
448
449
450    case ARGP_WORDDATA:
451
452        /* Get 2 bytes from the AML stream */
453
454        Opcode = AML_WORD_OP;
455        ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml);
456        Length = 2;
457        break;
458
459
460    case ARGP_DWORDDATA:
461
462        /* Get 4 bytes from the AML stream */
463
464        Opcode = AML_DWORD_OP;
465        ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml);
466        Length = 4;
467        break;
468
469
470    case ARGP_QWORDDATA:
471
472        /* Get 8 bytes from the AML stream */
473
474        Opcode = AML_QWORD_OP;
475        ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml);
476        Length = 8;
477        break;
478
479
480    case ARGP_CHARLIST:
481
482        /* Get a pointer to the string, point past the string */
483
484        Opcode = AML_STRING_OP;
485        Arg->Common.Value.String = ACPI_CAST_PTR (char, Aml);
486
487        /* Find the null terminator */
488
489        Length = 0;
490        while (Aml[Length])
491        {
492            Length++;
493        }
494        Length++;
495        break;
496
497
498    case ARGP_NAME:
499    case ARGP_NAMESTRING:
500
501        AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
502        Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
503        return_VOID;
504
505
506    default:
507
508        ACPI_ERROR ((AE_INFO, "Invalid ArgType 0x%X", ArgType));
509        return_VOID;
510    }
511
512    AcpiPsInitOp (Arg, Opcode);
513    ParserState->Aml += Length;
514    return_VOID;
515}
516
517
518/*******************************************************************************
519 *
520 * FUNCTION:    AcpiPsGetNextField
521 *
522 * PARAMETERS:  ParserState         - Current parser state object
523 *
524 * RETURN:      A newly allocated FIELD op
525 *
526 * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField)
527 *
528 ******************************************************************************/
529
530static ACPI_PARSE_OBJECT *
531AcpiPsGetNextField (
532    ACPI_PARSE_STATE        *ParserState)
533{
534    UINT32                  AmlOffset = (UINT32)
535                                ACPI_PTR_DIFF (ParserState->Aml,
536                                               ParserState->AmlStart);
537    ACPI_PARSE_OBJECT       *Field;
538    UINT16                  Opcode;
539    UINT32                  Name;
540
541
542    ACPI_FUNCTION_TRACE (PsGetNextField);
543
544
545    /* Determine field type */
546
547    switch (ACPI_GET8 (ParserState->Aml))
548    {
549    default:
550
551        Opcode = AML_INT_NAMEDFIELD_OP;
552        break;
553
554    case 0x00:
555
556        Opcode = AML_INT_RESERVEDFIELD_OP;
557        ParserState->Aml++;
558        break;
559
560    case 0x01:
561
562        Opcode = AML_INT_ACCESSFIELD_OP;
563        ParserState->Aml++;
564        break;
565    }
566
567    /* Allocate a new field op */
568
569    Field = AcpiPsAllocOp (Opcode);
570    if (!Field)
571    {
572        return_PTR (NULL);
573    }
574
575    Field->Common.AmlOffset = AmlOffset;
576
577    /* Decode the field type */
578
579    switch (Opcode)
580    {
581    case AML_INT_NAMEDFIELD_OP:
582
583        /* Get the 4-character name */
584
585        ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml);
586        AcpiPsSetName (Field, Name);
587        ParserState->Aml += ACPI_NAME_SIZE;
588
589        /* Get the length which is encoded as a package length */
590
591        Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
592        break;
593
594
595    case AML_INT_RESERVEDFIELD_OP:
596
597        /* Get the length which is encoded as a package length */
598
599        Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
600        break;
601
602
603    case AML_INT_ACCESSFIELD_OP:
604
605        /*
606         * Get AccessType and AccessAttrib and merge into the field Op
607         * AccessType is first operand, AccessAttribute is second
608         */
609        Field->Common.Value.Integer = (((UINT32) ACPI_GET8 (ParserState->Aml) << 8));
610        ParserState->Aml++;
611        Field->Common.Value.Integer |= ACPI_GET8 (ParserState->Aml);
612        ParserState->Aml++;
613        break;
614
615    default:
616
617        /* Opcode was set in previous switch */
618        break;
619    }
620
621    return_PTR (Field);
622}
623
624
625/*******************************************************************************
626 *
627 * FUNCTION:    AcpiPsGetNextArg
628 *
629 * PARAMETERS:  WalkState           - Current state
630 *              ParserState         - Current parser state object
631 *              ArgType             - The argument type (AML_*_ARG)
632 *              ReturnArg           - Where the next arg is returned
633 *
634 * RETURN:      Status, and an op object containing the next argument.
635 *
636 * DESCRIPTION: Get next argument (including complex list arguments that require
637 *              pushing the parser stack)
638 *
639 ******************************************************************************/
640
641ACPI_STATUS
642AcpiPsGetNextArg (
643    ACPI_WALK_STATE         *WalkState,
644    ACPI_PARSE_STATE        *ParserState,
645    UINT32                  ArgType,
646    ACPI_PARSE_OBJECT       **ReturnArg)
647{
648    ACPI_PARSE_OBJECT       *Arg = NULL;
649    ACPI_PARSE_OBJECT       *Prev = NULL;
650    ACPI_PARSE_OBJECT       *Field;
651    UINT32                  Subop;
652    ACPI_STATUS             Status = AE_OK;
653
654
655    ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState);
656
657
658    switch (ArgType)
659    {
660    case ARGP_BYTEDATA:
661    case ARGP_WORDDATA:
662    case ARGP_DWORDDATA:
663    case ARGP_CHARLIST:
664    case ARGP_NAME:
665    case ARGP_NAMESTRING:
666
667        /* Constants, strings, and namestrings are all the same size */
668
669        Arg = AcpiPsAllocOp (AML_BYTE_OP);
670        if (!Arg)
671        {
672            return_ACPI_STATUS (AE_NO_MEMORY);
673        }
674        AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg);
675        break;
676
677
678    case ARGP_PKGLENGTH:
679
680        /* Package length, nothing returned */
681
682        ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState);
683        break;
684
685
686    case ARGP_FIELDLIST:
687
688        if (ParserState->Aml < ParserState->PkgEnd)
689        {
690            /* Non-empty list */
691
692            while (ParserState->Aml < ParserState->PkgEnd)
693            {
694                Field = AcpiPsGetNextField (ParserState);
695                if (!Field)
696                {
697                    return_ACPI_STATUS (AE_NO_MEMORY);
698                }
699
700                if (Prev)
701                {
702                    Prev->Common.Next = Field;
703                }
704                else
705                {
706                    Arg = Field;
707                }
708                Prev = Field;
709            }
710
711            /* Skip to End of byte data */
712
713            ParserState->Aml = ParserState->PkgEnd;
714        }
715        break;
716
717
718    case ARGP_BYTELIST:
719
720        if (ParserState->Aml < ParserState->PkgEnd)
721        {
722            /* Non-empty list */
723
724            Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP);
725            if (!Arg)
726            {
727                return_ACPI_STATUS (AE_NO_MEMORY);
728            }
729
730            /* Fill in bytelist data */
731
732            Arg->Common.Value.Size = (UINT32)
733                ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml);
734            Arg->Named.Data = ParserState->Aml;
735
736            /* Skip to End of byte data */
737
738            ParserState->Aml = ParserState->PkgEnd;
739        }
740        break;
741
742
743    case ARGP_TARGET:
744    case ARGP_SUPERNAME:
745    case ARGP_SIMPLENAME:
746
747        Subop = AcpiPsPeekOpcode (ParserState);
748        if (Subop == 0                  ||
749            AcpiPsIsLeadingChar (Subop) ||
750            AcpiPsIsPrefixChar (Subop))
751        {
752            /* NullName or NameString */
753
754            Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
755            if (!Arg)
756            {
757                return_ACPI_STATUS (AE_NO_MEMORY);
758            }
759
760            /* To support SuperName arg of Unload */
761
762            if (WalkState->Opcode == AML_UNLOAD_OP)
763            {
764                Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 1);
765
766                /*
767                 * If the SuperName arg of Unload is a method call,
768                 * we have restored the AML pointer, just free this Arg
769                 */
770                if (Arg->Common.AmlOpcode == AML_INT_METHODCALL_OP)
771                {
772                    AcpiPsFreeOp (Arg);
773                    Arg = NULL;
774                }
775            }
776            else
777            {
778                Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 0);
779            }
780        }
781        else
782        {
783            /* Single complex argument, nothing returned */
784
785            WalkState->ArgCount = 1;
786        }
787        break;
788
789
790    case ARGP_DATAOBJ:
791    case ARGP_TERMARG:
792
793        /* Single complex argument, nothing returned */
794
795        WalkState->ArgCount = 1;
796        break;
797
798
799    case ARGP_DATAOBJLIST:
800    case ARGP_TERMLIST:
801    case ARGP_OBJLIST:
802
803        if (ParserState->Aml < ParserState->PkgEnd)
804        {
805            /* Non-empty list of variable arguments, nothing returned */
806
807            WalkState->ArgCount = ACPI_VAR_ARGS;
808        }
809        break;
810
811
812    default:
813
814        ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType));
815        Status = AE_AML_OPERAND_TYPE;
816        break;
817    }
818
819    *ReturnArg = Arg;
820    return_ACPI_STATUS (Status);
821}
822