linux/drivers/acpi/acpica/nsaccess.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/*******************************************************************************
   3 *
   4 * Module Name: nsaccess - Top-level functions for accessing ACPI namespace
   5 *
   6 ******************************************************************************/
   7
   8#include <acpi/acpi.h>
   9#include "accommon.h"
  10#include "amlcode.h"
  11#include "acnamesp.h"
  12#include "acdispat.h"
  13
  14#ifdef ACPI_ASL_COMPILER
  15#include "acdisasm.h"
  16#endif
  17
  18#define _COMPONENT          ACPI_NAMESPACE
  19ACPI_MODULE_NAME("nsaccess")
  20
  21/*******************************************************************************
  22 *
  23 * FUNCTION:    acpi_ns_root_initialize
  24 *
  25 * PARAMETERS:  None
  26 *
  27 * RETURN:      Status
  28 *
  29 * DESCRIPTION: Allocate and initialize the default root named objects
  30 *
  31 * MUTEX:       Locks namespace for entire execution
  32 *
  33 ******************************************************************************/
  34acpi_status acpi_ns_root_initialize(void)
  35{
  36        acpi_status status;
  37        const struct acpi_predefined_names *init_val = NULL;
  38        struct acpi_namespace_node *new_node;
  39        union acpi_operand_object *obj_desc;
  40        acpi_string val = NULL;
  41
  42        ACPI_FUNCTION_TRACE(ns_root_initialize);
  43
  44        status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
  45        if (ACPI_FAILURE(status)) {
  46                return_ACPI_STATUS(status);
  47        }
  48
  49        /*
  50         * The global root ptr is initially NULL, so a non-NULL value indicates
  51         * that acpi_ns_root_initialize() has already been called; just return.
  52         */
  53        if (acpi_gbl_root_node) {
  54                status = AE_OK;
  55                goto unlock_and_exit;
  56        }
  57
  58        /*
  59         * Tell the rest of the subsystem that the root is initialized
  60         * (This is OK because the namespace is locked)
  61         */
  62        acpi_gbl_root_node = &acpi_gbl_root_node_struct;
  63
  64        /* Enter the pre-defined names in the name table */
  65
  66        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  67                          "Entering predefined entries into namespace\n"));
  68
  69        for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) {
  70
  71                /* _OSI is optional for now, will be permanent later */
  72
  73                if (!strcmp(init_val->name, "_OSI")
  74                    && !acpi_gbl_create_osi_method) {
  75                        continue;
  76                }
  77
  78                status =
  79                    acpi_ns_lookup(NULL, ACPI_CAST_PTR(char, init_val->name),
  80                                   init_val->type, ACPI_IMODE_LOAD_PASS2,
  81                                   ACPI_NS_NO_UPSEARCH, NULL, &new_node);
  82                if (ACPI_FAILURE(status)) {
  83                        ACPI_EXCEPTION((AE_INFO, status,
  84                                        "Could not create predefined name %s",
  85                                        init_val->name));
  86                        continue;
  87                }
  88
  89                /*
  90                 * Name entered successfully. If entry in pre_defined_names[] specifies
  91                 * an initial value, create the initial value.
  92                 */
  93                if (init_val->val) {
  94                        status = acpi_os_predefined_override(init_val, &val);
  95                        if (ACPI_FAILURE(status)) {
  96                                ACPI_ERROR((AE_INFO,
  97                                            "Could not override predefined %s",
  98                                            init_val->name));
  99                        }
 100
 101                        if (!val) {
 102                                val = init_val->val;
 103                        }
 104
 105                        /*
 106                         * Entry requests an initial value, allocate a
 107                         * descriptor for it.
 108                         */
 109                        obj_desc =
 110                            acpi_ut_create_internal_object(init_val->type);
 111                        if (!obj_desc) {
 112                                status = AE_NO_MEMORY;
 113                                goto unlock_and_exit;
 114                        }
 115
 116                        /*
 117                         * Convert value string from table entry to
 118                         * internal representation. Only types actually
 119                         * used for initial values are implemented here.
 120                         */
 121                        switch (init_val->type) {
 122                        case ACPI_TYPE_METHOD:
 123
 124                                obj_desc->method.param_count =
 125                                    (u8) ACPI_TO_INTEGER(val);
 126                                obj_desc->common.flags |= AOPOBJ_DATA_VALID;
 127
 128#if defined (ACPI_ASL_COMPILER)
 129
 130                                /* Save the parameter count for the iASL compiler */
 131
 132                                new_node->value = obj_desc->method.param_count;
 133#else
 134                                /* Mark this as a very SPECIAL method */
 135
 136                                obj_desc->method.info_flags =
 137                                    ACPI_METHOD_INTERNAL_ONLY;
 138                                obj_desc->method.dispatch.implementation =
 139                                    acpi_ut_osi_implementation;
 140#endif
 141                                break;
 142
 143                        case ACPI_TYPE_INTEGER:
 144
 145                                obj_desc->integer.value = ACPI_TO_INTEGER(val);
 146                                break;
 147
 148                        case ACPI_TYPE_STRING:
 149
 150                                /* Build an object around the static string */
 151
 152                                obj_desc->string.length = (u32)strlen(val);
 153                                obj_desc->string.pointer = val;
 154                                obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
 155                                break;
 156
 157                        case ACPI_TYPE_MUTEX:
 158
 159                                obj_desc->mutex.node = new_node;
 160                                obj_desc->mutex.sync_level =
 161                                    (u8) (ACPI_TO_INTEGER(val) - 1);
 162
 163                                /* Create a mutex */
 164
 165                                status =
 166                                    acpi_os_create_mutex(&obj_desc->mutex.
 167                                                         os_mutex);
 168                                if (ACPI_FAILURE(status)) {
 169                                        acpi_ut_remove_reference(obj_desc);
 170                                        goto unlock_and_exit;
 171                                }
 172
 173                                /* Special case for ACPI Global Lock */
 174
 175                                if (strcmp(init_val->name, "_GL_") == 0) {
 176                                        acpi_gbl_global_lock_mutex = obj_desc;
 177
 178                                        /* Create additional counting semaphore for global lock */
 179
 180                                        status =
 181                                            acpi_os_create_semaphore(1, 0,
 182                                                                     &acpi_gbl_global_lock_semaphore);
 183                                        if (ACPI_FAILURE(status)) {
 184                                                acpi_ut_remove_reference
 185                                                    (obj_desc);
 186                                                goto unlock_and_exit;
 187                                        }
 188                                }
 189                                break;
 190
 191                        default:
 192
 193                                ACPI_ERROR((AE_INFO,
 194                                            "Unsupported initial type value 0x%X",
 195                                            init_val->type));
 196                                acpi_ut_remove_reference(obj_desc);
 197                                obj_desc = NULL;
 198                                continue;
 199                        }
 200
 201                        /* Store pointer to value descriptor in the Node */
 202
 203                        status = acpi_ns_attach_object(new_node, obj_desc,
 204                                                       obj_desc->common.type);
 205
 206                        /* Remove local reference to the object */
 207
 208                        acpi_ut_remove_reference(obj_desc);
 209                }
 210        }
 211
 212unlock_and_exit:
 213        (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 214
 215        /* Save a handle to "_GPE", it is always present */
 216
 217        if (ACPI_SUCCESS(status)) {
 218                status = acpi_ns_get_node(NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH,
 219                                          &acpi_gbl_fadt_gpe_device);
 220        }
 221
 222        return_ACPI_STATUS(status);
 223}
 224
 225/*******************************************************************************
 226 *
 227 * FUNCTION:    acpi_ns_lookup
 228 *
 229 * PARAMETERS:  scope_info      - Current scope info block
 230 *              pathname        - Search pathname, in internal format
 231 *                                (as represented in the AML stream)
 232 *              type            - Type associated with name
 233 *              interpreter_mode - IMODE_LOAD_PASS2 => add name if not found
 234 *              flags           - Flags describing the search restrictions
 235 *              walk_state      - Current state of the walk
 236 *              return_node     - Where the Node is placed (if found
 237 *                                or created successfully)
 238 *
 239 * RETURN:      Status
 240 *
 241 * DESCRIPTION: Find or enter the passed name in the name space.
 242 *              Log an error if name not found in Exec mode.
 243 *
 244 * MUTEX:       Assumes namespace is locked.
 245 *
 246 ******************************************************************************/
 247
 248acpi_status
 249acpi_ns_lookup(union acpi_generic_state *scope_info,
 250               char *pathname,
 251               acpi_object_type type,
 252               acpi_interpreter_mode interpreter_mode,
 253               u32 flags,
 254               struct acpi_walk_state *walk_state,
 255               struct acpi_namespace_node **return_node)
 256{
 257        acpi_status status;
 258        char *path = pathname;
 259        char *external_path;
 260        struct acpi_namespace_node *prefix_node;
 261        struct acpi_namespace_node *current_node = NULL;
 262        struct acpi_namespace_node *this_node = NULL;
 263        u32 num_segments;
 264        u32 num_carats;
 265        acpi_name simple_name;
 266        acpi_object_type type_to_check_for;
 267        acpi_object_type this_search_type;
 268        u32 search_parent_flag = ACPI_NS_SEARCH_PARENT;
 269        u32 local_flags;
 270
 271        ACPI_FUNCTION_TRACE(ns_lookup);
 272
 273        if (!return_node) {
 274                return_ACPI_STATUS(AE_BAD_PARAMETER);
 275        }
 276
 277        local_flags = flags &
 278            ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_OVERRIDE_IF_FOUND |
 279              ACPI_NS_SEARCH_PARENT);
 280        *return_node = ACPI_ENTRY_NOT_FOUND;
 281        acpi_gbl_ns_lookup_count++;
 282
 283        if (!acpi_gbl_root_node) {
 284                return_ACPI_STATUS(AE_NO_NAMESPACE);
 285        }
 286
 287        /* Get the prefix scope. A null scope means use the root scope */
 288
 289        if ((!scope_info) || (!scope_info->scope.node)) {
 290                ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 291                                  "Null scope prefix, using root node (%p)\n",
 292                                  acpi_gbl_root_node));
 293
 294                prefix_node = acpi_gbl_root_node;
 295        } else {
 296                prefix_node = scope_info->scope.node;
 297                if (ACPI_GET_DESCRIPTOR_TYPE(prefix_node) !=
 298                    ACPI_DESC_TYPE_NAMED) {
 299                        ACPI_ERROR((AE_INFO, "%p is not a namespace node [%s]",
 300                                    prefix_node,
 301                                    acpi_ut_get_descriptor_name(prefix_node)));
 302                        return_ACPI_STATUS(AE_AML_INTERNAL);
 303                }
 304
 305                if (!(flags & ACPI_NS_PREFIX_IS_SCOPE)) {
 306                        /*
 307                         * This node might not be a actual "scope" node (such as a
 308                         * Device/Method, etc.)  It could be a Package or other object
 309                         * node. Backup up the tree to find the containing scope node.
 310                         */
 311                        while (!acpi_ns_opens_scope(prefix_node->type) &&
 312                               prefix_node->type != ACPI_TYPE_ANY) {
 313                                prefix_node = prefix_node->parent;
 314                        }
 315                }
 316        }
 317
 318        /* Save type. TBD: may be no longer necessary */
 319
 320        type_to_check_for = type;
 321
 322        /*
 323         * Begin examination of the actual pathname
 324         */
 325        if (!pathname) {
 326
 327                /* A Null name_path is allowed and refers to the root */
 328
 329                num_segments = 0;
 330                this_node = acpi_gbl_root_node;
 331                path = "";
 332
 333                ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 334                                  "Null Pathname (Zero segments), Flags=%X\n",
 335                                  flags));
 336        } else {
 337                /*
 338                 * Name pointer is valid (and must be in internal name format)
 339                 *
 340                 * Check for scope prefixes:
 341                 *
 342                 * As represented in the AML stream, a namepath consists of an
 343                 * optional scope prefix followed by a name segment part.
 344                 *
 345                 * If present, the scope prefix is either a Root Prefix (in
 346                 * which case the name is fully qualified), or one or more
 347                 * Parent Prefixes (in which case the name's scope is relative
 348                 * to the current scope).
 349                 */
 350                if (*path == (u8) AML_ROOT_PREFIX) {
 351
 352                        /* Pathname is fully qualified, start from the root */
 353
 354                        this_node = acpi_gbl_root_node;
 355                        search_parent_flag = ACPI_NS_NO_UPSEARCH;
 356
 357                        /* Point to name segment part */
 358
 359                        path++;
 360
 361                        ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 362                                          "Path is absolute from root [%p]\n",
 363                                          this_node));
 364                } else {
 365                        /* Pathname is relative to current scope, start there */
 366
 367                        ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 368                                          "Searching relative to prefix scope [%4.4s] (%p)\n",
 369                                          acpi_ut_get_node_name(prefix_node),
 370                                          prefix_node));
 371
 372                        /*
 373                         * Handle multiple Parent Prefixes (carat) by just getting
 374                         * the parent node for each prefix instance.
 375                         */
 376                        this_node = prefix_node;
 377                        num_carats = 0;
 378                        while (*path == (u8) AML_PARENT_PREFIX) {
 379
 380                                /* Name is fully qualified, no search rules apply */
 381
 382                                search_parent_flag = ACPI_NS_NO_UPSEARCH;
 383
 384                                /*
 385                                 * Point past this prefix to the name segment
 386                                 * part or the next Parent Prefix
 387                                 */
 388                                path++;
 389
 390                                /* Backup to the parent node */
 391
 392                                num_carats++;
 393                                this_node = this_node->parent;
 394                                if (!this_node) {
 395                                        /*
 396                                         * Current scope has no parent scope. Externalize
 397                                         * the internal path for error message.
 398                                         */
 399                                        status =
 400                                            acpi_ns_externalize_name
 401                                            (ACPI_UINT32_MAX, pathname, NULL,
 402                                             &external_path);
 403                                        if (ACPI_SUCCESS(status)) {
 404                                                ACPI_ERROR((AE_INFO,
 405                                                            "%s: Path has too many parent prefixes (^)",
 406                                                            external_path));
 407
 408                                                ACPI_FREE(external_path);
 409                                        }
 410
 411                                        return_ACPI_STATUS(AE_NOT_FOUND);
 412                                }
 413                        }
 414
 415                        if (search_parent_flag == ACPI_NS_NO_UPSEARCH) {
 416                                ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 417                                                  "Search scope is [%4.4s], path has %u carat(s)\n",
 418                                                  acpi_ut_get_node_name
 419                                                  (this_node), num_carats));
 420                        }
 421                }
 422
 423                /*
 424                 * Determine the number of ACPI name segments in this pathname.
 425                 *
 426                 * The segment part consists of either:
 427                 *  - A Null name segment (0)
 428                 *  - A dual_name_prefix followed by two 4-byte name segments
 429                 *  - A multi_name_prefix followed by a byte indicating the
 430                 *      number of segments and the segments themselves.
 431                 *  - A single 4-byte name segment
 432                 *
 433                 * Examine the name prefix opcode, if any, to determine the number of
 434                 * segments.
 435                 */
 436                switch (*path) {
 437                case 0:
 438                        /*
 439                         * Null name after a root or parent prefixes. We already
 440                         * have the correct target node and there are no name segments.
 441                         */
 442                        num_segments = 0;
 443                        type = this_node->type;
 444
 445                        ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 446                                          "Prefix-only Pathname (Zero name segments), Flags=%X\n",
 447                                          flags));
 448                        break;
 449
 450                case AML_DUAL_NAME_PREFIX:
 451
 452                        /* More than one name_seg, search rules do not apply */
 453
 454                        search_parent_flag = ACPI_NS_NO_UPSEARCH;
 455
 456                        /* Two segments, point to first name segment */
 457
 458                        num_segments = 2;
 459                        path++;
 460
 461                        ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 462                                          "Dual Pathname (2 segments, Flags=%X)\n",
 463                                          flags));
 464                        break;
 465
 466                case AML_MULTI_NAME_PREFIX:
 467
 468                        /* More than one name_seg, search rules do not apply */
 469
 470                        search_parent_flag = ACPI_NS_NO_UPSEARCH;
 471
 472                        /* Extract segment count, point to first name segment */
 473
 474                        path++;
 475                        num_segments = (u32) (u8) * path;
 476                        path++;
 477
 478                        ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 479                                          "Multi Pathname (%u Segments, Flags=%X)\n",
 480                                          num_segments, flags));
 481                        break;
 482
 483                default:
 484                        /*
 485                         * Not a Null name, no Dual or Multi prefix, hence there is
 486                         * only one name segment and Pathname is already pointing to it.
 487                         */
 488                        num_segments = 1;
 489
 490                        ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 491                                          "Simple Pathname (1 segment, Flags=%X)\n",
 492                                          flags));
 493                        break;
 494                }
 495
 496                ACPI_DEBUG_EXEC(acpi_ns_print_pathname(num_segments, path));
 497        }
 498
 499        /*
 500         * Search namespace for each segment of the name. Loop through and
 501         * verify (or add to the namespace) each name segment.
 502         *
 503         * The object type is significant only at the last name
 504         * segment. (We don't care about the types along the path, only
 505         * the type of the final target object.)
 506         */
 507        this_search_type = ACPI_TYPE_ANY;
 508        current_node = this_node;
 509        while (num_segments && current_node) {
 510                num_segments--;
 511                if (!num_segments) {
 512
 513                        /* This is the last segment, enable typechecking */
 514
 515                        this_search_type = type;
 516
 517                        /*
 518                         * Only allow automatic parent search (search rules) if the caller
 519                         * requested it AND we have a single, non-fully-qualified name_seg
 520                         */
 521                        if ((search_parent_flag != ACPI_NS_NO_UPSEARCH) &&
 522                            (flags & ACPI_NS_SEARCH_PARENT)) {
 523                                local_flags |= ACPI_NS_SEARCH_PARENT;
 524                        }
 525
 526                        /* Set error flag according to caller */
 527
 528                        if (flags & ACPI_NS_ERROR_IF_FOUND) {
 529                                local_flags |= ACPI_NS_ERROR_IF_FOUND;
 530                        }
 531
 532                        /* Set override flag according to caller */
 533
 534                        if (flags & ACPI_NS_OVERRIDE_IF_FOUND) {
 535                                local_flags |= ACPI_NS_OVERRIDE_IF_FOUND;
 536                        }
 537                }
 538
 539                /* Extract one ACPI name from the front of the pathname */
 540
 541                ACPI_MOVE_32_TO_32(&simple_name, path);
 542
 543                /* Try to find the single (4 character) ACPI name */
 544
 545                status =
 546                    acpi_ns_search_and_enter(simple_name, walk_state,
 547                                             current_node, interpreter_mode,
 548                                             this_search_type, local_flags,
 549                                             &this_node);
 550                if (ACPI_FAILURE(status)) {
 551                        if (status == AE_NOT_FOUND) {
 552
 553                                /* Name not found in ACPI namespace */
 554
 555                                ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 556                                                  "Name [%4.4s] not found in scope [%4.4s] %p\n",
 557                                                  (char *)&simple_name,
 558                                                  (char *)&current_node->name,
 559                                                  current_node));
 560                        }
 561#ifdef ACPI_ASL_COMPILER
 562                        /*
 563                         * If this ACPI name already exists within the namespace as an
 564                         * external declaration, then mark the external as a conflicting
 565                         * declaration and proceed to process the current node as if it did
 566                         * not exist in the namespace. If this node is not processed as
 567                         * normal, then it could cause improper namespace resolution
 568                         * by failing to open a new scope.
 569                         */
 570                        if (acpi_gbl_disasm_flag &&
 571                            (status == AE_ALREADY_EXISTS) &&
 572                            ((this_node->flags & ANOBJ_IS_EXTERNAL) ||
 573                             (walk_state
 574                              && walk_state->opcode == AML_EXTERNAL_OP))) {
 575                                this_node->flags &= ~ANOBJ_IS_EXTERNAL;
 576                                this_node->type = (u8)this_search_type;
 577                                if (walk_state->opcode != AML_EXTERNAL_OP) {
 578                                        acpi_dm_mark_external_conflict
 579                                            (this_node);
 580                                }
 581                                break;
 582                        }
 583#endif
 584
 585                        *return_node = this_node;
 586                        return_ACPI_STATUS(status);
 587                }
 588
 589                /* More segments to follow? */
 590
 591                if (num_segments > 0) {
 592                        /*
 593                         * If we have an alias to an object that opens a scope (such as a
 594                         * device or processor), we need to dereference the alias here so
 595                         * that we can access any children of the original node (via the
 596                         * remaining segments).
 597                         */
 598                        if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) {
 599                                if (!this_node->object) {
 600                                        return_ACPI_STATUS(AE_NOT_EXIST);
 601                                }
 602
 603                                if (acpi_ns_opens_scope
 604                                    (((struct acpi_namespace_node *)
 605                                      this_node->object)->type)) {
 606                                        this_node =
 607                                            (struct acpi_namespace_node *)
 608                                            this_node->object;
 609                                }
 610                        }
 611                }
 612
 613                /* Special handling for the last segment (num_segments == 0) */
 614
 615                else {
 616#ifdef ACPI_ASL_COMPILER
 617                        if (!acpi_gbl_disasm_flag
 618                            && (this_node->flags & ANOBJ_IS_EXTERNAL)) {
 619                                this_node->flags &= ~IMPLICIT_EXTERNAL;
 620                        }
 621#endif
 622
 623                        /*
 624                         * Sanity typecheck of the target object:
 625                         *
 626                         * If 1) This is the last segment (num_segments == 0)
 627                         *    2) And we are looking for a specific type
 628                         *       (Not checking for TYPE_ANY)
 629                         *    3) Which is not an alias
 630                         *    4) Which is not a local type (TYPE_SCOPE)
 631                         *    5) And the type of target object is known (not TYPE_ANY)
 632                         *    6) And target object does not match what we are looking for
 633                         *
 634                         * Then we have a type mismatch. Just warn and ignore it.
 635                         */
 636                        if ((type_to_check_for != ACPI_TYPE_ANY) &&
 637                            (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) &&
 638                            (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS)
 639                            && (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE)
 640                            && (this_node->type != ACPI_TYPE_ANY)
 641                            && (this_node->type != type_to_check_for)) {
 642
 643                                /* Complain about a type mismatch */
 644
 645                                ACPI_WARNING((AE_INFO,
 646                                              "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)",
 647                                              ACPI_CAST_PTR(char, &simple_name),
 648                                              acpi_ut_get_type_name(this_node->
 649                                                                    type),
 650                                              acpi_ut_get_type_name
 651                                              (type_to_check_for)));
 652                        }
 653
 654                        /*
 655                         * If this is the last name segment and we are not looking for a
 656                         * specific type, but the type of found object is known, use that
 657                         * type to (later) see if it opens a scope.
 658                         */
 659                        if (type == ACPI_TYPE_ANY) {
 660                                type = this_node->type;
 661                        }
 662                }
 663
 664                /* Point to next name segment and make this node current */
 665
 666                path += ACPI_NAME_SIZE;
 667                current_node = this_node;
 668        }
 669
 670        /* Always check if we need to open a new scope */
 671
 672        if (!(flags & ACPI_NS_DONT_OPEN_SCOPE) && (walk_state)) {
 673                /*
 674                 * If entry is a type which opens a scope, push the new scope on the
 675                 * scope stack.
 676                 */
 677                if (acpi_ns_opens_scope(type)) {
 678                        status =
 679                            acpi_ds_scope_stack_push(this_node, type,
 680                                                     walk_state);
 681                        if (ACPI_FAILURE(status)) {
 682                                return_ACPI_STATUS(status);
 683                        }
 684                }
 685        }
 686
 687        *return_node = this_node;
 688        return_ACPI_STATUS(AE_OK);
 689}
 690