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