linux/drivers/acpi/acpica/dsfield.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Module Name: dsfield - Dispatcher field routines
   4 *
   5 *****************************************************************************/
   6
   7/*
   8 * Copyright (C) 2000 - 2011, Intel Corp.
   9 * All rights reserved.
  10 *
  11 * Redistribution and use in source and binary forms, with or without
  12 * modification, are permitted provided that the following conditions
  13 * are met:
  14 * 1. Redistributions of source code must retain the above copyright
  15 *    notice, this list of conditions, and the following disclaimer,
  16 *    without modification.
  17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18 *    substantially similar to the "NO WARRANTY" disclaimer below
  19 *    ("Disclaimer") and any redistribution must be conditioned upon
  20 *    including a substantially similar Disclaimer requirement for further
  21 *    binary redistribution.
  22 * 3. Neither the names of the above-listed copyright holders nor the names
  23 *    of any contributors may be used to endorse or promote products derived
  24 *    from this software without specific prior written permission.
  25 *
  26 * Alternatively, this software may be distributed under the terms of the
  27 * GNU General Public License ("GPL") version 2 as published by the Free
  28 * Software Foundation.
  29 *
  30 * NO WARRANTY
  31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41 * POSSIBILITY OF SUCH DAMAGES.
  42 */
  43
  44#include <acpi/acpi.h>
  45#include "accommon.h"
  46#include "amlcode.h"
  47#include "acdispat.h"
  48#include "acinterp.h"
  49#include "acnamesp.h"
  50#include "acparser.h"
  51
  52#define _COMPONENT          ACPI_DISPATCHER
  53ACPI_MODULE_NAME("dsfield")
  54
  55/* Local prototypes */
  56static acpi_status
  57acpi_ds_get_field_names(struct acpi_create_field_info *info,
  58                        struct acpi_walk_state *walk_state,
  59                        union acpi_parse_object *arg);
  60
  61/*******************************************************************************
  62 *
  63 * FUNCTION:    acpi_ds_create_buffer_field
  64 *
  65 * PARAMETERS:  Op                  - Current parse op (create_xXField)
  66 *              walk_state          - Current state
  67 *
  68 * RETURN:      Status
  69 *
  70 * DESCRIPTION: Execute the create_field operators:
  71 *              create_bit_field_op,
  72 *              create_byte_field_op,
  73 *              create_word_field_op,
  74 *              create_dword_field_op,
  75 *              create_qword_field_op,
  76 *              create_field_op     (all of which define a field in a buffer)
  77 *
  78 ******************************************************************************/
  79
  80acpi_status
  81acpi_ds_create_buffer_field(union acpi_parse_object *op,
  82                            struct acpi_walk_state *walk_state)
  83{
  84        union acpi_parse_object *arg;
  85        struct acpi_namespace_node *node;
  86        acpi_status status;
  87        union acpi_operand_object *obj_desc;
  88        union acpi_operand_object *second_desc = NULL;
  89        u32 flags;
  90
  91        ACPI_FUNCTION_TRACE(ds_create_buffer_field);
  92
  93        /*
  94         * Get the name_string argument (name of the new buffer_field)
  95         */
  96        if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
  97
  98                /* For create_field, name is the 4th argument */
  99
 100                arg = acpi_ps_get_arg(op, 3);
 101        } else {
 102                /* For all other create_xXXField operators, name is the 3rd argument */
 103
 104                arg = acpi_ps_get_arg(op, 2);
 105        }
 106
 107        if (!arg) {
 108                return_ACPI_STATUS(AE_AML_NO_OPERAND);
 109        }
 110
 111        if (walk_state->deferred_node) {
 112                node = walk_state->deferred_node;
 113                status = AE_OK;
 114        } else {
 115                /* Execute flag should always be set when this function is entered */
 116
 117                if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
 118                        return_ACPI_STATUS(AE_AML_INTERNAL);
 119                }
 120
 121                /* Creating new namespace node, should not already exist */
 122
 123                flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
 124                    ACPI_NS_ERROR_IF_FOUND;
 125
 126                /*
 127                 * Mark node temporary if we are executing a normal control
 128                 * method. (Don't mark if this is a module-level code method)
 129                 */
 130                if (walk_state->method_node &&
 131                    !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
 132                        flags |= ACPI_NS_TEMPORARY;
 133                }
 134
 135                /* Enter the name_string into the namespace */
 136
 137                status =
 138                    acpi_ns_lookup(walk_state->scope_info,
 139                                   arg->common.value.string, ACPI_TYPE_ANY,
 140                                   ACPI_IMODE_LOAD_PASS1, flags, walk_state,
 141                                   &node);
 142                if (ACPI_FAILURE(status)) {
 143                        ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
 144                        return_ACPI_STATUS(status);
 145                }
 146        }
 147
 148        /*
 149         * We could put the returned object (Node) on the object stack for later,
 150         * but for now, we will put it in the "op" object that the parser uses,
 151         * so we can get it again at the end of this scope.
 152         */
 153        op->common.node = node;
 154
 155        /*
 156         * If there is no object attached to the node, this node was just created
 157         * and we need to create the field object. Otherwise, this was a lookup
 158         * of an existing node and we don't want to create the field object again.
 159         */
 160        obj_desc = acpi_ns_get_attached_object(node);
 161        if (obj_desc) {
 162                return_ACPI_STATUS(AE_OK);
 163        }
 164
 165        /*
 166         * The Field definition is not fully parsed at this time.
 167         * (We must save the address of the AML for the buffer and index operands)
 168         */
 169
 170        /* Create the buffer field object */
 171
 172        obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER_FIELD);
 173        if (!obj_desc) {
 174                status = AE_NO_MEMORY;
 175                goto cleanup;
 176        }
 177
 178        /*
 179         * Remember location in AML stream of the field unit opcode and operands --
 180         * since the buffer and index operands must be evaluated.
 181         */
 182        second_desc = obj_desc->common.next_object;
 183        second_desc->extra.aml_start = op->named.data;
 184        second_desc->extra.aml_length = op->named.length;
 185        obj_desc->buffer_field.node = node;
 186
 187        /* Attach constructed field descriptors to parent node */
 188
 189        status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_BUFFER_FIELD);
 190        if (ACPI_FAILURE(status)) {
 191                goto cleanup;
 192        }
 193
 194      cleanup:
 195
 196        /* Remove local reference to the object */
 197
 198        acpi_ut_remove_reference(obj_desc);
 199        return_ACPI_STATUS(status);
 200}
 201
 202/*******************************************************************************
 203 *
 204 * FUNCTION:    acpi_ds_get_field_names
 205 *
 206 * PARAMETERS:  Info            - create_field info structure
 207 *  `           walk_state      - Current method state
 208 *              Arg             - First parser arg for the field name list
 209 *
 210 * RETURN:      Status
 211 *
 212 * DESCRIPTION: Process all named fields in a field declaration.  Names are
 213 *              entered into the namespace.
 214 *
 215 ******************************************************************************/
 216
 217static acpi_status
 218acpi_ds_get_field_names(struct acpi_create_field_info *info,
 219                        struct acpi_walk_state *walk_state,
 220                        union acpi_parse_object *arg)
 221{
 222        acpi_status status;
 223        u64 position;
 224
 225        ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info);
 226
 227        /* First field starts at bit zero */
 228
 229        info->field_bit_position = 0;
 230
 231        /* Process all elements in the field list (of parse nodes) */
 232
 233        while (arg) {
 234                /*
 235                 * Three types of field elements are handled:
 236                 * 1) Offset - specifies a bit offset
 237                 * 2) access_as - changes the access mode
 238                 * 3) Name - Enters a new named field into the namespace
 239                 */
 240                switch (arg->common.aml_opcode) {
 241                case AML_INT_RESERVEDFIELD_OP:
 242
 243                        position = (u64) info->field_bit_position
 244                            + (u64) arg->common.value.size;
 245
 246                        if (position > ACPI_UINT32_MAX) {
 247                                ACPI_ERROR((AE_INFO,
 248                                            "Bit offset within field too large (> 0xFFFFFFFF)"));
 249                                return_ACPI_STATUS(AE_SUPPORT);
 250                        }
 251
 252                        info->field_bit_position = (u32) position;
 253                        break;
 254
 255                case AML_INT_ACCESSFIELD_OP:
 256
 257                        /*
 258                         * Get a new access_type and access_attribute -- to be used for all
 259                         * field units that follow, until field end or another access_as
 260                         * keyword.
 261                         *
 262                         * In field_flags, preserve the flag bits other than the
 263                         * ACCESS_TYPE bits
 264                         */
 265                        info->field_flags = (u8)
 266                            ((info->
 267                              field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
 268                             ((u8) ((u32) arg->common.value.integer >> 8)));
 269
 270                        info->attribute = (u8) (arg->common.value.integer);
 271                        break;
 272
 273                case AML_INT_NAMEDFIELD_OP:
 274
 275                        /* Lookup the name, it should already exist */
 276
 277                        status = acpi_ns_lookup(walk_state->scope_info,
 278                                                (char *)&arg->named.name,
 279                                                info->field_type,
 280                                                ACPI_IMODE_EXECUTE,
 281                                                ACPI_NS_DONT_OPEN_SCOPE,
 282                                                walk_state, &info->field_node);
 283                        if (ACPI_FAILURE(status)) {
 284                                ACPI_ERROR_NAMESPACE((char *)&arg->named.name,
 285                                                     status);
 286                                return_ACPI_STATUS(status);
 287                        } else {
 288                                arg->common.node = info->field_node;
 289                                info->field_bit_length = arg->common.value.size;
 290
 291                                /*
 292                                 * If there is no object attached to the node, this node was
 293                                 * just created and we need to create the field object.
 294                                 * Otherwise, this was a lookup of an existing node and we
 295                                 * don't want to create the field object again.
 296                                 */
 297                                if (!acpi_ns_get_attached_object
 298                                    (info->field_node)) {
 299                                        status = acpi_ex_prep_field_value(info);
 300                                        if (ACPI_FAILURE(status)) {
 301                                                return_ACPI_STATUS(status);
 302                                        }
 303                                }
 304                        }
 305
 306                        /* Keep track of bit position for the next field */
 307
 308                        position = (u64) info->field_bit_position
 309                            + (u64) arg->common.value.size;
 310
 311                        if (position > ACPI_UINT32_MAX) {
 312                                ACPI_ERROR((AE_INFO,
 313                                            "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
 314                                            ACPI_CAST_PTR(char,
 315                                                          &info->field_node->
 316                                                          name)));
 317                                return_ACPI_STATUS(AE_SUPPORT);
 318                        }
 319
 320                        info->field_bit_position += info->field_bit_length;
 321                        break;
 322
 323                default:
 324
 325                        ACPI_ERROR((AE_INFO,
 326                                    "Invalid opcode in field list: 0x%X",
 327                                    arg->common.aml_opcode));
 328                        return_ACPI_STATUS(AE_AML_BAD_OPCODE);
 329                }
 330
 331                arg = arg->common.next;
 332        }
 333
 334        return_ACPI_STATUS(AE_OK);
 335}
 336
 337/*******************************************************************************
 338 *
 339 * FUNCTION:    acpi_ds_create_field
 340 *
 341 * PARAMETERS:  Op              - Op containing the Field definition and args
 342 *              region_node     - Object for the containing Operation Region
 343 *  `           walk_state      - Current method state
 344 *
 345 * RETURN:      Status
 346 *
 347 * DESCRIPTION: Create a new field in the specified operation region
 348 *
 349 ******************************************************************************/
 350
 351acpi_status
 352acpi_ds_create_field(union acpi_parse_object *op,
 353                     struct acpi_namespace_node *region_node,
 354                     struct acpi_walk_state *walk_state)
 355{
 356        acpi_status status;
 357        union acpi_parse_object *arg;
 358        struct acpi_create_field_info info;
 359
 360        ACPI_FUNCTION_TRACE_PTR(ds_create_field, op);
 361
 362        /* First arg is the name of the parent op_region (must already exist) */
 363
 364        arg = op->common.value.arg;
 365        if (!region_node) {
 366                status =
 367                    acpi_ns_lookup(walk_state->scope_info,
 368                                   arg->common.value.name, ACPI_TYPE_REGION,
 369                                   ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
 370                                   walk_state, &region_node);
 371                if (ACPI_FAILURE(status)) {
 372                        ACPI_ERROR_NAMESPACE(arg->common.value.name, status);
 373                        return_ACPI_STATUS(status);
 374                }
 375        }
 376
 377        /* Second arg is the field flags */
 378
 379        arg = arg->common.next;
 380        info.field_flags = (u8) arg->common.value.integer;
 381        info.attribute = 0;
 382
 383        /* Each remaining arg is a Named Field */
 384
 385        info.field_type = ACPI_TYPE_LOCAL_REGION_FIELD;
 386        info.region_node = region_node;
 387
 388        status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
 389
 390        return_ACPI_STATUS(status);
 391}
 392
 393/*******************************************************************************
 394 *
 395 * FUNCTION:    acpi_ds_init_field_objects
 396 *
 397 * PARAMETERS:  Op              - Op containing the Field definition and args
 398 *  `           walk_state      - Current method state
 399 *
 400 * RETURN:      Status
 401 *
 402 * DESCRIPTION: For each "Field Unit" name in the argument list that is
 403 *              part of the field declaration, enter the name into the
 404 *              namespace.
 405 *
 406 ******************************************************************************/
 407
 408acpi_status
 409acpi_ds_init_field_objects(union acpi_parse_object *op,
 410                           struct acpi_walk_state *walk_state)
 411{
 412        acpi_status status;
 413        union acpi_parse_object *arg = NULL;
 414        struct acpi_namespace_node *node;
 415        u8 type = 0;
 416        u32 flags;
 417
 418        ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op);
 419
 420        /* Execute flag should always be set when this function is entered */
 421
 422        if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
 423                if (walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP) {
 424
 425                        /* bank_field Op is deferred, just return OK */
 426
 427                        return_ACPI_STATUS(AE_OK);
 428                }
 429
 430                return_ACPI_STATUS(AE_AML_INTERNAL);
 431        }
 432
 433        /*
 434         * Get the field_list argument for this opcode. This is the start of the
 435         * list of field elements.
 436         */
 437        switch (walk_state->opcode) {
 438        case AML_FIELD_OP:
 439                arg = acpi_ps_get_arg(op, 2);
 440                type = ACPI_TYPE_LOCAL_REGION_FIELD;
 441                break;
 442
 443        case AML_BANK_FIELD_OP:
 444                arg = acpi_ps_get_arg(op, 4);
 445                type = ACPI_TYPE_LOCAL_BANK_FIELD;
 446                break;
 447
 448        case AML_INDEX_FIELD_OP:
 449                arg = acpi_ps_get_arg(op, 3);
 450                type = ACPI_TYPE_LOCAL_INDEX_FIELD;
 451                break;
 452
 453        default:
 454                return_ACPI_STATUS(AE_BAD_PARAMETER);
 455        }
 456
 457        /* Creating new namespace node(s), should not already exist */
 458
 459        flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
 460            ACPI_NS_ERROR_IF_FOUND;
 461
 462        /*
 463         * Mark node(s) temporary if we are executing a normal control
 464         * method. (Don't mark if this is a module-level code method)
 465         */
 466        if (walk_state->method_node &&
 467            !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
 468                flags |= ACPI_NS_TEMPORARY;
 469        }
 470
 471        /*
 472         * Walk the list of entries in the field_list
 473         * Note: field_list can be of zero length. In this case, Arg will be NULL.
 474         */
 475        while (arg) {
 476                /*
 477                 * Ignore OFFSET and ACCESSAS terms here; we are only interested in the
 478                 * field names in order to enter them into the namespace.
 479                 */
 480                if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
 481                        status = acpi_ns_lookup(walk_state->scope_info,
 482                                                (char *)&arg->named.name, type,
 483                                                ACPI_IMODE_LOAD_PASS1, flags,
 484                                                walk_state, &node);
 485                        if (ACPI_FAILURE(status)) {
 486                                ACPI_ERROR_NAMESPACE((char *)&arg->named.name,
 487                                                     status);
 488                                if (status != AE_ALREADY_EXISTS) {
 489                                        return_ACPI_STATUS(status);
 490                                }
 491
 492                                /* Name already exists, just ignore this error */
 493
 494                                status = AE_OK;
 495                        }
 496
 497                        arg->common.node = node;
 498                }
 499
 500                /* Get the next field element in the list */
 501
 502                arg = arg->common.next;
 503        }
 504
 505        return_ACPI_STATUS(AE_OK);
 506}
 507
 508/*******************************************************************************
 509 *
 510 * FUNCTION:    acpi_ds_create_bank_field
 511 *
 512 * PARAMETERS:  Op              - Op containing the Field definition and args
 513 *              region_node     - Object for the containing Operation Region
 514 *              walk_state      - Current method state
 515 *
 516 * RETURN:      Status
 517 *
 518 * DESCRIPTION: Create a new bank field in the specified operation region
 519 *
 520 ******************************************************************************/
 521
 522acpi_status
 523acpi_ds_create_bank_field(union acpi_parse_object *op,
 524                          struct acpi_namespace_node *region_node,
 525                          struct acpi_walk_state *walk_state)
 526{
 527        acpi_status status;
 528        union acpi_parse_object *arg;
 529        struct acpi_create_field_info info;
 530
 531        ACPI_FUNCTION_TRACE_PTR(ds_create_bank_field, op);
 532
 533        /* First arg is the name of the parent op_region (must already exist) */
 534
 535        arg = op->common.value.arg;
 536        if (!region_node) {
 537                status =
 538                    acpi_ns_lookup(walk_state->scope_info,
 539                                   arg->common.value.name, ACPI_TYPE_REGION,
 540                                   ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
 541                                   walk_state, &region_node);
 542                if (ACPI_FAILURE(status)) {
 543                        ACPI_ERROR_NAMESPACE(arg->common.value.name, status);
 544                        return_ACPI_STATUS(status);
 545                }
 546        }
 547
 548        /* Second arg is the Bank Register (Field) (must already exist) */
 549
 550        arg = arg->common.next;
 551        status =
 552            acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
 553                           ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
 554                           ACPI_NS_SEARCH_PARENT, walk_state,
 555                           &info.register_node);
 556        if (ACPI_FAILURE(status)) {
 557                ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
 558                return_ACPI_STATUS(status);
 559        }
 560
 561        /*
 562         * Third arg is the bank_value
 563         * This arg is a term_arg, not a constant
 564         * It will be evaluated later, by acpi_ds_eval_bank_field_operands
 565         */
 566        arg = arg->common.next;
 567
 568        /* Fourth arg is the field flags */
 569
 570        arg = arg->common.next;
 571        info.field_flags = (u8) arg->common.value.integer;
 572
 573        /* Each remaining arg is a Named Field */
 574
 575        info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD;
 576        info.region_node = region_node;
 577
 578        /*
 579         * Use Info.data_register_node to store bank_field Op
 580         * It's safe because data_register_node will never be used when create bank field
 581         * We store aml_start and aml_length in the bank_field Op for late evaluation
 582         * Used in acpi_ex_prep_field_value(Info)
 583         *
 584         * TBD: Or, should we add a field in struct acpi_create_field_info, like "void *ParentOp"?
 585         */
 586        info.data_register_node = (struct acpi_namespace_node *)op;
 587
 588        status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
 589        return_ACPI_STATUS(status);
 590}
 591
 592/*******************************************************************************
 593 *
 594 * FUNCTION:    acpi_ds_create_index_field
 595 *
 596 * PARAMETERS:  Op              - Op containing the Field definition and args
 597 *              region_node     - Object for the containing Operation Region
 598 *  `           walk_state      - Current method state
 599 *
 600 * RETURN:      Status
 601 *
 602 * DESCRIPTION: Create a new index field in the specified operation region
 603 *
 604 ******************************************************************************/
 605
 606acpi_status
 607acpi_ds_create_index_field(union acpi_parse_object *op,
 608                           struct acpi_namespace_node *region_node,
 609                           struct acpi_walk_state *walk_state)
 610{
 611        acpi_status status;
 612        union acpi_parse_object *arg;
 613        struct acpi_create_field_info info;
 614
 615        ACPI_FUNCTION_TRACE_PTR(ds_create_index_field, op);
 616
 617        /* First arg is the name of the Index register (must already exist) */
 618
 619        arg = op->common.value.arg;
 620        status =
 621            acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
 622                           ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
 623                           ACPI_NS_SEARCH_PARENT, walk_state,
 624                           &info.register_node);
 625        if (ACPI_FAILURE(status)) {
 626                ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
 627                return_ACPI_STATUS(status);
 628        }
 629
 630        /* Second arg is the data register (must already exist) */
 631
 632        arg = arg->common.next;
 633        status =
 634            acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
 635                           ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
 636                           ACPI_NS_SEARCH_PARENT, walk_state,
 637                           &info.data_register_node);
 638        if (ACPI_FAILURE(status)) {
 639                ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
 640                return_ACPI_STATUS(status);
 641        }
 642
 643        /* Next arg is the field flags */
 644
 645        arg = arg->common.next;
 646        info.field_flags = (u8) arg->common.value.integer;
 647
 648        /* Each remaining arg is a Named Field */
 649
 650        info.field_type = ACPI_TYPE_LOCAL_INDEX_FIELD;
 651        info.region_node = region_node;
 652
 653        status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
 654
 655        return_ACPI_STATUS(status);
 656}
 657