xref: /haiku/src/add-ons/kernel/bus_managers/acpi/acpica/components/namespace/nsutils.c (revision 220d04022750f40f8bac8f01fa551211e28d04f2)
1 /******************************************************************************
2  *
3  * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
4  *                        parents and siblings and Scope manipulation
5  *
6  *****************************************************************************/
7 
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2013, Intel Corp.
13  * All rights reserved.
14  *
15  * 2. License
16  *
17  * 2.1. This is your license from Intel Corp. under its intellectual property
18  * rights. You may have additional license terms from the party that provided
19  * you this software, covering your right to use that party's intellectual
20  * property rights.
21  *
22  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23  * copy of the source code appearing in this file ("Covered Code") an
24  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25  * base code distributed originally by Intel ("Original Intel Code") to copy,
26  * make derivatives, distribute, use and display any portion of the Covered
27  * Code in any form, with the right to sublicense such rights; and
28  *
29  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30  * license (with the right to sublicense), under only those claims of Intel
31  * patents that are infringed by the Original Intel Code, to make, use, sell,
32  * offer to sell, and import the Covered Code and derivative works thereof
33  * solely to the minimum extent necessary to exercise the above copyright
34  * license, and in no event shall the patent license extend to any additions
35  * to or modifications of the Original Intel Code. No other license or right
36  * is granted directly or by implication, estoppel or otherwise;
37  *
38  * The above copyright and patent license is granted only if the following
39  * conditions are met:
40  *
41  * 3. Conditions
42  *
43  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44  * Redistribution of source code of any substantial portion of the Covered
45  * Code or modification with rights to further distribute source must include
46  * the above Copyright Notice, the above License, this list of Conditions,
47  * and the following Disclaimer and Export Compliance provision. In addition,
48  * Licensee must cause all Covered Code to which Licensee contributes to
49  * contain a file documenting the changes Licensee made to create that Covered
50  * Code and the date of any change. Licensee must include in that file the
51  * documentation of any changes made by any predecessor Licensee. Licensee
52  * must include a prominent statement that the modification is derived,
53  * directly or indirectly, from Original Intel Code.
54  *
55  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56  * Redistribution of source code of any substantial portion of the Covered
57  * Code or modification without rights to further distribute source must
58  * include the following Disclaimer and Export Compliance provision in the
59  * documentation and/or other materials provided with distribution. In
60  * addition, Licensee may not authorize further sublicense of source of any
61  * portion of the Covered Code, and must include terms to the effect that the
62  * license from Licensee to its licensee is limited to the intellectual
63  * property embodied in the software Licensee provides to its licensee, and
64  * not to intellectual property embodied in modifications its licensee may
65  * make.
66  *
67  * 3.3. Redistribution of Executable. Redistribution in executable form of any
68  * substantial portion of the Covered Code or modification must reproduce the
69  * above Copyright Notice, and the following Disclaimer and Export Compliance
70  * provision in the documentation and/or other materials provided with the
71  * distribution.
72  *
73  * 3.4. Intel retains all right, title, and interest in and to the Original
74  * Intel Code.
75  *
76  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77  * Intel shall be used in advertising or otherwise to promote the sale, use or
78  * other dealings in products derived from or relating to the Covered Code
79  * without prior written authorization from Intel.
80  *
81  * 4. Disclaimer and Export Compliance
82  *
83  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
86  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
87  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89  * PARTICULAR PURPOSE.
90  *
91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98  * LIMITED REMEDY.
99  *
100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
101  * software or system incorporating such software without first obtaining any
102  * required license or other approval from the U. S. Department of Commerce or
103  * any other agency or department of the United States Government. In the
104  * event Licensee exports any such software from the United States or
105  * re-exports any such software from a foreign destination, Licensee shall
106  * ensure that the distribution and export/re-export of the software is in
107  * compliance with all laws, regulations, orders, or other restrictions of the
108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109  * any of its subsidiaries will export/re-export any technical data, process,
110  * software, or service, directly or indirectly, to any country for which the
111  * United States government or any agency thereof requires an export license,
112  * other governmental approval, or letter of assurance, without first obtaining
113  * such license, approval or letter.
114  *
115  *****************************************************************************/
116 
117 #define __NSUTILS_C__
118 
119 #include "acpi.h"
120 #include "accommon.h"
121 #include "acnamesp.h"
122 #include "amlcode.h"
123 
124 #define _COMPONENT          ACPI_NAMESPACE
125         ACPI_MODULE_NAME    ("nsutils")
126 
127 /* Local prototypes */
128 
129 #ifdef ACPI_OBSOLETE_FUNCTIONS
130 ACPI_NAME
131 AcpiNsFindParentName (
132     ACPI_NAMESPACE_NODE     *NodeToSearch);
133 #endif
134 
135 
136 /*******************************************************************************
137  *
138  * FUNCTION:    AcpiNsPrintNodePathname
139  *
140  * PARAMETERS:  Node            - Object
141  *              Message         - Prefix message
142  *
143  * DESCRIPTION: Print an object's full namespace pathname
144  *              Manages allocation/freeing of a pathname buffer
145  *
146  ******************************************************************************/
147 
148 void
149 AcpiNsPrintNodePathname (
150     ACPI_NAMESPACE_NODE     *Node,
151     const char              *Message)
152 {
153     ACPI_BUFFER             Buffer;
154     ACPI_STATUS             Status;
155 
156 
157     if (!Node)
158     {
159         AcpiOsPrintf ("[NULL NAME]");
160         return;
161     }
162 
163     /* Convert handle to full pathname and print it (with supplied message) */
164 
165     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
166 
167     Status = AcpiNsHandleToPathname (Node, &Buffer);
168     if (ACPI_SUCCESS (Status))
169     {
170         if (Message)
171         {
172             AcpiOsPrintf ("%s ", Message);
173         }
174 
175         AcpiOsPrintf ("[%s] (Node %p)", (char *) Buffer.Pointer, Node);
176         ACPI_FREE (Buffer.Pointer);
177     }
178 }
179 
180 
181 /*******************************************************************************
182  *
183  * FUNCTION:    AcpiNsGetType
184  *
185  * PARAMETERS:  Node        - Parent Node to be examined
186  *
187  * RETURN:      Type field from Node whose handle is passed
188  *
189  * DESCRIPTION: Return the type of a Namespace node
190  *
191  ******************************************************************************/
192 
193 ACPI_OBJECT_TYPE
194 AcpiNsGetType (
195     ACPI_NAMESPACE_NODE     *Node)
196 {
197     ACPI_FUNCTION_TRACE (NsGetType);
198 
199 
200     if (!Node)
201     {
202         ACPI_WARNING ((AE_INFO, "Null Node parameter"));
203         return_UINT8 (ACPI_TYPE_ANY);
204     }
205 
206     return_UINT8 (Node->Type);
207 }
208 
209 
210 /*******************************************************************************
211  *
212  * FUNCTION:    AcpiNsLocal
213  *
214  * PARAMETERS:  Type        - A namespace object type
215  *
216  * RETURN:      LOCAL if names must be found locally in objects of the
217  *              passed type, 0 if enclosing scopes should be searched
218  *
219  * DESCRIPTION: Returns scope rule for the given object type.
220  *
221  ******************************************************************************/
222 
223 UINT32
224 AcpiNsLocal (
225     ACPI_OBJECT_TYPE        Type)
226 {
227     ACPI_FUNCTION_TRACE (NsLocal);
228 
229 
230     if (!AcpiUtValidObjectType (Type))
231     {
232         /* Type code out of range  */
233 
234         ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
235         return_UINT32 (ACPI_NS_NORMAL);
236     }
237 
238     return_UINT32 (AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL);
239 }
240 
241 
242 /*******************************************************************************
243  *
244  * FUNCTION:    AcpiNsGetInternalNameLength
245  *
246  * PARAMETERS:  Info            - Info struct initialized with the
247  *                                external name pointer.
248  *
249  * RETURN:      None
250  *
251  * DESCRIPTION: Calculate the length of the internal (AML) namestring
252  *              corresponding to the external (ASL) namestring.
253  *
254  ******************************************************************************/
255 
256 void
257 AcpiNsGetInternalNameLength (
258     ACPI_NAMESTRING_INFO    *Info)
259 {
260     const char              *NextExternalChar;
261     UINT32                  i;
262 
263 
264     ACPI_FUNCTION_ENTRY ();
265 
266 
267     NextExternalChar = Info->ExternalName;
268     Info->NumCarats = 0;
269     Info->NumSegments = 0;
270     Info->FullyQualified = FALSE;
271 
272     /*
273      * For the internal name, the required length is 4 bytes per segment, plus
274      * 1 each for RootPrefix, MultiNamePrefixOp, segment count, trailing null
275      * (which is not really needed, but no there's harm in putting it there)
276      *
277      * strlen() + 1 covers the first NameSeg, which has no path separator
278      */
279     if (ACPI_IS_ROOT_PREFIX (*NextExternalChar))
280     {
281         Info->FullyQualified = TRUE;
282         NextExternalChar++;
283 
284         /* Skip redundant RootPrefix, like \\_SB.PCI0.SBRG.EC0 */
285 
286         while (ACPI_IS_ROOT_PREFIX (*NextExternalChar))
287         {
288             NextExternalChar++;
289         }
290     }
291     else
292     {
293         /* Handle Carat prefixes */
294 
295         while (ACPI_IS_PARENT_PREFIX (*NextExternalChar))
296         {
297             Info->NumCarats++;
298             NextExternalChar++;
299         }
300     }
301 
302     /*
303      * Determine the number of ACPI name "segments" by counting the number of
304      * path separators within the string. Start with one segment since the
305      * segment count is [(# separators) + 1], and zero separators is ok.
306      */
307     if (*NextExternalChar)
308     {
309         Info->NumSegments = 1;
310         for (i = 0; NextExternalChar[i]; i++)
311         {
312             if (ACPI_IS_PATH_SEPARATOR (NextExternalChar[i]))
313             {
314                 Info->NumSegments++;
315             }
316         }
317     }
318 
319     Info->Length = (ACPI_NAME_SIZE * Info->NumSegments) +
320                     4 + Info->NumCarats;
321 
322     Info->NextExternalChar = NextExternalChar;
323 }
324 
325 
326 /*******************************************************************************
327  *
328  * FUNCTION:    AcpiNsBuildInternalName
329  *
330  * PARAMETERS:  Info            - Info struct fully initialized
331  *
332  * RETURN:      Status
333  *
334  * DESCRIPTION: Construct the internal (AML) namestring
335  *              corresponding to the external (ASL) namestring.
336  *
337  ******************************************************************************/
338 
339 ACPI_STATUS
340 AcpiNsBuildInternalName (
341     ACPI_NAMESTRING_INFO    *Info)
342 {
343     UINT32                  NumSegments = Info->NumSegments;
344     char                    *InternalName = Info->InternalName;
345     const char              *ExternalName = Info->NextExternalChar;
346     char                    *Result = NULL;
347     UINT32                  i;
348 
349 
350     ACPI_FUNCTION_TRACE (NsBuildInternalName);
351 
352 
353     /* Setup the correct prefixes, counts, and pointers */
354 
355     if (Info->FullyQualified)
356     {
357         InternalName[0] = AML_ROOT_PREFIX;
358 
359         if (NumSegments <= 1)
360         {
361             Result = &InternalName[1];
362         }
363         else if (NumSegments == 2)
364         {
365             InternalName[1] = AML_DUAL_NAME_PREFIX;
366             Result = &InternalName[2];
367         }
368         else
369         {
370             InternalName[1] = AML_MULTI_NAME_PREFIX_OP;
371             InternalName[2] = (char) NumSegments;
372             Result = &InternalName[3];
373         }
374     }
375     else
376     {
377         /*
378          * Not fully qualified.
379          * Handle Carats first, then append the name segments
380          */
381         i = 0;
382         if (Info->NumCarats)
383         {
384             for (i = 0; i < Info->NumCarats; i++)
385             {
386                 InternalName[i] = AML_PARENT_PREFIX;
387             }
388         }
389 
390         if (NumSegments <= 1)
391         {
392             Result = &InternalName[i];
393         }
394         else if (NumSegments == 2)
395         {
396             InternalName[i] = AML_DUAL_NAME_PREFIX;
397             Result = &InternalName[(ACPI_SIZE) i+1];
398         }
399         else
400         {
401             InternalName[i] = AML_MULTI_NAME_PREFIX_OP;
402             InternalName[(ACPI_SIZE) i+1] = (char) NumSegments;
403             Result = &InternalName[(ACPI_SIZE) i+2];
404         }
405     }
406 
407     /* Build the name (minus path separators) */
408 
409     for (; NumSegments; NumSegments--)
410     {
411         for (i = 0; i < ACPI_NAME_SIZE; i++)
412         {
413             if (ACPI_IS_PATH_SEPARATOR (*ExternalName) ||
414                (*ExternalName == 0))
415             {
416                 /* Pad the segment with underscore(s) if segment is short */
417 
418                 Result[i] = '_';
419             }
420             else
421             {
422                 /* Convert the character to uppercase and save it */
423 
424                 Result[i] = (char) ACPI_TOUPPER ((int) *ExternalName);
425                 ExternalName++;
426             }
427         }
428 
429         /* Now we must have a path separator, or the pathname is bad */
430 
431         if (!ACPI_IS_PATH_SEPARATOR (*ExternalName) &&
432             (*ExternalName != 0))
433         {
434             return_ACPI_STATUS (AE_BAD_PATHNAME);
435         }
436 
437         /* Move on the next segment */
438 
439         ExternalName++;
440         Result += ACPI_NAME_SIZE;
441     }
442 
443     /* Terminate the string */
444 
445     *Result = 0;
446 
447     if (Info->FullyQualified)
448     {
449         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n",
450             InternalName, InternalName));
451     }
452     else
453     {
454         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
455             InternalName, InternalName));
456     }
457 
458     return_ACPI_STATUS (AE_OK);
459 }
460 
461 
462 /*******************************************************************************
463  *
464  * FUNCTION:    AcpiNsInternalizeName
465  *
466  * PARAMETERS:  *ExternalName           - External representation of name
467  *              **Converted Name        - Where to return the resulting
468  *                                        internal represention of the name
469  *
470  * RETURN:      Status
471  *
472  * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0")
473  *              to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
474  *
475  *******************************************************************************/
476 
477 ACPI_STATUS
478 AcpiNsInternalizeName (
479     const char              *ExternalName,
480     char                    **ConvertedName)
481 {
482     char                    *InternalName;
483     ACPI_NAMESTRING_INFO    Info;
484     ACPI_STATUS             Status;
485 
486 
487     ACPI_FUNCTION_TRACE (NsInternalizeName);
488 
489 
490     if ((!ExternalName)      ||
491         (*ExternalName == 0) ||
492         (!ConvertedName))
493     {
494         return_ACPI_STATUS (AE_BAD_PARAMETER);
495     }
496 
497     /* Get the length of the new internal name */
498 
499     Info.ExternalName = ExternalName;
500     AcpiNsGetInternalNameLength (&Info);
501 
502     /* We need a segment to store the internal  name */
503 
504     InternalName = ACPI_ALLOCATE_ZEROED (Info.Length);
505     if (!InternalName)
506     {
507         return_ACPI_STATUS (AE_NO_MEMORY);
508     }
509 
510     /* Build the name */
511 
512     Info.InternalName = InternalName;
513     Status = AcpiNsBuildInternalName (&Info);
514     if (ACPI_FAILURE (Status))
515     {
516         ACPI_FREE (InternalName);
517         return_ACPI_STATUS (Status);
518     }
519 
520     *ConvertedName = InternalName;
521     return_ACPI_STATUS (AE_OK);
522 }
523 
524 
525 /*******************************************************************************
526  *
527  * FUNCTION:    AcpiNsExternalizeName
528  *
529  * PARAMETERS:  InternalNameLength  - Lenth of the internal name below
530  *              InternalName        - Internal representation of name
531  *              ConvertedNameLength - Where the length is returned
532  *              ConvertedName       - Where the resulting external name
533  *                                    is returned
534  *
535  * RETURN:      Status
536  *
537  * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
538  *              to its external (printable) form (e.g. "\_PR_.CPU0")
539  *
540  ******************************************************************************/
541 
542 ACPI_STATUS
543 AcpiNsExternalizeName (
544     UINT32                  InternalNameLength,
545     const char              *InternalName,
546     UINT32                  *ConvertedNameLength,
547     char                    **ConvertedName)
548 {
549     UINT32                  NamesIndex = 0;
550     UINT32                  NumSegments = 0;
551     UINT32                  RequiredLength;
552     UINT32                  PrefixLength = 0;
553     UINT32                  i = 0;
554     UINT32                  j = 0;
555 
556 
557     ACPI_FUNCTION_TRACE (NsExternalizeName);
558 
559 
560     if (!InternalNameLength     ||
561         !InternalName           ||
562         !ConvertedName)
563     {
564         return_ACPI_STATUS (AE_BAD_PARAMETER);
565     }
566 
567     /* Check for a prefix (one '\' | one or more '^') */
568 
569     switch (InternalName[0])
570     {
571     case AML_ROOT_PREFIX:
572 
573         PrefixLength = 1;
574         break;
575 
576     case AML_PARENT_PREFIX:
577 
578         for (i = 0; i < InternalNameLength; i++)
579         {
580             if (ACPI_IS_PARENT_PREFIX (InternalName[i]))
581             {
582                 PrefixLength = i + 1;
583             }
584             else
585             {
586                 break;
587             }
588         }
589 
590         if (i == InternalNameLength)
591         {
592             PrefixLength = i;
593         }
594 
595         break;
596 
597     default:
598 
599         break;
600     }
601 
602     /*
603      * Check for object names. Note that there could be 0-255 of these
604      * 4-byte elements.
605      */
606     if (PrefixLength < InternalNameLength)
607     {
608         switch (InternalName[PrefixLength])
609         {
610         case AML_MULTI_NAME_PREFIX_OP:
611 
612             /* <count> 4-byte names */
613 
614             NamesIndex = PrefixLength + 2;
615             NumSegments = (UINT8)
616                 InternalName[(ACPI_SIZE) PrefixLength + 1];
617             break;
618 
619         case AML_DUAL_NAME_PREFIX:
620 
621             /* Two 4-byte names */
622 
623             NamesIndex = PrefixLength + 1;
624             NumSegments = 2;
625             break;
626 
627         case 0:
628 
629             /* NullName */
630 
631             NamesIndex = 0;
632             NumSegments = 0;
633             break;
634 
635         default:
636 
637             /* one 4-byte name */
638 
639             NamesIndex = PrefixLength;
640             NumSegments = 1;
641             break;
642         }
643     }
644 
645     /*
646      * Calculate the length of ConvertedName, which equals the length
647      * of the prefix, length of all object names, length of any required
648      * punctuation ('.') between object names, plus the NULL terminator.
649      */
650     RequiredLength = PrefixLength + (4 * NumSegments) +
651                         ((NumSegments > 0) ? (NumSegments - 1) : 0) + 1;
652 
653     /*
654      * Check to see if we're still in bounds. If not, there's a problem
655      * with InternalName (invalid format).
656      */
657     if (RequiredLength > InternalNameLength)
658     {
659         ACPI_ERROR ((AE_INFO, "Invalid internal name"));
660         return_ACPI_STATUS (AE_BAD_PATHNAME);
661     }
662 
663     /* Build the ConvertedName */
664 
665     *ConvertedName = ACPI_ALLOCATE_ZEROED (RequiredLength);
666     if (!(*ConvertedName))
667     {
668         return_ACPI_STATUS (AE_NO_MEMORY);
669     }
670 
671     j = 0;
672 
673     for (i = 0; i < PrefixLength; i++)
674     {
675         (*ConvertedName)[j++] = InternalName[i];
676     }
677 
678     if (NumSegments > 0)
679     {
680         for (i = 0; i < NumSegments; i++)
681         {
682             if (i > 0)
683             {
684                 (*ConvertedName)[j++] = '.';
685             }
686 
687             /* Copy and validate the 4-char name segment */
688 
689             ACPI_MOVE_NAME (&(*ConvertedName)[j], &InternalName[NamesIndex]);
690             AcpiUtRepairName (&(*ConvertedName)[j]);
691 
692             j += ACPI_NAME_SIZE;
693             NamesIndex += ACPI_NAME_SIZE;
694         }
695     }
696 
697     if (ConvertedNameLength)
698     {
699         *ConvertedNameLength = (UINT32) RequiredLength;
700     }
701 
702     return_ACPI_STATUS (AE_OK);
703 }
704 
705 
706 /*******************************************************************************
707  *
708  * FUNCTION:    AcpiNsValidateHandle
709  *
710  * PARAMETERS:  Handle          - Handle to be validated and typecast to a
711  *                                namespace node.
712  *
713  * RETURN:      A pointer to a namespace node
714  *
715  * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special
716  *              cases for the root node.
717  *
718  * NOTE: Real integer handles would allow for more verification
719  *       and keep all pointers within this subsystem - however this introduces
720  *       more overhead and has not been necessary to this point. Drivers
721  *       holding handles are typically notified before a node becomes invalid
722  *       due to a table unload.
723  *
724  ******************************************************************************/
725 
726 ACPI_NAMESPACE_NODE *
727 AcpiNsValidateHandle (
728     ACPI_HANDLE             Handle)
729 {
730 
731     ACPI_FUNCTION_ENTRY ();
732 
733 
734     /* Parameter validation */
735 
736     if ((!Handle) || (Handle == ACPI_ROOT_OBJECT))
737     {
738         return (AcpiGbl_RootNode);
739     }
740 
741     /* We can at least attempt to verify the handle */
742 
743     if (ACPI_GET_DESCRIPTOR_TYPE (Handle) != ACPI_DESC_TYPE_NAMED)
744     {
745         return (NULL);
746     }
747 
748     return (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle));
749 }
750 
751 
752 /*******************************************************************************
753  *
754  * FUNCTION:    AcpiNsTerminate
755  *
756  * PARAMETERS:  none
757  *
758  * RETURN:      none
759  *
760  * DESCRIPTION: free memory allocated for namespace and ACPI table storage.
761  *
762  ******************************************************************************/
763 
764 void
765 AcpiNsTerminate (
766     void)
767 {
768     ACPI_OPERAND_OBJECT     *ObjDesc;
769 
770 
771     ACPI_FUNCTION_TRACE (NsTerminate);
772 
773 
774     /*
775      * 1) Free the entire namespace -- all nodes and objects
776      *
777      * Delete all object descriptors attached to namepsace nodes
778      */
779     AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
780 
781     /* Detach any objects attached to the root */
782 
783     ObjDesc = AcpiNsGetAttachedObject (AcpiGbl_RootNode);
784     if (ObjDesc)
785     {
786         AcpiNsDetachObject (AcpiGbl_RootNode);
787     }
788 
789     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n"));
790     return_VOID;
791 }
792 
793 
794 /*******************************************************************************
795  *
796  * FUNCTION:    AcpiNsOpensScope
797  *
798  * PARAMETERS:  Type        - A valid namespace type
799  *
800  * RETURN:      NEWSCOPE if the passed type "opens a name scope" according
801  *              to the ACPI specification, else 0
802  *
803  ******************************************************************************/
804 
805 UINT32
806 AcpiNsOpensScope (
807     ACPI_OBJECT_TYPE        Type)
808 {
809     ACPI_FUNCTION_ENTRY ();
810 
811 
812     if (Type > ACPI_TYPE_LOCAL_MAX)
813     {
814         /* type code out of range  */
815 
816         ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
817         return (ACPI_NS_NORMAL);
818     }
819 
820     return (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE);
821 }
822 
823 
824 /*******************************************************************************
825  *
826  * FUNCTION:    AcpiNsGetNode
827  *
828  * PARAMETERS:  *Pathname   - Name to be found, in external (ASL) format. The
829  *                            \ (backslash) and ^ (carat) prefixes, and the
830  *                            . (period) to separate segments are supported.
831  *              PrefixNode   - Root of subtree to be searched, or NS_ALL for the
832  *                            root of the name space. If Name is fully
833  *                            qualified (first INT8 is '\'), the passed value
834  *                            of Scope will not be accessed.
835  *              Flags       - Used to indicate whether to perform upsearch or
836  *                            not.
837  *              ReturnNode  - Where the Node is returned
838  *
839  * DESCRIPTION: Look up a name relative to a given scope and return the
840  *              corresponding Node. NOTE: Scope can be null.
841  *
842  * MUTEX:       Locks namespace
843  *
844  ******************************************************************************/
845 
846 ACPI_STATUS
847 AcpiNsGetNode (
848     ACPI_NAMESPACE_NODE     *PrefixNode,
849     const char              *Pathname,
850     UINT32                  Flags,
851     ACPI_NAMESPACE_NODE     **ReturnNode)
852 {
853     ACPI_GENERIC_STATE      ScopeInfo;
854     ACPI_STATUS             Status;
855     char                    *InternalPath;
856 
857 
858     ACPI_FUNCTION_TRACE_PTR (NsGetNode, ACPI_CAST_PTR (char, Pathname));
859 
860 
861     /* Simplest case is a null pathname */
862 
863     if (!Pathname)
864     {
865         *ReturnNode = PrefixNode;
866         if (!PrefixNode)
867         {
868             *ReturnNode = AcpiGbl_RootNode;
869         }
870         return_ACPI_STATUS (AE_OK);
871     }
872 
873     /* Quick check for a reference to the root */
874 
875     if (ACPI_IS_ROOT_PREFIX (Pathname[0]) && (!Pathname[1]))
876     {
877         *ReturnNode = AcpiGbl_RootNode;
878         return_ACPI_STATUS (AE_OK);
879     }
880 
881     /* Convert path to internal representation */
882 
883     Status = AcpiNsInternalizeName (Pathname, &InternalPath);
884     if (ACPI_FAILURE (Status))
885     {
886         return_ACPI_STATUS (Status);
887     }
888 
889     /* Must lock namespace during lookup */
890 
891     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
892     if (ACPI_FAILURE (Status))
893     {
894         goto Cleanup;
895     }
896 
897     /* Setup lookup scope (search starting point) */
898 
899     ScopeInfo.Scope.Node = PrefixNode;
900 
901     /* Lookup the name in the namespace */
902 
903     Status = AcpiNsLookup (&ScopeInfo, InternalPath, ACPI_TYPE_ANY,
904                 ACPI_IMODE_EXECUTE, (Flags | ACPI_NS_DONT_OPEN_SCOPE),
905                 NULL, ReturnNode);
906     if (ACPI_FAILURE (Status))
907     {
908         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s, %s\n",
909                 Pathname, AcpiFormatException (Status)));
910     }
911 
912     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
913 
914 Cleanup:
915     ACPI_FREE (InternalPath);
916     return_ACPI_STATUS (Status);
917 }
918