ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

nsaccess.c
Go to the documentation of this file.
00001 /*******************************************************************************
00002  *
00003  * Module Name: nsaccess - Top-level functions for accessing ACPI namespace
00004  *
00005  ******************************************************************************/
00006 
00007 /******************************************************************************
00008  *
00009  * 1. Copyright Notice
00010  *
00011  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
00012  * All rights reserved.
00013  *
00014  * 2. License
00015  *
00016  * 2.1. This is your license from Intel Corp. under its intellectual property
00017  * rights.  You may have additional license terms from the party that provided
00018  * you this software, covering your right to use that party's intellectual
00019  * property rights.
00020  *
00021  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
00022  * copy of the source code appearing in this file ("Covered Code") an
00023  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
00024  * base code distributed originally by Intel ("Original Intel Code") to copy,
00025  * make derivatives, distribute, use and display any portion of the Covered
00026  * Code in any form, with the right to sublicense such rights; and
00027  *
00028  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
00029  * license (with the right to sublicense), under only those claims of Intel
00030  * patents that are infringed by the Original Intel Code, to make, use, sell,
00031  * offer to sell, and import the Covered Code and derivative works thereof
00032  * solely to the minimum extent necessary to exercise the above copyright
00033  * license, and in no event shall the patent license extend to any additions
00034  * to or modifications of the Original Intel Code.  No other license or right
00035  * is granted directly or by implication, estoppel or otherwise;
00036  *
00037  * The above copyright and patent license is granted only if the following
00038  * conditions are met:
00039  *
00040  * 3. Conditions
00041  *
00042  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
00043  * Redistribution of source code of any substantial portion of the Covered
00044  * Code or modification with rights to further distribute source must include
00045  * the above Copyright Notice, the above License, this list of Conditions,
00046  * and the following Disclaimer and Export Compliance provision.  In addition,
00047  * Licensee must cause all Covered Code to which Licensee contributes to
00048  * contain a file documenting the changes Licensee made to create that Covered
00049  * Code and the date of any change.  Licensee must include in that file the
00050  * documentation of any changes made by any predecessor Licensee.  Licensee
00051  * must include a prominent statement that the modification is derived,
00052  * directly or indirectly, from Original Intel Code.
00053  *
00054  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
00055  * Redistribution of source code of any substantial portion of the Covered
00056  * Code or modification without rights to further distribute source must
00057  * include the following Disclaimer and Export Compliance provision in the
00058  * documentation and/or other materials provided with distribution.  In
00059  * addition, Licensee may not authorize further sublicense of source of any
00060  * portion of the Covered Code, and must include terms to the effect that the
00061  * license from Licensee to its licensee is limited to the intellectual
00062  * property embodied in the software Licensee provides to its licensee, and
00063  * not to intellectual property embodied in modifications its licensee may
00064  * make.
00065  *
00066  * 3.3. Redistribution of Executable. Redistribution in executable form of any
00067  * substantial portion of the Covered Code or modification must reproduce the
00068  * above Copyright Notice, and the following Disclaimer and Export Compliance
00069  * provision in the documentation and/or other materials provided with the
00070  * distribution.
00071  *
00072  * 3.4. Intel retains all right, title, and interest in and to the Original
00073  * Intel Code.
00074  *
00075  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
00076  * Intel shall be used in advertising or otherwise to promote the sale, use or
00077  * other dealings in products derived from or relating to the Covered Code
00078  * without prior written authorization from Intel.
00079  *
00080  * 4. Disclaimer and Export Compliance
00081  *
00082  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
00083  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
00084  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
00085  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
00086  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
00087  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
00088  * PARTICULAR PURPOSE.
00089  *
00090  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
00091  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
00092  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
00093  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
00094  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
00095  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
00096  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
00097  * LIMITED REMEDY.
00098  *
00099  * 4.3. Licensee shall not export, either directly or indirectly, any of this
00100  * software or system incorporating such software without first obtaining any
00101  * required license or other approval from the U. S. Department of Commerce or
00102  * any other agency or department of the United States Government.  In the
00103  * event Licensee exports any such software from the United States or
00104  * re-exports any such software from a foreign destination, Licensee shall
00105  * ensure that the distribution and export/re-export of the software is in
00106  * compliance with all laws, regulations, orders, or other restrictions of the
00107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
00108  * any of its subsidiaries will export/re-export any technical data, process,
00109  * software, or service, directly or indirectly, to any country for which the
00110  * United States government or any agency thereof requires an export license,
00111  * other governmental approval, or letter of assurance, without first obtaining
00112  * such license, approval or letter.
00113  *
00114  *****************************************************************************/
00115 
00116 #define __NSACCESS_C__
00117 
00118 #include "acpi.h"
00119 #include "accommon.h"
00120 #include "amlcode.h"
00121 #include "acnamesp.h"
00122 #include "acdispat.h"
00123 
00124 
00125 #define _COMPONENT          ACPI_NAMESPACE
00126         ACPI_MODULE_NAME    ("nsaccess")
00127 
00128 
00129 /*******************************************************************************
00130  *
00131  * FUNCTION:    AcpiNsRootInitialize
00132  *
00133  * PARAMETERS:  None
00134  *
00135  * RETURN:      Status
00136  *
00137  * DESCRIPTION: Allocate and initialize the default root named objects
00138  *
00139  * MUTEX:       Locks namespace for entire execution
00140  *
00141  ******************************************************************************/
00142 
00143 ACPI_STATUS
00144 AcpiNsRootInitialize (
00145     void)
00146 {
00147     ACPI_STATUS                 Status;
00148     const ACPI_PREDEFINED_NAMES *InitVal = NULL;
00149     ACPI_NAMESPACE_NODE         *NewNode;
00150     ACPI_OPERAND_OBJECT         *ObjDesc;
00151     ACPI_STRING                 Val = NULL;
00152 
00153 
00154     ACPI_FUNCTION_TRACE (NsRootInitialize);
00155 
00156 
00157     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
00158     if (ACPI_FAILURE (Status))
00159     {
00160         return_ACPI_STATUS (Status);
00161     }
00162 
00163     /*
00164      * The global root ptr is initially NULL, so a non-NULL value indicates
00165      * that AcpiNsRootInitialize() has already been called; just return.
00166      */
00167     if (AcpiGbl_RootNode)
00168     {
00169         Status = AE_OK;
00170         goto UnlockAndExit;
00171     }
00172 
00173     /*
00174      * Tell the rest of the subsystem that the root is initialized
00175      * (This is OK because the namespace is locked)
00176      */
00177     AcpiGbl_RootNode = &AcpiGbl_RootNodeStruct;
00178 
00179     /* Enter the pre-defined names in the name table */
00180 
00181     ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
00182         "Entering predefined entries into namespace\n"));
00183 
00184     for (InitVal = AcpiGbl_PreDefinedNames; InitVal->Name; InitVal++)
00185     {
00186         /* _OSI is optional for now, will be permanent later */
00187 
00188         if (!ACPI_STRCMP (InitVal->Name, "_OSI") && !AcpiGbl_CreateOsiMethod)
00189         {
00190             continue;
00191         }
00192 
00193         Status = AcpiNsLookup (NULL, InitVal->Name, InitVal->Type,
00194                         ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH,
00195                         NULL, &NewNode);
00196 
00197         if (ACPI_FAILURE (Status) || (!NewNode)) /* Must be on same line for code converter */
00198         {
00199             ACPI_EXCEPTION ((AE_INFO, Status,
00200                 "Could not create predefined name %s",
00201                 InitVal->Name));
00202         }
00203 
00204         /*
00205          * Name entered successfully. If entry in PreDefinedNames[] specifies
00206          * an initial value, create the initial value.
00207          */
00208         if (InitVal->Val)
00209         {
00210             Status = AcpiOsPredefinedOverride (InitVal, &Val);
00211             if (ACPI_FAILURE (Status))
00212             {
00213                 ACPI_ERROR ((AE_INFO,
00214                     "Could not override predefined %s",
00215                     InitVal->Name));
00216             }
00217 
00218             if (!Val)
00219             {
00220                 Val = InitVal->Val;
00221             }
00222 
00223             /*
00224              * Entry requests an initial value, allocate a
00225              * descriptor for it.
00226              */
00227             ObjDesc = AcpiUtCreateInternalObject (InitVal->Type);
00228             if (!ObjDesc)
00229             {
00230                 Status = AE_NO_MEMORY;
00231                 goto UnlockAndExit;
00232             }
00233 
00234             /*
00235              * Convert value string from table entry to
00236              * internal representation. Only types actually
00237              * used for initial values are implemented here.
00238              */
00239             switch (InitVal->Type)
00240             {
00241             case ACPI_TYPE_METHOD:
00242                 ObjDesc->Method.ParamCount = (UINT8) ACPI_TO_INTEGER (Val);
00243                 ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID;
00244 
00245 #if defined (ACPI_ASL_COMPILER)
00246 
00247                 /* Save the parameter count for the iASL compiler */
00248 
00249                 NewNode->Value = ObjDesc->Method.ParamCount;
00250 #else
00251                 /* Mark this as a very SPECIAL method */
00252 
00253                 ObjDesc->Method.InfoFlags = ACPI_METHOD_INTERNAL_ONLY;
00254                 ObjDesc->Method.Dispatch.Implementation = AcpiUtOsiImplementation;
00255 #endif
00256                 break;
00257 
00258             case ACPI_TYPE_INTEGER:
00259 
00260                 ObjDesc->Integer.Value = ACPI_TO_INTEGER (Val);
00261                 break;
00262 
00263 
00264             case ACPI_TYPE_STRING:
00265 
00266                 /* Build an object around the static string */
00267 
00268                 ObjDesc->String.Length = (UINT32) ACPI_STRLEN (Val);
00269                 ObjDesc->String.Pointer = Val;
00270                 ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER;
00271                 break;
00272 
00273 
00274             case ACPI_TYPE_MUTEX:
00275 
00276                 ObjDesc->Mutex.Node = NewNode;
00277                 ObjDesc->Mutex.SyncLevel = (UINT8) (ACPI_TO_INTEGER (Val) - 1);
00278 
00279                 /* Create a mutex */
00280 
00281                 Status = AcpiOsCreateMutex (&ObjDesc->Mutex.OsMutex);
00282                 if (ACPI_FAILURE (Status))
00283                 {
00284                     AcpiUtRemoveReference (ObjDesc);
00285                     goto UnlockAndExit;
00286                 }
00287 
00288                 /* Special case for ACPI Global Lock */
00289 
00290                 if (ACPI_STRCMP (InitVal->Name, "_GL_") == 0)
00291                 {
00292                     AcpiGbl_GlobalLockMutex = ObjDesc;
00293 
00294                     /* Create additional counting semaphore for global lock */
00295 
00296                     Status = AcpiOsCreateSemaphore (
00297                                 1, 0, &AcpiGbl_GlobalLockSemaphore);
00298                     if (ACPI_FAILURE (Status))
00299                     {
00300                         AcpiUtRemoveReference (ObjDesc);
00301                         goto UnlockAndExit;
00302                     }
00303                 }
00304                 break;
00305 
00306 
00307             default:
00308 
00309                 ACPI_ERROR ((AE_INFO, "Unsupported initial type value 0x%X",
00310                     InitVal->Type));
00311                 AcpiUtRemoveReference (ObjDesc);
00312                 ObjDesc = NULL;
00313                 continue;
00314             }
00315 
00316             /* Store pointer to value descriptor in the Node */
00317 
00318             Status = AcpiNsAttachObject (NewNode, ObjDesc,
00319                         ObjDesc->Common.Type);
00320 
00321             /* Remove local reference to the object */
00322 
00323             AcpiUtRemoveReference (ObjDesc);
00324         }
00325     }
00326 
00327 
00328 UnlockAndExit:
00329     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
00330 
00331     /* Save a handle to "_GPE", it is always present */
00332 
00333     if (ACPI_SUCCESS (Status))
00334     {
00335         Status = AcpiNsGetNode (NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH,
00336                     &AcpiGbl_FadtGpeDevice);
00337     }
00338 
00339     return_ACPI_STATUS (Status);
00340 }
00341 
00342 
00343 /*******************************************************************************
00344  *
00345  * FUNCTION:    AcpiNsLookup
00346  *
00347  * PARAMETERS:  ScopeInfo       - Current scope info block
00348  *              Pathname        - Search pathname, in internal format
00349  *                                (as represented in the AML stream)
00350  *              Type            - Type associated with name
00351  *              InterpreterMode - IMODE_LOAD_PASS2 => add name if not found
00352  *              Flags           - Flags describing the search restrictions
00353  *              WalkState       - Current state of the walk
00354  *              ReturnNode      - Where the Node is placed (if found
00355  *                                or created successfully)
00356  *
00357  * RETURN:      Status
00358  *
00359  * DESCRIPTION: Find or enter the passed name in the name space.
00360  *              Log an error if name not found in Exec mode.
00361  *
00362  * MUTEX:       Assumes namespace is locked.
00363  *
00364  ******************************************************************************/
00365 
00366 ACPI_STATUS
00367 AcpiNsLookup (
00368     ACPI_GENERIC_STATE      *ScopeInfo,
00369     char                    *Pathname,
00370     ACPI_OBJECT_TYPE        Type,
00371     ACPI_INTERPRETER_MODE   InterpreterMode,
00372     UINT32                  Flags,
00373     ACPI_WALK_STATE         *WalkState,
00374     ACPI_NAMESPACE_NODE     **ReturnNode)
00375 {
00376     ACPI_STATUS             Status;
00377     char                    *Path = Pathname;
00378     ACPI_NAMESPACE_NODE     *PrefixNode;
00379     ACPI_NAMESPACE_NODE     *CurrentNode = NULL;
00380     ACPI_NAMESPACE_NODE     *ThisNode = NULL;
00381     UINT32                  NumSegments;
00382     UINT32                  NumCarats;
00383     ACPI_NAME               SimpleName;
00384     ACPI_OBJECT_TYPE        TypeToCheckFor;
00385     ACPI_OBJECT_TYPE        ThisSearchType;
00386     UINT32                  SearchParentFlag = ACPI_NS_SEARCH_PARENT;
00387     UINT32                  LocalFlags;
00388 
00389 
00390     ACPI_FUNCTION_TRACE (NsLookup);
00391 
00392 
00393     if (!ReturnNode)
00394     {
00395         return_ACPI_STATUS (AE_BAD_PARAMETER);
00396     }
00397 
00398     LocalFlags = Flags & ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_SEARCH_PARENT);
00399     *ReturnNode = ACPI_ENTRY_NOT_FOUND;
00400     AcpiGbl_NsLookupCount++;
00401 
00402     if (!AcpiGbl_RootNode)
00403     {
00404         return_ACPI_STATUS (AE_NO_NAMESPACE);
00405     }
00406 
00407     /* Get the prefix scope. A null scope means use the root scope */
00408 
00409     if ((!ScopeInfo) ||
00410         (!ScopeInfo->Scope.Node))
00411     {
00412         ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
00413             "Null scope prefix, using root node (%p)\n",
00414             AcpiGbl_RootNode));
00415 
00416         PrefixNode = AcpiGbl_RootNode;
00417     }
00418     else
00419     {
00420         PrefixNode = ScopeInfo->Scope.Node;
00421         if (ACPI_GET_DESCRIPTOR_TYPE (PrefixNode) != ACPI_DESC_TYPE_NAMED)
00422         {
00423             ACPI_ERROR ((AE_INFO, "%p is not a namespace node [%s]",
00424                 PrefixNode, AcpiUtGetDescriptorName (PrefixNode)));
00425             return_ACPI_STATUS (AE_AML_INTERNAL);
00426         }
00427 
00428         if (!(Flags & ACPI_NS_PREFIX_IS_SCOPE))
00429         {
00430             /*
00431              * This node might not be a actual "scope" node (such as a
00432              * Device/Method, etc.)  It could be a Package or other object
00433              * node. Backup up the tree to find the containing scope node.
00434              */
00435             while (!AcpiNsOpensScope (PrefixNode->Type) &&
00436                     PrefixNode->Type != ACPI_TYPE_ANY)
00437             {
00438                 PrefixNode = PrefixNode->Parent;
00439             }
00440         }
00441     }
00442 
00443     /* Save type. TBD: may be no longer necessary */
00444 
00445     TypeToCheckFor = Type;
00446 
00447     /*
00448      * Begin examination of the actual pathname
00449      */
00450     if (!Pathname)
00451     {
00452         /* A Null NamePath is allowed and refers to the root */
00453 
00454         NumSegments = 0;
00455         ThisNode = AcpiGbl_RootNode;
00456         Path = "";
00457 
00458         ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
00459             "Null Pathname (Zero segments), Flags=%X\n", Flags));
00460     }
00461     else
00462     {
00463         /*
00464          * Name pointer is valid (and must be in internal name format)
00465          *
00466          * Check for scope prefixes:
00467          *
00468          * As represented in the AML stream, a namepath consists of an
00469          * optional scope prefix followed by a name segment part.
00470          *
00471          * If present, the scope prefix is either a Root Prefix (in
00472          * which case the name is fully qualified), or one or more
00473          * Parent Prefixes (in which case the name's scope is relative
00474          * to the current scope).
00475          */
00476         if (*Path == (UINT8) AML_ROOT_PREFIX)
00477         {
00478             /* Pathname is fully qualified, start from the root */
00479 
00480             ThisNode = AcpiGbl_RootNode;
00481             SearchParentFlag = ACPI_NS_NO_UPSEARCH;
00482 
00483             /* Point to name segment part */
00484 
00485             Path++;
00486 
00487             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
00488                 "Path is absolute from root [%p]\n", ThisNode));
00489         }
00490         else
00491         {
00492             /* Pathname is relative to current scope, start there */
00493 
00494             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
00495                 "Searching relative to prefix scope [%4.4s] (%p)\n",
00496                 AcpiUtGetNodeName (PrefixNode), PrefixNode));
00497 
00498             /*
00499              * Handle multiple Parent Prefixes (carat) by just getting
00500              * the parent node for each prefix instance.
00501              */
00502             ThisNode = PrefixNode;
00503             NumCarats = 0;
00504             while (*Path == (UINT8) AML_PARENT_PREFIX)
00505             {
00506                 /* Name is fully qualified, no search rules apply */
00507 
00508                 SearchParentFlag = ACPI_NS_NO_UPSEARCH;
00509 
00510                 /*
00511                  * Point past this prefix to the name segment
00512                  * part or the next Parent Prefix
00513                  */
00514                 Path++;
00515 
00516                 /* Backup to the parent node */
00517 
00518                 NumCarats++;
00519                 ThisNode = ThisNode->Parent;
00520                 if (!ThisNode)
00521                 {
00522                     /* Current scope has no parent scope */
00523 
00524                     ACPI_ERROR ((AE_INFO,
00525                         "ACPI path has too many parent prefixes (^) "
00526                         "- reached beyond root node"));
00527                     return_ACPI_STATUS (AE_NOT_FOUND);
00528                 }
00529             }
00530 
00531             if (SearchParentFlag == ACPI_NS_NO_UPSEARCH)
00532             {
00533                 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
00534                     "Search scope is [%4.4s], path has %u carat(s)\n",
00535                     AcpiUtGetNodeName (ThisNode), NumCarats));
00536             }
00537         }
00538 
00539         /*
00540          * Determine the number of ACPI name segments in this pathname.
00541          *
00542          * The segment part consists of either:
00543          *  - A Null name segment (0)
00544          *  - A DualNamePrefix followed by two 4-byte name segments
00545          *  - A MultiNamePrefix followed by a byte indicating the
00546          *      number of segments and the segments themselves.
00547          *  - A single 4-byte name segment
00548          *
00549          * Examine the name prefix opcode, if any, to determine the number of
00550          * segments.
00551          */
00552         switch (*Path)
00553         {
00554         case 0:
00555             /*
00556              * Null name after a root or parent prefixes. We already
00557              * have the correct target node and there are no name segments.
00558              */
00559             NumSegments  = 0;
00560             Type = ThisNode->Type;
00561 
00562             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
00563                 "Prefix-only Pathname (Zero name segments), Flags=%X\n",
00564                 Flags));
00565             break;
00566 
00567         case AML_DUAL_NAME_PREFIX:
00568 
00569             /* More than one NameSeg, search rules do not apply */
00570 
00571             SearchParentFlag = ACPI_NS_NO_UPSEARCH;
00572 
00573             /* Two segments, point to first name segment */
00574 
00575             NumSegments = 2;
00576             Path++;
00577 
00578             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
00579                 "Dual Pathname (2 segments, Flags=%X)\n", Flags));
00580             break;
00581 
00582         case AML_MULTI_NAME_PREFIX_OP:
00583 
00584             /* More than one NameSeg, search rules do not apply */
00585 
00586             SearchParentFlag = ACPI_NS_NO_UPSEARCH;
00587 
00588             /* Extract segment count, point to first name segment */
00589 
00590             Path++;
00591             NumSegments = (UINT32) (UINT8) *Path;
00592             Path++;
00593 
00594             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
00595                 "Multi Pathname (%u Segments, Flags=%X)\n",
00596                 NumSegments, Flags));
00597             break;
00598 
00599         default:
00600             /*
00601              * Not a Null name, no Dual or Multi prefix, hence there is
00602              * only one name segment and Pathname is already pointing to it.
00603              */
00604             NumSegments = 1;
00605 
00606             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
00607                 "Simple Pathname (1 segment, Flags=%X)\n", Flags));
00608             break;
00609         }
00610 
00611         ACPI_DEBUG_EXEC (AcpiNsPrintPathname (NumSegments, Path));
00612     }
00613 
00614 
00615     /*
00616      * Search namespace for each segment of the name. Loop through and
00617      * verify (or add to the namespace) each name segment.
00618      *
00619      * The object type is significant only at the last name
00620      * segment. (We don't care about the types along the path, only
00621      * the type of the final target object.)
00622      */
00623     ThisSearchType = ACPI_TYPE_ANY;
00624     CurrentNode = ThisNode;
00625     while (NumSegments && CurrentNode)
00626     {
00627         NumSegments--;
00628         if (!NumSegments)
00629         {
00630             /* This is the last segment, enable typechecking */
00631 
00632             ThisSearchType = Type;
00633 
00634             /*
00635              * Only allow automatic parent search (search rules) if the caller
00636              * requested it AND we have a single, non-fully-qualified NameSeg
00637              */
00638             if ((SearchParentFlag != ACPI_NS_NO_UPSEARCH) &&
00639                 (Flags & ACPI_NS_SEARCH_PARENT))
00640             {
00641                 LocalFlags |= ACPI_NS_SEARCH_PARENT;
00642             }
00643 
00644             /* Set error flag according to caller */
00645 
00646             if (Flags & ACPI_NS_ERROR_IF_FOUND)
00647             {
00648                 LocalFlags |= ACPI_NS_ERROR_IF_FOUND;
00649             }
00650         }
00651 
00652         /* Extract one ACPI name from the front of the pathname */
00653 
00654         ACPI_MOVE_32_TO_32 (&SimpleName, Path);
00655 
00656         /* Try to find the single (4 character) ACPI name */
00657 
00658         Status = AcpiNsSearchAndEnter (SimpleName, WalkState, CurrentNode,
00659                     InterpreterMode, ThisSearchType, LocalFlags, &ThisNode);
00660         if (ACPI_FAILURE (Status))
00661         {
00662             if (Status == AE_NOT_FOUND)
00663             {
00664                 /* Name not found in ACPI namespace */
00665 
00666                 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
00667                     "Name [%4.4s] not found in scope [%4.4s] %p\n",
00668                     (char *) &SimpleName, (char *) &CurrentNode->Name,
00669                     CurrentNode));
00670             }
00671 
00672             *ReturnNode = ThisNode;
00673             return_ACPI_STATUS (Status);
00674         }
00675 
00676         /* More segments to follow? */
00677 
00678         if (NumSegments > 0)
00679         {
00680             /*
00681              * If we have an alias to an object that opens a scope (such as a
00682              * device or processor), we need to dereference the alias here so
00683              * that we can access any children of the original node (via the
00684              * remaining segments).
00685              */
00686             if (ThisNode->Type == ACPI_TYPE_LOCAL_ALIAS)
00687             {
00688                 if (!ThisNode->Object)
00689                 {
00690                     return_ACPI_STATUS (AE_NOT_EXIST);
00691                 }
00692 
00693                 if (AcpiNsOpensScope (((ACPI_NAMESPACE_NODE *)
00694                         ThisNode->Object)->Type))
00695                 {
00696                     ThisNode = (ACPI_NAMESPACE_NODE *) ThisNode->Object;
00697                 }
00698             }
00699         }
00700 
00701         /* Special handling for the last segment (NumSegments == 0) */
00702 
00703         else
00704         {
00705             /*
00706              * Sanity typecheck of the target object:
00707              *
00708              * If 1) This is the last segment (NumSegments == 0)
00709              *    2) And we are looking for a specific type
00710              *       (Not checking for TYPE_ANY)
00711              *    3) Which is not an alias
00712              *    4) Which is not a local type (TYPE_SCOPE)
00713              *    5) And the type of target object is known (not TYPE_ANY)
00714              *    6) And target object does not match what we are looking for
00715              *
00716              * Then we have a type mismatch. Just warn and ignore it.
00717              */
00718             if ((TypeToCheckFor != ACPI_TYPE_ANY)                   &&
00719                 (TypeToCheckFor != ACPI_TYPE_LOCAL_ALIAS)           &&
00720                 (TypeToCheckFor != ACPI_TYPE_LOCAL_METHOD_ALIAS)    &&
00721                 (TypeToCheckFor != ACPI_TYPE_LOCAL_SCOPE)           &&
00722                 (ThisNode->Type != ACPI_TYPE_ANY)                   &&
00723                 (ThisNode->Type != TypeToCheckFor))
00724             {
00725                 /* Complain about a type mismatch */
00726 
00727                 ACPI_WARNING ((AE_INFO,
00728                     "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)",
00729                     ACPI_CAST_PTR (char, &SimpleName),
00730                     AcpiUtGetTypeName (ThisNode->Type),
00731                     AcpiUtGetTypeName (TypeToCheckFor)));
00732             }
00733 
00734             /*
00735              * If this is the last name segment and we are not looking for a
00736              * specific type, but the type of found object is known, use that
00737              * type to (later) see if it opens a scope.
00738              */
00739             if (Type == ACPI_TYPE_ANY)
00740             {
00741                 Type = ThisNode->Type;
00742             }
00743         }
00744 
00745         /* Point to next name segment and make this node current */
00746 
00747         Path += ACPI_NAME_SIZE;
00748         CurrentNode = ThisNode;
00749     }
00750 
00751     /* Always check if we need to open a new scope */
00752 
00753     if (!(Flags & ACPI_NS_DONT_OPEN_SCOPE) && (WalkState))
00754     {
00755         /*
00756          * If entry is a type which opens a scope, push the new scope on the
00757          * scope stack.
00758          */
00759         if (AcpiNsOpensScope (Type))
00760         {
00761             Status = AcpiDsScopeStackPush (ThisNode, Type, WalkState);
00762             if (ACPI_FAILURE (Status))
00763             {
00764                 return_ACPI_STATUS (Status);
00765             }
00766         }
00767     }
00768 
00769     *ReturnNode = ThisNode;
00770     return_ACPI_STATUS (AE_OK);
00771 }
00772 

Generated on Sat May 26 2012 04:25:53 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.