1*3446Smrj /******************************************************************************
2*3446Smrj  *
3*3446Smrj  * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
4*3446Smrj  *                        parents and siblings and Scope manipulation
5*3446Smrj  *              $Revision: 1.153 $
6*3446Smrj  *
7*3446Smrj  *****************************************************************************/
8*3446Smrj 
9*3446Smrj /******************************************************************************
10*3446Smrj  *
11*3446Smrj  * 1. Copyright Notice
12*3446Smrj  *
13*3446Smrj  * Some or all of this work - Copyright (c) 1999 - 2006, Intel Corp.
14*3446Smrj  * All rights reserved.
15*3446Smrj  *
16*3446Smrj  * 2. License
17*3446Smrj  *
18*3446Smrj  * 2.1. This is your license from Intel Corp. under its intellectual property
19*3446Smrj  * rights.  You may have additional license terms from the party that provided
20*3446Smrj  * you this software, covering your right to use that party's intellectual
21*3446Smrj  * property rights.
22*3446Smrj  *
23*3446Smrj  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24*3446Smrj  * copy of the source code appearing in this file ("Covered Code") an
25*3446Smrj  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26*3446Smrj  * base code distributed originally by Intel ("Original Intel Code") to copy,
27*3446Smrj  * make derivatives, distribute, use and display any portion of the Covered
28*3446Smrj  * Code in any form, with the right to sublicense such rights; and
29*3446Smrj  *
30*3446Smrj  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31*3446Smrj  * license (with the right to sublicense), under only those claims of Intel
32*3446Smrj  * patents that are infringed by the Original Intel Code, to make, use, sell,
33*3446Smrj  * offer to sell, and import the Covered Code and derivative works thereof
34*3446Smrj  * solely to the minimum extent necessary to exercise the above copyright
35*3446Smrj  * license, and in no event shall the patent license extend to any additions
36*3446Smrj  * to or modifications of the Original Intel Code.  No other license or right
37*3446Smrj  * is granted directly or by implication, estoppel or otherwise;
38*3446Smrj  *
39*3446Smrj  * The above copyright and patent license is granted only if the following
40*3446Smrj  * conditions are met:
41*3446Smrj  *
42*3446Smrj  * 3. Conditions
43*3446Smrj  *
44*3446Smrj  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45*3446Smrj  * Redistribution of source code of any substantial portion of the Covered
46*3446Smrj  * Code or modification with rights to further distribute source must include
47*3446Smrj  * the above Copyright Notice, the above License, this list of Conditions,
48*3446Smrj  * and the following Disclaimer and Export Compliance provision.  In addition,
49*3446Smrj  * Licensee must cause all Covered Code to which Licensee contributes to
50*3446Smrj  * contain a file documenting the changes Licensee made to create that Covered
51*3446Smrj  * Code and the date of any change.  Licensee must include in that file the
52*3446Smrj  * documentation of any changes made by any predecessor Licensee.  Licensee
53*3446Smrj  * must include a prominent statement that the modification is derived,
54*3446Smrj  * directly or indirectly, from Original Intel Code.
55*3446Smrj  *
56*3446Smrj  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57*3446Smrj  * Redistribution of source code of any substantial portion of the Covered
58*3446Smrj  * Code or modification without rights to further distribute source must
59*3446Smrj  * include the following Disclaimer and Export Compliance provision in the
60*3446Smrj  * documentation and/or other materials provided with distribution.  In
61*3446Smrj  * addition, Licensee may not authorize further sublicense of source of any
62*3446Smrj  * portion of the Covered Code, and must include terms to the effect that the
63*3446Smrj  * license from Licensee to its licensee is limited to the intellectual
64*3446Smrj  * property embodied in the software Licensee provides to its licensee, and
65*3446Smrj  * not to intellectual property embodied in modifications its licensee may
66*3446Smrj  * make.
67*3446Smrj  *
68*3446Smrj  * 3.3. Redistribution of Executable. Redistribution in executable form of any
69*3446Smrj  * substantial portion of the Covered Code or modification must reproduce the
70*3446Smrj  * above Copyright Notice, and the following Disclaimer and Export Compliance
71*3446Smrj  * provision in the documentation and/or other materials provided with the
72*3446Smrj  * distribution.
73*3446Smrj  *
74*3446Smrj  * 3.4. Intel retains all right, title, and interest in and to the Original
75*3446Smrj  * Intel Code.
76*3446Smrj  *
77*3446Smrj  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78*3446Smrj  * Intel shall be used in advertising or otherwise to promote the sale, use or
79*3446Smrj  * other dealings in products derived from or relating to the Covered Code
80*3446Smrj  * without prior written authorization from Intel.
81*3446Smrj  *
82*3446Smrj  * 4. Disclaimer and Export Compliance
83*3446Smrj  *
84*3446Smrj  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85*3446Smrj  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86*3446Smrj  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87*3446Smrj  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88*3446Smrj  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89*3446Smrj  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90*3446Smrj  * PARTICULAR PURPOSE.
91*3446Smrj  *
92*3446Smrj  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93*3446Smrj  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94*3446Smrj  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95*3446Smrj  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96*3446Smrj  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97*3446Smrj  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98*3446Smrj  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99*3446Smrj  * LIMITED REMEDY.
100*3446Smrj  *
101*3446Smrj  * 4.3. Licensee shall not export, either directly or indirectly, any of this
102*3446Smrj  * software or system incorporating such software without first obtaining any
103*3446Smrj  * required license or other approval from the U. S. Department of Commerce or
104*3446Smrj  * any other agency or department of the United States Government.  In the
105*3446Smrj  * event Licensee exports any such software from the United States or
106*3446Smrj  * re-exports any such software from a foreign destination, Licensee shall
107*3446Smrj  * ensure that the distribution and export/re-export of the software is in
108*3446Smrj  * compliance with all laws, regulations, orders, or other restrictions of the
109*3446Smrj  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110*3446Smrj  * any of its subsidiaries will export/re-export any technical data, process,
111*3446Smrj  * software, or service, directly or indirectly, to any country for which the
112*3446Smrj  * United States government or any agency thereof requires an export license,
113*3446Smrj  * other governmental approval, or letter of assurance, without first obtaining
114*3446Smrj  * such license, approval or letter.
115*3446Smrj  *
116*3446Smrj  *****************************************************************************/
117*3446Smrj 
118*3446Smrj #define __NSUTILS_C__
119*3446Smrj 
120*3446Smrj #include "acpi.h"
121*3446Smrj #include "acnamesp.h"
122*3446Smrj #include "amlcode.h"
123*3446Smrj #include "actables.h"
124*3446Smrj 
125*3446Smrj #define _COMPONENT          ACPI_NAMESPACE
126*3446Smrj         ACPI_MODULE_NAME    ("nsutils")
127*3446Smrj 
128*3446Smrj /* Local prototypes */
129*3446Smrj 
130*3446Smrj static BOOLEAN
131*3446Smrj AcpiNsValidPathSeparator (
132*3446Smrj     char                    Sep);
133*3446Smrj 
134*3446Smrj #ifdef ACPI_OBSOLETE_FUNCTIONS
135*3446Smrj ACPI_NAME
136*3446Smrj AcpiNsFindParentName (
137*3446Smrj     ACPI_NAMESPACE_NODE     *NodeToSearch);
138*3446Smrj #endif
139*3446Smrj 
140*3446Smrj 
141*3446Smrj /*******************************************************************************
142*3446Smrj  *
143*3446Smrj  * FUNCTION:    AcpiNsReportError
144*3446Smrj  *
145*3446Smrj  * PARAMETERS:  ModuleName          - Caller's module name (for error output)
146*3446Smrj  *              LineNumber          - Caller's line number (for error output)
147*3446Smrj  *              InternalName        - Name or path of the namespace node
148*3446Smrj  *              LookupStatus        - Exception code from NS lookup
149*3446Smrj  *
150*3446Smrj  * RETURN:      None
151*3446Smrj  *
152*3446Smrj  * DESCRIPTION: Print warning message with full pathname
153*3446Smrj  *
154*3446Smrj  ******************************************************************************/
155*3446Smrj 
156*3446Smrj void
157*3446Smrj AcpiNsReportError (
158*3446Smrj     char                    *ModuleName,
159*3446Smrj     UINT32                  LineNumber,
160*3446Smrj     char                    *InternalName,
161*3446Smrj     ACPI_STATUS             LookupStatus)
162*3446Smrj {
163*3446Smrj     ACPI_STATUS             Status;
164*3446Smrj     UINT32                  BadName;
165*3446Smrj     char                    *Name = NULL;
166*3446Smrj 
167*3446Smrj 
168*3446Smrj     AcpiOsPrintf ("ACPI Error (%s-%04d): ", ModuleName, LineNumber);
169*3446Smrj 
170*3446Smrj     if (LookupStatus == AE_BAD_CHARACTER)
171*3446Smrj     {
172*3446Smrj         /* There is a non-ascii character in the name */
173*3446Smrj 
174*3446Smrj         ACPI_MOVE_32_TO_32 (&BadName, InternalName);
175*3446Smrj         AcpiOsPrintf ("[0x%4.4X] (NON-ASCII)", BadName);
176*3446Smrj     }
177*3446Smrj     else
178*3446Smrj     {
179*3446Smrj         /* Convert path to external format */
180*3446Smrj 
181*3446Smrj         Status = AcpiNsExternalizeName (ACPI_UINT32_MAX,
182*3446Smrj                     InternalName, NULL, &Name);
183*3446Smrj 
184*3446Smrj         /* Print target name */
185*3446Smrj 
186*3446Smrj         if (ACPI_SUCCESS (Status))
187*3446Smrj         {
188*3446Smrj             AcpiOsPrintf ("[%s]", Name);
189*3446Smrj         }
190*3446Smrj         else
191*3446Smrj         {
192*3446Smrj             AcpiOsPrintf ("[COULD NOT EXTERNALIZE NAME]");
193*3446Smrj         }
194*3446Smrj 
195*3446Smrj         if (Name)
196*3446Smrj         {
197*3446Smrj             ACPI_FREE (Name);
198*3446Smrj         }
199*3446Smrj     }
200*3446Smrj 
201*3446Smrj     AcpiOsPrintf (" Namespace lookup failure, %s\n",
202*3446Smrj         AcpiFormatException (LookupStatus));
203*3446Smrj }
204*3446Smrj 
205*3446Smrj 
206*3446Smrj /*******************************************************************************
207*3446Smrj  *
208*3446Smrj  * FUNCTION:    AcpiNsReportMethodError
209*3446Smrj  *
210*3446Smrj  * PARAMETERS:  ModuleName          - Caller's module name (for error output)
211*3446Smrj  *              LineNumber          - Caller's line number (for error output)
212*3446Smrj  *              Message             - Error message to use on failure
213*3446Smrj  *              PrefixNode          - Prefix relative to the path
214*3446Smrj  *              Path                - Path to the node (optional)
215*3446Smrj  *              MethodStatus        - Execution status
216*3446Smrj  *
217*3446Smrj  * RETURN:      None
218*3446Smrj  *
219*3446Smrj  * DESCRIPTION: Print warning message with full pathname
220*3446Smrj  *
221*3446Smrj  ******************************************************************************/
222*3446Smrj 
223*3446Smrj void
224*3446Smrj AcpiNsReportMethodError (
225*3446Smrj     char                    *ModuleName,
226*3446Smrj     UINT32                  LineNumber,
227*3446Smrj     char                    *Message,
228*3446Smrj     ACPI_NAMESPACE_NODE     *PrefixNode,
229*3446Smrj     char                    *Path,
230*3446Smrj     ACPI_STATUS             MethodStatus)
231*3446Smrj {
232*3446Smrj     ACPI_STATUS             Status;
233*3446Smrj     ACPI_NAMESPACE_NODE     *Node = PrefixNode;
234*3446Smrj 
235*3446Smrj 
236*3446Smrj     AcpiOsPrintf ("ACPI Error (%s-%04d): ", ModuleName, LineNumber);
237*3446Smrj 
238*3446Smrj     if (Path)
239*3446Smrj     {
240*3446Smrj         Status = AcpiNsGetNode (PrefixNode, Path, ACPI_NS_NO_UPSEARCH,
241*3446Smrj                     &Node);
242*3446Smrj         if (ACPI_FAILURE (Status))
243*3446Smrj         {
244*3446Smrj             AcpiOsPrintf ("[Could not get node by pathname]");
245*3446Smrj         }
246*3446Smrj     }
247*3446Smrj 
248*3446Smrj     AcpiNsPrintNodePathname (Node, Message);
249*3446Smrj     AcpiOsPrintf (", %s\n", AcpiFormatException (MethodStatus));
250*3446Smrj }
251*3446Smrj 
252*3446Smrj 
253*3446Smrj /*******************************************************************************
254*3446Smrj  *
255*3446Smrj  * FUNCTION:    AcpiNsPrintNodePathname
256*3446Smrj  *
257*3446Smrj  * PARAMETERS:  Node            - Object
258*3446Smrj  *              Message         - Prefix message
259*3446Smrj  *
260*3446Smrj  * DESCRIPTION: Print an object's full namespace pathname
261*3446Smrj  *              Manages allocation/freeing of a pathname buffer
262*3446Smrj  *
263*3446Smrj  ******************************************************************************/
264*3446Smrj 
265*3446Smrj void
266*3446Smrj AcpiNsPrintNodePathname (
267*3446Smrj     ACPI_NAMESPACE_NODE     *Node,
268*3446Smrj     char                    *Message)
269*3446Smrj {
270*3446Smrj     ACPI_BUFFER             Buffer;
271*3446Smrj     ACPI_STATUS             Status;
272*3446Smrj 
273*3446Smrj 
274*3446Smrj     if (!Node)
275*3446Smrj     {
276*3446Smrj         AcpiOsPrintf ("[NULL NAME]");
277*3446Smrj         return;
278*3446Smrj     }
279*3446Smrj 
280*3446Smrj     /* Convert handle to full pathname and print it (with supplied message) */
281*3446Smrj 
282*3446Smrj     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
283*3446Smrj 
284*3446Smrj     Status = AcpiNsHandleToPathname (Node, &Buffer);
285*3446Smrj     if (ACPI_SUCCESS (Status))
286*3446Smrj     {
287*3446Smrj         if (Message)
288*3446Smrj         {
289*3446Smrj             AcpiOsPrintf ("%s ", Message);
290*3446Smrj         }
291*3446Smrj 
292*3446Smrj         AcpiOsPrintf ("[%s] (Node %p)", (char *) Buffer.Pointer, Node);
293*3446Smrj         ACPI_FREE (Buffer.Pointer);
294*3446Smrj     }
295*3446Smrj }
296*3446Smrj 
297*3446Smrj 
298*3446Smrj /*******************************************************************************
299*3446Smrj  *
300*3446Smrj  * FUNCTION:    AcpiNsValidRootPrefix
301*3446Smrj  *
302*3446Smrj  * PARAMETERS:  Prefix          - Character to be checked
303*3446Smrj  *
304*3446Smrj  * RETURN:      TRUE if a valid prefix
305*3446Smrj  *
306*3446Smrj  * DESCRIPTION: Check if a character is a valid ACPI Root prefix
307*3446Smrj  *
308*3446Smrj  ******************************************************************************/
309*3446Smrj 
310*3446Smrj BOOLEAN
311*3446Smrj AcpiNsValidRootPrefix (
312*3446Smrj     char                    Prefix)
313*3446Smrj {
314*3446Smrj 
315*3446Smrj     return ((BOOLEAN) (Prefix == '\\'));
316*3446Smrj }
317*3446Smrj 
318*3446Smrj 
319*3446Smrj /*******************************************************************************
320*3446Smrj  *
321*3446Smrj  * FUNCTION:    AcpiNsValidPathSeparator
322*3446Smrj  *
323*3446Smrj  * PARAMETERS:  Sep         - Character to be checked
324*3446Smrj  *
325*3446Smrj  * RETURN:      TRUE if a valid path separator
326*3446Smrj  *
327*3446Smrj  * DESCRIPTION: Check if a character is a valid ACPI path separator
328*3446Smrj  *
329*3446Smrj  ******************************************************************************/
330*3446Smrj 
331*3446Smrj static BOOLEAN
332*3446Smrj AcpiNsValidPathSeparator (
333*3446Smrj     char                    Sep)
334*3446Smrj {
335*3446Smrj 
336*3446Smrj     return ((BOOLEAN) (Sep == '.'));
337*3446Smrj }
338*3446Smrj 
339*3446Smrj 
340*3446Smrj /*******************************************************************************
341*3446Smrj  *
342*3446Smrj  * FUNCTION:    AcpiNsGetType
343*3446Smrj  *
344*3446Smrj  * PARAMETERS:  Node        - Parent Node to be examined
345*3446Smrj  *
346*3446Smrj  * RETURN:      Type field from Node whose handle is passed
347*3446Smrj  *
348*3446Smrj  * DESCRIPTION: Return the type of a Namespace node
349*3446Smrj  *
350*3446Smrj  ******************************************************************************/
351*3446Smrj 
352*3446Smrj ACPI_OBJECT_TYPE
353*3446Smrj AcpiNsGetType (
354*3446Smrj     ACPI_NAMESPACE_NODE     *Node)
355*3446Smrj {
356*3446Smrj     ACPI_FUNCTION_TRACE (NsGetType);
357*3446Smrj 
358*3446Smrj 
359*3446Smrj     if (!Node)
360*3446Smrj     {
361*3446Smrj         ACPI_WARNING ((AE_INFO, "Null Node parameter"));
362*3446Smrj         return_UINT32 (ACPI_TYPE_ANY);
363*3446Smrj     }
364*3446Smrj 
365*3446Smrj     return_UINT32 ((ACPI_OBJECT_TYPE) Node->Type);
366*3446Smrj }
367*3446Smrj 
368*3446Smrj 
369*3446Smrj /*******************************************************************************
370*3446Smrj  *
371*3446Smrj  * FUNCTION:    AcpiNsLocal
372*3446Smrj  *
373*3446Smrj  * PARAMETERS:  Type        - A namespace object type
374*3446Smrj  *
375*3446Smrj  * RETURN:      LOCAL if names must be found locally in objects of the
376*3446Smrj  *              passed type, 0 if enclosing scopes should be searched
377*3446Smrj  *
378*3446Smrj  * DESCRIPTION: Returns scope rule for the given object type.
379*3446Smrj  *
380*3446Smrj  ******************************************************************************/
381*3446Smrj 
382*3446Smrj UINT32
383*3446Smrj AcpiNsLocal (
384*3446Smrj     ACPI_OBJECT_TYPE        Type)
385*3446Smrj {
386*3446Smrj     ACPI_FUNCTION_TRACE (NsLocal);
387*3446Smrj 
388*3446Smrj 
389*3446Smrj     if (!AcpiUtValidObjectType (Type))
390*3446Smrj     {
391*3446Smrj         /* Type code out of range  */
392*3446Smrj 
393*3446Smrj         ACPI_WARNING ((AE_INFO, "Invalid Object Type %X", Type));
394*3446Smrj         return_UINT32 (ACPI_NS_NORMAL);
395*3446Smrj     }
396*3446Smrj 
397*3446Smrj     return_UINT32 ((UINT32) AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL);
398*3446Smrj }
399*3446Smrj 
400*3446Smrj 
401*3446Smrj /*******************************************************************************
402*3446Smrj  *
403*3446Smrj  * FUNCTION:    AcpiNsGetInternalNameLength
404*3446Smrj  *
405*3446Smrj  * PARAMETERS:  Info            - Info struct initialized with the
406*3446Smrj  *                                external name pointer.
407*3446Smrj  *
408*3446Smrj  * RETURN:      None
409*3446Smrj  *
410*3446Smrj  * DESCRIPTION: Calculate the length of the internal (AML) namestring
411*3446Smrj  *              corresponding to the external (ASL) namestring.
412*3446Smrj  *
413*3446Smrj  ******************************************************************************/
414*3446Smrj 
415*3446Smrj void
416*3446Smrj AcpiNsGetInternalNameLength (
417*3446Smrj     ACPI_NAMESTRING_INFO    *Info)
418*3446Smrj {
419*3446Smrj     char                    *NextExternalChar;
420*3446Smrj     UINT32                  i;
421*3446Smrj 
422*3446Smrj 
423*3446Smrj     ACPI_FUNCTION_ENTRY ();
424*3446Smrj 
425*3446Smrj 
426*3446Smrj     NextExternalChar = Info->ExternalName;
427*3446Smrj     Info->NumCarats = 0;
428*3446Smrj     Info->NumSegments = 0;
429*3446Smrj     Info->FullyQualified = FALSE;
430*3446Smrj 
431*3446Smrj     /*
432*3446Smrj      * For the internal name, the required length is 4 bytes per segment, plus
433*3446Smrj      * 1 each for RootPrefix, MultiNamePrefixOp, segment count, trailing null
434*3446Smrj      * (which is not really needed, but no there's harm in putting it there)
435*3446Smrj      *
436*3446Smrj      * strlen() + 1 covers the first NameSeg, which has no path separator
437*3446Smrj      */
438*3446Smrj     if (AcpiNsValidRootPrefix (NextExternalChar[0]))
439*3446Smrj     {
440*3446Smrj         Info->FullyQualified = TRUE;
441*3446Smrj         NextExternalChar++;
442*3446Smrj     }
443*3446Smrj     else
444*3446Smrj     {
445*3446Smrj         /*
446*3446Smrj          * Handle Carat prefixes
447*3446Smrj          */
448*3446Smrj         while (*NextExternalChar == '^')
449*3446Smrj         {
450*3446Smrj             Info->NumCarats++;
451*3446Smrj             NextExternalChar++;
452*3446Smrj         }
453*3446Smrj     }
454*3446Smrj 
455*3446Smrj     /*
456*3446Smrj      * Determine the number of ACPI name "segments" by counting the number of
457*3446Smrj      * path separators within the string. Start with one segment since the
458*3446Smrj      * segment count is [(# separators) + 1], and zero separators is ok.
459*3446Smrj      */
460*3446Smrj     if (*NextExternalChar)
461*3446Smrj     {
462*3446Smrj         Info->NumSegments = 1;
463*3446Smrj         for (i = 0; NextExternalChar[i]; i++)
464*3446Smrj         {
465*3446Smrj             if (AcpiNsValidPathSeparator (NextExternalChar[i]))
466*3446Smrj             {
467*3446Smrj                 Info->NumSegments++;
468*3446Smrj             }
469*3446Smrj         }
470*3446Smrj     }
471*3446Smrj 
472*3446Smrj     Info->Length = (ACPI_NAME_SIZE * Info->NumSegments) +
473*3446Smrj                     4 + Info->NumCarats;
474*3446Smrj 
475*3446Smrj     Info->NextExternalChar = NextExternalChar;
476*3446Smrj }
477*3446Smrj 
478*3446Smrj 
479*3446Smrj /*******************************************************************************
480*3446Smrj  *
481*3446Smrj  * FUNCTION:    AcpiNsBuildInternalName
482*3446Smrj  *
483*3446Smrj  * PARAMETERS:  Info            - Info struct fully initialized
484*3446Smrj  *
485*3446Smrj  * RETURN:      Status
486*3446Smrj  *
487*3446Smrj  * DESCRIPTION: Construct the internal (AML) namestring
488*3446Smrj  *              corresponding to the external (ASL) namestring.
489*3446Smrj  *
490*3446Smrj  ******************************************************************************/
491*3446Smrj 
492*3446Smrj ACPI_STATUS
493*3446Smrj AcpiNsBuildInternalName (
494*3446Smrj     ACPI_NAMESTRING_INFO    *Info)
495*3446Smrj {
496*3446Smrj     UINT32                  NumSegments = Info->NumSegments;
497*3446Smrj     char                    *InternalName = Info->InternalName;
498*3446Smrj     char                    *ExternalName = Info->NextExternalChar;
499*3446Smrj     char                    *Result = NULL;
500*3446Smrj     ACPI_NATIVE_UINT        i;
501*3446Smrj 
502*3446Smrj 
503*3446Smrj     ACPI_FUNCTION_TRACE (NsBuildInternalName);
504*3446Smrj 
505*3446Smrj 
506*3446Smrj     /* Setup the correct prefixes, counts, and pointers */
507*3446Smrj 
508*3446Smrj     if (Info->FullyQualified)
509*3446Smrj     {
510*3446Smrj         InternalName[0] = '\\';
511*3446Smrj 
512*3446Smrj         if (NumSegments <= 1)
513*3446Smrj         {
514*3446Smrj             Result = &InternalName[1];
515*3446Smrj         }
516*3446Smrj         else if (NumSegments == 2)
517*3446Smrj         {
518*3446Smrj             InternalName[1] = AML_DUAL_NAME_PREFIX;
519*3446Smrj             Result = &InternalName[2];
520*3446Smrj         }
521*3446Smrj         else
522*3446Smrj         {
523*3446Smrj             InternalName[1] = AML_MULTI_NAME_PREFIX_OP;
524*3446Smrj             InternalName[2] = (char) NumSegments;
525*3446Smrj             Result = &InternalName[3];
526*3446Smrj         }
527*3446Smrj     }
528*3446Smrj     else
529*3446Smrj     {
530*3446Smrj         /*
531*3446Smrj          * Not fully qualified.
532*3446Smrj          * Handle Carats first, then append the name segments
533*3446Smrj          */
534*3446Smrj         i = 0;
535*3446Smrj         if (Info->NumCarats)
536*3446Smrj         {
537*3446Smrj             for (i = 0; i < Info->NumCarats; i++)
538*3446Smrj             {
539*3446Smrj                 InternalName[i] = '^';
540*3446Smrj             }
541*3446Smrj         }
542*3446Smrj 
543*3446Smrj         if (NumSegments <= 1)
544*3446Smrj         {
545*3446Smrj             Result = &InternalName[i];
546*3446Smrj         }
547*3446Smrj         else if (NumSegments == 2)
548*3446Smrj         {
549*3446Smrj             InternalName[i] = AML_DUAL_NAME_PREFIX;
550*3446Smrj             Result = &InternalName[(ACPI_NATIVE_UINT) (i+1)];
551*3446Smrj         }
552*3446Smrj         else
553*3446Smrj         {
554*3446Smrj             InternalName[i] = AML_MULTI_NAME_PREFIX_OP;
555*3446Smrj             InternalName[(ACPI_NATIVE_UINT) (i+1)] = (char) NumSegments;
556*3446Smrj             Result = &InternalName[(ACPI_NATIVE_UINT) (i+2)];
557*3446Smrj         }
558*3446Smrj     }
559*3446Smrj 
560*3446Smrj     /* Build the name (minus path separators) */
561*3446Smrj 
562*3446Smrj     for (; NumSegments; NumSegments--)
563*3446Smrj     {
564*3446Smrj         for (i = 0; i < ACPI_NAME_SIZE; i++)
565*3446Smrj         {
566*3446Smrj             if (AcpiNsValidPathSeparator (*ExternalName) ||
567*3446Smrj                (*ExternalName == 0))
568*3446Smrj             {
569*3446Smrj                 /* Pad the segment with underscore(s) if segment is short */
570*3446Smrj 
571*3446Smrj                 Result[i] = '_';
572*3446Smrj             }
573*3446Smrj             else
574*3446Smrj             {
575*3446Smrj                 /* Convert the character to uppercase and save it */
576*3446Smrj 
577*3446Smrj                 Result[i] = (char) ACPI_TOUPPER ((int) *ExternalName);
578*3446Smrj                 ExternalName++;
579*3446Smrj             }
580*3446Smrj         }
581*3446Smrj 
582*3446Smrj         /* Now we must have a path separator, or the pathname is bad */
583*3446Smrj 
584*3446Smrj         if (!AcpiNsValidPathSeparator (*ExternalName) &&
585*3446Smrj             (*ExternalName != 0))
586*3446Smrj         {
587*3446Smrj             return_ACPI_STATUS (AE_BAD_PARAMETER);
588*3446Smrj         }
589*3446Smrj 
590*3446Smrj         /* Move on the next segment */
591*3446Smrj 
592*3446Smrj         ExternalName++;
593*3446Smrj         Result += ACPI_NAME_SIZE;
594*3446Smrj     }
595*3446Smrj 
596*3446Smrj     /* Terminate the string */
597*3446Smrj 
598*3446Smrj     *Result = 0;
599*3446Smrj 
600*3446Smrj     if (Info->FullyQualified)
601*3446Smrj     {
602*3446Smrj         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n",
603*3446Smrj             InternalName, InternalName));
604*3446Smrj     }
605*3446Smrj     else
606*3446Smrj     {
607*3446Smrj         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
608*3446Smrj             InternalName, InternalName));
609*3446Smrj     }
610*3446Smrj 
611*3446Smrj     return_ACPI_STATUS (AE_OK);
612*3446Smrj }
613*3446Smrj 
614*3446Smrj 
615*3446Smrj /*******************************************************************************
616*3446Smrj  *
617*3446Smrj  * FUNCTION:    AcpiNsInternalizeName
618*3446Smrj  *
619*3446Smrj  * PARAMETERS:  *ExternalName           - External representation of name
620*3446Smrj  *              **Converted Name        - Where to return the resulting
621*3446Smrj  *                                        internal represention of the name
622*3446Smrj  *
623*3446Smrj  * RETURN:      Status
624*3446Smrj  *
625*3446Smrj  * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0")
626*3446Smrj  *              to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
627*3446Smrj  *
628*3446Smrj  *******************************************************************************/
629*3446Smrj 
630*3446Smrj ACPI_STATUS
631*3446Smrj AcpiNsInternalizeName (
632*3446Smrj     char                    *ExternalName,
633*3446Smrj     char                    **ConvertedName)
634*3446Smrj {
635*3446Smrj     char                    *InternalName;
636*3446Smrj     ACPI_NAMESTRING_INFO    Info;
637*3446Smrj     ACPI_STATUS             Status;
638*3446Smrj 
639*3446Smrj 
640*3446Smrj     ACPI_FUNCTION_TRACE (NsInternalizeName);
641*3446Smrj 
642*3446Smrj 
643*3446Smrj     if ((!ExternalName)      ||
644*3446Smrj         (*ExternalName == 0) ||
645*3446Smrj         (!ConvertedName))
646*3446Smrj     {
647*3446Smrj         return_ACPI_STATUS (AE_BAD_PARAMETER);
648*3446Smrj     }
649*3446Smrj 
650*3446Smrj     /* Get the length of the new internal name */
651*3446Smrj 
652*3446Smrj     Info.ExternalName = ExternalName;
653*3446Smrj     AcpiNsGetInternalNameLength (&Info);
654*3446Smrj 
655*3446Smrj     /* We need a segment to store the internal  name */
656*3446Smrj 
657*3446Smrj     InternalName = ACPI_ALLOCATE_ZEROED (Info.Length);
658*3446Smrj     if (!InternalName)
659*3446Smrj     {
660*3446Smrj         return_ACPI_STATUS (AE_NO_MEMORY);
661*3446Smrj     }
662*3446Smrj 
663*3446Smrj     /* Build the name */
664*3446Smrj 
665*3446Smrj     Info.InternalName = InternalName;
666*3446Smrj     Status = AcpiNsBuildInternalName (&Info);
667*3446Smrj     if (ACPI_FAILURE (Status))
668*3446Smrj     {
669*3446Smrj         ACPI_FREE (InternalName);
670*3446Smrj         return_ACPI_STATUS (Status);
671*3446Smrj     }
672*3446Smrj 
673*3446Smrj     *ConvertedName = InternalName;
674*3446Smrj     return_ACPI_STATUS (AE_OK);
675*3446Smrj }
676*3446Smrj 
677*3446Smrj 
678*3446Smrj /*******************************************************************************
679*3446Smrj  *
680*3446Smrj  * FUNCTION:    AcpiNsExternalizeName
681*3446Smrj  *
682*3446Smrj  * PARAMETERS:  InternalNameLength  - Lenth of the internal name below
683*3446Smrj  *              InternalName        - Internal representation of name
684*3446Smrj  *              ConvertedNameLength - Where the length is returned
685*3446Smrj  *              ConvertedName       - Where the resulting external name
686*3446Smrj  *                                    is returned
687*3446Smrj  *
688*3446Smrj  * RETURN:      Status
689*3446Smrj  *
690*3446Smrj  * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
691*3446Smrj  *              to its external (printable) form (e.g. "\_PR_.CPU0")
692*3446Smrj  *
693*3446Smrj  ******************************************************************************/
694*3446Smrj 
695*3446Smrj ACPI_STATUS
696*3446Smrj AcpiNsExternalizeName (
697*3446Smrj     UINT32                  InternalNameLength,
698*3446Smrj     char                    *InternalName,
699*3446Smrj     UINT32                  *ConvertedNameLength,
700*3446Smrj     char                    **ConvertedName)
701*3446Smrj {
702*3446Smrj     ACPI_NATIVE_UINT        NamesIndex = 0;
703*3446Smrj     ACPI_NATIVE_UINT        NumSegments = 0;
704*3446Smrj     ACPI_NATIVE_UINT        RequiredLength;
705*3446Smrj     ACPI_NATIVE_UINT        PrefixLength = 0;
706*3446Smrj     ACPI_NATIVE_UINT        i = 0;
707*3446Smrj     ACPI_NATIVE_UINT        j = 0;
708*3446Smrj 
709*3446Smrj 
710*3446Smrj     ACPI_FUNCTION_TRACE (NsExternalizeName);
711*3446Smrj 
712*3446Smrj 
713*3446Smrj     if (!InternalNameLength     ||
714*3446Smrj         !InternalName           ||
715*3446Smrj         !ConvertedName)
716*3446Smrj     {
717*3446Smrj         return_ACPI_STATUS (AE_BAD_PARAMETER);
718*3446Smrj     }
719*3446Smrj 
720*3446Smrj     /*
721*3446Smrj      * Check for a prefix (one '\' | one or more '^').
722*3446Smrj      */
723*3446Smrj     switch (InternalName[0])
724*3446Smrj     {
725*3446Smrj     case '\\':
726*3446Smrj         PrefixLength = 1;
727*3446Smrj         break;
728*3446Smrj 
729*3446Smrj     case '^':
730*3446Smrj         for (i = 0; i < InternalNameLength; i++)
731*3446Smrj         {
732*3446Smrj             if (InternalName[i] == '^')
733*3446Smrj             {
734*3446Smrj                 PrefixLength = i + 1;
735*3446Smrj             }
736*3446Smrj             else
737*3446Smrj             {
738*3446Smrj                 break;
739*3446Smrj             }
740*3446Smrj         }
741*3446Smrj 
742*3446Smrj         if (i == InternalNameLength)
743*3446Smrj         {
744*3446Smrj             PrefixLength = i;
745*3446Smrj         }
746*3446Smrj 
747*3446Smrj         break;
748*3446Smrj 
749*3446Smrj     default:
750*3446Smrj         break;
751*3446Smrj     }
752*3446Smrj 
753*3446Smrj     /*
754*3446Smrj      * Check for object names.  Note that there could be 0-255 of these
755*3446Smrj      * 4-byte elements.
756*3446Smrj      */
757*3446Smrj     if (PrefixLength < InternalNameLength)
758*3446Smrj     {
759*3446Smrj         switch (InternalName[PrefixLength])
760*3446Smrj         {
761*3446Smrj         case AML_MULTI_NAME_PREFIX_OP:
762*3446Smrj 
763*3446Smrj             /* <count> 4-byte names */
764*3446Smrj 
765*3446Smrj             NamesIndex = PrefixLength + 2;
766*3446Smrj             NumSegments = (ACPI_NATIVE_UINT) (UINT8)
767*3446Smrj                           InternalName[(ACPI_NATIVE_UINT) (PrefixLength + 1)];
768*3446Smrj             break;
769*3446Smrj 
770*3446Smrj         case AML_DUAL_NAME_PREFIX:
771*3446Smrj 
772*3446Smrj             /* Two 4-byte names */
773*3446Smrj 
774*3446Smrj             NamesIndex = PrefixLength + 1;
775*3446Smrj             NumSegments = 2;
776*3446Smrj             break;
777*3446Smrj 
778*3446Smrj         case 0:
779*3446Smrj 
780*3446Smrj             /* NullName */
781*3446Smrj 
782*3446Smrj             NamesIndex = 0;
783*3446Smrj             NumSegments = 0;
784*3446Smrj             break;
785*3446Smrj 
786*3446Smrj         default:
787*3446Smrj 
788*3446Smrj             /* one 4-byte name */
789*3446Smrj 
790*3446Smrj             NamesIndex = PrefixLength;
791*3446Smrj             NumSegments = 1;
792*3446Smrj             break;
793*3446Smrj         }
794*3446Smrj     }
795*3446Smrj 
796*3446Smrj     /*
797*3446Smrj      * Calculate the length of ConvertedName, which equals the length
798*3446Smrj      * of the prefix, length of all object names, length of any required
799*3446Smrj      * punctuation ('.') between object names, plus the NULL terminator.
800*3446Smrj      */
801*3446Smrj     RequiredLength = PrefixLength + (4 * NumSegments) +
802*3446Smrj                         ((NumSegments > 0) ? (NumSegments - 1) : 0) + 1;
803*3446Smrj 
804*3446Smrj     /*
805*3446Smrj      * Check to see if we're still in bounds.  If not, there's a problem
806*3446Smrj      * with InternalName (invalid format).
807*3446Smrj      */
808*3446Smrj     if (RequiredLength > InternalNameLength)
809*3446Smrj     {
810*3446Smrj         ACPI_ERROR ((AE_INFO, "Invalid internal name"));
811*3446Smrj         return_ACPI_STATUS (AE_BAD_PATHNAME);
812*3446Smrj     }
813*3446Smrj 
814*3446Smrj     /*
815*3446Smrj      * Build ConvertedName
816*3446Smrj      */
817*3446Smrj     *ConvertedName = ACPI_ALLOCATE_ZEROED (RequiredLength);
818*3446Smrj     if (!(*ConvertedName))
819*3446Smrj     {
820*3446Smrj         return_ACPI_STATUS (AE_NO_MEMORY);
821*3446Smrj     }
822*3446Smrj 
823*3446Smrj     j = 0;
824*3446Smrj 
825*3446Smrj     for (i = 0; i < PrefixLength; i++)
826*3446Smrj     {
827*3446Smrj         (*ConvertedName)[j++] = InternalName[i];
828*3446Smrj     }
829*3446Smrj 
830*3446Smrj     if (NumSegments > 0)
831*3446Smrj     {
832*3446Smrj         for (i = 0; i < NumSegments; i++)
833*3446Smrj         {
834*3446Smrj             if (i > 0)
835*3446Smrj             {
836*3446Smrj                 (*ConvertedName)[j++] = '.';
837*3446Smrj             }
838*3446Smrj 
839*3446Smrj             (*ConvertedName)[j++] = InternalName[NamesIndex++];
840*3446Smrj             (*ConvertedName)[j++] = InternalName[NamesIndex++];
841*3446Smrj             (*ConvertedName)[j++] = InternalName[NamesIndex++];
842*3446Smrj             (*ConvertedName)[j++] = InternalName[NamesIndex++];
843*3446Smrj         }
844*3446Smrj     }
845*3446Smrj 
846*3446Smrj     if (ConvertedNameLength)
847*3446Smrj     {
848*3446Smrj         *ConvertedNameLength = (UINT32) RequiredLength;
849*3446Smrj     }
850*3446Smrj 
851*3446Smrj     return_ACPI_STATUS (AE_OK);
852*3446Smrj }
853*3446Smrj 
854*3446Smrj 
855*3446Smrj /*******************************************************************************
856*3446Smrj  *
857*3446Smrj  * FUNCTION:    AcpiNsMapHandleToNode
858*3446Smrj  *
859*3446Smrj  * PARAMETERS:  Handle          - Handle to be converted to an Node
860*3446Smrj  *
861*3446Smrj  * RETURN:      A Name table entry pointer
862*3446Smrj  *
863*3446Smrj  * DESCRIPTION: Convert a namespace handle to a real Node
864*3446Smrj  *
865*3446Smrj  * Note: Real integer handles would allow for more verification
866*3446Smrj  *       and keep all pointers within this subsystem - however this introduces
867*3446Smrj  *       more (and perhaps unnecessary) overhead.
868*3446Smrj  *
869*3446Smrj  ******************************************************************************/
870*3446Smrj 
871*3446Smrj ACPI_NAMESPACE_NODE *
872*3446Smrj AcpiNsMapHandleToNode (
873*3446Smrj     ACPI_HANDLE             Handle)
874*3446Smrj {
875*3446Smrj 
876*3446Smrj     ACPI_FUNCTION_ENTRY ();
877*3446Smrj 
878*3446Smrj 
879*3446Smrj     /*
880*3446Smrj      * Simple implementation
881*3446Smrj      */
882*3446Smrj     if ((!Handle) || (Handle == ACPI_ROOT_OBJECT))
883*3446Smrj     {
884*3446Smrj         return (AcpiGbl_RootNode);
885*3446Smrj     }
886*3446Smrj 
887*3446Smrj     /* We can at least attempt to verify the handle */
888*3446Smrj 
889*3446Smrj     if (ACPI_GET_DESCRIPTOR_TYPE (Handle) != ACPI_DESC_TYPE_NAMED)
890*3446Smrj     {
891*3446Smrj         return (NULL);
892*3446Smrj     }
893*3446Smrj 
894*3446Smrj     return (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle));
895*3446Smrj }
896*3446Smrj 
897*3446Smrj 
898*3446Smrj /*******************************************************************************
899*3446Smrj  *
900*3446Smrj  * FUNCTION:    AcpiNsConvertEntryToHandle
901*3446Smrj  *
902*3446Smrj  * PARAMETERS:  Node          - Node to be converted to a Handle
903*3446Smrj  *
904*3446Smrj  * RETURN:      A user handle
905*3446Smrj  *
906*3446Smrj  * DESCRIPTION: Convert a real Node to a namespace handle
907*3446Smrj  *
908*3446Smrj  ******************************************************************************/
909*3446Smrj 
910*3446Smrj ACPI_HANDLE
911*3446Smrj AcpiNsConvertEntryToHandle (
912*3446Smrj     ACPI_NAMESPACE_NODE         *Node)
913*3446Smrj {
914*3446Smrj 
915*3446Smrj 
916*3446Smrj     /*
917*3446Smrj      * Simple implementation for now;
918*3446Smrj      */
919*3446Smrj     return ((ACPI_HANDLE) Node);
920*3446Smrj 
921*3446Smrj 
922*3446Smrj /* Example future implementation ---------------------
923*3446Smrj 
924*3446Smrj     if (!Node)
925*3446Smrj     {
926*3446Smrj         return (NULL);
927*3446Smrj     }
928*3446Smrj 
929*3446Smrj     if (Node == AcpiGbl_RootNode)
930*3446Smrj     {
931*3446Smrj         return (ACPI_ROOT_OBJECT);
932*3446Smrj     }
933*3446Smrj 
934*3446Smrj 
935*3446Smrj     return ((ACPI_HANDLE) Node);
936*3446Smrj ------------------------------------------------------*/
937*3446Smrj }
938*3446Smrj 
939*3446Smrj 
940*3446Smrj /*******************************************************************************
941*3446Smrj  *
942*3446Smrj  * FUNCTION:    AcpiNsTerminate
943*3446Smrj  *
944*3446Smrj  * PARAMETERS:  none
945*3446Smrj  *
946*3446Smrj  * RETURN:      none
947*3446Smrj  *
948*3446Smrj  * DESCRIPTION: free memory allocated for namespace and ACPI table storage.
949*3446Smrj  *
950*3446Smrj  ******************************************************************************/
951*3446Smrj 
952*3446Smrj void
953*3446Smrj AcpiNsTerminate (
954*3446Smrj     void)
955*3446Smrj {
956*3446Smrj     ACPI_OPERAND_OBJECT     *ObjDesc;
957*3446Smrj 
958*3446Smrj 
959*3446Smrj     ACPI_FUNCTION_TRACE (NsTerminate);
960*3446Smrj 
961*3446Smrj 
962*3446Smrj     /*
963*3446Smrj      * 1) Free the entire namespace -- all nodes and objects
964*3446Smrj      *
965*3446Smrj      * Delete all object descriptors attached to namepsace nodes
966*3446Smrj      */
967*3446Smrj     AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
968*3446Smrj 
969*3446Smrj     /* Detach any objects attached to the root */
970*3446Smrj 
971*3446Smrj     ObjDesc = AcpiNsGetAttachedObject (AcpiGbl_RootNode);
972*3446Smrj     if (ObjDesc)
973*3446Smrj     {
974*3446Smrj         AcpiNsDetachObject (AcpiGbl_RootNode);
975*3446Smrj     }
976*3446Smrj 
977*3446Smrj     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n"));
978*3446Smrj 
979*3446Smrj     /*
980*3446Smrj      * 2) Now we can delete the ACPI tables
981*3446Smrj      */
982*3446Smrj     AcpiTbDeleteAllTables ();
983*3446Smrj     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
984*3446Smrj 
985*3446Smrj     return_VOID;
986*3446Smrj }
987*3446Smrj 
988*3446Smrj 
989*3446Smrj /*******************************************************************************
990*3446Smrj  *
991*3446Smrj  * FUNCTION:    AcpiNsOpensScope
992*3446Smrj  *
993*3446Smrj  * PARAMETERS:  Type        - A valid namespace type
994*3446Smrj  *
995*3446Smrj  * RETURN:      NEWSCOPE if the passed type "opens a name scope" according
996*3446Smrj  *              to the ACPI specification, else 0
997*3446Smrj  *
998*3446Smrj  ******************************************************************************/
999*3446Smrj 
1000*3446Smrj UINT32
1001*3446Smrj AcpiNsOpensScope (
1002*3446Smrj     ACPI_OBJECT_TYPE        Type)
1003*3446Smrj {
1004*3446Smrj     ACPI_FUNCTION_TRACE_STR (NsOpensScope, AcpiUtGetTypeName (Type));
1005*3446Smrj 
1006*3446Smrj 
1007*3446Smrj     if (!AcpiUtValidObjectType (Type))
1008*3446Smrj     {
1009*3446Smrj         /* type code out of range  */
1010*3446Smrj 
1011*3446Smrj         ACPI_WARNING ((AE_INFO, "Invalid Object Type %X", Type));
1012*3446Smrj         return_UINT32 (ACPI_NS_NORMAL);
1013*3446Smrj     }
1014*3446Smrj 
1015*3446Smrj     return_UINT32 (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE);
1016*3446Smrj }
1017*3446Smrj 
1018*3446Smrj 
1019*3446Smrj /*******************************************************************************
1020*3446Smrj  *
1021*3446Smrj  * FUNCTION:    AcpiNsGetNode
1022*3446Smrj  *
1023*3446Smrj  * PARAMETERS:  *Pathname   - Name to be found, in external (ASL) format. The
1024*3446Smrj  *                            \ (backslash) and ^ (carat) prefixes, and the
1025*3446Smrj  *                            . (period) to separate segments are supported.
1026*3446Smrj  *              PrefixNode   - Root of subtree to be searched, or NS_ALL for the
1027*3446Smrj  *                            root of the name space.  If Name is fully
1028*3446Smrj  *                            qualified (first INT8 is '\'), the passed value
1029*3446Smrj  *                            of Scope will not be accessed.
1030*3446Smrj  *              Flags       - Used to indicate whether to perform upsearch or
1031*3446Smrj  *                            not.
1032*3446Smrj  *              ReturnNode  - Where the Node is returned
1033*3446Smrj  *
1034*3446Smrj  * DESCRIPTION: Look up a name relative to a given scope and return the
1035*3446Smrj  *              corresponding Node.  NOTE: Scope can be null.
1036*3446Smrj  *
1037*3446Smrj  * MUTEX:       Locks namespace
1038*3446Smrj  *
1039*3446Smrj  ******************************************************************************/
1040*3446Smrj 
1041*3446Smrj ACPI_STATUS
1042*3446Smrj AcpiNsGetNode (
1043*3446Smrj     ACPI_NAMESPACE_NODE     *PrefixNode,
1044*3446Smrj     char                    *Pathname,
1045*3446Smrj     UINT32                  Flags,
1046*3446Smrj     ACPI_NAMESPACE_NODE     **ReturnNode)
1047*3446Smrj {
1048*3446Smrj     ACPI_GENERIC_STATE      ScopeInfo;
1049*3446Smrj     ACPI_STATUS             Status;
1050*3446Smrj     char                    *InternalPath;
1051*3446Smrj 
1052*3446Smrj 
1053*3446Smrj     ACPI_FUNCTION_TRACE_PTR (NsGetNode, Pathname);
1054*3446Smrj 
1055*3446Smrj 
1056*3446Smrj     if (!Pathname)
1057*3446Smrj     {
1058*3446Smrj         *ReturnNode = PrefixNode;
1059*3446Smrj         if (!PrefixNode)
1060*3446Smrj         {
1061*3446Smrj             *ReturnNode = AcpiGbl_RootNode;
1062*3446Smrj         }
1063*3446Smrj         return_ACPI_STATUS (AE_OK);
1064*3446Smrj     }
1065*3446Smrj 
1066*3446Smrj     /* Convert path to internal representation */
1067*3446Smrj 
1068*3446Smrj     Status = AcpiNsInternalizeName (Pathname, &InternalPath);
1069*3446Smrj     if (ACPI_FAILURE (Status))
1070*3446Smrj     {
1071*3446Smrj         return_ACPI_STATUS (Status);
1072*3446Smrj     }
1073*3446Smrj 
1074*3446Smrj     /* Must lock namespace during lookup */
1075*3446Smrj 
1076*3446Smrj     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1077*3446Smrj     if (ACPI_FAILURE (Status))
1078*3446Smrj     {
1079*3446Smrj         goto Cleanup;
1080*3446Smrj     }
1081*3446Smrj 
1082*3446Smrj     /* Setup lookup scope (search starting point) */
1083*3446Smrj 
1084*3446Smrj     ScopeInfo.Scope.Node = PrefixNode;
1085*3446Smrj 
1086*3446Smrj     /* Lookup the name in the namespace */
1087*3446Smrj 
1088*3446Smrj     Status = AcpiNsLookup (&ScopeInfo, InternalPath, ACPI_TYPE_ANY,
1089*3446Smrj                 ACPI_IMODE_EXECUTE, (Flags | ACPI_NS_DONT_OPEN_SCOPE),
1090*3446Smrj                 NULL, ReturnNode);
1091*3446Smrj     if (ACPI_FAILURE (Status))
1092*3446Smrj     {
1093*3446Smrj         ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s, %s\n",
1094*3446Smrj                 Pathname, AcpiFormatException (Status)));
1095*3446Smrj     }
1096*3446Smrj 
1097*3446Smrj     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1098*3446Smrj 
1099*3446Smrj Cleanup:
1100*3446Smrj     ACPI_FREE (InternalPath);
1101*3446Smrj     return_ACPI_STATUS (Status);
1102*3446Smrj }
1103*3446Smrj 
1104*3446Smrj 
1105*3446Smrj /*******************************************************************************
1106*3446Smrj  *
1107*3446Smrj  * FUNCTION:    AcpiNsGetParentNode
1108*3446Smrj  *
1109*3446Smrj  * PARAMETERS:  Node       - Current table entry
1110*3446Smrj  *
1111*3446Smrj  * RETURN:      Parent entry of the given entry
1112*3446Smrj  *
1113*3446Smrj  * DESCRIPTION: Obtain the parent entry for a given entry in the namespace.
1114*3446Smrj  *
1115*3446Smrj  ******************************************************************************/
1116*3446Smrj 
1117*3446Smrj ACPI_NAMESPACE_NODE *
1118*3446Smrj AcpiNsGetParentNode (
1119*3446Smrj     ACPI_NAMESPACE_NODE     *Node)
1120*3446Smrj {
1121*3446Smrj     ACPI_FUNCTION_ENTRY ();
1122*3446Smrj 
1123*3446Smrj 
1124*3446Smrj     if (!Node)
1125*3446Smrj     {
1126*3446Smrj         return (NULL);
1127*3446Smrj     }
1128*3446Smrj 
1129*3446Smrj     /*
1130*3446Smrj      * Walk to the end of this peer list. The last entry is marked with a flag
1131*3446Smrj      * and the peer pointer is really a pointer back to the parent. This saves
1132*3446Smrj      * putting a parent back pointer in each and every named object!
1133*3446Smrj      */
1134*3446Smrj     while (!(Node->Flags & ANOBJ_END_OF_PEER_LIST))
1135*3446Smrj     {
1136*3446Smrj         Node = Node->Peer;
1137*3446Smrj     }
1138*3446Smrj 
1139*3446Smrj     return (Node->Peer);
1140*3446Smrj }
1141*3446Smrj 
1142*3446Smrj 
1143*3446Smrj /*******************************************************************************
1144*3446Smrj  *
1145*3446Smrj  * FUNCTION:    AcpiNsGetNextValidNode
1146*3446Smrj  *
1147*3446Smrj  * PARAMETERS:  Node       - Current table entry
1148*3446Smrj  *
1149*3446Smrj  * RETURN:      Next valid Node in the linked node list. NULL if no more valid
1150*3446Smrj  *              nodes.
1151*3446Smrj  *
1152*3446Smrj  * DESCRIPTION: Find the next valid node within a name table.
1153*3446Smrj  *              Useful for implementing NULL-end-of-list loops.
1154*3446Smrj  *
1155*3446Smrj  ******************************************************************************/
1156*3446Smrj 
1157*3446Smrj ACPI_NAMESPACE_NODE *
1158*3446Smrj AcpiNsGetNextValidNode (
1159*3446Smrj     ACPI_NAMESPACE_NODE     *Node)
1160*3446Smrj {
1161*3446Smrj 
1162*3446Smrj     /* If we are at the end of this peer list, return NULL */
1163*3446Smrj 
1164*3446Smrj     if (Node->Flags & ANOBJ_END_OF_PEER_LIST)
1165*3446Smrj     {
1166*3446Smrj         return NULL;
1167*3446Smrj     }
1168*3446Smrj 
1169*3446Smrj     /* Otherwise just return the next peer */
1170*3446Smrj 
1171*3446Smrj     return (Node->Peer);
1172*3446Smrj }
1173*3446Smrj 
1174*3446Smrj 
1175*3446Smrj #ifdef ACPI_OBSOLETE_FUNCTIONS
1176*3446Smrj /*******************************************************************************
1177*3446Smrj  *
1178*3446Smrj  * FUNCTION:    AcpiNsFindParentName
1179*3446Smrj  *
1180*3446Smrj  * PARAMETERS:  *ChildNode             - Named Obj whose name is to be found
1181*3446Smrj  *
1182*3446Smrj  * RETURN:      The ACPI name
1183*3446Smrj  *
1184*3446Smrj  * DESCRIPTION: Search for the given obj in its parent scope and return the
1185*3446Smrj  *              name segment, or "????" if the parent name can't be found
1186*3446Smrj  *              (which "should not happen").
1187*3446Smrj  *
1188*3446Smrj  ******************************************************************************/
1189*3446Smrj 
1190*3446Smrj ACPI_NAME
1191*3446Smrj AcpiNsFindParentName (
1192*3446Smrj     ACPI_NAMESPACE_NODE     *ChildNode)
1193*3446Smrj {
1194*3446Smrj     ACPI_NAMESPACE_NODE     *ParentNode;
1195*3446Smrj 
1196*3446Smrj 
1197*3446Smrj     ACPI_FUNCTION_TRACE (NsFindParentName);
1198*3446Smrj 
1199*3446Smrj 
1200*3446Smrj     if (ChildNode)
1201*3446Smrj     {
1202*3446Smrj         /* Valid entry.  Get the parent Node */
1203*3446Smrj 
1204*3446Smrj         ParentNode = AcpiNsGetParentNode (ChildNode);
1205*3446Smrj         if (ParentNode)
1206*3446Smrj         {
1207*3446Smrj             ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
1208*3446Smrj                 "Parent of %p [%4.4s] is %p [%4.4s]\n",
1209*3446Smrj                 ChildNode,  AcpiUtGetNodeName (ChildNode),
1210*3446Smrj                 ParentNode, AcpiUtGetNodeName (ParentNode)));
1211*3446Smrj 
1212*3446Smrj             if (ParentNode->Name.Integer)
1213*3446Smrj             {
1214*3446Smrj                 return_VALUE ((ACPI_NAME) ParentNode->Name.Integer);
1215*3446Smrj             }
1216*3446Smrj         }
1217*3446Smrj 
1218*3446Smrj         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
1219*3446Smrj             "Unable to find parent of %p (%4.4s)\n",
1220*3446Smrj             ChildNode, AcpiUtGetNodeName (ChildNode)));
1221*3446Smrj     }
1222*3446Smrj 
1223*3446Smrj     return_VALUE (ACPI_UNKNOWN_NAME);
1224*3446Smrj }
1225*3446Smrj #endif
1226*3446Smrj 
1227*3446Smrj 
1228