linux/drivers/acpi/acpica/psargs.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/******************************************************************************
   3 *
   4 * Module Name: psargs - Parse AML opcode arguments
   5 *
   6 * Copyright (C) 2000 - 2020, Intel Corp.
   7 *
   8 *****************************************************************************/
   9
  10#include <acpi/acpi.h>
  11#include "accommon.h"
  12#include "acparser.h"
  13#include "amlcode.h"
  14#include "acnamesp.h"
  15#include "acdispat.h"
  16#include "acconvert.h"
  17
  18#define _COMPONENT          ACPI_PARSER
  19ACPI_MODULE_NAME("psargs")
  20
  21/* Local prototypes */
  22static u32
  23acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state);
  24
  25static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
  26                                                       *parser_state);
  27
  28/*******************************************************************************
  29 *
  30 * FUNCTION:    acpi_ps_get_next_package_length
  31 *
  32 * PARAMETERS:  parser_state        - Current parser state object
  33 *
  34 * RETURN:      Decoded package length. On completion, the AML pointer points
  35 *              past the length byte or bytes.
  36 *
  37 * DESCRIPTION: Decode and return a package length field.
  38 *              Note: Largest package length is 28 bits, from ACPI specification
  39 *
  40 ******************************************************************************/
  41
  42static u32
  43acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
  44{
  45        u8 *aml = parser_state->aml;
  46        u32 package_length = 0;
  47        u32 byte_count;
  48        u8 byte_zero_mask = 0x3F;       /* Default [0:5] */
  49
  50        ACPI_FUNCTION_TRACE(ps_get_next_package_length);
  51
  52        /*
  53         * Byte 0 bits [6:7] contain the number of additional bytes
  54         * used to encode the package length, either 0,1,2, or 3
  55         */
  56        byte_count = (aml[0] >> 6);
  57        parser_state->aml += ((acpi_size)byte_count + 1);
  58
  59        /* Get bytes 3, 2, 1 as needed */
  60
  61        while (byte_count) {
  62                /*
  63                 * Final bit positions for the package length bytes:
  64                 *      Byte3->[20:27]
  65                 *      Byte2->[12:19]
  66                 *      Byte1->[04:11]
  67                 *      Byte0->[00:03]
  68                 */
  69                package_length |= (aml[byte_count] << ((byte_count << 3) - 4));
  70
  71                byte_zero_mask = 0x0F;  /* Use bits [0:3] of byte 0 */
  72                byte_count--;
  73        }
  74
  75        /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
  76
  77        package_length |= (aml[0] & byte_zero_mask);
  78        return_UINT32(package_length);
  79}
  80
  81/*******************************************************************************
  82 *
  83 * FUNCTION:    acpi_ps_get_next_package_end
  84 *
  85 * PARAMETERS:  parser_state        - Current parser state object
  86 *
  87 * RETURN:      Pointer to end-of-package +1
  88 *
  89 * DESCRIPTION: Get next package length and return a pointer past the end of
  90 *              the package. Consumes the package length field
  91 *
  92 ******************************************************************************/
  93
  94u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state)
  95{
  96        u8 *start = parser_state->aml;
  97        u32 package_length;
  98
  99        ACPI_FUNCTION_TRACE(ps_get_next_package_end);
 100
 101        /* Function below updates parser_state->Aml */
 102
 103        package_length = acpi_ps_get_next_package_length(parser_state);
 104
 105        return_PTR(start + package_length);     /* end of package */
 106}
 107
 108/*******************************************************************************
 109 *
 110 * FUNCTION:    acpi_ps_get_next_namestring
 111 *
 112 * PARAMETERS:  parser_state        - Current parser state object
 113 *
 114 * RETURN:      Pointer to the start of the name string (pointer points into
 115 *              the AML.
 116 *
 117 * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
 118 *              prefix characters. Set parser state to point past the string.
 119 *              (Name is consumed from the AML.)
 120 *
 121 ******************************************************************************/
 122
 123char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
 124{
 125        u8 *start = parser_state->aml;
 126        u8 *end = parser_state->aml;
 127
 128        ACPI_FUNCTION_TRACE(ps_get_next_namestring);
 129
 130        /* Point past any namestring prefix characters (backslash or carat) */
 131
 132        while (ACPI_IS_ROOT_PREFIX(*end) || ACPI_IS_PARENT_PREFIX(*end)) {
 133                end++;
 134        }
 135
 136        /* Decode the path prefix character */
 137
 138        switch (*end) {
 139        case 0:
 140
 141                /* null_name */
 142
 143                if (end == start) {
 144                        start = NULL;
 145                }
 146                end++;
 147                break;
 148
 149        case AML_DUAL_NAME_PREFIX:
 150
 151                /* Two name segments */
 152
 153                end += 1 + (2 * ACPI_NAMESEG_SIZE);
 154                break;
 155
 156        case AML_MULTI_NAME_PREFIX:
 157
 158                /* Multiple name segments, 4 chars each, count in next byte */
 159
 160                end += 2 + (*(end + 1) * ACPI_NAMESEG_SIZE);
 161                break;
 162
 163        default:
 164
 165                /* Single name segment */
 166
 167                end += ACPI_NAMESEG_SIZE;
 168                break;
 169        }
 170
 171        parser_state->aml = end;
 172        return_PTR((char *)start);
 173}
 174
 175/*******************************************************************************
 176 *
 177 * FUNCTION:    acpi_ps_get_next_namepath
 178 *
 179 * PARAMETERS:  parser_state        - Current parser state object
 180 *              arg                 - Where the namepath will be stored
 181 *              arg_count           - If the namepath points to a control method
 182 *                                    the method's argument is returned here.
 183 *              possible_method_call - Whether the namepath can possibly be the
 184 *                                    start of a method call
 185 *
 186 * RETURN:      Status
 187 *
 188 * DESCRIPTION: Get next name (if method call, return # of required args).
 189 *              Names are looked up in the internal namespace to determine
 190 *              if the name represents a control method. If a method
 191 *              is found, the number of arguments to the method is returned.
 192 *              This information is critical for parsing to continue correctly.
 193 *
 194 ******************************************************************************/
 195
 196acpi_status
 197acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
 198                          struct acpi_parse_state *parser_state,
 199                          union acpi_parse_object *arg, u8 possible_method_call)
 200{
 201        acpi_status status;
 202        char *path;
 203        union acpi_parse_object *name_op;
 204        union acpi_operand_object *method_desc;
 205        struct acpi_namespace_node *node;
 206        u8 *start = parser_state->aml;
 207
 208        ACPI_FUNCTION_TRACE(ps_get_next_namepath);
 209
 210        path = acpi_ps_get_next_namestring(parser_state);
 211        acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
 212
 213        /* Null path case is allowed, just exit */
 214
 215        if (!path) {
 216                arg->common.value.name = path;
 217                return_ACPI_STATUS(AE_OK);
 218        }
 219
 220        /*
 221         * Lookup the name in the internal namespace, starting with the current
 222         * scope. We don't want to add anything new to the namespace here,
 223         * however, so we use MODE_EXECUTE.
 224         * Allow searching of the parent tree, but don't open a new scope -
 225         * we just want to lookup the object (must be mode EXECUTE to perform
 226         * the upsearch)
 227         */
 228        status = acpi_ns_lookup(walk_state->scope_info, path,
 229                                ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
 230                                ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
 231                                NULL, &node);
 232
 233        /*
 234         * If this name is a control method invocation, we must
 235         * setup the method call
 236         */
 237        if (ACPI_SUCCESS(status) &&
 238            possible_method_call && (node->type == ACPI_TYPE_METHOD)) {
 239                if ((GET_CURRENT_ARG_TYPE(walk_state->arg_types) ==
 240                     ARGP_SUPERNAME)
 241                    || (GET_CURRENT_ARG_TYPE(walk_state->arg_types) ==
 242                        ARGP_TARGET)) {
 243                        /*
 244                         * acpi_ps_get_next_namestring has increased the AML pointer past
 245                         * the method invocation namestring, so we need to restore the
 246                         * saved AML pointer back to the original method invocation
 247                         * namestring.
 248                         */
 249                        walk_state->parser_state.aml = start;
 250                        walk_state->arg_count = 1;
 251                        acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
 252                }
 253
 254                /* This name is actually a control method invocation */
 255
 256                method_desc = acpi_ns_get_attached_object(node);
 257                ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
 258                                  "Control Method invocation %4.4s - %p Desc %p Path=%p\n",
 259                                  node->name.ascii, node, method_desc, path));
 260
 261                name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, start);
 262                if (!name_op) {
 263                        return_ACPI_STATUS(AE_NO_MEMORY);
 264                }
 265
 266                /* Change Arg into a METHOD CALL and attach name to it */
 267
 268                acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
 269                name_op->common.value.name = path;
 270
 271                /* Point METHODCALL/NAME to the METHOD Node */
 272
 273                name_op->common.node = node;
 274                acpi_ps_append_arg(arg, name_op);
 275
 276                if (!method_desc) {
 277                        ACPI_ERROR((AE_INFO,
 278                                    "Control Method %p has no attached object",
 279                                    node));
 280                        return_ACPI_STATUS(AE_AML_INTERNAL);
 281                }
 282
 283                ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
 284                                  "Control Method - %p Args %X\n",
 285                                  node, method_desc->method.param_count));
 286
 287                /* Get the number of arguments to expect */
 288
 289                walk_state->arg_count = method_desc->method.param_count;
 290                return_ACPI_STATUS(AE_OK);
 291        }
 292
 293        /*
 294         * Special handling if the name was not found during the lookup -
 295         * some not_found cases are allowed
 296         */
 297        if (status == AE_NOT_FOUND) {
 298
 299                /* 1) not_found is ok during load pass 1/2 (allow forward references) */
 300
 301                if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) !=
 302                    ACPI_PARSE_EXECUTE) {
 303                        status = AE_OK;
 304                }
 305
 306                /* 2) not_found during a cond_ref_of(x) is ok by definition */
 307
 308                else if (walk_state->op->common.aml_opcode ==
 309                         AML_CONDITIONAL_REF_OF_OP) {
 310                        status = AE_OK;
 311                }
 312
 313                /*
 314                 * 3) not_found while building a Package is ok at this point, we
 315                 * may flag as an error later if slack mode is not enabled.
 316                 * (Some ASL code depends on allowing this behavior)
 317                 */
 318                else if ((arg->common.parent) &&
 319                         ((arg->common.parent->common.aml_opcode ==
 320                           AML_PACKAGE_OP)
 321                          || (arg->common.parent->common.aml_opcode ==
 322                              AML_VARIABLE_PACKAGE_OP))) {
 323                        status = AE_OK;
 324                }
 325        }
 326
 327        /* Final exception check (may have been changed from code above) */
 328
 329        if (ACPI_FAILURE(status)) {
 330                ACPI_ERROR_NAMESPACE(walk_state->scope_info, path, status);
 331
 332                if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
 333                    ACPI_PARSE_EXECUTE) {
 334
 335                        /* Report a control method execution error */
 336
 337                        status = acpi_ds_method_error(status, walk_state);
 338                }
 339        }
 340
 341        /* Save the namepath */
 342
 343        arg->common.value.name = path;
 344        return_ACPI_STATUS(status);
 345}
 346
 347/*******************************************************************************
 348 *
 349 * FUNCTION:    acpi_ps_get_next_simple_arg
 350 *
 351 * PARAMETERS:  parser_state        - Current parser state object
 352 *              arg_type            - The argument type (AML_*_ARG)
 353 *              arg                 - Where the argument is returned
 354 *
 355 * RETURN:      None
 356 *
 357 * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
 358 *
 359 ******************************************************************************/
 360
 361void
 362acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
 363                            u32 arg_type, union acpi_parse_object *arg)
 364{
 365        u32 length;
 366        u16 opcode;
 367        u8 *aml = parser_state->aml;
 368
 369        ACPI_FUNCTION_TRACE_U32(ps_get_next_simple_arg, arg_type);
 370
 371        switch (arg_type) {
 372        case ARGP_BYTEDATA:
 373
 374                /* Get 1 byte from the AML stream */
 375
 376                opcode = AML_BYTE_OP;
 377                arg->common.value.integer = (u64) *aml;
 378                length = 1;
 379                break;
 380
 381        case ARGP_WORDDATA:
 382
 383                /* Get 2 bytes from the AML stream */
 384
 385                opcode = AML_WORD_OP;
 386                ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml);
 387                length = 2;
 388                break;
 389
 390        case ARGP_DWORDDATA:
 391
 392                /* Get 4 bytes from the AML stream */
 393
 394                opcode = AML_DWORD_OP;
 395                ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml);
 396                length = 4;
 397                break;
 398
 399        case ARGP_QWORDDATA:
 400
 401                /* Get 8 bytes from the AML stream */
 402
 403                opcode = AML_QWORD_OP;
 404                ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml);
 405                length = 8;
 406                break;
 407
 408        case ARGP_CHARLIST:
 409
 410                /* Get a pointer to the string, point past the string */
 411
 412                opcode = AML_STRING_OP;
 413                arg->common.value.string = ACPI_CAST_PTR(char, aml);
 414
 415                /* Find the null terminator */
 416
 417                length = 0;
 418                while (aml[length]) {
 419                        length++;
 420                }
 421                length++;
 422                break;
 423
 424        case ARGP_NAME:
 425        case ARGP_NAMESTRING:
 426
 427                acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
 428                arg->common.value.name =
 429                    acpi_ps_get_next_namestring(parser_state);
 430                return_VOID;
 431
 432        default:
 433
 434                ACPI_ERROR((AE_INFO, "Invalid ArgType 0x%X", arg_type));
 435                return_VOID;
 436        }
 437
 438        acpi_ps_init_op(arg, opcode);
 439        parser_state->aml += length;
 440        return_VOID;
 441}
 442
 443/*******************************************************************************
 444 *
 445 * FUNCTION:    acpi_ps_get_next_field
 446 *
 447 * PARAMETERS:  parser_state        - Current parser state object
 448 *
 449 * RETURN:      A newly allocated FIELD op
 450 *
 451 * DESCRIPTION: Get next field (named_field, reserved_field, or access_field)
 452 *
 453 ******************************************************************************/
 454
 455static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
 456                                                       *parser_state)
 457{
 458        u8 *aml;
 459        union acpi_parse_object *field;
 460        union acpi_parse_object *arg = NULL;
 461        u16 opcode;
 462        u32 name;
 463        u8 access_type;
 464        u8 access_attribute;
 465        u8 access_length;
 466        u32 pkg_length;
 467        u8 *pkg_end;
 468        u32 buffer_length;
 469
 470        ACPI_FUNCTION_TRACE(ps_get_next_field);
 471
 472        ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
 473        aml = parser_state->aml;
 474
 475        /* Determine field type */
 476
 477        switch (ACPI_GET8(parser_state->aml)) {
 478        case AML_FIELD_OFFSET_OP:
 479
 480                opcode = AML_INT_RESERVEDFIELD_OP;
 481                parser_state->aml++;
 482                break;
 483
 484        case AML_FIELD_ACCESS_OP:
 485
 486                opcode = AML_INT_ACCESSFIELD_OP;
 487                parser_state->aml++;
 488                break;
 489
 490        case AML_FIELD_CONNECTION_OP:
 491
 492                opcode = AML_INT_CONNECTION_OP;
 493                parser_state->aml++;
 494                break;
 495
 496        case AML_FIELD_EXT_ACCESS_OP:
 497
 498                opcode = AML_INT_EXTACCESSFIELD_OP;
 499                parser_state->aml++;
 500                break;
 501
 502        default:
 503
 504                opcode = AML_INT_NAMEDFIELD_OP;
 505                break;
 506        }
 507
 508        /* Allocate a new field op */
 509
 510        field = acpi_ps_alloc_op(opcode, aml);
 511        if (!field) {
 512                return_PTR(NULL);
 513        }
 514
 515        /* Decode the field type */
 516
 517        ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
 518        switch (opcode) {
 519        case AML_INT_NAMEDFIELD_OP:
 520
 521                /* Get the 4-character name */
 522
 523                ACPI_MOVE_32_TO_32(&name, parser_state->aml);
 524                acpi_ps_set_name(field, name);
 525                parser_state->aml += ACPI_NAMESEG_SIZE;
 526
 527                ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
 528
 529#ifdef ACPI_ASL_COMPILER
 530                /*
 531                 * Because the package length isn't represented as a parse tree object,
 532                 * take comments surrounding this and add to the previously created
 533                 * parse node.
 534                 */
 535                if (field->common.inline_comment) {
 536                        field->common.name_comment =
 537                            field->common.inline_comment;
 538                }
 539                field->common.inline_comment = acpi_gbl_current_inline_comment;
 540                acpi_gbl_current_inline_comment = NULL;
 541#endif
 542
 543                /* Get the length which is encoded as a package length */
 544
 545                field->common.value.size =
 546                    acpi_ps_get_next_package_length(parser_state);
 547                break;
 548
 549        case AML_INT_RESERVEDFIELD_OP:
 550
 551                /* Get the length which is encoded as a package length */
 552
 553                field->common.value.size =
 554                    acpi_ps_get_next_package_length(parser_state);
 555                break;
 556
 557        case AML_INT_ACCESSFIELD_OP:
 558        case AML_INT_EXTACCESSFIELD_OP:
 559
 560                /*
 561                 * Get access_type and access_attrib and merge into the field Op
 562                 * access_type is first operand, access_attribute is second. stuff
 563                 * these bytes into the node integer value for convenience.
 564                 */
 565
 566                /* Get the two bytes (Type/Attribute) */
 567
 568                access_type = ACPI_GET8(parser_state->aml);
 569                parser_state->aml++;
 570                access_attribute = ACPI_GET8(parser_state->aml);
 571                parser_state->aml++;
 572
 573                field->common.value.integer = (u8)access_type;
 574                field->common.value.integer |= (u16)(access_attribute << 8);
 575
 576                /* This opcode has a third byte, access_length */
 577
 578                if (opcode == AML_INT_EXTACCESSFIELD_OP) {
 579                        access_length = ACPI_GET8(parser_state->aml);
 580                        parser_state->aml++;
 581
 582                        field->common.value.integer |=
 583                            (u32)(access_length << 16);
 584                }
 585                break;
 586
 587        case AML_INT_CONNECTION_OP:
 588
 589                /*
 590                 * Argument for Connection operator can be either a Buffer
 591                 * (resource descriptor), or a name_string.
 592                 */
 593                aml = parser_state->aml;
 594                if (ACPI_GET8(parser_state->aml) == AML_BUFFER_OP) {
 595                        parser_state->aml++;
 596
 597                        ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
 598                        pkg_end = parser_state->aml;
 599                        pkg_length =
 600                            acpi_ps_get_next_package_length(parser_state);
 601                        pkg_end += pkg_length;
 602
 603                        ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
 604                        if (parser_state->aml < pkg_end) {
 605
 606                                /* Non-empty list */
 607
 608                                arg =
 609                                    acpi_ps_alloc_op(AML_INT_BYTELIST_OP, aml);
 610                                if (!arg) {
 611                                        acpi_ps_free_op(field);
 612                                        return_PTR(NULL);
 613                                }
 614
 615                                /* Get the actual buffer length argument */
 616
 617                                opcode = ACPI_GET8(parser_state->aml);
 618                                parser_state->aml++;
 619
 620                                ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
 621                                switch (opcode) {
 622                                case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
 623
 624                                        buffer_length =
 625                                            ACPI_GET8(parser_state->aml);
 626                                        parser_state->aml += 1;
 627                                        break;
 628
 629                                case AML_WORD_OP:       /* AML_WORDDATA_ARG */
 630
 631                                        buffer_length =
 632                                            ACPI_GET16(parser_state->aml);
 633                                        parser_state->aml += 2;
 634                                        break;
 635
 636                                case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
 637
 638                                        buffer_length =
 639                                            ACPI_GET32(parser_state->aml);
 640                                        parser_state->aml += 4;
 641                                        break;
 642
 643                                default:
 644
 645                                        buffer_length = 0;
 646                                        break;
 647                                }
 648
 649                                /* Fill in bytelist data */
 650
 651                                ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
 652                                arg->named.value.size = buffer_length;
 653                                arg->named.data = parser_state->aml;
 654                        }
 655
 656                        /* Skip to End of byte data */
 657
 658                        parser_state->aml = pkg_end;
 659                } else {
 660                        arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, aml);
 661                        if (!arg) {
 662                                acpi_ps_free_op(field);
 663                                return_PTR(NULL);
 664                        }
 665
 666                        /* Get the Namestring argument */
 667
 668                        arg->common.value.name =
 669                            acpi_ps_get_next_namestring(parser_state);
 670                }
 671
 672                /* Link the buffer/namestring to parent (CONNECTION_OP) */
 673
 674                acpi_ps_append_arg(field, arg);
 675                break;
 676
 677        default:
 678
 679                /* Opcode was set in previous switch */
 680                break;
 681        }
 682
 683        return_PTR(field);
 684}
 685
 686/*******************************************************************************
 687 *
 688 * FUNCTION:    acpi_ps_get_next_arg
 689 *
 690 * PARAMETERS:  walk_state          - Current state
 691 *              parser_state        - Current parser state object
 692 *              arg_type            - The argument type (AML_*_ARG)
 693 *              return_arg          - Where the next arg is returned
 694 *
 695 * RETURN:      Status, and an op object containing the next argument.
 696 *
 697 * DESCRIPTION: Get next argument (including complex list arguments that require
 698 *              pushing the parser stack)
 699 *
 700 ******************************************************************************/
 701
 702acpi_status
 703acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
 704                     struct acpi_parse_state *parser_state,
 705                     u32 arg_type, union acpi_parse_object **return_arg)
 706{
 707        union acpi_parse_object *arg = NULL;
 708        union acpi_parse_object *prev = NULL;
 709        union acpi_parse_object *field;
 710        u32 subop;
 711        acpi_status status = AE_OK;
 712
 713        ACPI_FUNCTION_TRACE_PTR(ps_get_next_arg, parser_state);
 714
 715        ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
 716                          "Expected argument type ARGP: %s (%2.2X)\n",
 717                          acpi_ut_get_argument_type_name(arg_type), arg_type));
 718
 719        switch (arg_type) {
 720        case ARGP_BYTEDATA:
 721        case ARGP_WORDDATA:
 722        case ARGP_DWORDDATA:
 723        case ARGP_CHARLIST:
 724        case ARGP_NAME:
 725        case ARGP_NAMESTRING:
 726
 727                /* Constants, strings, and namestrings are all the same size */
 728
 729                arg = acpi_ps_alloc_op(AML_BYTE_OP, parser_state->aml);
 730                if (!arg) {
 731                        return_ACPI_STATUS(AE_NO_MEMORY);
 732                }
 733
 734                acpi_ps_get_next_simple_arg(parser_state, arg_type, arg);
 735                break;
 736
 737        case ARGP_PKGLENGTH:
 738
 739                /* Package length, nothing returned */
 740
 741                parser_state->pkg_end =
 742                    acpi_ps_get_next_package_end(parser_state);
 743                break;
 744
 745        case ARGP_FIELDLIST:
 746
 747                if (parser_state->aml < parser_state->pkg_end) {
 748
 749                        /* Non-empty list */
 750
 751                        while (parser_state->aml < parser_state->pkg_end) {
 752                                field = acpi_ps_get_next_field(parser_state);
 753                                if (!field) {
 754                                        return_ACPI_STATUS(AE_NO_MEMORY);
 755                                }
 756
 757                                if (prev) {
 758                                        prev->common.next = field;
 759                                } else {
 760                                        arg = field;
 761                                }
 762                                prev = field;
 763                        }
 764
 765                        /* Skip to End of byte data */
 766
 767                        parser_state->aml = parser_state->pkg_end;
 768                }
 769                break;
 770
 771        case ARGP_BYTELIST:
 772
 773                if (parser_state->aml < parser_state->pkg_end) {
 774
 775                        /* Non-empty list */
 776
 777                        arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP,
 778                                               parser_state->aml);
 779                        if (!arg) {
 780                                return_ACPI_STATUS(AE_NO_MEMORY);
 781                        }
 782
 783                        /* Fill in bytelist data */
 784
 785                        arg->common.value.size = (u32)
 786                            ACPI_PTR_DIFF(parser_state->pkg_end,
 787                                          parser_state->aml);
 788                        arg->named.data = parser_state->aml;
 789
 790                        /* Skip to End of byte data */
 791
 792                        parser_state->aml = parser_state->pkg_end;
 793                }
 794                break;
 795
 796        case ARGP_SIMPLENAME:
 797        case ARGP_NAME_OR_REF:
 798
 799                ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
 800                                  "**** SimpleName/NameOrRef: %s (%2.2X)\n",
 801                                  acpi_ut_get_argument_type_name(arg_type),
 802                                  arg_type));
 803
 804                subop = acpi_ps_peek_opcode(parser_state);
 805                if (subop == 0 ||
 806                    acpi_ps_is_leading_char(subop) ||
 807                    ACPI_IS_ROOT_PREFIX(subop) ||
 808                    ACPI_IS_PARENT_PREFIX(subop)) {
 809
 810                        /* null_name or name_string */
 811
 812                        arg =
 813                            acpi_ps_alloc_op(AML_INT_NAMEPATH_OP,
 814                                             parser_state->aml);
 815                        if (!arg) {
 816                                return_ACPI_STATUS(AE_NO_MEMORY);
 817                        }
 818
 819                        status =
 820                            acpi_ps_get_next_namepath(walk_state, parser_state,
 821                                                      arg,
 822                                                      ACPI_NOT_METHOD_CALL);
 823                } else {
 824                        /* Single complex argument, nothing returned */
 825
 826                        walk_state->arg_count = 1;
 827                }
 828                break;
 829
 830        case ARGP_TARGET:
 831        case ARGP_SUPERNAME:
 832
 833                ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
 834                                  "**** Target/Supername: %s (%2.2X)\n",
 835                                  acpi_ut_get_argument_type_name(arg_type),
 836                                  arg_type));
 837
 838                subop = acpi_ps_peek_opcode(parser_state);
 839                if (subop == 0 ||
 840                    acpi_ps_is_leading_char(subop) ||
 841                    ACPI_IS_ROOT_PREFIX(subop) ||
 842                    ACPI_IS_PARENT_PREFIX(subop)) {
 843
 844                        /* NULL target (zero). Convert to a NULL namepath */
 845
 846                        arg =
 847                            acpi_ps_alloc_op(AML_INT_NAMEPATH_OP,
 848                                             parser_state->aml);
 849                        if (!arg) {
 850                                return_ACPI_STATUS(AE_NO_MEMORY);
 851                        }
 852
 853                        status =
 854                            acpi_ps_get_next_namepath(walk_state, parser_state,
 855                                                      arg,
 856                                                      ACPI_POSSIBLE_METHOD_CALL);
 857
 858                        if (arg->common.aml_opcode == AML_INT_METHODCALL_OP) {
 859
 860                                /* Free method call op and corresponding namestring sub-ob */
 861
 862                                acpi_ps_free_op(arg->common.value.arg);
 863                                acpi_ps_free_op(arg);
 864                                arg = NULL;
 865                                walk_state->arg_count = 1;
 866                        }
 867                } else {
 868                        /* Single complex argument, nothing returned */
 869
 870                        walk_state->arg_count = 1;
 871                }
 872                break;
 873
 874        case ARGP_DATAOBJ:
 875        case ARGP_TERMARG:
 876
 877                ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
 878                                  "**** TermArg/DataObj: %s (%2.2X)\n",
 879                                  acpi_ut_get_argument_type_name(arg_type),
 880                                  arg_type));
 881
 882                /* Single complex argument, nothing returned */
 883
 884                walk_state->arg_count = 1;
 885                break;
 886
 887        case ARGP_DATAOBJLIST:
 888        case ARGP_TERMLIST:
 889        case ARGP_OBJLIST:
 890
 891                if (parser_state->aml < parser_state->pkg_end) {
 892
 893                        /* Non-empty list of variable arguments, nothing returned */
 894
 895                        walk_state->arg_count = ACPI_VAR_ARGS;
 896                }
 897                break;
 898
 899        default:
 900
 901                ACPI_ERROR((AE_INFO, "Invalid ArgType: 0x%X", arg_type));
 902                status = AE_AML_OPERAND_TYPE;
 903                break;
 904        }
 905
 906        *return_arg = arg;
 907        return_ACPI_STATUS(status);
 908}
 909