xref: /minix3/minix/drivers/power/acpi/namespace/nsutils.c (revision 29492bb71c7148a089a5afafa0c99409161218df)
1433d6423SLionel Sambuc /******************************************************************************
2433d6423SLionel Sambuc  *
3433d6423SLionel Sambuc  * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
4433d6423SLionel Sambuc  *                        parents and siblings and Scope manipulation
5433d6423SLionel Sambuc  *
6433d6423SLionel Sambuc  *****************************************************************************/
7433d6423SLionel Sambuc 
8*29492bb7SDavid van Moolenbroek /*
9*29492bb7SDavid van Moolenbroek  * Copyright (C) 2000 - 2014, Intel Corp.
10433d6423SLionel Sambuc  * All rights reserved.
11433d6423SLionel Sambuc  *
12*29492bb7SDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
13*29492bb7SDavid van Moolenbroek  * modification, are permitted provided that the following conditions
14*29492bb7SDavid van Moolenbroek  * are met:
15*29492bb7SDavid van Moolenbroek  * 1. Redistributions of source code must retain the above copyright
16*29492bb7SDavid van Moolenbroek  *    notice, this list of conditions, and the following disclaimer,
17*29492bb7SDavid van Moolenbroek  *    without modification.
18*29492bb7SDavid van Moolenbroek  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19*29492bb7SDavid van Moolenbroek  *    substantially similar to the "NO WARRANTY" disclaimer below
20*29492bb7SDavid van Moolenbroek  *    ("Disclaimer") and any redistribution must be conditioned upon
21*29492bb7SDavid van Moolenbroek  *    including a substantially similar Disclaimer requirement for further
22*29492bb7SDavid van Moolenbroek  *    binary redistribution.
23*29492bb7SDavid van Moolenbroek  * 3. Neither the names of the above-listed copyright holders nor the names
24*29492bb7SDavid van Moolenbroek  *    of any contributors may be used to endorse or promote products derived
25*29492bb7SDavid van Moolenbroek  *    from this software without specific prior written permission.
26433d6423SLionel Sambuc  *
27*29492bb7SDavid van Moolenbroek  * Alternatively, this software may be distributed under the terms of the
28*29492bb7SDavid van Moolenbroek  * GNU General Public License ("GPL") version 2 as published by the Free
29*29492bb7SDavid van Moolenbroek  * Software Foundation.
30433d6423SLionel Sambuc  *
31*29492bb7SDavid van Moolenbroek  * NO WARRANTY
32*29492bb7SDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33*29492bb7SDavid van Moolenbroek  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34*29492bb7SDavid van Moolenbroek  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35*29492bb7SDavid van Moolenbroek  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36*29492bb7SDavid van Moolenbroek  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37*29492bb7SDavid van Moolenbroek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38*29492bb7SDavid van Moolenbroek  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39*29492bb7SDavid van Moolenbroek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40*29492bb7SDavid van Moolenbroek  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41*29492bb7SDavid van Moolenbroek  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42*29492bb7SDavid van Moolenbroek  * POSSIBILITY OF SUCH DAMAGES.
43*29492bb7SDavid van Moolenbroek  */
44433d6423SLionel Sambuc 
45433d6423SLionel Sambuc #include "acpi.h"
46433d6423SLionel Sambuc #include "accommon.h"
47433d6423SLionel Sambuc #include "acnamesp.h"
48433d6423SLionel Sambuc #include "amlcode.h"
49433d6423SLionel Sambuc 
50433d6423SLionel Sambuc #define _COMPONENT          ACPI_NAMESPACE
51433d6423SLionel Sambuc         ACPI_MODULE_NAME    ("nsutils")
52433d6423SLionel Sambuc 
53433d6423SLionel Sambuc /* Local prototypes */
54433d6423SLionel Sambuc 
55433d6423SLionel Sambuc #ifdef ACPI_OBSOLETE_FUNCTIONS
56433d6423SLionel Sambuc ACPI_NAME
57433d6423SLionel Sambuc AcpiNsFindParentName (
58433d6423SLionel Sambuc     ACPI_NAMESPACE_NODE     *NodeToSearch);
59433d6423SLionel Sambuc #endif
60433d6423SLionel Sambuc 
61433d6423SLionel Sambuc 
62433d6423SLionel Sambuc /*******************************************************************************
63433d6423SLionel Sambuc  *
64433d6423SLionel Sambuc  * FUNCTION:    AcpiNsPrintNodePathname
65433d6423SLionel Sambuc  *
66433d6423SLionel Sambuc  * PARAMETERS:  Node            - Object
67433d6423SLionel Sambuc  *              Message         - Prefix message
68433d6423SLionel Sambuc  *
69433d6423SLionel Sambuc  * DESCRIPTION: Print an object's full namespace pathname
70433d6423SLionel Sambuc  *              Manages allocation/freeing of a pathname buffer
71433d6423SLionel Sambuc  *
72433d6423SLionel Sambuc  ******************************************************************************/
73433d6423SLionel Sambuc 
74433d6423SLionel Sambuc void
AcpiNsPrintNodePathname(ACPI_NAMESPACE_NODE * Node,const char * Message)75433d6423SLionel Sambuc AcpiNsPrintNodePathname (
76433d6423SLionel Sambuc     ACPI_NAMESPACE_NODE     *Node,
77433d6423SLionel Sambuc     const char              *Message)
78433d6423SLionel Sambuc {
79433d6423SLionel Sambuc     ACPI_BUFFER             Buffer;
80433d6423SLionel Sambuc     ACPI_STATUS             Status;
81433d6423SLionel Sambuc 
82433d6423SLionel Sambuc 
83433d6423SLionel Sambuc     if (!Node)
84433d6423SLionel Sambuc     {
85433d6423SLionel Sambuc         AcpiOsPrintf ("[NULL NAME]");
86433d6423SLionel Sambuc         return;
87433d6423SLionel Sambuc     }
88433d6423SLionel Sambuc 
89433d6423SLionel Sambuc     /* Convert handle to full pathname and print it (with supplied message) */
90433d6423SLionel Sambuc 
91433d6423SLionel Sambuc     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
92433d6423SLionel Sambuc 
93433d6423SLionel Sambuc     Status = AcpiNsHandleToPathname (Node, &Buffer);
94433d6423SLionel Sambuc     if (ACPI_SUCCESS (Status))
95433d6423SLionel Sambuc     {
96433d6423SLionel Sambuc         if (Message)
97433d6423SLionel Sambuc         {
98433d6423SLionel Sambuc             AcpiOsPrintf ("%s ", Message);
99433d6423SLionel Sambuc         }
100433d6423SLionel Sambuc 
101433d6423SLionel Sambuc         AcpiOsPrintf ("[%s] (Node %p)", (char *) Buffer.Pointer, Node);
102433d6423SLionel Sambuc         ACPI_FREE (Buffer.Pointer);
103433d6423SLionel Sambuc     }
104433d6423SLionel Sambuc }
105433d6423SLionel Sambuc 
106433d6423SLionel Sambuc 
107433d6423SLionel Sambuc /*******************************************************************************
108433d6423SLionel Sambuc  *
109433d6423SLionel Sambuc  * FUNCTION:    AcpiNsGetType
110433d6423SLionel Sambuc  *
111433d6423SLionel Sambuc  * PARAMETERS:  Node        - Parent Node to be examined
112433d6423SLionel Sambuc  *
113433d6423SLionel Sambuc  * RETURN:      Type field from Node whose handle is passed
114433d6423SLionel Sambuc  *
115433d6423SLionel Sambuc  * DESCRIPTION: Return the type of a Namespace node
116433d6423SLionel Sambuc  *
117433d6423SLionel Sambuc  ******************************************************************************/
118433d6423SLionel Sambuc 
119433d6423SLionel Sambuc ACPI_OBJECT_TYPE
AcpiNsGetType(ACPI_NAMESPACE_NODE * Node)120433d6423SLionel Sambuc AcpiNsGetType (
121433d6423SLionel Sambuc     ACPI_NAMESPACE_NODE     *Node)
122433d6423SLionel Sambuc {
123433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (NsGetType);
124433d6423SLionel Sambuc 
125433d6423SLionel Sambuc 
126433d6423SLionel Sambuc     if (!Node)
127433d6423SLionel Sambuc     {
128433d6423SLionel Sambuc         ACPI_WARNING ((AE_INFO, "Null Node parameter"));
129*29492bb7SDavid van Moolenbroek         return_UINT8 (ACPI_TYPE_ANY);
130433d6423SLionel Sambuc     }
131433d6423SLionel Sambuc 
132*29492bb7SDavid van Moolenbroek     return_UINT8 (Node->Type);
133433d6423SLionel Sambuc }
134433d6423SLionel Sambuc 
135433d6423SLionel Sambuc 
136433d6423SLionel Sambuc /*******************************************************************************
137433d6423SLionel Sambuc  *
138433d6423SLionel Sambuc  * FUNCTION:    AcpiNsLocal
139433d6423SLionel Sambuc  *
140433d6423SLionel Sambuc  * PARAMETERS:  Type        - A namespace object type
141433d6423SLionel Sambuc  *
142433d6423SLionel Sambuc  * RETURN:      LOCAL if names must be found locally in objects of the
143433d6423SLionel Sambuc  *              passed type, 0 if enclosing scopes should be searched
144433d6423SLionel Sambuc  *
145433d6423SLionel Sambuc  * DESCRIPTION: Returns scope rule for the given object type.
146433d6423SLionel Sambuc  *
147433d6423SLionel Sambuc  ******************************************************************************/
148433d6423SLionel Sambuc 
149433d6423SLionel Sambuc UINT32
AcpiNsLocal(ACPI_OBJECT_TYPE Type)150433d6423SLionel Sambuc AcpiNsLocal (
151433d6423SLionel Sambuc     ACPI_OBJECT_TYPE        Type)
152433d6423SLionel Sambuc {
153433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (NsLocal);
154433d6423SLionel Sambuc 
155433d6423SLionel Sambuc 
156433d6423SLionel Sambuc     if (!AcpiUtValidObjectType (Type))
157433d6423SLionel Sambuc     {
158433d6423SLionel Sambuc         /* Type code out of range  */
159433d6423SLionel Sambuc 
160433d6423SLionel Sambuc         ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
161433d6423SLionel Sambuc         return_UINT32 (ACPI_NS_NORMAL);
162433d6423SLionel Sambuc     }
163433d6423SLionel Sambuc 
164*29492bb7SDavid van Moolenbroek     return_UINT32 (AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL);
165433d6423SLionel Sambuc }
166433d6423SLionel Sambuc 
167433d6423SLionel Sambuc 
168433d6423SLionel Sambuc /*******************************************************************************
169433d6423SLionel Sambuc  *
170433d6423SLionel Sambuc  * FUNCTION:    AcpiNsGetInternalNameLength
171433d6423SLionel Sambuc  *
172433d6423SLionel Sambuc  * PARAMETERS:  Info            - Info struct initialized with the
173433d6423SLionel Sambuc  *                                external name pointer.
174433d6423SLionel Sambuc  *
175433d6423SLionel Sambuc  * RETURN:      None
176433d6423SLionel Sambuc  *
177433d6423SLionel Sambuc  * DESCRIPTION: Calculate the length of the internal (AML) namestring
178433d6423SLionel Sambuc  *              corresponding to the external (ASL) namestring.
179433d6423SLionel Sambuc  *
180433d6423SLionel Sambuc  ******************************************************************************/
181433d6423SLionel Sambuc 
182433d6423SLionel Sambuc void
AcpiNsGetInternalNameLength(ACPI_NAMESTRING_INFO * Info)183433d6423SLionel Sambuc AcpiNsGetInternalNameLength (
184433d6423SLionel Sambuc     ACPI_NAMESTRING_INFO    *Info)
185433d6423SLionel Sambuc {
186433d6423SLionel Sambuc     const char              *NextExternalChar;
187433d6423SLionel Sambuc     UINT32                  i;
188433d6423SLionel Sambuc 
189433d6423SLionel Sambuc 
190433d6423SLionel Sambuc     ACPI_FUNCTION_ENTRY ();
191433d6423SLionel Sambuc 
192433d6423SLionel Sambuc 
193433d6423SLionel Sambuc     NextExternalChar = Info->ExternalName;
194433d6423SLionel Sambuc     Info->NumCarats = 0;
195433d6423SLionel Sambuc     Info->NumSegments = 0;
196433d6423SLionel Sambuc     Info->FullyQualified = FALSE;
197433d6423SLionel Sambuc 
198433d6423SLionel Sambuc     /*
199433d6423SLionel Sambuc      * For the internal name, the required length is 4 bytes per segment, plus
200433d6423SLionel Sambuc      * 1 each for RootPrefix, MultiNamePrefixOp, segment count, trailing null
201433d6423SLionel Sambuc      * (which is not really needed, but no there's harm in putting it there)
202433d6423SLionel Sambuc      *
203433d6423SLionel Sambuc      * strlen() + 1 covers the first NameSeg, which has no path separator
204433d6423SLionel Sambuc      */
205*29492bb7SDavid van Moolenbroek     if (ACPI_IS_ROOT_PREFIX (*NextExternalChar))
206433d6423SLionel Sambuc     {
207433d6423SLionel Sambuc         Info->FullyQualified = TRUE;
208433d6423SLionel Sambuc         NextExternalChar++;
209433d6423SLionel Sambuc 
210433d6423SLionel Sambuc         /* Skip redundant RootPrefix, like \\_SB.PCI0.SBRG.EC0 */
211433d6423SLionel Sambuc 
212*29492bb7SDavid van Moolenbroek         while (ACPI_IS_ROOT_PREFIX (*NextExternalChar))
213433d6423SLionel Sambuc         {
214433d6423SLionel Sambuc             NextExternalChar++;
215433d6423SLionel Sambuc         }
216433d6423SLionel Sambuc     }
217433d6423SLionel Sambuc     else
218433d6423SLionel Sambuc     {
219433d6423SLionel Sambuc         /* Handle Carat prefixes */
220433d6423SLionel Sambuc 
221*29492bb7SDavid van Moolenbroek         while (ACPI_IS_PARENT_PREFIX (*NextExternalChar))
222433d6423SLionel Sambuc         {
223433d6423SLionel Sambuc             Info->NumCarats++;
224433d6423SLionel Sambuc             NextExternalChar++;
225433d6423SLionel Sambuc         }
226433d6423SLionel Sambuc     }
227433d6423SLionel Sambuc 
228433d6423SLionel Sambuc     /*
229433d6423SLionel Sambuc      * Determine the number of ACPI name "segments" by counting the number of
230433d6423SLionel Sambuc      * path separators within the string. Start with one segment since the
231433d6423SLionel Sambuc      * segment count is [(# separators) + 1], and zero separators is ok.
232433d6423SLionel Sambuc      */
233433d6423SLionel Sambuc     if (*NextExternalChar)
234433d6423SLionel Sambuc     {
235433d6423SLionel Sambuc         Info->NumSegments = 1;
236433d6423SLionel Sambuc         for (i = 0; NextExternalChar[i]; i++)
237433d6423SLionel Sambuc         {
238*29492bb7SDavid van Moolenbroek             if (ACPI_IS_PATH_SEPARATOR (NextExternalChar[i]))
239433d6423SLionel Sambuc             {
240433d6423SLionel Sambuc                 Info->NumSegments++;
241433d6423SLionel Sambuc             }
242433d6423SLionel Sambuc         }
243433d6423SLionel Sambuc     }
244433d6423SLionel Sambuc 
245433d6423SLionel Sambuc     Info->Length = (ACPI_NAME_SIZE * Info->NumSegments) +
246433d6423SLionel Sambuc                     4 + Info->NumCarats;
247433d6423SLionel Sambuc 
248433d6423SLionel Sambuc     Info->NextExternalChar = NextExternalChar;
249433d6423SLionel Sambuc }
250433d6423SLionel Sambuc 
251433d6423SLionel Sambuc 
252433d6423SLionel Sambuc /*******************************************************************************
253433d6423SLionel Sambuc  *
254433d6423SLionel Sambuc  * FUNCTION:    AcpiNsBuildInternalName
255433d6423SLionel Sambuc  *
256433d6423SLionel Sambuc  * PARAMETERS:  Info            - Info struct fully initialized
257433d6423SLionel Sambuc  *
258433d6423SLionel Sambuc  * RETURN:      Status
259433d6423SLionel Sambuc  *
260433d6423SLionel Sambuc  * DESCRIPTION: Construct the internal (AML) namestring
261433d6423SLionel Sambuc  *              corresponding to the external (ASL) namestring.
262433d6423SLionel Sambuc  *
263433d6423SLionel Sambuc  ******************************************************************************/
264433d6423SLionel Sambuc 
265433d6423SLionel Sambuc ACPI_STATUS
AcpiNsBuildInternalName(ACPI_NAMESTRING_INFO * Info)266433d6423SLionel Sambuc AcpiNsBuildInternalName (
267433d6423SLionel Sambuc     ACPI_NAMESTRING_INFO    *Info)
268433d6423SLionel Sambuc {
269433d6423SLionel Sambuc     UINT32                  NumSegments = Info->NumSegments;
270433d6423SLionel Sambuc     char                    *InternalName = Info->InternalName;
271433d6423SLionel Sambuc     const char              *ExternalName = Info->NextExternalChar;
272433d6423SLionel Sambuc     char                    *Result = NULL;
273433d6423SLionel Sambuc     UINT32                  i;
274433d6423SLionel Sambuc 
275433d6423SLionel Sambuc 
276433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (NsBuildInternalName);
277433d6423SLionel Sambuc 
278433d6423SLionel Sambuc 
279433d6423SLionel Sambuc     /* Setup the correct prefixes, counts, and pointers */
280433d6423SLionel Sambuc 
281433d6423SLionel Sambuc     if (Info->FullyQualified)
282433d6423SLionel Sambuc     {
283*29492bb7SDavid van Moolenbroek         InternalName[0] = AML_ROOT_PREFIX;
284433d6423SLionel Sambuc 
285433d6423SLionel Sambuc         if (NumSegments <= 1)
286433d6423SLionel Sambuc         {
287433d6423SLionel Sambuc             Result = &InternalName[1];
288433d6423SLionel Sambuc         }
289433d6423SLionel Sambuc         else if (NumSegments == 2)
290433d6423SLionel Sambuc         {
291433d6423SLionel Sambuc             InternalName[1] = AML_DUAL_NAME_PREFIX;
292433d6423SLionel Sambuc             Result = &InternalName[2];
293433d6423SLionel Sambuc         }
294433d6423SLionel Sambuc         else
295433d6423SLionel Sambuc         {
296433d6423SLionel Sambuc             InternalName[1] = AML_MULTI_NAME_PREFIX_OP;
297433d6423SLionel Sambuc             InternalName[2] = (char) NumSegments;
298433d6423SLionel Sambuc             Result = &InternalName[3];
299433d6423SLionel Sambuc         }
300433d6423SLionel Sambuc     }
301433d6423SLionel Sambuc     else
302433d6423SLionel Sambuc     {
303433d6423SLionel Sambuc         /*
304433d6423SLionel Sambuc          * Not fully qualified.
305433d6423SLionel Sambuc          * Handle Carats first, then append the name segments
306433d6423SLionel Sambuc          */
307433d6423SLionel Sambuc         i = 0;
308433d6423SLionel Sambuc         if (Info->NumCarats)
309433d6423SLionel Sambuc         {
310433d6423SLionel Sambuc             for (i = 0; i < Info->NumCarats; i++)
311433d6423SLionel Sambuc             {
312*29492bb7SDavid van Moolenbroek                 InternalName[i] = AML_PARENT_PREFIX;
313433d6423SLionel Sambuc             }
314433d6423SLionel Sambuc         }
315433d6423SLionel Sambuc 
316433d6423SLionel Sambuc         if (NumSegments <= 1)
317433d6423SLionel Sambuc         {
318433d6423SLionel Sambuc             Result = &InternalName[i];
319433d6423SLionel Sambuc         }
320433d6423SLionel Sambuc         else if (NumSegments == 2)
321433d6423SLionel Sambuc         {
322433d6423SLionel Sambuc             InternalName[i] = AML_DUAL_NAME_PREFIX;
323433d6423SLionel Sambuc             Result = &InternalName[(ACPI_SIZE) i+1];
324433d6423SLionel Sambuc         }
325433d6423SLionel Sambuc         else
326433d6423SLionel Sambuc         {
327433d6423SLionel Sambuc             InternalName[i] = AML_MULTI_NAME_PREFIX_OP;
328433d6423SLionel Sambuc             InternalName[(ACPI_SIZE) i+1] = (char) NumSegments;
329433d6423SLionel Sambuc             Result = &InternalName[(ACPI_SIZE) i+2];
330433d6423SLionel Sambuc         }
331433d6423SLionel Sambuc     }
332433d6423SLionel Sambuc 
333433d6423SLionel Sambuc     /* Build the name (minus path separators) */
334433d6423SLionel Sambuc 
335433d6423SLionel Sambuc     for (; NumSegments; NumSegments--)
336433d6423SLionel Sambuc     {
337433d6423SLionel Sambuc         for (i = 0; i < ACPI_NAME_SIZE; i++)
338433d6423SLionel Sambuc         {
339*29492bb7SDavid van Moolenbroek             if (ACPI_IS_PATH_SEPARATOR (*ExternalName) ||
340433d6423SLionel Sambuc                (*ExternalName == 0))
341433d6423SLionel Sambuc             {
342433d6423SLionel Sambuc                 /* Pad the segment with underscore(s) if segment is short */
343433d6423SLionel Sambuc 
344433d6423SLionel Sambuc                 Result[i] = '_';
345433d6423SLionel Sambuc             }
346433d6423SLionel Sambuc             else
347433d6423SLionel Sambuc             {
348433d6423SLionel Sambuc                 /* Convert the character to uppercase and save it */
349433d6423SLionel Sambuc 
350433d6423SLionel Sambuc                 Result[i] = (char) ACPI_TOUPPER ((int) *ExternalName);
351433d6423SLionel Sambuc                 ExternalName++;
352433d6423SLionel Sambuc             }
353433d6423SLionel Sambuc         }
354433d6423SLionel Sambuc 
355433d6423SLionel Sambuc         /* Now we must have a path separator, or the pathname is bad */
356433d6423SLionel Sambuc 
357*29492bb7SDavid van Moolenbroek         if (!ACPI_IS_PATH_SEPARATOR (*ExternalName) &&
358433d6423SLionel Sambuc             (*ExternalName != 0))
359433d6423SLionel Sambuc         {
360*29492bb7SDavid van Moolenbroek             return_ACPI_STATUS (AE_BAD_PATHNAME);
361433d6423SLionel Sambuc         }
362433d6423SLionel Sambuc 
363433d6423SLionel Sambuc         /* Move on the next segment */
364433d6423SLionel Sambuc 
365433d6423SLionel Sambuc         ExternalName++;
366433d6423SLionel Sambuc         Result += ACPI_NAME_SIZE;
367433d6423SLionel Sambuc     }
368433d6423SLionel Sambuc 
369433d6423SLionel Sambuc     /* Terminate the string */
370433d6423SLionel Sambuc 
371433d6423SLionel Sambuc     *Result = 0;
372433d6423SLionel Sambuc 
373433d6423SLionel Sambuc     if (Info->FullyQualified)
374433d6423SLionel Sambuc     {
375433d6423SLionel Sambuc         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n",
376433d6423SLionel Sambuc             InternalName, InternalName));
377433d6423SLionel Sambuc     }
378433d6423SLionel Sambuc     else
379433d6423SLionel Sambuc     {
380433d6423SLionel Sambuc         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
381433d6423SLionel Sambuc             InternalName, InternalName));
382433d6423SLionel Sambuc     }
383433d6423SLionel Sambuc 
384433d6423SLionel Sambuc     return_ACPI_STATUS (AE_OK);
385433d6423SLionel Sambuc }
386433d6423SLionel Sambuc 
387433d6423SLionel Sambuc 
388433d6423SLionel Sambuc /*******************************************************************************
389433d6423SLionel Sambuc  *
390433d6423SLionel Sambuc  * FUNCTION:    AcpiNsInternalizeName
391433d6423SLionel Sambuc  *
392433d6423SLionel Sambuc  * PARAMETERS:  *ExternalName           - External representation of name
393433d6423SLionel Sambuc  *              **Converted Name        - Where to return the resulting
394433d6423SLionel Sambuc  *                                        internal represention of the name
395433d6423SLionel Sambuc  *
396433d6423SLionel Sambuc  * RETURN:      Status
397433d6423SLionel Sambuc  *
398433d6423SLionel Sambuc  * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0")
399433d6423SLionel Sambuc  *              to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
400433d6423SLionel Sambuc  *
401433d6423SLionel Sambuc  *******************************************************************************/
402433d6423SLionel Sambuc 
403433d6423SLionel Sambuc ACPI_STATUS
AcpiNsInternalizeName(const char * ExternalName,char ** ConvertedName)404433d6423SLionel Sambuc AcpiNsInternalizeName (
405433d6423SLionel Sambuc     const char              *ExternalName,
406433d6423SLionel Sambuc     char                    **ConvertedName)
407433d6423SLionel Sambuc {
408433d6423SLionel Sambuc     char                    *InternalName;
409433d6423SLionel Sambuc     ACPI_NAMESTRING_INFO    Info;
410433d6423SLionel Sambuc     ACPI_STATUS             Status;
411433d6423SLionel Sambuc 
412433d6423SLionel Sambuc 
413433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (NsInternalizeName);
414433d6423SLionel Sambuc 
415433d6423SLionel Sambuc 
416433d6423SLionel Sambuc     if ((!ExternalName)      ||
417433d6423SLionel Sambuc         (*ExternalName == 0) ||
418433d6423SLionel Sambuc         (!ConvertedName))
419433d6423SLionel Sambuc     {
420433d6423SLionel Sambuc         return_ACPI_STATUS (AE_BAD_PARAMETER);
421433d6423SLionel Sambuc     }
422433d6423SLionel Sambuc 
423433d6423SLionel Sambuc     /* Get the length of the new internal name */
424433d6423SLionel Sambuc 
425433d6423SLionel Sambuc     Info.ExternalName = ExternalName;
426433d6423SLionel Sambuc     AcpiNsGetInternalNameLength (&Info);
427433d6423SLionel Sambuc 
428433d6423SLionel Sambuc     /* We need a segment to store the internal  name */
429433d6423SLionel Sambuc 
430433d6423SLionel Sambuc     InternalName = ACPI_ALLOCATE_ZEROED (Info.Length);
431433d6423SLionel Sambuc     if (!InternalName)
432433d6423SLionel Sambuc     {
433433d6423SLionel Sambuc         return_ACPI_STATUS (AE_NO_MEMORY);
434433d6423SLionel Sambuc     }
435433d6423SLionel Sambuc 
436433d6423SLionel Sambuc     /* Build the name */
437433d6423SLionel Sambuc 
438433d6423SLionel Sambuc     Info.InternalName = InternalName;
439433d6423SLionel Sambuc     Status = AcpiNsBuildInternalName (&Info);
440433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
441433d6423SLionel Sambuc     {
442433d6423SLionel Sambuc         ACPI_FREE (InternalName);
443433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
444433d6423SLionel Sambuc     }
445433d6423SLionel Sambuc 
446433d6423SLionel Sambuc     *ConvertedName = InternalName;
447433d6423SLionel Sambuc     return_ACPI_STATUS (AE_OK);
448433d6423SLionel Sambuc }
449433d6423SLionel Sambuc 
450433d6423SLionel Sambuc 
451433d6423SLionel Sambuc /*******************************************************************************
452433d6423SLionel Sambuc  *
453433d6423SLionel Sambuc  * FUNCTION:    AcpiNsExternalizeName
454433d6423SLionel Sambuc  *
455433d6423SLionel Sambuc  * PARAMETERS:  InternalNameLength  - Lenth of the internal name below
456433d6423SLionel Sambuc  *              InternalName        - Internal representation of name
457433d6423SLionel Sambuc  *              ConvertedNameLength - Where the length is returned
458433d6423SLionel Sambuc  *              ConvertedName       - Where the resulting external name
459433d6423SLionel Sambuc  *                                    is returned
460433d6423SLionel Sambuc  *
461433d6423SLionel Sambuc  * RETURN:      Status
462433d6423SLionel Sambuc  *
463433d6423SLionel Sambuc  * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
464433d6423SLionel Sambuc  *              to its external (printable) form (e.g. "\_PR_.CPU0")
465433d6423SLionel Sambuc  *
466433d6423SLionel Sambuc  ******************************************************************************/
467433d6423SLionel Sambuc 
468433d6423SLionel Sambuc ACPI_STATUS
AcpiNsExternalizeName(UINT32 InternalNameLength,const char * InternalName,UINT32 * ConvertedNameLength,char ** ConvertedName)469433d6423SLionel Sambuc AcpiNsExternalizeName (
470433d6423SLionel Sambuc     UINT32                  InternalNameLength,
471433d6423SLionel Sambuc     const char              *InternalName,
472433d6423SLionel Sambuc     UINT32                  *ConvertedNameLength,
473433d6423SLionel Sambuc     char                    **ConvertedName)
474433d6423SLionel Sambuc {
475433d6423SLionel Sambuc     UINT32                  NamesIndex = 0;
476433d6423SLionel Sambuc     UINT32                  NumSegments = 0;
477433d6423SLionel Sambuc     UINT32                  RequiredLength;
478433d6423SLionel Sambuc     UINT32                  PrefixLength = 0;
479433d6423SLionel Sambuc     UINT32                  i = 0;
480433d6423SLionel Sambuc     UINT32                  j = 0;
481433d6423SLionel Sambuc 
482433d6423SLionel Sambuc 
483433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (NsExternalizeName);
484433d6423SLionel Sambuc 
485433d6423SLionel Sambuc 
486433d6423SLionel Sambuc     if (!InternalNameLength     ||
487433d6423SLionel Sambuc         !InternalName           ||
488433d6423SLionel Sambuc         !ConvertedName)
489433d6423SLionel Sambuc     {
490433d6423SLionel Sambuc         return_ACPI_STATUS (AE_BAD_PARAMETER);
491433d6423SLionel Sambuc     }
492433d6423SLionel Sambuc 
493433d6423SLionel Sambuc     /* Check for a prefix (one '\' | one or more '^') */
494433d6423SLionel Sambuc 
495433d6423SLionel Sambuc     switch (InternalName[0])
496433d6423SLionel Sambuc     {
497*29492bb7SDavid van Moolenbroek     case AML_ROOT_PREFIX:
498*29492bb7SDavid van Moolenbroek 
499433d6423SLionel Sambuc         PrefixLength = 1;
500433d6423SLionel Sambuc         break;
501433d6423SLionel Sambuc 
502*29492bb7SDavid van Moolenbroek     case AML_PARENT_PREFIX:
503*29492bb7SDavid van Moolenbroek 
504433d6423SLionel Sambuc         for (i = 0; i < InternalNameLength; i++)
505433d6423SLionel Sambuc         {
506*29492bb7SDavid van Moolenbroek             if (ACPI_IS_PARENT_PREFIX (InternalName[i]))
507433d6423SLionel Sambuc             {
508433d6423SLionel Sambuc                 PrefixLength = i + 1;
509433d6423SLionel Sambuc             }
510433d6423SLionel Sambuc             else
511433d6423SLionel Sambuc             {
512433d6423SLionel Sambuc                 break;
513433d6423SLionel Sambuc             }
514433d6423SLionel Sambuc         }
515433d6423SLionel Sambuc 
516433d6423SLionel Sambuc         if (i == InternalNameLength)
517433d6423SLionel Sambuc         {
518433d6423SLionel Sambuc             PrefixLength = i;
519433d6423SLionel Sambuc         }
520433d6423SLionel Sambuc 
521433d6423SLionel Sambuc         break;
522433d6423SLionel Sambuc 
523433d6423SLionel Sambuc     default:
524*29492bb7SDavid van Moolenbroek 
525433d6423SLionel Sambuc         break;
526433d6423SLionel Sambuc     }
527433d6423SLionel Sambuc 
528433d6423SLionel Sambuc     /*
529433d6423SLionel Sambuc      * Check for object names. Note that there could be 0-255 of these
530433d6423SLionel Sambuc      * 4-byte elements.
531433d6423SLionel Sambuc      */
532433d6423SLionel Sambuc     if (PrefixLength < InternalNameLength)
533433d6423SLionel Sambuc     {
534433d6423SLionel Sambuc         switch (InternalName[PrefixLength])
535433d6423SLionel Sambuc         {
536433d6423SLionel Sambuc         case AML_MULTI_NAME_PREFIX_OP:
537433d6423SLionel Sambuc 
538433d6423SLionel Sambuc             /* <count> 4-byte names */
539433d6423SLionel Sambuc 
540433d6423SLionel Sambuc             NamesIndex = PrefixLength + 2;
541433d6423SLionel Sambuc             NumSegments = (UINT8)
542433d6423SLionel Sambuc                 InternalName[(ACPI_SIZE) PrefixLength + 1];
543433d6423SLionel Sambuc             break;
544433d6423SLionel Sambuc 
545433d6423SLionel Sambuc         case AML_DUAL_NAME_PREFIX:
546433d6423SLionel Sambuc 
547433d6423SLionel Sambuc             /* Two 4-byte names */
548433d6423SLionel Sambuc 
549433d6423SLionel Sambuc             NamesIndex = PrefixLength + 1;
550433d6423SLionel Sambuc             NumSegments = 2;
551433d6423SLionel Sambuc             break;
552433d6423SLionel Sambuc 
553433d6423SLionel Sambuc         case 0:
554433d6423SLionel Sambuc 
555433d6423SLionel Sambuc             /* NullName */
556433d6423SLionel Sambuc 
557433d6423SLionel Sambuc             NamesIndex = 0;
558433d6423SLionel Sambuc             NumSegments = 0;
559433d6423SLionel Sambuc             break;
560433d6423SLionel Sambuc 
561433d6423SLionel Sambuc         default:
562433d6423SLionel Sambuc 
563433d6423SLionel Sambuc             /* one 4-byte name */
564433d6423SLionel Sambuc 
565433d6423SLionel Sambuc             NamesIndex = PrefixLength;
566433d6423SLionel Sambuc             NumSegments = 1;
567433d6423SLionel Sambuc             break;
568433d6423SLionel Sambuc         }
569433d6423SLionel Sambuc     }
570433d6423SLionel Sambuc 
571433d6423SLionel Sambuc     /*
572433d6423SLionel Sambuc      * Calculate the length of ConvertedName, which equals the length
573433d6423SLionel Sambuc      * of the prefix, length of all object names, length of any required
574433d6423SLionel Sambuc      * punctuation ('.') between object names, plus the NULL terminator.
575433d6423SLionel Sambuc      */
576433d6423SLionel Sambuc     RequiredLength = PrefixLength + (4 * NumSegments) +
577433d6423SLionel Sambuc                         ((NumSegments > 0) ? (NumSegments - 1) : 0) + 1;
578433d6423SLionel Sambuc 
579433d6423SLionel Sambuc     /*
580433d6423SLionel Sambuc      * Check to see if we're still in bounds. If not, there's a problem
581433d6423SLionel Sambuc      * with InternalName (invalid format).
582433d6423SLionel Sambuc      */
583433d6423SLionel Sambuc     if (RequiredLength > InternalNameLength)
584433d6423SLionel Sambuc     {
585433d6423SLionel Sambuc         ACPI_ERROR ((AE_INFO, "Invalid internal name"));
586433d6423SLionel Sambuc         return_ACPI_STATUS (AE_BAD_PATHNAME);
587433d6423SLionel Sambuc     }
588433d6423SLionel Sambuc 
589433d6423SLionel Sambuc     /* Build the ConvertedName */
590433d6423SLionel Sambuc 
591433d6423SLionel Sambuc     *ConvertedName = ACPI_ALLOCATE_ZEROED (RequiredLength);
592433d6423SLionel Sambuc     if (!(*ConvertedName))
593433d6423SLionel Sambuc     {
594433d6423SLionel Sambuc         return_ACPI_STATUS (AE_NO_MEMORY);
595433d6423SLionel Sambuc     }
596433d6423SLionel Sambuc 
597433d6423SLionel Sambuc     j = 0;
598433d6423SLionel Sambuc 
599433d6423SLionel Sambuc     for (i = 0; i < PrefixLength; i++)
600433d6423SLionel Sambuc     {
601433d6423SLionel Sambuc         (*ConvertedName)[j++] = InternalName[i];
602433d6423SLionel Sambuc     }
603433d6423SLionel Sambuc 
604433d6423SLionel Sambuc     if (NumSegments > 0)
605433d6423SLionel Sambuc     {
606433d6423SLionel Sambuc         for (i = 0; i < NumSegments; i++)
607433d6423SLionel Sambuc         {
608433d6423SLionel Sambuc             if (i > 0)
609433d6423SLionel Sambuc             {
610433d6423SLionel Sambuc                 (*ConvertedName)[j++] = '.';
611433d6423SLionel Sambuc             }
612433d6423SLionel Sambuc 
613*29492bb7SDavid van Moolenbroek             /* Copy and validate the 4-char name segment */
614*29492bb7SDavid van Moolenbroek 
615*29492bb7SDavid van Moolenbroek             ACPI_MOVE_NAME (&(*ConvertedName)[j], &InternalName[NamesIndex]);
616*29492bb7SDavid van Moolenbroek             AcpiUtRepairName (&(*ConvertedName)[j]);
617*29492bb7SDavid van Moolenbroek 
618*29492bb7SDavid van Moolenbroek             j += ACPI_NAME_SIZE;
619*29492bb7SDavid van Moolenbroek             NamesIndex += ACPI_NAME_SIZE;
620433d6423SLionel Sambuc         }
621433d6423SLionel Sambuc     }
622433d6423SLionel Sambuc 
623433d6423SLionel Sambuc     if (ConvertedNameLength)
624433d6423SLionel Sambuc     {
625433d6423SLionel Sambuc         *ConvertedNameLength = (UINT32) RequiredLength;
626433d6423SLionel Sambuc     }
627433d6423SLionel Sambuc 
628433d6423SLionel Sambuc     return_ACPI_STATUS (AE_OK);
629433d6423SLionel Sambuc }
630433d6423SLionel Sambuc 
631433d6423SLionel Sambuc 
632433d6423SLionel Sambuc /*******************************************************************************
633433d6423SLionel Sambuc  *
634433d6423SLionel Sambuc  * FUNCTION:    AcpiNsValidateHandle
635433d6423SLionel Sambuc  *
636433d6423SLionel Sambuc  * PARAMETERS:  Handle          - Handle to be validated and typecast to a
637433d6423SLionel Sambuc  *                                namespace node.
638433d6423SLionel Sambuc  *
639433d6423SLionel Sambuc  * RETURN:      A pointer to a namespace node
640433d6423SLionel Sambuc  *
641433d6423SLionel Sambuc  * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special
642433d6423SLionel Sambuc  *              cases for the root node.
643433d6423SLionel Sambuc  *
644433d6423SLionel Sambuc  * NOTE: Real integer handles would allow for more verification
645433d6423SLionel Sambuc  *       and keep all pointers within this subsystem - however this introduces
646433d6423SLionel Sambuc  *       more overhead and has not been necessary to this point. Drivers
647433d6423SLionel Sambuc  *       holding handles are typically notified before a node becomes invalid
648433d6423SLionel Sambuc  *       due to a table unload.
649433d6423SLionel Sambuc  *
650433d6423SLionel Sambuc  ******************************************************************************/
651433d6423SLionel Sambuc 
652433d6423SLionel Sambuc ACPI_NAMESPACE_NODE *
AcpiNsValidateHandle(ACPI_HANDLE Handle)653433d6423SLionel Sambuc AcpiNsValidateHandle (
654433d6423SLionel Sambuc     ACPI_HANDLE             Handle)
655433d6423SLionel Sambuc {
656433d6423SLionel Sambuc 
657433d6423SLionel Sambuc     ACPI_FUNCTION_ENTRY ();
658433d6423SLionel Sambuc 
659433d6423SLionel Sambuc 
660433d6423SLionel Sambuc     /* Parameter validation */
661433d6423SLionel Sambuc 
662433d6423SLionel Sambuc     if ((!Handle) || (Handle == ACPI_ROOT_OBJECT))
663433d6423SLionel Sambuc     {
664433d6423SLionel Sambuc         return (AcpiGbl_RootNode);
665433d6423SLionel Sambuc     }
666433d6423SLionel Sambuc 
667433d6423SLionel Sambuc     /* We can at least attempt to verify the handle */
668433d6423SLionel Sambuc 
669433d6423SLionel Sambuc     if (ACPI_GET_DESCRIPTOR_TYPE (Handle) != ACPI_DESC_TYPE_NAMED)
670433d6423SLionel Sambuc     {
671433d6423SLionel Sambuc         return (NULL);
672433d6423SLionel Sambuc     }
673433d6423SLionel Sambuc 
674433d6423SLionel Sambuc     return (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle));
675433d6423SLionel Sambuc }
676433d6423SLionel Sambuc 
677433d6423SLionel Sambuc 
678433d6423SLionel Sambuc /*******************************************************************************
679433d6423SLionel Sambuc  *
680433d6423SLionel Sambuc  * FUNCTION:    AcpiNsTerminate
681433d6423SLionel Sambuc  *
682433d6423SLionel Sambuc  * PARAMETERS:  none
683433d6423SLionel Sambuc  *
684433d6423SLionel Sambuc  * RETURN:      none
685433d6423SLionel Sambuc  *
686433d6423SLionel Sambuc  * DESCRIPTION: free memory allocated for namespace and ACPI table storage.
687433d6423SLionel Sambuc  *
688433d6423SLionel Sambuc  ******************************************************************************/
689433d6423SLionel Sambuc 
690433d6423SLionel Sambuc void
AcpiNsTerminate(void)691433d6423SLionel Sambuc AcpiNsTerminate (
692433d6423SLionel Sambuc     void)
693433d6423SLionel Sambuc {
694*29492bb7SDavid van Moolenbroek     ACPI_STATUS             Status;
695433d6423SLionel Sambuc 
696433d6423SLionel Sambuc 
697433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (NsTerminate);
698433d6423SLionel Sambuc 
699433d6423SLionel Sambuc 
700433d6423SLionel Sambuc     /*
701*29492bb7SDavid van Moolenbroek      * Free the entire namespace -- all nodes and all objects
702*29492bb7SDavid van Moolenbroek      * attached to the nodes
703433d6423SLionel Sambuc      */
704433d6423SLionel Sambuc     AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
705433d6423SLionel Sambuc 
706*29492bb7SDavid van Moolenbroek     /* Delete any objects attached to the root node */
707433d6423SLionel Sambuc 
708*29492bb7SDavid van Moolenbroek     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
709*29492bb7SDavid van Moolenbroek     if (ACPI_FAILURE (Status))
710433d6423SLionel Sambuc     {
711*29492bb7SDavid van Moolenbroek         return_VOID;
712433d6423SLionel Sambuc     }
713433d6423SLionel Sambuc 
714*29492bb7SDavid van Moolenbroek     AcpiNsDeleteNode (AcpiGbl_RootNode);
715*29492bb7SDavid van Moolenbroek     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
716*29492bb7SDavid van Moolenbroek 
717433d6423SLionel Sambuc     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n"));
718433d6423SLionel Sambuc     return_VOID;
719433d6423SLionel Sambuc }
720433d6423SLionel Sambuc 
721433d6423SLionel Sambuc 
722433d6423SLionel Sambuc /*******************************************************************************
723433d6423SLionel Sambuc  *
724433d6423SLionel Sambuc  * FUNCTION:    AcpiNsOpensScope
725433d6423SLionel Sambuc  *
726433d6423SLionel Sambuc  * PARAMETERS:  Type        - A valid namespace type
727433d6423SLionel Sambuc  *
728433d6423SLionel Sambuc  * RETURN:      NEWSCOPE if the passed type "opens a name scope" according
729433d6423SLionel Sambuc  *              to the ACPI specification, else 0
730433d6423SLionel Sambuc  *
731433d6423SLionel Sambuc  ******************************************************************************/
732433d6423SLionel Sambuc 
733433d6423SLionel Sambuc UINT32
AcpiNsOpensScope(ACPI_OBJECT_TYPE Type)734433d6423SLionel Sambuc AcpiNsOpensScope (
735433d6423SLionel Sambuc     ACPI_OBJECT_TYPE        Type)
736433d6423SLionel Sambuc {
737*29492bb7SDavid van Moolenbroek     ACPI_FUNCTION_ENTRY ();
738433d6423SLionel Sambuc 
739433d6423SLionel Sambuc 
740*29492bb7SDavid van Moolenbroek     if (Type > ACPI_TYPE_LOCAL_MAX)
741433d6423SLionel Sambuc     {
742433d6423SLionel Sambuc         /* type code out of range  */
743433d6423SLionel Sambuc 
744433d6423SLionel Sambuc         ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
745*29492bb7SDavid van Moolenbroek         return (ACPI_NS_NORMAL);
746433d6423SLionel Sambuc     }
747433d6423SLionel Sambuc 
748*29492bb7SDavid van Moolenbroek     return (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE);
749433d6423SLionel Sambuc }
750433d6423SLionel Sambuc 
751433d6423SLionel Sambuc 
752433d6423SLionel Sambuc /*******************************************************************************
753433d6423SLionel Sambuc  *
754433d6423SLionel Sambuc  * FUNCTION:    AcpiNsGetNode
755433d6423SLionel Sambuc  *
756433d6423SLionel Sambuc  * PARAMETERS:  *Pathname   - Name to be found, in external (ASL) format. The
757433d6423SLionel Sambuc  *                            \ (backslash) and ^ (carat) prefixes, and the
758433d6423SLionel Sambuc  *                            . (period) to separate segments are supported.
759433d6423SLionel Sambuc  *              PrefixNode   - Root of subtree to be searched, or NS_ALL for the
760433d6423SLionel Sambuc  *                            root of the name space. If Name is fully
761433d6423SLionel Sambuc  *                            qualified (first INT8 is '\'), the passed value
762433d6423SLionel Sambuc  *                            of Scope will not be accessed.
763433d6423SLionel Sambuc  *              Flags       - Used to indicate whether to perform upsearch or
764433d6423SLionel Sambuc  *                            not.
765433d6423SLionel Sambuc  *              ReturnNode  - Where the Node is returned
766433d6423SLionel Sambuc  *
767433d6423SLionel Sambuc  * DESCRIPTION: Look up a name relative to a given scope and return the
768433d6423SLionel Sambuc  *              corresponding Node. NOTE: Scope can be null.
769433d6423SLionel Sambuc  *
770433d6423SLionel Sambuc  * MUTEX:       Locks namespace
771433d6423SLionel Sambuc  *
772433d6423SLionel Sambuc  ******************************************************************************/
773433d6423SLionel Sambuc 
774433d6423SLionel Sambuc ACPI_STATUS
AcpiNsGetNode(ACPI_NAMESPACE_NODE * PrefixNode,const char * Pathname,UINT32 Flags,ACPI_NAMESPACE_NODE ** ReturnNode)775433d6423SLionel Sambuc AcpiNsGetNode (
776433d6423SLionel Sambuc     ACPI_NAMESPACE_NODE     *PrefixNode,
777433d6423SLionel Sambuc     const char              *Pathname,
778433d6423SLionel Sambuc     UINT32                  Flags,
779433d6423SLionel Sambuc     ACPI_NAMESPACE_NODE     **ReturnNode)
780433d6423SLionel Sambuc {
781433d6423SLionel Sambuc     ACPI_GENERIC_STATE      ScopeInfo;
782433d6423SLionel Sambuc     ACPI_STATUS             Status;
783433d6423SLionel Sambuc     char                    *InternalPath;
784433d6423SLionel Sambuc 
785433d6423SLionel Sambuc 
786433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE_PTR (NsGetNode, ACPI_CAST_PTR (char, Pathname));
787433d6423SLionel Sambuc 
788433d6423SLionel Sambuc 
789*29492bb7SDavid van Moolenbroek     /* Simplest case is a null pathname */
790*29492bb7SDavid van Moolenbroek 
791433d6423SLionel Sambuc     if (!Pathname)
792433d6423SLionel Sambuc     {
793433d6423SLionel Sambuc         *ReturnNode = PrefixNode;
794433d6423SLionel Sambuc         if (!PrefixNode)
795433d6423SLionel Sambuc         {
796433d6423SLionel Sambuc             *ReturnNode = AcpiGbl_RootNode;
797433d6423SLionel Sambuc         }
798433d6423SLionel Sambuc         return_ACPI_STATUS (AE_OK);
799433d6423SLionel Sambuc     }
800433d6423SLionel Sambuc 
801*29492bb7SDavid van Moolenbroek     /* Quick check for a reference to the root */
802*29492bb7SDavid van Moolenbroek 
803*29492bb7SDavid van Moolenbroek     if (ACPI_IS_ROOT_PREFIX (Pathname[0]) && (!Pathname[1]))
804*29492bb7SDavid van Moolenbroek     {
805*29492bb7SDavid van Moolenbroek         *ReturnNode = AcpiGbl_RootNode;
806*29492bb7SDavid van Moolenbroek         return_ACPI_STATUS (AE_OK);
807*29492bb7SDavid van Moolenbroek     }
808*29492bb7SDavid van Moolenbroek 
809433d6423SLionel Sambuc     /* Convert path to internal representation */
810433d6423SLionel Sambuc 
811433d6423SLionel Sambuc     Status = AcpiNsInternalizeName (Pathname, &InternalPath);
812433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
813433d6423SLionel Sambuc     {
814433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
815433d6423SLionel Sambuc     }
816433d6423SLionel Sambuc 
817433d6423SLionel Sambuc     /* Must lock namespace during lookup */
818433d6423SLionel Sambuc 
819433d6423SLionel Sambuc     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
820433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
821433d6423SLionel Sambuc     {
822433d6423SLionel Sambuc         goto Cleanup;
823433d6423SLionel Sambuc     }
824433d6423SLionel Sambuc 
825433d6423SLionel Sambuc     /* Setup lookup scope (search starting point) */
826433d6423SLionel Sambuc 
827433d6423SLionel Sambuc     ScopeInfo.Scope.Node = PrefixNode;
828433d6423SLionel Sambuc 
829433d6423SLionel Sambuc     /* Lookup the name in the namespace */
830433d6423SLionel Sambuc 
831433d6423SLionel Sambuc     Status = AcpiNsLookup (&ScopeInfo, InternalPath, ACPI_TYPE_ANY,
832433d6423SLionel Sambuc                 ACPI_IMODE_EXECUTE, (Flags | ACPI_NS_DONT_OPEN_SCOPE),
833433d6423SLionel Sambuc                 NULL, ReturnNode);
834433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
835433d6423SLionel Sambuc     {
836433d6423SLionel Sambuc         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s, %s\n",
837433d6423SLionel Sambuc                 Pathname, AcpiFormatException (Status)));
838433d6423SLionel Sambuc     }
839433d6423SLionel Sambuc 
840433d6423SLionel Sambuc     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
841433d6423SLionel Sambuc 
842433d6423SLionel Sambuc Cleanup:
843433d6423SLionel Sambuc     ACPI_FREE (InternalPath);
844433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
845433d6423SLionel Sambuc }
846