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