The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/acpica/components/namespace/nsaccess.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*******************************************************************************
    2  *
    3  * Module Name: nsaccess - Top-level functions for accessing ACPI namespace
    4  *
    5  ******************************************************************************/
    6 
    7 /******************************************************************************
    8  *
    9  * 1. Copyright Notice
   10  *
   11  * Some or all of this work - Copyright (c) 1999 - 2022, Intel Corp.
   12  * All rights reserved.
   13  *
   14  * 2. License
   15  *
   16  * 2.1. This is your license from Intel Corp. under its intellectual property
   17  * rights. You may have additional license terms from the party that provided
   18  * you this software, covering your right to use that party's intellectual
   19  * property rights.
   20  *
   21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
   22  * copy of the source code appearing in this file ("Covered Code") an
   23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
   24  * base code distributed originally by Intel ("Original Intel Code") to copy,
   25  * make derivatives, distribute, use and display any portion of the Covered
   26  * Code in any form, with the right to sublicense such rights; and
   27  *
   28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
   29  * license (with the right to sublicense), under only those claims of Intel
   30  * patents that are infringed by the Original Intel Code, to make, use, sell,
   31  * offer to sell, and import the Covered Code and derivative works thereof
   32  * solely to the minimum extent necessary to exercise the above copyright
   33  * license, and in no event shall the patent license extend to any additions
   34  * to or modifications of the Original Intel Code. No other license or right
   35  * is granted directly or by implication, estoppel or otherwise;
   36  *
   37  * The above copyright and patent license is granted only if the following
   38  * conditions are met:
   39  *
   40  * 3. Conditions
   41  *
   42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
   43  * Redistribution of source code of any substantial portion of the Covered
   44  * Code or modification with rights to further distribute source must include
   45  * the above Copyright Notice, the above License, this list of Conditions,
   46  * and the following Disclaimer and Export Compliance provision. In addition,
   47  * Licensee must cause all Covered Code to which Licensee contributes to
   48  * contain a file documenting the changes Licensee made to create that Covered
   49  * Code and the date of any change. Licensee must include in that file the
   50  * documentation of any changes made by any predecessor Licensee. Licensee
   51  * must include a prominent statement that the modification is derived,
   52  * directly or indirectly, from Original Intel Code.
   53  *
   54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
   55  * Redistribution of source code of any substantial portion of the Covered
   56  * Code or modification without rights to further distribute source must
   57  * include the following Disclaimer and Export Compliance provision in the
   58  * documentation and/or other materials provided with distribution. In
   59  * addition, Licensee may not authorize further sublicense of source of any
   60  * portion of the Covered Code, and must include terms to the effect that the
   61  * license from Licensee to its licensee is limited to the intellectual
   62  * property embodied in the software Licensee provides to its licensee, and
   63  * not to intellectual property embodied in modifications its licensee may
   64  * make.
   65  *
   66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
   67  * substantial portion of the Covered Code or modification must reproduce the
   68  * above Copyright Notice, and the following Disclaimer and Export Compliance
   69  * provision in the documentation and/or other materials provided with the
   70  * distribution.
   71  *
   72  * 3.4. Intel retains all right, title, and interest in and to the Original
   73  * Intel Code.
   74  *
   75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
   76  * Intel shall be used in advertising or otherwise to promote the sale, use or
   77  * other dealings in products derived from or relating to the Covered Code
   78  * without prior written authorization from Intel.
   79  *
   80  * 4. Disclaimer and Export Compliance
   81  *
   82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
   83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
   84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
   85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
   86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
   87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
   88  * PARTICULAR PURPOSE.
   89  *
   90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
   91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
   92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
   93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
   94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
   95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
   96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
   97  * LIMITED REMEDY.
   98  *
   99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
  100  * software or system incorporating such software without first obtaining any
  101  * required license or other approval from the U. S. Department of Commerce or
  102  * any other agency or department of the United States Government. In the
  103  * event Licensee exports any such software from the United States or
  104  * re-exports any such software from a foreign destination, Licensee shall
  105  * ensure that the distribution and export/re-export of the software is in
  106  * compliance with all laws, regulations, orders, or other restrictions of the
  107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  108  * any of its subsidiaries will export/re-export any technical data, process,
  109  * software, or service, directly or indirectly, to any country for which the
  110  * United States government or any agency thereof requires an export license,
  111  * other governmental approval, or letter of assurance, without first obtaining
  112  * such license, approval or letter.
  113  *
  114  *****************************************************************************
  115  *
  116  * Alternatively, you may choose to be licensed under the terms of the
  117  * following license:
  118  *
  119  * Redistribution and use in source and binary forms, with or without
  120  * modification, are permitted provided that the following conditions
  121  * are met:
  122  * 1. Redistributions of source code must retain the above copyright
  123  *    notice, this list of conditions, and the following disclaimer,
  124  *    without modification.
  125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  126  *    substantially similar to the "NO WARRANTY" disclaimer below
  127  *    ("Disclaimer") and any redistribution must be conditioned upon
  128  *    including a substantially similar Disclaimer requirement for further
  129  *    binary redistribution.
  130  * 3. Neither the names of the above-listed copyright holders nor the names
  131  *    of any contributors may be used to endorse or promote products derived
  132  *    from this software without specific prior written permission.
  133  *
  134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  145  *
  146  * Alternatively, you may choose to be licensed under the terms of the
  147  * GNU General Public License ("GPL") version 2 as published by the Free
  148  * Software Foundation.
  149  *
  150  *****************************************************************************/
  151 
  152 #include <contrib/dev/acpica/include/acpi.h>
  153 #include <contrib/dev/acpica/include/accommon.h>
  154 #include <contrib/dev/acpica/include/amlcode.h>
  155 #include <contrib/dev/acpica/include/acnamesp.h>
  156 #include <contrib/dev/acpica/include/acdispat.h>
  157 
  158 #ifdef ACPI_ASL_COMPILER
  159     #include <contrib/dev/acpica/include/acdisasm.h>
  160 #endif
  161 
  162 #define _COMPONENT          ACPI_NAMESPACE
  163         ACPI_MODULE_NAME    ("nsaccess")
  164 
  165 
  166 /*******************************************************************************
  167  *
  168  * FUNCTION:    AcpiNsRootInitialize
  169  *
  170  * PARAMETERS:  None
  171  *
  172  * RETURN:      Status
  173  *
  174  * DESCRIPTION: Allocate and initialize the default root named objects
  175  *
  176  * MUTEX:       Locks namespace for entire execution
  177  *
  178  ******************************************************************************/
  179 
  180 ACPI_STATUS
  181 AcpiNsRootInitialize (
  182     void)
  183 {
  184     ACPI_STATUS                 Status;
  185     const ACPI_PREDEFINED_NAMES *InitVal = NULL;
  186     ACPI_NAMESPACE_NODE         *NewNode;
  187     ACPI_NAMESPACE_NODE         *PrevNode = NULL;
  188     ACPI_OPERAND_OBJECT         *ObjDesc;
  189     ACPI_STRING                 Val = NULL;
  190 
  191 
  192     ACPI_FUNCTION_TRACE (NsRootInitialize);
  193 
  194 
  195     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  196     if (ACPI_FAILURE (Status))
  197     {
  198         return_ACPI_STATUS (Status);
  199     }
  200 
  201     /*
  202      * The global root ptr is initially NULL, so a non-NULL value indicates
  203      * that AcpiNsRootInitialize() has already been called; just return.
  204      */
  205     if (AcpiGbl_RootNode)
  206     {
  207         Status = AE_OK;
  208         goto UnlockAndExit;
  209     }
  210 
  211     /*
  212      * Tell the rest of the subsystem that the root is initialized
  213      * (This is OK because the namespace is locked)
  214      */
  215     AcpiGbl_RootNode = &AcpiGbl_RootNodeStruct;
  216 
  217     /* Enter the predefined names in the name table */
  218 
  219     ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  220         "Entering predefined entries into namespace\n"));
  221 
  222     /*
  223      * Create the initial (default) namespace.
  224      * This namespace looks like something similar to this:
  225      *
  226      *   ACPI Namespace (from Namespace Root):
  227      *    0  _GPE Scope        00203160 00
  228      *    0  _PR_ Scope        002031D0 00
  229      *    0  _SB_ Device       00203240 00 Notify Object: 0020ADD8
  230      *    0  _SI_ Scope        002032B0 00
  231      *    0  _TZ_ Device       00203320 00
  232      *    0  _REV Integer      00203390 00 = 0000000000000002
  233      *    0  _OS_ String       00203488 00 Len 14 "Microsoft Windows NT"
  234      *    0  _GL_ Mutex        00203580 00 Object 002035F0
  235      *    0  _OSI Method       00203678 00 Args 1 Len 0000 Aml 00000000
  236      */
  237     for (InitVal = AcpiGbl_PreDefinedNames; InitVal->Name; InitVal++)
  238     {
  239         Status = AE_OK;
  240 
  241         /* _OSI is optional for now, will be permanent later */
  242 
  243         if (!strcmp (InitVal->Name, "_OSI") && !AcpiGbl_CreateOsiMethod)
  244         {
  245             continue;
  246         }
  247 
  248         /*
  249          * Create, init, and link the new predefined name
  250          * Note: No need to use AcpiNsLookup here because all the
  251          * predefined names are at the root level. It is much easier to
  252          * just create and link the new node(s) here.
  253          */
  254         NewNode = AcpiNsCreateNode (*ACPI_CAST_PTR (UINT32, InitVal->Name));
  255         if (!NewNode)
  256         {
  257             Status = AE_NO_MEMORY;
  258             goto UnlockAndExit;
  259         }
  260 
  261         NewNode->DescriptorType = ACPI_DESC_TYPE_NAMED;
  262         NewNode->Type = InitVal->Type;
  263 
  264         if (!PrevNode)
  265         {
  266             AcpiGbl_RootNodeStruct.Child = NewNode;
  267         }
  268         else
  269         {
  270             PrevNode->Peer = NewNode;
  271         }
  272 
  273         NewNode->Parent = &AcpiGbl_RootNodeStruct;
  274         PrevNode = NewNode;
  275 
  276         /*
  277          * Name entered successfully. If entry in PreDefinedNames[] specifies
  278          * an initial value, create the initial value.
  279          */
  280         if (InitVal->Val)
  281         {
  282             Status = AcpiOsPredefinedOverride (InitVal, &Val);
  283             if (ACPI_FAILURE (Status))
  284             {
  285                 ACPI_ERROR ((AE_INFO,
  286                     "Could not override predefined %s",
  287                     InitVal->Name));
  288             }
  289 
  290             if (!Val)
  291             {
  292                 Val = InitVal->Val;
  293             }
  294 
  295             /*
  296              * Entry requests an initial value, allocate a
  297              * descriptor for it.
  298              */
  299             ObjDesc = AcpiUtCreateInternalObject (InitVal->Type);
  300             if (!ObjDesc)
  301             {
  302                 Status = AE_NO_MEMORY;
  303                 goto UnlockAndExit;
  304             }
  305 
  306             /*
  307              * Convert value string from table entry to
  308              * internal representation. Only types actually
  309              * used for initial values are implemented here.
  310              */
  311             switch (InitVal->Type)
  312             {
  313             case ACPI_TYPE_METHOD:
  314 
  315                 ObjDesc->Method.ParamCount = (UINT8) ACPI_TO_INTEGER (Val);
  316                 ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID;
  317 
  318 #if defined (ACPI_ASL_COMPILER)
  319 
  320                 /* Save the parameter count for the iASL compiler */
  321 
  322                 NewNode->Value = ObjDesc->Method.ParamCount;
  323 #else
  324                 /* Mark this as a very SPECIAL method (_OSI) */
  325 
  326                 ObjDesc->Method.InfoFlags = ACPI_METHOD_INTERNAL_ONLY;
  327                 ObjDesc->Method.Dispatch.Implementation = AcpiUtOsiImplementation;
  328 #endif
  329                 break;
  330 
  331             case ACPI_TYPE_INTEGER:
  332 
  333                 ObjDesc->Integer.Value = ACPI_TO_INTEGER (Val);
  334                 break;
  335 
  336             case ACPI_TYPE_STRING:
  337 
  338                 /* Build an object around the static string */
  339 
  340                 ObjDesc->String.Length = (UINT32) strlen (Val);
  341                 ObjDesc->String.Pointer = Val;
  342                 ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER;
  343                 break;
  344 
  345             case ACPI_TYPE_MUTEX:
  346 
  347                 ObjDesc->Mutex.Node = NewNode;
  348                 ObjDesc->Mutex.SyncLevel = (UINT8) (ACPI_TO_INTEGER (Val) - 1);
  349 
  350                 /* Create a mutex */
  351 
  352                 Status = AcpiOsCreateMutex (&ObjDesc->Mutex.OsMutex);
  353                 if (ACPI_FAILURE (Status))
  354                 {
  355                     AcpiUtRemoveReference (ObjDesc);
  356                     goto UnlockAndExit;
  357                 }
  358 
  359                 /* Special case for ACPI Global Lock */
  360 
  361                 if (strcmp (InitVal->Name, "_GL_") == 0)
  362                 {
  363                     AcpiGbl_GlobalLockMutex = ObjDesc;
  364 
  365                     /* Create additional counting semaphore for global lock */
  366 
  367                     Status = AcpiOsCreateSemaphore (
  368                         1, 0, &AcpiGbl_GlobalLockSemaphore);
  369                     if (ACPI_FAILURE (Status))
  370                     {
  371                         AcpiUtRemoveReference (ObjDesc);
  372                         goto UnlockAndExit;
  373                     }
  374                 }
  375                 break;
  376 
  377             default:
  378 
  379                 ACPI_ERROR ((AE_INFO, "Unsupported initial type value 0x%X",
  380                     InitVal->Type));
  381                 AcpiUtRemoveReference (ObjDesc);
  382                 ObjDesc = NULL;
  383                 continue;
  384             }
  385 
  386             /* Store pointer to value descriptor in the Node */
  387 
  388             Status = AcpiNsAttachObject (NewNode, ObjDesc,
  389                 ObjDesc->Common.Type);
  390 
  391             /* Remove local reference to the object */
  392 
  393             AcpiUtRemoveReference (ObjDesc);
  394         }
  395     }
  396 
  397 UnlockAndExit:
  398     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  399 
  400     /* Save a handle to "_GPE", it is always present */
  401 
  402     if (ACPI_SUCCESS (Status))
  403     {
  404         Status = AcpiNsGetNode (NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH,
  405             &AcpiGbl_FadtGpeDevice);
  406     }
  407 
  408     return_ACPI_STATUS (Status);
  409 }
  410 
  411 
  412 /*******************************************************************************
  413  *
  414  * FUNCTION:    AcpiNsLookup
  415  *
  416  * PARAMETERS:  ScopeInfo       - Current scope info block
  417  *              Pathname        - Search pathname, in internal format
  418  *                                (as represented in the AML stream)
  419  *              Type            - Type associated with name
  420  *              InterpreterMode - IMODE_LOAD_PASS2 => add name if not found
  421  *              Flags           - Flags describing the search restrictions
  422  *              WalkState       - Current state of the walk
  423  *              ReturnNode      - Where the Node is placed (if found
  424  *                                or created successfully)
  425  *
  426  * RETURN:      Status
  427  *
  428  * DESCRIPTION: Find or enter the passed name in the name space.
  429  *              Log an error if name not found in Exec mode.
  430  *
  431  * MUTEX:       Assumes namespace is locked.
  432  *
  433  ******************************************************************************/
  434 
  435 ACPI_STATUS
  436 AcpiNsLookup (
  437     ACPI_GENERIC_STATE      *ScopeInfo,
  438     char                    *Pathname,
  439     ACPI_OBJECT_TYPE        Type,
  440     ACPI_INTERPRETER_MODE   InterpreterMode,
  441     UINT32                  Flags,
  442     ACPI_WALK_STATE         *WalkState,
  443     ACPI_NAMESPACE_NODE     **ReturnNode)
  444 {
  445     ACPI_STATUS             Status;
  446     char                    *Path = Pathname;
  447     char                    *ExternalPath;
  448     ACPI_NAMESPACE_NODE     *PrefixNode;
  449     ACPI_NAMESPACE_NODE     *CurrentNode = NULL;
  450     ACPI_NAMESPACE_NODE     *ThisNode = NULL;
  451     UINT32                  NumSegments;
  452     UINT32                  NumCarats;
  453     ACPI_NAME               SimpleName;
  454     ACPI_OBJECT_TYPE        TypeToCheckFor;
  455     ACPI_OBJECT_TYPE        ThisSearchType;
  456     UINT32                  SearchParentFlag = ACPI_NS_SEARCH_PARENT;
  457     UINT32                  LocalFlags;
  458     ACPI_INTERPRETER_MODE   LocalInterpreterMode;
  459 
  460 
  461     ACPI_FUNCTION_TRACE (NsLookup);
  462 
  463 
  464     if (!ReturnNode)
  465     {
  466         return_ACPI_STATUS (AE_BAD_PARAMETER);
  467     }
  468 
  469     LocalFlags = Flags &
  470         ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_OVERRIDE_IF_FOUND |
  471           ACPI_NS_SEARCH_PARENT);
  472     *ReturnNode = ACPI_ENTRY_NOT_FOUND;
  473     AcpiGbl_NsLookupCount++;
  474 
  475     if (!AcpiGbl_RootNode)
  476     {
  477         return_ACPI_STATUS (AE_NO_NAMESPACE);
  478     }
  479 
  480     /* Get the prefix scope. A null scope means use the root scope */
  481 
  482     if ((!ScopeInfo) ||
  483         (!ScopeInfo->Scope.Node))
  484     {
  485         ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
  486             "Null scope prefix, using root node (%p)\n",
  487             AcpiGbl_RootNode));
  488 
  489         PrefixNode = AcpiGbl_RootNode;
  490     }
  491     else
  492     {
  493         PrefixNode = ScopeInfo->Scope.Node;
  494         if (ACPI_GET_DESCRIPTOR_TYPE (PrefixNode) != ACPI_DESC_TYPE_NAMED)
  495         {
  496             ACPI_ERROR ((AE_INFO, "%p is not a namespace node [%s]",
  497                 PrefixNode, AcpiUtGetDescriptorName (PrefixNode)));
  498             return_ACPI_STATUS (AE_AML_INTERNAL);
  499         }
  500 
  501         if (!(Flags & ACPI_NS_PREFIX_IS_SCOPE))
  502         {
  503             /*
  504              * This node might not be a actual "scope" node (such as a
  505              * Device/Method, etc.)  It could be a Package or other object
  506              * node. Backup up the tree to find the containing scope node.
  507              */
  508             while (!AcpiNsOpensScope (PrefixNode->Type) &&
  509                     PrefixNode->Type != ACPI_TYPE_ANY)
  510             {
  511                 PrefixNode = PrefixNode->Parent;
  512             }
  513         }
  514     }
  515 
  516     /* Save type. TBD: may be no longer necessary */
  517 
  518     TypeToCheckFor = Type;
  519 
  520     /*
  521      * Begin examination of the actual pathname
  522      */
  523     if (!Pathname)
  524     {
  525         /* A Null NamePath is allowed and refers to the root */
  526 
  527         NumSegments = 0;
  528         ThisNode = AcpiGbl_RootNode;
  529         Path = "";
  530 
  531         ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
  532             "Null Pathname (Zero segments), Flags=%X\n", Flags));
  533     }
  534     else
  535     {
  536         /*
  537          * Name pointer is valid (and must be in internal name format)
  538          *
  539          * Check for scope prefixes:
  540          *
  541          * As represented in the AML stream, a namepath consists of an
  542          * optional scope prefix followed by a name segment part.
  543          *
  544          * If present, the scope prefix is either a Root Prefix (in
  545          * which case the name is fully qualified), or one or more
  546          * Parent Prefixes (in which case the name's scope is relative
  547          * to the current scope).
  548          */
  549         if (*Path == (UINT8) AML_ROOT_PREFIX)
  550         {
  551             /* Pathname is fully qualified, start from the root */
  552 
  553             ThisNode = AcpiGbl_RootNode;
  554             SearchParentFlag = ACPI_NS_NO_UPSEARCH;
  555 
  556             /* Point to name segment part */
  557 
  558             Path++;
  559 
  560             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
  561                 "Path is absolute from root [%p]\n", ThisNode));
  562         }
  563         else
  564         {
  565             /* Pathname is relative to current scope, start there */
  566 
  567             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
  568                 "Searching relative to prefix scope [%4.4s] (%p)\n",
  569                 AcpiUtGetNodeName (PrefixNode), PrefixNode));
  570 
  571             /*
  572              * Handle multiple Parent Prefixes (carat) by just getting
  573              * the parent node for each prefix instance.
  574              */
  575             ThisNode = PrefixNode;
  576             NumCarats = 0;
  577             while (*Path == (UINT8) AML_PARENT_PREFIX)
  578             {
  579                 /* Name is fully qualified, no search rules apply */
  580 
  581                 SearchParentFlag = ACPI_NS_NO_UPSEARCH;
  582 
  583                 /*
  584                  * Point past this prefix to the name segment
  585                  * part or the next Parent Prefix
  586                  */
  587                 Path++;
  588 
  589                 /* Backup to the parent node */
  590 
  591                 NumCarats++;
  592                 ThisNode = ThisNode->Parent;
  593                 if (!ThisNode)
  594                 {
  595                     /*
  596                      * Current scope has no parent scope. Externalize
  597                      * the internal path for error message.
  598                      */
  599                     Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Pathname,
  600                         NULL, &ExternalPath);
  601                     if (ACPI_SUCCESS (Status))
  602                     {
  603                         ACPI_ERROR ((AE_INFO,
  604                             "%s: Path has too many parent prefixes (^)",
  605                             ExternalPath));
  606 
  607                         ACPI_FREE (ExternalPath);
  608                     }
  609 
  610                     return_ACPI_STATUS (AE_NOT_FOUND);
  611                 }
  612             }
  613 
  614             if (SearchParentFlag == ACPI_NS_NO_UPSEARCH)
  615             {
  616                 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
  617                     "Search scope is [%4.4s], path has %u carat(s)\n",
  618                     AcpiUtGetNodeName (ThisNode), NumCarats));
  619             }
  620         }
  621 
  622         /*
  623          * Determine the number of ACPI name segments in this pathname.
  624          *
  625          * The segment part consists of either:
  626          *  - A Null name segment (0)
  627          *  - A DualNamePrefix followed by two 4-byte name segments
  628          *  - A MultiNamePrefix followed by a byte indicating the
  629          *      number of segments and the segments themselves.
  630          *  - A single 4-byte name segment
  631          *
  632          * Examine the name prefix opcode, if any, to determine the number of
  633          * segments.
  634          */
  635         switch (*Path)
  636         {
  637         case 0:
  638             /*
  639              * Null name after a root or parent prefixes. We already
  640              * have the correct target node and there are no name segments.
  641              */
  642             NumSegments  = 0;
  643             Type = ThisNode->Type;
  644 
  645             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
  646                 "Prefix-only Pathname (Zero name segments), Flags=%X\n",
  647                 Flags));
  648             break;
  649 
  650         case AML_DUAL_NAME_PREFIX:
  651 
  652             /* More than one NameSeg, search rules do not apply */
  653 
  654             SearchParentFlag = ACPI_NS_NO_UPSEARCH;
  655 
  656             /* Two segments, point to first name segment */
  657 
  658             NumSegments = 2;
  659             Path++;
  660 
  661             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
  662                 "Dual Pathname (2 segments, Flags=%X)\n", Flags));
  663             break;
  664 
  665         case AML_MULTI_NAME_PREFIX:
  666 
  667             /* More than one NameSeg, search rules do not apply */
  668 
  669             SearchParentFlag = ACPI_NS_NO_UPSEARCH;
  670 
  671             /* Extract segment count, point to first name segment */
  672 
  673             Path++;
  674             NumSegments = (UINT32) (UINT8) *Path;
  675             Path++;
  676 
  677             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
  678                 "Multi Pathname (%u Segments, Flags=%X)\n",
  679                 NumSegments, Flags));
  680             break;
  681 
  682         default:
  683             /*
  684              * Not a Null name, no Dual or Multi prefix, hence there is
  685              * only one name segment and Pathname is already pointing to it.
  686              */
  687             NumSegments = 1;
  688 
  689             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
  690                 "Simple Pathname (1 segment, Flags=%X)\n", Flags));
  691             break;
  692         }
  693 
  694         ACPI_DEBUG_EXEC (AcpiNsPrintPathname (NumSegments, Path));
  695     }
  696 
  697 
  698     /*
  699      * Search namespace for each segment of the name. Loop through and
  700      * verify (or add to the namespace) each name segment.
  701      *
  702      * The object type is significant only at the last name
  703      * segment. (We don't care about the types along the path, only
  704      * the type of the final target object.)
  705      */
  706     ThisSearchType = ACPI_TYPE_ANY;
  707     CurrentNode = ThisNode;
  708 
  709     while (NumSegments && CurrentNode)
  710     {
  711         NumSegments--;
  712         if (!NumSegments)
  713         {
  714             /* This is the last segment, enable typechecking */
  715 
  716             ThisSearchType = Type;
  717 
  718             /*
  719              * Only allow automatic parent search (search rules) if the caller
  720              * requested it AND we have a single, non-fully-qualified NameSeg
  721              */
  722             if ((SearchParentFlag != ACPI_NS_NO_UPSEARCH) &&
  723                 (Flags & ACPI_NS_SEARCH_PARENT))
  724             {
  725                 LocalFlags |= ACPI_NS_SEARCH_PARENT;
  726             }
  727 
  728             /* Set error flag according to caller */
  729 
  730             if (Flags & ACPI_NS_ERROR_IF_FOUND)
  731             {
  732                 LocalFlags |= ACPI_NS_ERROR_IF_FOUND;
  733             }
  734 
  735             /* Set override flag according to caller */
  736 
  737             if (Flags & ACPI_NS_OVERRIDE_IF_FOUND)
  738             {
  739                 LocalFlags |= ACPI_NS_OVERRIDE_IF_FOUND;
  740             }
  741         }
  742 
  743         /* Handle opcodes that create a new NameSeg via a full NamePath */
  744 
  745         LocalInterpreterMode = InterpreterMode;
  746         if ((Flags & ACPI_NS_PREFIX_MUST_EXIST) && (NumSegments > 0))
  747         {
  748             /* Every element of the path must exist (except for the final NameSeg) */
  749 
  750             LocalInterpreterMode = ACPI_IMODE_EXECUTE;
  751         }
  752 
  753         /* Extract one ACPI name from the front of the pathname */
  754 
  755         ACPI_MOVE_32_TO_32 (&SimpleName, Path);
  756 
  757         /* Try to find the single (4 character) ACPI name */
  758 
  759         Status = AcpiNsSearchAndEnter (SimpleName, WalkState, CurrentNode,
  760             LocalInterpreterMode, ThisSearchType, LocalFlags, &ThisNode);
  761         if (ACPI_FAILURE (Status))
  762         {
  763             if (Status == AE_NOT_FOUND)
  764             {
  765 #if !defined ACPI_ASL_COMPILER /* Note: iASL reports this error by itself, not needed here */
  766                 if (Flags & ACPI_NS_PREFIX_MUST_EXIST)
  767                 {
  768                     AcpiOsPrintf (ACPI_MSG_BIOS_ERROR
  769                         "Object does not exist: %4.4s\n", (char *) &SimpleName);
  770                 }
  771 #endif
  772                 /* Name not found in ACPI namespace */
  773 
  774                 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
  775                     "Name [%4.4s] not found in scope [%4.4s] %p\n",
  776                     (char *) &SimpleName, (char *) &CurrentNode->Name,
  777                     CurrentNode));
  778             }
  779 
  780 #ifdef ACPI_EXEC_APP
  781             if ((Status == AE_ALREADY_EXISTS) &&
  782                 (ThisNode->Flags & ANOBJ_NODE_EARLY_INIT))
  783             {
  784                 ThisNode->Flags &= ~ANOBJ_NODE_EARLY_INIT;
  785                 Status = AE_OK;
  786             }
  787 #endif
  788 
  789 #ifdef ACPI_ASL_COMPILER
  790             /*
  791              * If this ACPI name already exists within the namespace as an
  792              * external declaration, then mark the external as a conflicting
  793              * declaration and proceed to process the current node as if it did
  794              * not exist in the namespace. If this node is not processed as
  795              * normal, then it could cause improper namespace resolution
  796              * by failing to open a new scope.
  797              */
  798             if (AcpiGbl_DisasmFlag &&
  799                 (Status == AE_ALREADY_EXISTS) &&
  800                 ((ThisNode->Flags & ANOBJ_IS_EXTERNAL) ||
  801                     (WalkState && WalkState->Opcode == AML_EXTERNAL_OP)))
  802             {
  803                 ThisNode->Flags &= ~ANOBJ_IS_EXTERNAL;
  804                 ThisNode->Type = (UINT8)ThisSearchType;
  805                 if (WalkState->Opcode != AML_EXTERNAL_OP)
  806                 {
  807                     AcpiDmMarkExternalConflict (ThisNode);
  808                 }
  809                 break;
  810             }
  811 #endif
  812 
  813             *ReturnNode = ThisNode;
  814             return_ACPI_STATUS (Status);
  815         }
  816 
  817         /* More segments to follow? */
  818 
  819         if (NumSegments > 0)
  820         {
  821             /*
  822              * If we have an alias to an object that opens a scope (such as a
  823              * device or processor), we need to dereference the alias here so
  824              * that we can access any children of the original node (via the
  825              * remaining segments).
  826              */
  827             if (ThisNode->Type == ACPI_TYPE_LOCAL_ALIAS)
  828             {
  829                 if (!ThisNode->Object)
  830                 {
  831                     return_ACPI_STATUS (AE_NOT_EXIST);
  832                 }
  833 
  834                 if (AcpiNsOpensScope (((ACPI_NAMESPACE_NODE *)
  835                         ThisNode->Object)->Type))
  836                 {
  837                     ThisNode = (ACPI_NAMESPACE_NODE *) ThisNode->Object;
  838                 }
  839             }
  840         }
  841 
  842         /* Special handling for the last segment (NumSegments == 0) */
  843 
  844         else
  845         {
  846             /*
  847              * Sanity typecheck of the target object:
  848              *
  849              * If 1) This is the last segment (NumSegments == 0)
  850              *    2) And we are looking for a specific type
  851              *       (Not checking for TYPE_ANY)
  852              *    3) Which is not an alias
  853              *    4) Which is not a local type (TYPE_SCOPE)
  854              *    5) And the type of target object is known (not TYPE_ANY)
  855              *    6) And target object does not match what we are looking for
  856              *
  857              * Then we have a type mismatch. Just warn and ignore it.
  858              */
  859             if ((TypeToCheckFor != ACPI_TYPE_ANY)                   &&
  860                 (TypeToCheckFor != ACPI_TYPE_LOCAL_ALIAS)           &&
  861                 (TypeToCheckFor != ACPI_TYPE_LOCAL_METHOD_ALIAS)    &&
  862                 (TypeToCheckFor != ACPI_TYPE_LOCAL_SCOPE)           &&
  863                 (ThisNode->Type != ACPI_TYPE_ANY)                   &&
  864                 (ThisNode->Type != TypeToCheckFor))
  865             {
  866                 /* Complain about a type mismatch */
  867 
  868                 ACPI_WARNING ((AE_INFO,
  869                     "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)",
  870                     ACPI_CAST_PTR (char, &SimpleName),
  871                     AcpiUtGetTypeName (ThisNode->Type),
  872                     AcpiUtGetTypeName (TypeToCheckFor)));
  873             }
  874 
  875             /*
  876              * If this is the last name segment and we are not looking for a
  877              * specific type, but the type of found object is known, use that
  878              * type to (later) see if it opens a scope.
  879              */
  880             if (Type == ACPI_TYPE_ANY)
  881             {
  882                 Type = ThisNode->Type;
  883             }
  884         }
  885 
  886         /* Point to next name segment and make this node current */
  887 
  888         Path += ACPI_NAMESEG_SIZE;
  889         CurrentNode = ThisNode;
  890     }
  891 
  892     /* Always check if we need to open a new scope */
  893 
  894     if (!(Flags & ACPI_NS_DONT_OPEN_SCOPE) && (WalkState))
  895     {
  896         /*
  897          * If entry is a type which opens a scope, push the new scope on the
  898          * scope stack.
  899          */
  900         if (AcpiNsOpensScope (Type))
  901         {
  902             Status = AcpiDsScopeStackPush (ThisNode, Type, WalkState);
  903             if (ACPI_FAILURE (Status))
  904             {
  905                 return_ACPI_STATUS (Status);
  906             }
  907         }
  908     }
  909 
  910 #ifdef ACPI_EXEC_APP
  911     if (Flags & ACPI_NS_EARLY_INIT)
  912     {
  913         ThisNode->Flags |= ANOBJ_NODE_EARLY_INIT;
  914     }
  915 #endif
  916 
  917     *ReturnNode = ThisNode;
  918     return_ACPI_STATUS (AE_OK);
  919 }

Cache object: 243bfc50cb27a3531ab2b720d61898ad


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.