linux/drivers/acpi/acpica/dsfield.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/******************************************************************************
   3 *
   4 * Module Name: dsfield - Dispatcher field routines
   5 *
   6 * Copyright (C) 2000 - 2019, Intel Corp.
   7 *
   8 *****************************************************************************/
   9
  10#include <acpi/acpi.h>
  11#include "accommon.h"
  12#include "amlcode.h"
  13#include "acdispat.h"
  14#include "acinterp.h"
  15#include "acnamesp.h"
  16#include "acparser.h"
  17
  18#ifdef ACPI_EXEC_APP
  19#include "aecommon.h"
  20#endif
  21
  22#define _COMPONENT          ACPI_DISPATCHER
  23ACPI_MODULE_NAME("dsfield")
  24
  25/* Local prototypes */
  26#ifdef ACPI_ASL_COMPILER
  27#include "acdisasm.h"
  28static acpi_status
  29acpi_ds_create_external_region(acpi_status lookup_status,
  30                               union acpi_parse_object *op,
  31                               char *path,
  32                               struct acpi_walk_state *walk_state,
  33                               struct acpi_namespace_node **node);
  34#endif
  35
  36static acpi_status
  37acpi_ds_get_field_names(struct acpi_create_field_info *info,
  38                        struct acpi_walk_state *walk_state,
  39                        union acpi_parse_object *arg);
  40
  41#ifdef ACPI_ASL_COMPILER
  42/*******************************************************************************
  43 *
  44 * FUNCTION:    acpi_ds_create_external_region (iASL Disassembler only)
  45 *
  46 * PARAMETERS:  lookup_status   - Status from ns_lookup operation
  47 *              op              - Op containing the Field definition and args
  48 *              path            - Pathname of the region
  49 *  `           walk_state      - Current method state
  50 *              node            - Where the new region node is returned
  51 *
  52 * RETURN:      Status
  53 *
  54 * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new
  55 *              region node/object.
  56 *
  57 ******************************************************************************/
  58
  59static acpi_status
  60acpi_ds_create_external_region(acpi_status lookup_status,
  61                               union acpi_parse_object *op,
  62                               char *path,
  63                               struct acpi_walk_state *walk_state,
  64                               struct acpi_namespace_node **node)
  65{
  66        acpi_status status;
  67        union acpi_operand_object *obj_desc;
  68
  69        if (lookup_status != AE_NOT_FOUND) {
  70                return (lookup_status);
  71        }
  72
  73        /*
  74         * Table disassembly:
  75         * operation_region not found. Generate an External for it, and
  76         * insert the name into the namespace.
  77         */
  78        acpi_dm_add_op_to_external_list(op, path, ACPI_TYPE_REGION, 0, 0);
  79
  80        status = acpi_ns_lookup(walk_state->scope_info, path, ACPI_TYPE_REGION,
  81                                ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT,
  82                                walk_state, node);
  83        if (ACPI_FAILURE(status)) {
  84                return (status);
  85        }
  86
  87        /* Must create and install a region object for the new node */
  88
  89        obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION);
  90        if (!obj_desc) {
  91                return (AE_NO_MEMORY);
  92        }
  93
  94        obj_desc->region.node = *node;
  95        status = acpi_ns_attach_object(*node, obj_desc, ACPI_TYPE_REGION);
  96        return (status);
  97}
  98#endif
  99
 100/*******************************************************************************
 101 *
 102 * FUNCTION:    acpi_ds_create_buffer_field
 103 *
 104 * PARAMETERS:  op                  - Current parse op (create_XXField)
 105 *              walk_state          - Current state
 106 *
 107 * RETURN:      Status
 108 *
 109 * DESCRIPTION: Execute the create_field operators:
 110 *              create_bit_field_op,
 111 *              create_byte_field_op,
 112 *              create_word_field_op,
 113 *              create_dword_field_op,
 114 *              create_qword_field_op,
 115 *              create_field_op     (all of which define a field in a buffer)
 116 *
 117 ******************************************************************************/
 118
 119acpi_status
 120acpi_ds_create_buffer_field(union acpi_parse_object *op,
 121                            struct acpi_walk_state *walk_state)
 122{
 123        union acpi_parse_object *arg;
 124        struct acpi_namespace_node *node;
 125        acpi_status status;
 126        union acpi_operand_object *obj_desc;
 127        union acpi_operand_object *second_desc = NULL;
 128        u32 flags;
 129
 130        ACPI_FUNCTION_TRACE(ds_create_buffer_field);
 131
 132        /*
 133         * Get the name_string argument (name of the new buffer_field)
 134         */
 135        if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
 136
 137                /* For create_field, name is the 4th argument */
 138
 139                arg = acpi_ps_get_arg(op, 3);
 140        } else {
 141                /* For all other create_XXXField operators, name is the 3rd argument */
 142
 143                arg = acpi_ps_get_arg(op, 2);
 144        }
 145
 146        if (!arg) {
 147                return_ACPI_STATUS(AE_AML_NO_OPERAND);
 148        }
 149
 150        if (walk_state->deferred_node) {
 151                node = walk_state->deferred_node;
 152                status = AE_OK;
 153        } else {
 154                /* Execute flag should always be set when this function is entered */
 155
 156                if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
 157                        ACPI_ERROR((AE_INFO, "Parse execute mode is not set"));
 158                        return_ACPI_STATUS(AE_AML_INTERNAL);
 159                }
 160
 161                /* Creating new namespace node, should not already exist */
 162
 163                flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
 164                    ACPI_NS_ERROR_IF_FOUND;
 165
 166                /*
 167                 * Mark node temporary if we are executing a normal control
 168                 * method. (Don't mark if this is a module-level code method)
 169                 */
 170                if (walk_state->method_node &&
 171                    !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
 172                        flags |= ACPI_NS_TEMPORARY;
 173                }
 174
 175                /* Enter the name_string into the namespace */
 176
 177                status = acpi_ns_lookup(walk_state->scope_info,
 178                                        arg->common.value.string, ACPI_TYPE_ANY,
 179                                        ACPI_IMODE_LOAD_PASS1, flags,
 180                                        walk_state, &node);
 181                if (ACPI_FAILURE(status)) {
 182                        ACPI_ERROR_NAMESPACE(walk_state->scope_info,
 183                                             arg->common.value.string, status);
 184                        return_ACPI_STATUS(status);
 185                }
 186        }
 187
 188        /*
 189         * We could put the returned object (Node) on the object stack for later,
 190         * but for now, we will put it in the "op" object that the parser uses,
 191         * so we can get it again at the end of this scope.
 192         */
 193        op->common.node = node;
 194
 195        /*
 196         * If there is no object attached to the node, this node was just created
 197         * and we need to create the field object. Otherwise, this was a lookup
 198         * of an existing node and we don't want to create the field object again.
 199         */
 200        obj_desc = acpi_ns_get_attached_object(node);
 201        if (obj_desc) {
 202                return_ACPI_STATUS(AE_OK);
 203        }
 204
 205        /*
 206         * The Field definition is not fully parsed at this time.
 207         * (We must save the address of the AML for the buffer and index operands)
 208         */
 209
 210        /* Create the buffer field object */
 211
 212        obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER_FIELD);
 213        if (!obj_desc) {
 214                status = AE_NO_MEMORY;
 215                goto cleanup;
 216        }
 217
 218        /*
 219         * Remember location in AML stream of the field unit opcode and operands
 220         * -- since the buffer and index operands must be evaluated.
 221         */
 222        second_desc = obj_desc->common.next_object;
 223        second_desc->extra.aml_start = op->named.data;
 224        second_desc->extra.aml_length = op->named.length;
 225        obj_desc->buffer_field.node = node;
 226
 227        /* Attach constructed field descriptors to parent node */
 228
 229        status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_BUFFER_FIELD);
 230        if (ACPI_FAILURE(status)) {
 231                goto cleanup;
 232        }
 233
 234cleanup:
 235
 236        /* Remove local reference to the object */
 237
 238        acpi_ut_remove_reference(obj_desc);
 239        return_ACPI_STATUS(status);
 240}
 241
 242/*******************************************************************************
 243 *
 244 * FUNCTION:    acpi_ds_get_field_names
 245 *
 246 * PARAMETERS:  info            - create_field info structure
 247 *  `           walk_state      - Current method state
 248 *              arg             - First parser arg for the field name list
 249 *
 250 * RETURN:      Status
 251 *
 252 * DESCRIPTION: Process all named fields in a field declaration. Names are
 253 *              entered into the namespace.
 254 *
 255 ******************************************************************************/
 256
 257static acpi_status
 258acpi_ds_get_field_names(struct acpi_create_field_info *info,
 259                        struct acpi_walk_state *walk_state,
 260                        union acpi_parse_object *arg)
 261{
 262        acpi_status status;
 263        u64 position;
 264        union acpi_parse_object *child;
 265
 266#ifdef ACPI_EXEC_APP
 267        u64 value = 0;
 268        union acpi_operand_object *result_desc;
 269        union acpi_operand_object *obj_desc;
 270        char *name_path;
 271#endif
 272
 273        ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info);
 274
 275        /* First field starts at bit zero */
 276
 277        info->field_bit_position = 0;
 278
 279        /* Process all elements in the field list (of parse nodes) */
 280
 281        while (arg) {
 282                /*
 283                 * Four types of field elements are handled:
 284                 * 1) name - Enters a new named field into the namespace
 285                 * 2) offset - specifies a bit offset
 286                 * 3) access_as - changes the access mode/attributes
 287                 * 4) connection - Associate a resource template with the field
 288                 */
 289                switch (arg->common.aml_opcode) {
 290                case AML_INT_RESERVEDFIELD_OP:
 291
 292                        position = (u64)info->field_bit_position +
 293                            (u64)arg->common.value.size;
 294
 295                        if (position > ACPI_UINT32_MAX) {
 296                                ACPI_ERROR((AE_INFO,
 297                                            "Bit offset within field too large (> 0xFFFFFFFF)"));
 298                                return_ACPI_STATUS(AE_SUPPORT);
 299                        }
 300
 301                        info->field_bit_position = (u32) position;
 302                        break;
 303
 304                case AML_INT_ACCESSFIELD_OP:
 305                case AML_INT_EXTACCESSFIELD_OP:
 306                        /*
 307                         * Get new access_type, access_attribute, and access_length fields
 308                         * -- to be used for all field units that follow, until the
 309                         * end-of-field or another access_as keyword is encountered.
 310                         * NOTE. These three bytes are encoded in the integer value
 311                         * of the parseop for convenience.
 312                         *
 313                         * In field_flags, preserve the flag bits other than the
 314                         * ACCESS_TYPE bits.
 315                         */
 316
 317                        /* access_type (byte_acc, word_acc, etc.) */
 318
 319                        info->field_flags = (u8)
 320                            ((info->
 321                              field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
 322                             ((u8)((u32)(arg->common.value.integer & 0x07))));
 323
 324                        /* access_attribute (attrib_quick, attrib_byte, etc.) */
 325
 326                        info->attribute = (u8)
 327                            ((arg->common.value.integer >> 8) & 0xFF);
 328
 329                        /* access_length (for serial/buffer protocols) */
 330
 331                        info->access_length = (u8)
 332                            ((arg->common.value.integer >> 16) & 0xFF);
 333                        break;
 334
 335                case AML_INT_CONNECTION_OP:
 336                        /*
 337                         * Clear any previous connection. New connection is used for all
 338                         * fields that follow, similar to access_as
 339                         */
 340                        info->resource_buffer = NULL;
 341                        info->connection_node = NULL;
 342                        info->pin_number_index = 0;
 343
 344                        /*
 345                         * A Connection() is either an actual resource descriptor (buffer)
 346                         * or a named reference to a resource template
 347                         */
 348                        child = arg->common.value.arg;
 349                        if (child->common.aml_opcode == AML_INT_BYTELIST_OP) {
 350                                info->resource_buffer = child->named.data;
 351                                info->resource_length =
 352                                    (u16)child->named.value.integer;
 353                        } else {
 354                                /* Lookup the Connection() namepath, it should already exist */
 355
 356                                status = acpi_ns_lookup(walk_state->scope_info,
 357                                                        child->common.value.
 358                                                        name, ACPI_TYPE_ANY,
 359                                                        ACPI_IMODE_EXECUTE,
 360                                                        ACPI_NS_DONT_OPEN_SCOPE,
 361                                                        walk_state,
 362                                                        &info->connection_node);
 363                                if (ACPI_FAILURE(status)) {
 364                                        ACPI_ERROR_NAMESPACE(walk_state->
 365                                                             scope_info,
 366                                                             child->common.
 367                                                             value.name,
 368                                                             status);
 369                                        return_ACPI_STATUS(status);
 370                                }
 371                        }
 372                        break;
 373
 374                case AML_INT_NAMEDFIELD_OP:
 375
 376                        /* Lookup the name, it should already exist */
 377
 378                        status = acpi_ns_lookup(walk_state->scope_info,
 379                                                (char *)&arg->named.name,
 380                                                info->field_type,
 381                                                ACPI_IMODE_EXECUTE,
 382                                                ACPI_NS_DONT_OPEN_SCOPE,
 383                                                walk_state, &info->field_node);
 384                        if (ACPI_FAILURE(status)) {
 385                                ACPI_ERROR_NAMESPACE(walk_state->scope_info,
 386                                                     (char *)&arg->named.name,
 387                                                     status);
 388                                return_ACPI_STATUS(status);
 389                        } else {
 390                                arg->common.node = info->field_node;
 391                                info->field_bit_length = arg->common.value.size;
 392
 393                                /*
 394                                 * If there is no object attached to the node, this node was
 395                                 * just created and we need to create the field object.
 396                                 * Otherwise, this was a lookup of an existing node and we
 397                                 * don't want to create the field object again.
 398                                 */
 399                                if (!acpi_ns_get_attached_object
 400                                    (info->field_node)) {
 401                                        status = acpi_ex_prep_field_value(info);
 402                                        if (ACPI_FAILURE(status)) {
 403                                                return_ACPI_STATUS(status);
 404                                        }
 405#ifdef ACPI_EXEC_APP
 406                                        name_path =
 407                                            acpi_ns_get_external_pathname(info->
 408                                                                          field_node);
 409                                        obj_desc =
 410                                            acpi_ut_create_integer_object
 411                                            (value);
 412                                        if (ACPI_SUCCESS
 413                                            (ae_lookup_init_file_entry
 414                                             (name_path, &value))) {
 415                                                acpi_ex_write_data_to_field
 416                                                    (obj_desc,
 417                                                     acpi_ns_get_attached_object
 418                                                     (info->field_node),
 419                                                     &result_desc);
 420                                        }
 421                                        acpi_ut_remove_reference(obj_desc);
 422                                        ACPI_FREE(name_path);
 423#endif
 424                                }
 425                        }
 426
 427                        /* Keep track of bit position for the next field */
 428
 429                        position = (u64)info->field_bit_position +
 430                            (u64)arg->common.value.size;
 431
 432                        if (position > ACPI_UINT32_MAX) {
 433                                ACPI_ERROR((AE_INFO,
 434                                            "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
 435                                            ACPI_CAST_PTR(char,
 436                                                          &info->field_node->
 437                                                          name)));
 438                                return_ACPI_STATUS(AE_SUPPORT);
 439                        }
 440
 441                        info->field_bit_position += info->field_bit_length;
 442                        info->pin_number_index++;       /* Index relative to previous Connection() */
 443                        break;
 444
 445                default:
 446
 447                        ACPI_ERROR((AE_INFO,
 448                                    "Invalid opcode in field list: 0x%X",
 449                                    arg->common.aml_opcode));
 450                        return_ACPI_STATUS(AE_AML_BAD_OPCODE);
 451                }
 452
 453                arg = arg->common.next;
 454        }
 455
 456        return_ACPI_STATUS(AE_OK);
 457}
 458
 459/*******************************************************************************
 460 *
 461 * FUNCTION:    acpi_ds_create_field
 462 *
 463 * PARAMETERS:  op              - Op containing the Field definition and args
 464 *              region_node     - Object for the containing Operation Region
 465 *  `           walk_state      - Current method state
 466 *
 467 * RETURN:      Status
 468 *
 469 * DESCRIPTION: Create a new field in the specified operation region
 470 *
 471 ******************************************************************************/
 472
 473acpi_status
 474acpi_ds_create_field(union acpi_parse_object *op,
 475                     struct acpi_namespace_node *region_node,
 476                     struct acpi_walk_state *walk_state)
 477{
 478        acpi_status status;
 479        union acpi_parse_object *arg;
 480        struct acpi_create_field_info info;
 481
 482        ACPI_FUNCTION_TRACE_PTR(ds_create_field, op);
 483
 484        /* First arg is the name of the parent op_region (must already exist) */
 485
 486        arg = op->common.value.arg;
 487
 488        if (!region_node) {
 489                status =
 490                    acpi_ns_lookup(walk_state->scope_info,
 491                                   arg->common.value.name, ACPI_TYPE_REGION,
 492                                   ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
 493                                   walk_state, &region_node);
 494#ifdef ACPI_ASL_COMPILER
 495                status = acpi_ds_create_external_region(status, arg,
 496                                                        arg->common.value.name,
 497                                                        walk_state,
 498                                                        &region_node);
 499#endif
 500                if (ACPI_FAILURE(status)) {
 501                        ACPI_ERROR_NAMESPACE(walk_state->scope_info,
 502                                             arg->common.value.name, status);
 503                        return_ACPI_STATUS(status);
 504                }
 505        }
 506
 507        memset(&info, 0, sizeof(struct acpi_create_field_info));
 508
 509        /* Second arg is the field flags */
 510
 511        arg = arg->common.next;
 512        info.field_flags = (u8) arg->common.value.integer;
 513        info.attribute = 0;
 514
 515        /* Each remaining arg is a Named Field */
 516
 517        info.field_type = ACPI_TYPE_LOCAL_REGION_FIELD;
 518        info.region_node = region_node;
 519
 520        status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
 521        if (info.region_node->object->region.space_id ==
 522            ACPI_ADR_SPACE_PLATFORM_COMM
 523            && !(region_node->object->field.internal_pcc_buffer =
 524                 ACPI_ALLOCATE_ZEROED(info.region_node->object->region.
 525                                      length))) {
 526                return_ACPI_STATUS(AE_NO_MEMORY);
 527        }
 528        return_ACPI_STATUS(status);
 529}
 530
 531/*******************************************************************************
 532 *
 533 * FUNCTION:    acpi_ds_init_field_objects
 534 *
 535 * PARAMETERS:  op              - Op containing the Field definition and args
 536 *  `           walk_state      - Current method state
 537 *
 538 * RETURN:      Status
 539 *
 540 * DESCRIPTION: For each "Field Unit" name in the argument list that is
 541 *              part of the field declaration, enter the name into the
 542 *              namespace.
 543 *
 544 ******************************************************************************/
 545
 546acpi_status
 547acpi_ds_init_field_objects(union acpi_parse_object *op,
 548                           struct acpi_walk_state *walk_state)
 549{
 550        acpi_status status;
 551        union acpi_parse_object *arg = NULL;
 552        struct acpi_namespace_node *node;
 553        u8 type = 0;
 554        u32 flags;
 555
 556        ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op);
 557
 558        /* Execute flag should always be set when this function is entered */
 559
 560        if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
 561                if (walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP) {
 562
 563                        /* bank_field Op is deferred, just return OK */
 564
 565                        return_ACPI_STATUS(AE_OK);
 566                }
 567
 568                ACPI_ERROR((AE_INFO, "Parse deferred mode is not set"));
 569                return_ACPI_STATUS(AE_AML_INTERNAL);
 570        }
 571
 572        /*
 573         * Get the field_list argument for this opcode. This is the start of the
 574         * list of field elements.
 575         */
 576        switch (walk_state->opcode) {
 577        case AML_FIELD_OP:
 578
 579                arg = acpi_ps_get_arg(op, 2);
 580                type = ACPI_TYPE_LOCAL_REGION_FIELD;
 581                break;
 582
 583        case AML_BANK_FIELD_OP:
 584
 585                arg = acpi_ps_get_arg(op, 4);
 586                type = ACPI_TYPE_LOCAL_BANK_FIELD;
 587                break;
 588
 589        case AML_INDEX_FIELD_OP:
 590
 591                arg = acpi_ps_get_arg(op, 3);
 592                type = ACPI_TYPE_LOCAL_INDEX_FIELD;
 593                break;
 594
 595        default:
 596
 597                return_ACPI_STATUS(AE_BAD_PARAMETER);
 598        }
 599
 600        /* Creating new namespace node(s), should not already exist */
 601
 602        flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
 603            ACPI_NS_ERROR_IF_FOUND;
 604
 605        /*
 606         * Mark node(s) temporary if we are executing a normal control
 607         * method. (Don't mark if this is a module-level code method)
 608         */
 609        if (walk_state->method_node &&
 610            !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
 611                flags |= ACPI_NS_TEMPORARY;
 612        }
 613#ifdef ACPI_EXEC_APP
 614        flags |= ACPI_NS_OVERRIDE_IF_FOUND;
 615#endif
 616        /*
 617         * Walk the list of entries in the field_list
 618         * Note: field_list can be of zero length. In this case, Arg will be NULL.
 619         */
 620        while (arg) {
 621                /*
 622                 * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
 623                 * in the field names in order to enter them into the namespace.
 624                 */
 625                if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
 626                        status = acpi_ns_lookup(walk_state->scope_info,
 627                                                (char *)&arg->named.name, type,
 628                                                ACPI_IMODE_LOAD_PASS1, flags,
 629                                                walk_state, &node);
 630                        if (ACPI_FAILURE(status)) {
 631                                ACPI_ERROR_NAMESPACE(walk_state->scope_info,
 632                                                     (char *)&arg->named.name,
 633                                                     status);
 634                                if (status != AE_ALREADY_EXISTS) {
 635                                        return_ACPI_STATUS(status);
 636                                }
 637
 638                                /* Name already exists, just ignore this error */
 639
 640                                status = AE_OK;
 641                        }
 642
 643                        arg->common.node = node;
 644                }
 645
 646                /* Get the next field element in the list */
 647
 648                arg = arg->common.next;
 649        }
 650
 651        return_ACPI_STATUS(AE_OK);
 652}
 653
 654/*******************************************************************************
 655 *
 656 * FUNCTION:    acpi_ds_create_bank_field
 657 *
 658 * PARAMETERS:  op              - Op containing the Field definition and args
 659 *              region_node     - Object for the containing Operation Region
 660 *              walk_state      - Current method state
 661 *
 662 * RETURN:      Status
 663 *
 664 * DESCRIPTION: Create a new bank field in the specified operation region
 665 *
 666 ******************************************************************************/
 667
 668acpi_status
 669acpi_ds_create_bank_field(union acpi_parse_object *op,
 670                          struct acpi_namespace_node *region_node,
 671                          struct acpi_walk_state *walk_state)
 672{
 673        acpi_status status;
 674        union acpi_parse_object *arg;
 675        struct acpi_create_field_info info;
 676
 677        ACPI_FUNCTION_TRACE_PTR(ds_create_bank_field, op);
 678
 679        /* First arg is the name of the parent op_region (must already exist) */
 680
 681        arg = op->common.value.arg;
 682        if (!region_node) {
 683                status =
 684                    acpi_ns_lookup(walk_state->scope_info,
 685                                   arg->common.value.name, ACPI_TYPE_REGION,
 686                                   ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
 687                                   walk_state, &region_node);
 688#ifdef ACPI_ASL_COMPILER
 689                status = acpi_ds_create_external_region(status, arg,
 690                                                        arg->common.value.name,
 691                                                        walk_state,
 692                                                        &region_node);
 693#endif
 694                if (ACPI_FAILURE(status)) {
 695                        ACPI_ERROR_NAMESPACE(walk_state->scope_info,
 696                                             arg->common.value.name, status);
 697                        return_ACPI_STATUS(status);
 698                }
 699        }
 700
 701        /* Second arg is the Bank Register (Field) (must already exist) */
 702
 703        arg = arg->common.next;
 704        status =
 705            acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
 706                           ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
 707                           ACPI_NS_SEARCH_PARENT, walk_state,
 708                           &info.register_node);
 709        if (ACPI_FAILURE(status)) {
 710                ACPI_ERROR_NAMESPACE(walk_state->scope_info,
 711                                     arg->common.value.string, status);
 712                return_ACPI_STATUS(status);
 713        }
 714
 715        /*
 716         * Third arg is the bank_value
 717         * This arg is a term_arg, not a constant
 718         * It will be evaluated later, by acpi_ds_eval_bank_field_operands
 719         */
 720        arg = arg->common.next;
 721
 722        /* Fourth arg is the field flags */
 723
 724        arg = arg->common.next;
 725        info.field_flags = (u8) arg->common.value.integer;
 726
 727        /* Each remaining arg is a Named Field */
 728
 729        info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD;
 730        info.region_node = region_node;
 731
 732        /*
 733         * Use Info.data_register_node to store bank_field Op
 734         * It's safe because data_register_node will never be used when create
 735         * bank field \we store aml_start and aml_length in the bank_field Op for
 736         * late evaluation. Used in acpi_ex_prep_field_value(Info)
 737         *
 738         * TBD: Or, should we add a field in struct acpi_create_field_info, like
 739         * "void *ParentOp"?
 740         */
 741        info.data_register_node = (struct acpi_namespace_node *)op;
 742
 743        status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
 744        return_ACPI_STATUS(status);
 745}
 746
 747/*******************************************************************************
 748 *
 749 * FUNCTION:    acpi_ds_create_index_field
 750 *
 751 * PARAMETERS:  op              - Op containing the Field definition and args
 752 *              region_node     - Object for the containing Operation Region
 753 *  `           walk_state      - Current method state
 754 *
 755 * RETURN:      Status
 756 *
 757 * DESCRIPTION: Create a new index field in the specified operation region
 758 *
 759 ******************************************************************************/
 760
 761acpi_status
 762acpi_ds_create_index_field(union acpi_parse_object *op,
 763                           struct acpi_namespace_node *region_node,
 764                           struct acpi_walk_state *walk_state)
 765{
 766        acpi_status status;
 767        union acpi_parse_object *arg;
 768        struct acpi_create_field_info info;
 769
 770        ACPI_FUNCTION_TRACE_PTR(ds_create_index_field, op);
 771
 772        /* First arg is the name of the Index register (must already exist) */
 773
 774        arg = op->common.value.arg;
 775        status =
 776            acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
 777                           ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
 778                           ACPI_NS_SEARCH_PARENT, walk_state,
 779                           &info.register_node);
 780        if (ACPI_FAILURE(status)) {
 781                ACPI_ERROR_NAMESPACE(walk_state->scope_info,
 782                                     arg->common.value.string, status);
 783                return_ACPI_STATUS(status);
 784        }
 785
 786        /* Second arg is the data register (must already exist) */
 787
 788        arg = arg->common.next;
 789        status =
 790            acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
 791                           ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
 792                           ACPI_NS_SEARCH_PARENT, walk_state,
 793                           &info.data_register_node);
 794        if (ACPI_FAILURE(status)) {
 795                ACPI_ERROR_NAMESPACE(walk_state->scope_info,
 796                                     arg->common.value.string, status);
 797                return_ACPI_STATUS(status);
 798        }
 799
 800        /* Next arg is the field flags */
 801
 802        arg = arg->common.next;
 803        info.field_flags = (u8) arg->common.value.integer;
 804
 805        /* Each remaining arg is a Named Field */
 806
 807        info.field_type = ACPI_TYPE_LOCAL_INDEX_FIELD;
 808        info.region_node = region_node;
 809
 810        status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
 811        return_ACPI_STATUS(status);
 812}
 813