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