1ae115bc7Smrj /******************************************************************************
2ae115bc7Smrj *
3ae115bc7Smrj * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
4ae115bc7Smrj * parents and siblings and Scope manipulation
5ae115bc7Smrj *
6ae115bc7Smrj *****************************************************************************/
7ae115bc7Smrj
826f3cdf0SGordon Ross /*
9*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp.
10ae115bc7Smrj * All rights reserved.
11ae115bc7Smrj *
1226f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without
1326f3cdf0SGordon Ross * modification, are permitted provided that the following conditions
1426f3cdf0SGordon Ross * are met:
1526f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright
1626f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer,
1726f3cdf0SGordon Ross * without modification.
1826f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1926f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below
2026f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon
2126f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further
2226f3cdf0SGordon Ross * binary redistribution.
2326f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names
2426f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived
2526f3cdf0SGordon Ross * from this software without specific prior written permission.
26ae115bc7Smrj *
2726f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the
2826f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free
2926f3cdf0SGordon Ross * Software Foundation.
30ae115bc7Smrj *
3126f3cdf0SGordon Ross * NO WARRANTY
3226f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3326f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3426f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3526f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3626f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3726f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3826f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3926f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4026f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4126f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4226f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES.
4326f3cdf0SGordon Ross */
44ae115bc7Smrj
45ae115bc7Smrj #include "acpi.h"
46aa2aa9a6SDana Myers #include "accommon.h"
47ae115bc7Smrj #include "acnamesp.h"
48ae115bc7Smrj #include "amlcode.h"
49ae115bc7Smrj
50ae115bc7Smrj #define _COMPONENT ACPI_NAMESPACE
51ae115bc7Smrj ACPI_MODULE_NAME ("nsutils")
52ae115bc7Smrj
53ae115bc7Smrj /* Local prototypes */
54ae115bc7Smrj
55ae115bc7Smrj #ifdef ACPI_OBSOLETE_FUNCTIONS
56ae115bc7Smrj ACPI_NAME
57ae115bc7Smrj AcpiNsFindParentName (
58ae115bc7Smrj ACPI_NAMESPACE_NODE *NodeToSearch);
59ae115bc7Smrj #endif
60ae115bc7Smrj
61ae115bc7Smrj
62ae115bc7Smrj /*******************************************************************************
63ae115bc7Smrj *
64ae115bc7Smrj * FUNCTION: AcpiNsPrintNodePathname
65ae115bc7Smrj *
66ae115bc7Smrj * PARAMETERS: Node - Object
67ae115bc7Smrj * Message - Prefix message
68ae115bc7Smrj *
69ae115bc7Smrj * DESCRIPTION: Print an object's full namespace pathname
70ae115bc7Smrj * Manages allocation/freeing of a pathname buffer
71ae115bc7Smrj *
72ae115bc7Smrj ******************************************************************************/
73ae115bc7Smrj
74ae115bc7Smrj void
AcpiNsPrintNodePathname(ACPI_NAMESPACE_NODE * Node,const char * Message)75ae115bc7Smrj AcpiNsPrintNodePathname (
76ae115bc7Smrj ACPI_NAMESPACE_NODE *Node,
77db2bae30SDana Myers const char *Message)
78ae115bc7Smrj {
79ae115bc7Smrj ACPI_BUFFER Buffer;
80ae115bc7Smrj ACPI_STATUS Status;
81ae115bc7Smrj
82ae115bc7Smrj
83ae115bc7Smrj if (!Node)
84ae115bc7Smrj {
85ae115bc7Smrj AcpiOsPrintf ("[NULL NAME]");
86ae115bc7Smrj return;
87ae115bc7Smrj }
88ae115bc7Smrj
89ae115bc7Smrj /* Convert handle to full pathname and print it (with supplied message) */
90ae115bc7Smrj
91ae115bc7Smrj Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
92ae115bc7Smrj
93*385cc6b4SJerry Jelinek Status = AcpiNsHandleToPathname (Node, &Buffer, TRUE);
94ae115bc7Smrj if (ACPI_SUCCESS (Status))
95ae115bc7Smrj {
96ae115bc7Smrj if (Message)
97ae115bc7Smrj {
98ae115bc7Smrj AcpiOsPrintf ("%s ", Message);
99ae115bc7Smrj }
100ae115bc7Smrj
101ae115bc7Smrj AcpiOsPrintf ("[%s] (Node %p)", (char *) Buffer.Pointer, Node);
102ae115bc7Smrj ACPI_FREE (Buffer.Pointer);
103ae115bc7Smrj }
104ae115bc7Smrj }
105ae115bc7Smrj
106ae115bc7Smrj
107ae115bc7Smrj /*******************************************************************************
108ae115bc7Smrj *
109ae115bc7Smrj * FUNCTION: AcpiNsGetType
110ae115bc7Smrj *
111ae115bc7Smrj * PARAMETERS: Node - Parent Node to be examined
112ae115bc7Smrj *
113ae115bc7Smrj * RETURN: Type field from Node whose handle is passed
114ae115bc7Smrj *
115ae115bc7Smrj * DESCRIPTION: Return the type of a Namespace node
116ae115bc7Smrj *
117ae115bc7Smrj ******************************************************************************/
118ae115bc7Smrj
119ae115bc7Smrj ACPI_OBJECT_TYPE
AcpiNsGetType(ACPI_NAMESPACE_NODE * Node)120ae115bc7Smrj AcpiNsGetType (
121ae115bc7Smrj ACPI_NAMESPACE_NODE *Node)
122ae115bc7Smrj {
123ae115bc7Smrj ACPI_FUNCTION_TRACE (NsGetType);
124ae115bc7Smrj
125ae115bc7Smrj
126ae115bc7Smrj if (!Node)
127ae115bc7Smrj {
128ae115bc7Smrj ACPI_WARNING ((AE_INFO, "Null Node parameter"));
129*385cc6b4SJerry Jelinek return_UINT8 (ACPI_TYPE_ANY);
130ae115bc7Smrj }
131ae115bc7Smrj
132*385cc6b4SJerry Jelinek return_UINT8 (Node->Type);
133ae115bc7Smrj }
134ae115bc7Smrj
135ae115bc7Smrj
136ae115bc7Smrj /*******************************************************************************
137ae115bc7Smrj *
138ae115bc7Smrj * FUNCTION: AcpiNsLocal
139ae115bc7Smrj *
140ae115bc7Smrj * PARAMETERS: Type - A namespace object type
141ae115bc7Smrj *
142ae115bc7Smrj * RETURN: LOCAL if names must be found locally in objects of the
143ae115bc7Smrj * passed type, 0 if enclosing scopes should be searched
144ae115bc7Smrj *
145ae115bc7Smrj * DESCRIPTION: Returns scope rule for the given object type.
146ae115bc7Smrj *
147ae115bc7Smrj ******************************************************************************/
148ae115bc7Smrj
149ae115bc7Smrj UINT32
AcpiNsLocal(ACPI_OBJECT_TYPE Type)150ae115bc7Smrj AcpiNsLocal (
151ae115bc7Smrj ACPI_OBJECT_TYPE Type)
152ae115bc7Smrj {
153ae115bc7Smrj ACPI_FUNCTION_TRACE (NsLocal);
154ae115bc7Smrj
155ae115bc7Smrj
156ae115bc7Smrj if (!AcpiUtValidObjectType (Type))
157ae115bc7Smrj {
158ae115bc7Smrj /* Type code out of range */
159ae115bc7Smrj
16026f3cdf0SGordon Ross ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
161ae115bc7Smrj return_UINT32 (ACPI_NS_NORMAL);
162ae115bc7Smrj }
163ae115bc7Smrj
164*385cc6b4SJerry Jelinek return_UINT32 (AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL);
165ae115bc7Smrj }
166ae115bc7Smrj
167ae115bc7Smrj
168ae115bc7Smrj /*******************************************************************************
169ae115bc7Smrj *
170ae115bc7Smrj * FUNCTION: AcpiNsGetInternalNameLength
171ae115bc7Smrj *
172ae115bc7Smrj * PARAMETERS: Info - Info struct initialized with the
173ae115bc7Smrj * external name pointer.
174ae115bc7Smrj *
175ae115bc7Smrj * RETURN: None
176ae115bc7Smrj *
177ae115bc7Smrj * DESCRIPTION: Calculate the length of the internal (AML) namestring
178ae115bc7Smrj * corresponding to the external (ASL) namestring.
179ae115bc7Smrj *
180ae115bc7Smrj ******************************************************************************/
181ae115bc7Smrj
182ae115bc7Smrj void
AcpiNsGetInternalNameLength(ACPI_NAMESTRING_INFO * Info)183ae115bc7Smrj AcpiNsGetInternalNameLength (
184ae115bc7Smrj ACPI_NAMESTRING_INFO *Info)
185ae115bc7Smrj {
186db2bae30SDana Myers const char *NextExternalChar;
187ae115bc7Smrj UINT32 i;
188ae115bc7Smrj
189ae115bc7Smrj
190ae115bc7Smrj ACPI_FUNCTION_ENTRY ();
191ae115bc7Smrj
192ae115bc7Smrj
193ae115bc7Smrj NextExternalChar = Info->ExternalName;
194ae115bc7Smrj Info->NumCarats = 0;
195ae115bc7Smrj Info->NumSegments = 0;
196ae115bc7Smrj Info->FullyQualified = FALSE;
197ae115bc7Smrj
198ae115bc7Smrj /*
199*385cc6b4SJerry Jelinek * For the internal name, the required length is 4 bytes per segment,
200*385cc6b4SJerry Jelinek * plus 1 each for RootPrefix, MultiNamePrefixOp, segment count,
201*385cc6b4SJerry Jelinek * trailing null (which is not really needed, but no there's harm in
202*385cc6b4SJerry Jelinek * putting it there)
203ae115bc7Smrj *
204ae115bc7Smrj * strlen() + 1 covers the first NameSeg, which has no path separator
205ae115bc7Smrj */
206*385cc6b4SJerry Jelinek if (ACPI_IS_ROOT_PREFIX (*NextExternalChar))
207ae115bc7Smrj {
208ae115bc7Smrj Info->FullyQualified = TRUE;
209ae115bc7Smrj NextExternalChar++;
210aa2aa9a6SDana Myers
211aa2aa9a6SDana Myers /* Skip redundant RootPrefix, like \\_SB.PCI0.SBRG.EC0 */
212aa2aa9a6SDana Myers
213*385cc6b4SJerry Jelinek while (ACPI_IS_ROOT_PREFIX (*NextExternalChar))
214aa2aa9a6SDana Myers {
215aa2aa9a6SDana Myers NextExternalChar++;
216aa2aa9a6SDana Myers }
217ae115bc7Smrj }
218ae115bc7Smrj else
219ae115bc7Smrj {
220aa2aa9a6SDana Myers /* Handle Carat prefixes */
221aa2aa9a6SDana Myers
222*385cc6b4SJerry Jelinek while (ACPI_IS_PARENT_PREFIX (*NextExternalChar))
223ae115bc7Smrj {
224ae115bc7Smrj Info->NumCarats++;
225ae115bc7Smrj NextExternalChar++;
226ae115bc7Smrj }
227ae115bc7Smrj }
228ae115bc7Smrj
229ae115bc7Smrj /*
230ae115bc7Smrj * Determine the number of ACPI name "segments" by counting the number of
231ae115bc7Smrj * path separators within the string. Start with one segment since the
232ae115bc7Smrj * segment count is [(# separators) + 1], and zero separators is ok.
233ae115bc7Smrj */
234ae115bc7Smrj if (*NextExternalChar)
235ae115bc7Smrj {
236ae115bc7Smrj Info->NumSegments = 1;
237ae115bc7Smrj for (i = 0; NextExternalChar[i]; i++)
238ae115bc7Smrj {
239*385cc6b4SJerry Jelinek if (ACPI_IS_PATH_SEPARATOR (NextExternalChar[i]))
240ae115bc7Smrj {
241ae115bc7Smrj Info->NumSegments++;
242ae115bc7Smrj }
243ae115bc7Smrj }
244ae115bc7Smrj }
245ae115bc7Smrj
246ae115bc7Smrj Info->Length = (ACPI_NAME_SIZE * Info->NumSegments) +
247ae115bc7Smrj 4 + Info->NumCarats;
248ae115bc7Smrj
249ae115bc7Smrj Info->NextExternalChar = NextExternalChar;
250ae115bc7Smrj }
251ae115bc7Smrj
252ae115bc7Smrj
253ae115bc7Smrj /*******************************************************************************
254ae115bc7Smrj *
255ae115bc7Smrj * FUNCTION: AcpiNsBuildInternalName
256ae115bc7Smrj *
257ae115bc7Smrj * PARAMETERS: Info - Info struct fully initialized
258ae115bc7Smrj *
259ae115bc7Smrj * RETURN: Status
260ae115bc7Smrj *
261ae115bc7Smrj * DESCRIPTION: Construct the internal (AML) namestring
262ae115bc7Smrj * corresponding to the external (ASL) namestring.
263ae115bc7Smrj *
264ae115bc7Smrj ******************************************************************************/
265ae115bc7Smrj
266ae115bc7Smrj ACPI_STATUS
AcpiNsBuildInternalName(ACPI_NAMESTRING_INFO * Info)267ae115bc7Smrj AcpiNsBuildInternalName (
268ae115bc7Smrj ACPI_NAMESTRING_INFO *Info)
269ae115bc7Smrj {
270ae115bc7Smrj UINT32 NumSegments = Info->NumSegments;
271ae115bc7Smrj char *InternalName = Info->InternalName;
272db2bae30SDana Myers const char *ExternalName = Info->NextExternalChar;
273ae115bc7Smrj char *Result = NULL;
274db2bae30SDana Myers UINT32 i;
275ae115bc7Smrj
276ae115bc7Smrj
277ae115bc7Smrj ACPI_FUNCTION_TRACE (NsBuildInternalName);
278ae115bc7Smrj
279ae115bc7Smrj
280ae115bc7Smrj /* Setup the correct prefixes, counts, and pointers */
281ae115bc7Smrj
282ae115bc7Smrj if (Info->FullyQualified)
283ae115bc7Smrj {
284*385cc6b4SJerry Jelinek InternalName[0] = AML_ROOT_PREFIX;
285ae115bc7Smrj
286ae115bc7Smrj if (NumSegments <= 1)
287ae115bc7Smrj {
288ae115bc7Smrj Result = &InternalName[1];
289ae115bc7Smrj }
290ae115bc7Smrj else if (NumSegments == 2)
291ae115bc7Smrj {
292ae115bc7Smrj InternalName[1] = AML_DUAL_NAME_PREFIX;
293ae115bc7Smrj Result = &InternalName[2];
294ae115bc7Smrj }
295ae115bc7Smrj else
296ae115bc7Smrj {
297ae115bc7Smrj InternalName[1] = AML_MULTI_NAME_PREFIX_OP;
298ae115bc7Smrj InternalName[2] = (char) NumSegments;
299ae115bc7Smrj Result = &InternalName[3];
300ae115bc7Smrj }
301ae115bc7Smrj }
302ae115bc7Smrj else
303ae115bc7Smrj {
304ae115bc7Smrj /*
305ae115bc7Smrj * Not fully qualified.
306ae115bc7Smrj * Handle Carats first, then append the name segments
307ae115bc7Smrj */
308ae115bc7Smrj i = 0;
309ae115bc7Smrj if (Info->NumCarats)
310ae115bc7Smrj {
311ae115bc7Smrj for (i = 0; i < Info->NumCarats; i++)
312ae115bc7Smrj {
313*385cc6b4SJerry Jelinek InternalName[i] = AML_PARENT_PREFIX;
314ae115bc7Smrj }
315ae115bc7Smrj }
316ae115bc7Smrj
317ae115bc7Smrj if (NumSegments <= 1)
318ae115bc7Smrj {
319ae115bc7Smrj Result = &InternalName[i];
320ae115bc7Smrj }
321ae115bc7Smrj else if (NumSegments == 2)
322ae115bc7Smrj {
323ae115bc7Smrj InternalName[i] = AML_DUAL_NAME_PREFIX;
324db2bae30SDana Myers Result = &InternalName[(ACPI_SIZE) i+1];
325ae115bc7Smrj }
326ae115bc7Smrj else
327ae115bc7Smrj {
328ae115bc7Smrj InternalName[i] = AML_MULTI_NAME_PREFIX_OP;
329db2bae30SDana Myers InternalName[(ACPI_SIZE) i+1] = (char) NumSegments;
330db2bae30SDana Myers Result = &InternalName[(ACPI_SIZE) i+2];
331ae115bc7Smrj }
332ae115bc7Smrj }
333ae115bc7Smrj
334ae115bc7Smrj /* Build the name (minus path separators) */
335ae115bc7Smrj
336ae115bc7Smrj for (; NumSegments; NumSegments--)
337ae115bc7Smrj {
338ae115bc7Smrj for (i = 0; i < ACPI_NAME_SIZE; i++)
339ae115bc7Smrj {
340*385cc6b4SJerry Jelinek if (ACPI_IS_PATH_SEPARATOR (*ExternalName) ||
341ae115bc7Smrj (*ExternalName == 0))
342ae115bc7Smrj {
343ae115bc7Smrj /* Pad the segment with underscore(s) if segment is short */
344ae115bc7Smrj
345ae115bc7Smrj Result[i] = '_';
346ae115bc7Smrj }
347ae115bc7Smrj else
348ae115bc7Smrj {
349ae115bc7Smrj /* Convert the character to uppercase and save it */
350ae115bc7Smrj
351*385cc6b4SJerry Jelinek Result[i] = (char) toupper ((int) *ExternalName);
352ae115bc7Smrj ExternalName++;
353ae115bc7Smrj }
354ae115bc7Smrj }
355ae115bc7Smrj
356ae115bc7Smrj /* Now we must have a path separator, or the pathname is bad */
357ae115bc7Smrj
358*385cc6b4SJerry Jelinek if (!ACPI_IS_PATH_SEPARATOR (*ExternalName) &&
359ae115bc7Smrj (*ExternalName != 0))
360ae115bc7Smrj {
361*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_BAD_PATHNAME);
362ae115bc7Smrj }
363ae115bc7Smrj
364ae115bc7Smrj /* Move on the next segment */
365ae115bc7Smrj
366ae115bc7Smrj ExternalName++;
367ae115bc7Smrj Result += ACPI_NAME_SIZE;
368ae115bc7Smrj }
369ae115bc7Smrj
370ae115bc7Smrj /* Terminate the string */
371ae115bc7Smrj
372ae115bc7Smrj *Result = 0;
373ae115bc7Smrj
374ae115bc7Smrj if (Info->FullyQualified)
375ae115bc7Smrj {
376ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n",
377ae115bc7Smrj InternalName, InternalName));
378ae115bc7Smrj }
379ae115bc7Smrj else
380ae115bc7Smrj {
381ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
382ae115bc7Smrj InternalName, InternalName));
383ae115bc7Smrj }
384ae115bc7Smrj
385ae115bc7Smrj return_ACPI_STATUS (AE_OK);
386ae115bc7Smrj }
387ae115bc7Smrj
388ae115bc7Smrj
389ae115bc7Smrj /*******************************************************************************
390ae115bc7Smrj *
391ae115bc7Smrj * FUNCTION: AcpiNsInternalizeName
392ae115bc7Smrj *
393ae115bc7Smrj * PARAMETERS: *ExternalName - External representation of name
394ae115bc7Smrj * **Converted Name - Where to return the resulting
395ae115bc7Smrj * internal represention of the name
396ae115bc7Smrj *
397ae115bc7Smrj * RETURN: Status
398ae115bc7Smrj *
399ae115bc7Smrj * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0")
400ae115bc7Smrj * to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
401ae115bc7Smrj *
402ae115bc7Smrj *******************************************************************************/
403ae115bc7Smrj
404ae115bc7Smrj ACPI_STATUS
AcpiNsInternalizeName(const char * ExternalName,char ** ConvertedName)405ae115bc7Smrj AcpiNsInternalizeName (
406db2bae30SDana Myers const char *ExternalName,
407ae115bc7Smrj char **ConvertedName)
408ae115bc7Smrj {
409ae115bc7Smrj char *InternalName;
410ae115bc7Smrj ACPI_NAMESTRING_INFO Info;
411ae115bc7Smrj ACPI_STATUS Status;
412ae115bc7Smrj
413ae115bc7Smrj
414ae115bc7Smrj ACPI_FUNCTION_TRACE (NsInternalizeName);
415ae115bc7Smrj
416ae115bc7Smrj
417ae115bc7Smrj if ((!ExternalName) ||
418ae115bc7Smrj (*ExternalName == 0) ||
419ae115bc7Smrj (!ConvertedName))
420ae115bc7Smrj {
421ae115bc7Smrj return_ACPI_STATUS (AE_BAD_PARAMETER);
422ae115bc7Smrj }
423ae115bc7Smrj
424ae115bc7Smrj /* Get the length of the new internal name */
425ae115bc7Smrj
426ae115bc7Smrj Info.ExternalName = ExternalName;
427ae115bc7Smrj AcpiNsGetInternalNameLength (&Info);
428ae115bc7Smrj
429ae115bc7Smrj /* We need a segment to store the internal name */
430ae115bc7Smrj
431ae115bc7Smrj InternalName = ACPI_ALLOCATE_ZEROED (Info.Length);
432ae115bc7Smrj if (!InternalName)
433ae115bc7Smrj {
434ae115bc7Smrj return_ACPI_STATUS (AE_NO_MEMORY);
435ae115bc7Smrj }
436ae115bc7Smrj
437ae115bc7Smrj /* Build the name */
438ae115bc7Smrj
439ae115bc7Smrj Info.InternalName = InternalName;
440ae115bc7Smrj Status = AcpiNsBuildInternalName (&Info);
441ae115bc7Smrj if (ACPI_FAILURE (Status))
442ae115bc7Smrj {
443ae115bc7Smrj ACPI_FREE (InternalName);
444ae115bc7Smrj return_ACPI_STATUS (Status);
445ae115bc7Smrj }
446ae115bc7Smrj
447ae115bc7Smrj *ConvertedName = InternalName;
448ae115bc7Smrj return_ACPI_STATUS (AE_OK);
449ae115bc7Smrj }
450ae115bc7Smrj
451ae115bc7Smrj
452ae115bc7Smrj /*******************************************************************************
453ae115bc7Smrj *
454ae115bc7Smrj * FUNCTION: AcpiNsExternalizeName
455ae115bc7Smrj *
456ae115bc7Smrj * PARAMETERS: InternalNameLength - Lenth of the internal name below
457ae115bc7Smrj * InternalName - Internal representation of name
458ae115bc7Smrj * ConvertedNameLength - Where the length is returned
459ae115bc7Smrj * ConvertedName - Where the resulting external name
460ae115bc7Smrj * is returned
461ae115bc7Smrj *
462ae115bc7Smrj * RETURN: Status
463ae115bc7Smrj *
464ae115bc7Smrj * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
465ae115bc7Smrj * to its external (printable) form (e.g. "\_PR_.CPU0")
466ae115bc7Smrj *
467ae115bc7Smrj ******************************************************************************/
468ae115bc7Smrj
469ae115bc7Smrj ACPI_STATUS
AcpiNsExternalizeName(UINT32 InternalNameLength,const char * InternalName,UINT32 * ConvertedNameLength,char ** ConvertedName)470ae115bc7Smrj AcpiNsExternalizeName (
471ae115bc7Smrj UINT32 InternalNameLength,
472db2bae30SDana Myers const char *InternalName,
473ae115bc7Smrj UINT32 *ConvertedNameLength,
474ae115bc7Smrj char **ConvertedName)
475ae115bc7Smrj {
476db2bae30SDana Myers UINT32 NamesIndex = 0;
477db2bae30SDana Myers UINT32 NumSegments = 0;
478db2bae30SDana Myers UINT32 RequiredLength;
479db2bae30SDana Myers UINT32 PrefixLength = 0;
480db2bae30SDana Myers UINT32 i = 0;
481db2bae30SDana Myers UINT32 j = 0;
482ae115bc7Smrj
483ae115bc7Smrj
484ae115bc7Smrj ACPI_FUNCTION_TRACE (NsExternalizeName);
485ae115bc7Smrj
486ae115bc7Smrj
487ae115bc7Smrj if (!InternalNameLength ||
488ae115bc7Smrj !InternalName ||
489ae115bc7Smrj !ConvertedName)
490ae115bc7Smrj {
491ae115bc7Smrj return_ACPI_STATUS (AE_BAD_PARAMETER);
492ae115bc7Smrj }
493ae115bc7Smrj
494aa2aa9a6SDana Myers /* Check for a prefix (one '\' | one or more '^') */
495aa2aa9a6SDana Myers
496ae115bc7Smrj switch (InternalName[0])
497ae115bc7Smrj {
498*385cc6b4SJerry Jelinek case AML_ROOT_PREFIX:
499*385cc6b4SJerry Jelinek
500ae115bc7Smrj PrefixLength = 1;
501ae115bc7Smrj break;
502ae115bc7Smrj
503*385cc6b4SJerry Jelinek case AML_PARENT_PREFIX:
504*385cc6b4SJerry Jelinek
505ae115bc7Smrj for (i = 0; i < InternalNameLength; i++)
506ae115bc7Smrj {
507*385cc6b4SJerry Jelinek if (ACPI_IS_PARENT_PREFIX (InternalName[i]))
508ae115bc7Smrj {
509ae115bc7Smrj PrefixLength = i + 1;
510ae115bc7Smrj }
511ae115bc7Smrj else
512ae115bc7Smrj {
513ae115bc7Smrj break;
514ae115bc7Smrj }
515ae115bc7Smrj }
516ae115bc7Smrj
517ae115bc7Smrj if (i == InternalNameLength)
518ae115bc7Smrj {
519ae115bc7Smrj PrefixLength = i;
520ae115bc7Smrj }
521ae115bc7Smrj
522ae115bc7Smrj break;
523ae115bc7Smrj
524ae115bc7Smrj default:
525*385cc6b4SJerry Jelinek
526ae115bc7Smrj break;
527ae115bc7Smrj }
528ae115bc7Smrj
529ae115bc7Smrj /*
530ae115bc7Smrj * Check for object names. Note that there could be 0-255 of these
531ae115bc7Smrj * 4-byte elements.
532ae115bc7Smrj */
533ae115bc7Smrj if (PrefixLength < InternalNameLength)
534ae115bc7Smrj {
535ae115bc7Smrj switch (InternalName[PrefixLength])
536ae115bc7Smrj {
537ae115bc7Smrj case AML_MULTI_NAME_PREFIX_OP:
538ae115bc7Smrj
539ae115bc7Smrj /* <count> 4-byte names */
540ae115bc7Smrj
541ae115bc7Smrj NamesIndex = PrefixLength + 2;
542db2bae30SDana Myers NumSegments = (UINT8)
543db2bae30SDana Myers InternalName[(ACPI_SIZE) PrefixLength + 1];
544ae115bc7Smrj break;
545ae115bc7Smrj
546ae115bc7Smrj case AML_DUAL_NAME_PREFIX:
547ae115bc7Smrj
548ae115bc7Smrj /* Two 4-byte names */
549ae115bc7Smrj
550ae115bc7Smrj NamesIndex = PrefixLength + 1;
551ae115bc7Smrj NumSegments = 2;
552ae115bc7Smrj break;
553ae115bc7Smrj
554ae115bc7Smrj case 0:
555ae115bc7Smrj
556ae115bc7Smrj /* NullName */
557ae115bc7Smrj
558ae115bc7Smrj NamesIndex = 0;
559ae115bc7Smrj NumSegments = 0;
560ae115bc7Smrj break;
561ae115bc7Smrj
562ae115bc7Smrj default:
563ae115bc7Smrj
564ae115bc7Smrj /* one 4-byte name */
565ae115bc7Smrj
566ae115bc7Smrj NamesIndex = PrefixLength;
567ae115bc7Smrj NumSegments = 1;
568ae115bc7Smrj break;
569ae115bc7Smrj }
570ae115bc7Smrj }
571ae115bc7Smrj
572ae115bc7Smrj /*
573ae115bc7Smrj * Calculate the length of ConvertedName, which equals the length
574ae115bc7Smrj * of the prefix, length of all object names, length of any required
575ae115bc7Smrj * punctuation ('.') between object names, plus the NULL terminator.
576ae115bc7Smrj */
577ae115bc7Smrj RequiredLength = PrefixLength + (4 * NumSegments) +
578ae115bc7Smrj ((NumSegments > 0) ? (NumSegments - 1) : 0) + 1;
579ae115bc7Smrj
580ae115bc7Smrj /*
581ae115bc7Smrj * Check to see if we're still in bounds. If not, there's a problem
582ae115bc7Smrj * with InternalName (invalid format).
583ae115bc7Smrj */
584ae115bc7Smrj if (RequiredLength > InternalNameLength)
585ae115bc7Smrj {
586ae115bc7Smrj ACPI_ERROR ((AE_INFO, "Invalid internal name"));
587ae115bc7Smrj return_ACPI_STATUS (AE_BAD_PATHNAME);
588ae115bc7Smrj }
589ae115bc7Smrj
590aa2aa9a6SDana Myers /* Build the ConvertedName */
591aa2aa9a6SDana Myers
592ae115bc7Smrj *ConvertedName = ACPI_ALLOCATE_ZEROED (RequiredLength);
593ae115bc7Smrj if (!(*ConvertedName))
594ae115bc7Smrj {
595ae115bc7Smrj return_ACPI_STATUS (AE_NO_MEMORY);
596ae115bc7Smrj }
597ae115bc7Smrj
598ae115bc7Smrj j = 0;
599ae115bc7Smrj
600ae115bc7Smrj for (i = 0; i < PrefixLength; i++)
601ae115bc7Smrj {
602ae115bc7Smrj (*ConvertedName)[j++] = InternalName[i];
603ae115bc7Smrj }
604ae115bc7Smrj
605ae115bc7Smrj if (NumSegments > 0)
606ae115bc7Smrj {
607ae115bc7Smrj for (i = 0; i < NumSegments; i++)
608ae115bc7Smrj {
609ae115bc7Smrj if (i > 0)
610ae115bc7Smrj {
611ae115bc7Smrj (*ConvertedName)[j++] = '.';
612ae115bc7Smrj }
613ae115bc7Smrj
614*385cc6b4SJerry Jelinek /* Copy and validate the 4-char name segment */
615*385cc6b4SJerry Jelinek
616*385cc6b4SJerry Jelinek ACPI_MOVE_NAME (&(*ConvertedName)[j],
617*385cc6b4SJerry Jelinek &InternalName[NamesIndex]);
618*385cc6b4SJerry Jelinek AcpiUtRepairName (&(*ConvertedName)[j]);
619*385cc6b4SJerry Jelinek
620*385cc6b4SJerry Jelinek j += ACPI_NAME_SIZE;
621*385cc6b4SJerry Jelinek NamesIndex += ACPI_NAME_SIZE;
622ae115bc7Smrj }
623ae115bc7Smrj }
624ae115bc7Smrj
625ae115bc7Smrj if (ConvertedNameLength)
626ae115bc7Smrj {
627ae115bc7Smrj *ConvertedNameLength = (UINT32) RequiredLength;
628ae115bc7Smrj }
629ae115bc7Smrj
630ae115bc7Smrj return_ACPI_STATUS (AE_OK);
631ae115bc7Smrj }
632ae115bc7Smrj
633ae115bc7Smrj
634ae115bc7Smrj /*******************************************************************************
635ae115bc7Smrj *
63626f3cdf0SGordon Ross * FUNCTION: AcpiNsValidateHandle
637ae115bc7Smrj *
63826f3cdf0SGordon Ross * PARAMETERS: Handle - Handle to be validated and typecast to a
63926f3cdf0SGordon Ross * namespace node.
640ae115bc7Smrj *
64126f3cdf0SGordon Ross * RETURN: A pointer to a namespace node
642ae115bc7Smrj *
64326f3cdf0SGordon Ross * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special
64426f3cdf0SGordon Ross * cases for the root node.
645ae115bc7Smrj *
64626f3cdf0SGordon Ross * NOTE: Real integer handles would allow for more verification
647ae115bc7Smrj * and keep all pointers within this subsystem - however this introduces
64826f3cdf0SGordon Ross * more overhead and has not been necessary to this point. Drivers
64926f3cdf0SGordon Ross * holding handles are typically notified before a node becomes invalid
65026f3cdf0SGordon Ross * due to a table unload.
651aa2aa9a6SDana Myers *
652ae115bc7Smrj ******************************************************************************/
653ae115bc7Smrj
654ae115bc7Smrj ACPI_NAMESPACE_NODE *
AcpiNsValidateHandle(ACPI_HANDLE Handle)65526f3cdf0SGordon Ross AcpiNsValidateHandle (
656ae115bc7Smrj ACPI_HANDLE Handle)
657ae115bc7Smrj {
658ae115bc7Smrj
659ae115bc7Smrj ACPI_FUNCTION_ENTRY ();
660ae115bc7Smrj
661ae115bc7Smrj
662aa2aa9a6SDana Myers /* Parameter validation */
663aa2aa9a6SDana Myers
664ae115bc7Smrj if ((!Handle) || (Handle == ACPI_ROOT_OBJECT))
665ae115bc7Smrj {
666ae115bc7Smrj return (AcpiGbl_RootNode);
667ae115bc7Smrj }
668ae115bc7Smrj
669ae115bc7Smrj /* We can at least attempt to verify the handle */
670ae115bc7Smrj
671ae115bc7Smrj if (ACPI_GET_DESCRIPTOR_TYPE (Handle) != ACPI_DESC_TYPE_NAMED)
672ae115bc7Smrj {
673ae115bc7Smrj return (NULL);
674ae115bc7Smrj }
675ae115bc7Smrj
676ae115bc7Smrj return (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle));
677ae115bc7Smrj }
678ae115bc7Smrj
679ae115bc7Smrj
680ae115bc7Smrj /*******************************************************************************
681ae115bc7Smrj *
682ae115bc7Smrj * FUNCTION: AcpiNsTerminate
683ae115bc7Smrj *
684ae115bc7Smrj * PARAMETERS: none
685ae115bc7Smrj *
686ae115bc7Smrj * RETURN: none
687ae115bc7Smrj *
688ae115bc7Smrj * DESCRIPTION: free memory allocated for namespace and ACPI table storage.
689ae115bc7Smrj *
690ae115bc7Smrj ******************************************************************************/
691ae115bc7Smrj
692ae115bc7Smrj void
AcpiNsTerminate(void)693ae115bc7Smrj AcpiNsTerminate (
694ae115bc7Smrj void)
695ae115bc7Smrj {
696*385cc6b4SJerry Jelinek ACPI_STATUS Status;
697ae115bc7Smrj
698ae115bc7Smrj
699ae115bc7Smrj ACPI_FUNCTION_TRACE (NsTerminate);
700ae115bc7Smrj
701ae115bc7Smrj
702*385cc6b4SJerry Jelinek #ifdef ACPI_EXEC_APP
703*385cc6b4SJerry Jelinek {
704*385cc6b4SJerry Jelinek ACPI_OPERAND_OBJECT *Prev;
705*385cc6b4SJerry Jelinek ACPI_OPERAND_OBJECT *Next;
706*385cc6b4SJerry Jelinek
707*385cc6b4SJerry Jelinek /* Delete any module-level code blocks */
708*385cc6b4SJerry Jelinek
709*385cc6b4SJerry Jelinek Next = AcpiGbl_ModuleCodeList;
710*385cc6b4SJerry Jelinek while (Next)
711*385cc6b4SJerry Jelinek {
712*385cc6b4SJerry Jelinek Prev = Next;
713*385cc6b4SJerry Jelinek Next = Next->Method.Mutex;
714*385cc6b4SJerry Jelinek Prev->Method.Mutex = NULL; /* Clear the Mutex (cheated) field */
715*385cc6b4SJerry Jelinek AcpiUtRemoveReference (Prev);
716*385cc6b4SJerry Jelinek }
717*385cc6b4SJerry Jelinek }
718*385cc6b4SJerry Jelinek #endif
719*385cc6b4SJerry Jelinek
720ae115bc7Smrj /*
721*385cc6b4SJerry Jelinek * Free the entire namespace -- all nodes and all objects
722*385cc6b4SJerry Jelinek * attached to the nodes
723ae115bc7Smrj */
724ae115bc7Smrj AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
725ae115bc7Smrj
726*385cc6b4SJerry Jelinek /* Delete any objects attached to the root node */
727ae115bc7Smrj
728*385cc6b4SJerry Jelinek Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
729*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status))
730ae115bc7Smrj {
731*385cc6b4SJerry Jelinek return_VOID;
732ae115bc7Smrj }
733ae115bc7Smrj
734*385cc6b4SJerry Jelinek AcpiNsDeleteNode (AcpiGbl_RootNode);
735*385cc6b4SJerry Jelinek (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
736*385cc6b4SJerry Jelinek
737ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n"));
738ae115bc7Smrj return_VOID;
739ae115bc7Smrj }
740ae115bc7Smrj
741ae115bc7Smrj
742ae115bc7Smrj /*******************************************************************************
743ae115bc7Smrj *
744ae115bc7Smrj * FUNCTION: AcpiNsOpensScope
745ae115bc7Smrj *
746ae115bc7Smrj * PARAMETERS: Type - A valid namespace type
747ae115bc7Smrj *
748ae115bc7Smrj * RETURN: NEWSCOPE if the passed type "opens a name scope" according
749ae115bc7Smrj * to the ACPI specification, else 0
750ae115bc7Smrj *
751ae115bc7Smrj ******************************************************************************/
752ae115bc7Smrj
753ae115bc7Smrj UINT32
AcpiNsOpensScope(ACPI_OBJECT_TYPE Type)754ae115bc7Smrj AcpiNsOpensScope (
755ae115bc7Smrj ACPI_OBJECT_TYPE Type)
756ae115bc7Smrj {
757*385cc6b4SJerry Jelinek ACPI_FUNCTION_ENTRY ();
758ae115bc7Smrj
759ae115bc7Smrj
760*385cc6b4SJerry Jelinek if (Type > ACPI_TYPE_LOCAL_MAX)
761ae115bc7Smrj {
762ae115bc7Smrj /* type code out of range */
763ae115bc7Smrj
76426f3cdf0SGordon Ross ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
765*385cc6b4SJerry Jelinek return (ACPI_NS_NORMAL);
766ae115bc7Smrj }
767ae115bc7Smrj
768*385cc6b4SJerry Jelinek return (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE);
769ae115bc7Smrj }
770ae115bc7Smrj
771ae115bc7Smrj
772ae115bc7Smrj /*******************************************************************************
773ae115bc7Smrj *
774ae115bc7Smrj * FUNCTION: AcpiNsGetNode
775ae115bc7Smrj *
776ae115bc7Smrj * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The
777ae115bc7Smrj * \ (backslash) and ^ (carat) prefixes, and the
778ae115bc7Smrj * . (period) to separate segments are supported.
779ae115bc7Smrj * PrefixNode - Root of subtree to be searched, or NS_ALL for the
780ae115bc7Smrj * root of the name space. If Name is fully
781ae115bc7Smrj * qualified (first INT8 is '\'), the passed value
782ae115bc7Smrj * of Scope will not be accessed.
783ae115bc7Smrj * Flags - Used to indicate whether to perform upsearch or
784ae115bc7Smrj * not.
785ae115bc7Smrj * ReturnNode - Where the Node is returned
786ae115bc7Smrj *
787ae115bc7Smrj * DESCRIPTION: Look up a name relative to a given scope and return the
788ae115bc7Smrj * corresponding Node. NOTE: Scope can be null.
789ae115bc7Smrj *
790ae115bc7Smrj * MUTEX: Locks namespace
791ae115bc7Smrj *
792ae115bc7Smrj ******************************************************************************/
793ae115bc7Smrj
794ae115bc7Smrj ACPI_STATUS
AcpiNsGetNode(ACPI_NAMESPACE_NODE * PrefixNode,const char * Pathname,UINT32 Flags,ACPI_NAMESPACE_NODE ** ReturnNode)795ae115bc7Smrj AcpiNsGetNode (
796ae115bc7Smrj ACPI_NAMESPACE_NODE *PrefixNode,
797db2bae30SDana Myers const char *Pathname,
798ae115bc7Smrj UINT32 Flags,
799ae115bc7Smrj ACPI_NAMESPACE_NODE **ReturnNode)
800ae115bc7Smrj {
801ae115bc7Smrj ACPI_GENERIC_STATE ScopeInfo;
802ae115bc7Smrj ACPI_STATUS Status;
803ae115bc7Smrj char *InternalPath;
804ae115bc7Smrj
805ae115bc7Smrj
80657190917SDana Myers ACPI_FUNCTION_TRACE_PTR (NsGetNode, ACPI_CAST_PTR (char, Pathname));
807ae115bc7Smrj
808ae115bc7Smrj
809*385cc6b4SJerry Jelinek /* Simplest case is a null pathname */
810*385cc6b4SJerry Jelinek
811ae115bc7Smrj if (!Pathname)
812ae115bc7Smrj {
813ae115bc7Smrj *ReturnNode = PrefixNode;
814ae115bc7Smrj if (!PrefixNode)
815ae115bc7Smrj {
816ae115bc7Smrj *ReturnNode = AcpiGbl_RootNode;
817ae115bc7Smrj }
818*385cc6b4SJerry Jelinek
819*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_OK);
820*385cc6b4SJerry Jelinek }
821*385cc6b4SJerry Jelinek
822*385cc6b4SJerry Jelinek /* Quick check for a reference to the root */
823*385cc6b4SJerry Jelinek
824*385cc6b4SJerry Jelinek if (ACPI_IS_ROOT_PREFIX (Pathname[0]) && (!Pathname[1]))
825*385cc6b4SJerry Jelinek {
826*385cc6b4SJerry Jelinek *ReturnNode = AcpiGbl_RootNode;
827ae115bc7Smrj return_ACPI_STATUS (AE_OK);
828ae115bc7Smrj }
829ae115bc7Smrj
830ae115bc7Smrj /* Convert path to internal representation */
831ae115bc7Smrj
832ae115bc7Smrj Status = AcpiNsInternalizeName (Pathname, &InternalPath);
833ae115bc7Smrj if (ACPI_FAILURE (Status))
834ae115bc7Smrj {
835ae115bc7Smrj return_ACPI_STATUS (Status);
836ae115bc7Smrj }
837ae115bc7Smrj
838ae115bc7Smrj /* Must lock namespace during lookup */
839ae115bc7Smrj
840ae115bc7Smrj Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
841ae115bc7Smrj if (ACPI_FAILURE (Status))
842ae115bc7Smrj {
843ae115bc7Smrj goto Cleanup;
844ae115bc7Smrj }
845ae115bc7Smrj
846ae115bc7Smrj /* Setup lookup scope (search starting point) */
847ae115bc7Smrj
848ae115bc7Smrj ScopeInfo.Scope.Node = PrefixNode;
849ae115bc7Smrj
850ae115bc7Smrj /* Lookup the name in the namespace */
851ae115bc7Smrj
852ae115bc7Smrj Status = AcpiNsLookup (&ScopeInfo, InternalPath, ACPI_TYPE_ANY,
853ae115bc7Smrj ACPI_IMODE_EXECUTE, (Flags | ACPI_NS_DONT_OPEN_SCOPE),
854ae115bc7Smrj NULL, ReturnNode);
855ae115bc7Smrj if (ACPI_FAILURE (Status))
856ae115bc7Smrj {
857aa2aa9a6SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s, %s\n",
858ae115bc7Smrj Pathname, AcpiFormatException (Status)));
859ae115bc7Smrj }
860ae115bc7Smrj
861ae115bc7Smrj (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
862ae115bc7Smrj
863ae115bc7Smrj Cleanup:
864ae115bc7Smrj ACPI_FREE (InternalPath);
865ae115bc7Smrj return_ACPI_STATUS (Status);
866ae115bc7Smrj }
867