128c506b8Sjruoho /******************************************************************************
228c506b8Sjruoho *
328c506b8Sjruoho * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
428c506b8Sjruoho * parents and siblings and Scope manipulation
528c506b8Sjruoho *
628c506b8Sjruoho *****************************************************************************/
728c506b8Sjruoho
8124f4c82Sjruoho /*
9*046a2985Schristos * Copyright (C) 2000 - 2023, Intel Corp.
1028c506b8Sjruoho * All rights reserved.
1128c506b8Sjruoho *
12124f4c82Sjruoho * Redistribution and use in source and binary forms, with or without
13124f4c82Sjruoho * modification, are permitted provided that the following conditions
14124f4c82Sjruoho * are met:
15124f4c82Sjruoho * 1. Redistributions of source code must retain the above copyright
16124f4c82Sjruoho * notice, this list of conditions, and the following disclaimer,
17124f4c82Sjruoho * without modification.
18124f4c82Sjruoho * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19124f4c82Sjruoho * substantially similar to the "NO WARRANTY" disclaimer below
20124f4c82Sjruoho * ("Disclaimer") and any redistribution must be conditioned upon
21124f4c82Sjruoho * including a substantially similar Disclaimer requirement for further
22124f4c82Sjruoho * binary redistribution.
23124f4c82Sjruoho * 3. Neither the names of the above-listed copyright holders nor the names
24124f4c82Sjruoho * of any contributors may be used to endorse or promote products derived
25124f4c82Sjruoho * from this software without specific prior written permission.
2628c506b8Sjruoho *
27124f4c82Sjruoho * Alternatively, this software may be distributed under the terms of the
28124f4c82Sjruoho * GNU General Public License ("GPL") version 2 as published by the Free
29124f4c82Sjruoho * Software Foundation.
3028c506b8Sjruoho *
31124f4c82Sjruoho * NO WARRANTY
32124f4c82Sjruoho * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33124f4c82Sjruoho * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3446a330b4Schristos * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
35124f4c82Sjruoho * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36124f4c82Sjruoho * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37124f4c82Sjruoho * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38124f4c82Sjruoho * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39124f4c82Sjruoho * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40124f4c82Sjruoho * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41124f4c82Sjruoho * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42124f4c82Sjruoho * POSSIBILITY OF SUCH DAMAGES.
43124f4c82Sjruoho */
4428c506b8Sjruoho
4528c506b8Sjruoho #include "acpi.h"
4628c506b8Sjruoho #include "accommon.h"
4728c506b8Sjruoho #include "acnamesp.h"
4828c506b8Sjruoho #include "amlcode.h"
4928c506b8Sjruoho
5028c506b8Sjruoho #define _COMPONENT ACPI_NAMESPACE
5128c506b8Sjruoho ACPI_MODULE_NAME ("nsutils")
5228c506b8Sjruoho
5328c506b8Sjruoho /* Local prototypes */
5428c506b8Sjruoho
5528c506b8Sjruoho #ifdef ACPI_OBSOLETE_FUNCTIONS
5628c506b8Sjruoho ACPI_NAME
5728c506b8Sjruoho AcpiNsFindParentName (
5828c506b8Sjruoho ACPI_NAMESPACE_NODE *NodeToSearch);
5928c506b8Sjruoho #endif
6028c506b8Sjruoho
6128c506b8Sjruoho
6228c506b8Sjruoho /*******************************************************************************
6328c506b8Sjruoho *
6428c506b8Sjruoho * FUNCTION: AcpiNsPrintNodePathname
6528c506b8Sjruoho *
6628c506b8Sjruoho * PARAMETERS: Node - Object
6728c506b8Sjruoho * Message - Prefix message
6828c506b8Sjruoho *
6928c506b8Sjruoho * DESCRIPTION: Print an object's full namespace pathname
7028c506b8Sjruoho * Manages allocation/freeing of a pathname buffer
7128c506b8Sjruoho *
7228c506b8Sjruoho ******************************************************************************/
7328c506b8Sjruoho
7428c506b8Sjruoho void
AcpiNsPrintNodePathname(ACPI_NAMESPACE_NODE * Node,const char * Message)7528c506b8Sjruoho AcpiNsPrintNodePathname (
7628c506b8Sjruoho ACPI_NAMESPACE_NODE *Node,
7728c506b8Sjruoho const char *Message)
7828c506b8Sjruoho {
7928c506b8Sjruoho ACPI_BUFFER Buffer;
8028c506b8Sjruoho ACPI_STATUS Status;
8128c506b8Sjruoho
8228c506b8Sjruoho
8328c506b8Sjruoho if (!Node)
8428c506b8Sjruoho {
8528c506b8Sjruoho AcpiOsPrintf ("[NULL NAME]");
8628c506b8Sjruoho return;
8728c506b8Sjruoho }
8828c506b8Sjruoho
8928c506b8Sjruoho /* Convert handle to full pathname and print it (with supplied message) */
9028c506b8Sjruoho
9128c506b8Sjruoho Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
9228c506b8Sjruoho
9371e38f1dSchristos Status = AcpiNsHandleToPathname (Node, &Buffer, TRUE);
9428c506b8Sjruoho if (ACPI_SUCCESS (Status))
9528c506b8Sjruoho {
9628c506b8Sjruoho if (Message)
9728c506b8Sjruoho {
9828c506b8Sjruoho AcpiOsPrintf ("%s ", Message);
9928c506b8Sjruoho }
10028c506b8Sjruoho
10189b8eb6cSchristos AcpiOsPrintf ("%s", (char *) Buffer.Pointer);
10228c506b8Sjruoho ACPI_FREE (Buffer.Pointer);
10328c506b8Sjruoho }
10428c506b8Sjruoho }
10528c506b8Sjruoho
10628c506b8Sjruoho
10728c506b8Sjruoho /*******************************************************************************
10828c506b8Sjruoho *
10928c506b8Sjruoho * FUNCTION: AcpiNsGetType
11028c506b8Sjruoho *
11128c506b8Sjruoho * PARAMETERS: Node - Parent Node to be examined
11228c506b8Sjruoho *
11328c506b8Sjruoho * RETURN: Type field from Node whose handle is passed
11428c506b8Sjruoho *
11528c506b8Sjruoho * DESCRIPTION: Return the type of a Namespace node
11628c506b8Sjruoho *
11728c506b8Sjruoho ******************************************************************************/
11828c506b8Sjruoho
11928c506b8Sjruoho ACPI_OBJECT_TYPE
AcpiNsGetType(ACPI_NAMESPACE_NODE * Node)12028c506b8Sjruoho AcpiNsGetType (
12128c506b8Sjruoho ACPI_NAMESPACE_NODE *Node)
12228c506b8Sjruoho {
12328c506b8Sjruoho ACPI_FUNCTION_TRACE (NsGetType);
12428c506b8Sjruoho
12528c506b8Sjruoho
12628c506b8Sjruoho if (!Node)
12728c506b8Sjruoho {
12828c506b8Sjruoho ACPI_WARNING ((AE_INFO, "Null Node parameter"));
129ff4a156dSchristos return_UINT8 (ACPI_TYPE_ANY);
13028c506b8Sjruoho }
13128c506b8Sjruoho
132ff4a156dSchristos return_UINT8 (Node->Type);
13328c506b8Sjruoho }
13428c506b8Sjruoho
13528c506b8Sjruoho
13628c506b8Sjruoho /*******************************************************************************
13728c506b8Sjruoho *
13828c506b8Sjruoho * FUNCTION: AcpiNsLocal
13928c506b8Sjruoho *
14028c506b8Sjruoho * PARAMETERS: Type - A namespace object type
14128c506b8Sjruoho *
14228c506b8Sjruoho * RETURN: LOCAL if names must be found locally in objects of the
14328c506b8Sjruoho * passed type, 0 if enclosing scopes should be searched
14428c506b8Sjruoho *
14528c506b8Sjruoho * DESCRIPTION: Returns scope rule for the given object type.
14628c506b8Sjruoho *
14728c506b8Sjruoho ******************************************************************************/
14828c506b8Sjruoho
14928c506b8Sjruoho UINT32
AcpiNsLocal(ACPI_OBJECT_TYPE Type)15028c506b8Sjruoho AcpiNsLocal (
15128c506b8Sjruoho ACPI_OBJECT_TYPE Type)
15228c506b8Sjruoho {
15328c506b8Sjruoho ACPI_FUNCTION_TRACE (NsLocal);
15428c506b8Sjruoho
15528c506b8Sjruoho
15628c506b8Sjruoho if (!AcpiUtValidObjectType (Type))
15728c506b8Sjruoho {
15828c506b8Sjruoho /* Type code out of range */
15928c506b8Sjruoho
16028c506b8Sjruoho ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
16128c506b8Sjruoho return_UINT32 (ACPI_NS_NORMAL);
16228c506b8Sjruoho }
16328c506b8Sjruoho
164ff4a156dSchristos return_UINT32 (AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL);
16528c506b8Sjruoho }
16628c506b8Sjruoho
16728c506b8Sjruoho
16828c506b8Sjruoho /*******************************************************************************
16928c506b8Sjruoho *
17028c506b8Sjruoho * FUNCTION: AcpiNsGetInternalNameLength
17128c506b8Sjruoho *
17228c506b8Sjruoho * PARAMETERS: Info - Info struct initialized with the
17328c506b8Sjruoho * external name pointer.
17428c506b8Sjruoho *
17528c506b8Sjruoho * RETURN: None
17628c506b8Sjruoho *
17728c506b8Sjruoho * DESCRIPTION: Calculate the length of the internal (AML) namestring
17828c506b8Sjruoho * corresponding to the external (ASL) namestring.
17928c506b8Sjruoho *
18028c506b8Sjruoho ******************************************************************************/
18128c506b8Sjruoho
18228c506b8Sjruoho void
AcpiNsGetInternalNameLength(ACPI_NAMESTRING_INFO * Info)18328c506b8Sjruoho AcpiNsGetInternalNameLength (
18428c506b8Sjruoho ACPI_NAMESTRING_INFO *Info)
18528c506b8Sjruoho {
18628c506b8Sjruoho const char *NextExternalChar;
18728c506b8Sjruoho UINT32 i;
18828c506b8Sjruoho
18928c506b8Sjruoho
19028c506b8Sjruoho ACPI_FUNCTION_ENTRY ();
19128c506b8Sjruoho
19228c506b8Sjruoho
19328c506b8Sjruoho NextExternalChar = Info->ExternalName;
19428c506b8Sjruoho Info->NumCarats = 0;
19528c506b8Sjruoho Info->NumSegments = 0;
19628c506b8Sjruoho Info->FullyQualified = FALSE;
19728c506b8Sjruoho
19828c506b8Sjruoho /*
19971e38f1dSchristos * For the internal name, the required length is 4 bytes per segment,
20071e38f1dSchristos * plus 1 each for RootPrefix, MultiNamePrefixOp, segment count,
20171e38f1dSchristos * trailing null (which is not really needed, but no there's harm in
20271e38f1dSchristos * putting it there)
20328c506b8Sjruoho *
20428c506b8Sjruoho * strlen() + 1 covers the first NameSeg, which has no path separator
20528c506b8Sjruoho */
206ff4a156dSchristos if (ACPI_IS_ROOT_PREFIX (*NextExternalChar))
20728c506b8Sjruoho {
20828c506b8Sjruoho Info->FullyQualified = TRUE;
20928c506b8Sjruoho NextExternalChar++;
21028c506b8Sjruoho
21128c506b8Sjruoho /* Skip redundant RootPrefix, like \\_SB.PCI0.SBRG.EC0 */
21228c506b8Sjruoho
213ff4a156dSchristos while (ACPI_IS_ROOT_PREFIX (*NextExternalChar))
21428c506b8Sjruoho {
21528c506b8Sjruoho NextExternalChar++;
21628c506b8Sjruoho }
21728c506b8Sjruoho }
21828c506b8Sjruoho else
21928c506b8Sjruoho {
22028c506b8Sjruoho /* Handle Carat prefixes */
22128c506b8Sjruoho
222ff4a156dSchristos while (ACPI_IS_PARENT_PREFIX (*NextExternalChar))
22328c506b8Sjruoho {
22428c506b8Sjruoho Info->NumCarats++;
22528c506b8Sjruoho NextExternalChar++;
22628c506b8Sjruoho }
22728c506b8Sjruoho }
22828c506b8Sjruoho
22928c506b8Sjruoho /*
23028c506b8Sjruoho * Determine the number of ACPI name "segments" by counting the number of
23128c506b8Sjruoho * path separators within the string. Start with one segment since the
23228c506b8Sjruoho * segment count is [(# separators) + 1], and zero separators is ok.
23328c506b8Sjruoho */
23428c506b8Sjruoho if (*NextExternalChar)
23528c506b8Sjruoho {
23628c506b8Sjruoho Info->NumSegments = 1;
23728c506b8Sjruoho for (i = 0; NextExternalChar[i]; i++)
23828c506b8Sjruoho {
239ff4a156dSchristos if (ACPI_IS_PATH_SEPARATOR (NextExternalChar[i]))
24028c506b8Sjruoho {
24128c506b8Sjruoho Info->NumSegments++;
24228c506b8Sjruoho }
24328c506b8Sjruoho }
24428c506b8Sjruoho }
24528c506b8Sjruoho
24694783addSchristos Info->Length = (ACPI_NAMESEG_SIZE * Info->NumSegments) +
24728c506b8Sjruoho 4 + Info->NumCarats;
24828c506b8Sjruoho
24928c506b8Sjruoho Info->NextExternalChar = NextExternalChar;
25028c506b8Sjruoho }
25128c506b8Sjruoho
25228c506b8Sjruoho
25328c506b8Sjruoho /*******************************************************************************
25428c506b8Sjruoho *
25528c506b8Sjruoho * FUNCTION: AcpiNsBuildInternalName
25628c506b8Sjruoho *
25728c506b8Sjruoho * PARAMETERS: Info - Info struct fully initialized
25828c506b8Sjruoho *
25928c506b8Sjruoho * RETURN: Status
26028c506b8Sjruoho *
26128c506b8Sjruoho * DESCRIPTION: Construct the internal (AML) namestring
26228c506b8Sjruoho * corresponding to the external (ASL) namestring.
26328c506b8Sjruoho *
26428c506b8Sjruoho ******************************************************************************/
26528c506b8Sjruoho
26628c506b8Sjruoho ACPI_STATUS
AcpiNsBuildInternalName(ACPI_NAMESTRING_INFO * Info)26728c506b8Sjruoho AcpiNsBuildInternalName (
26828c506b8Sjruoho ACPI_NAMESTRING_INFO *Info)
26928c506b8Sjruoho {
27028c506b8Sjruoho UINT32 NumSegments = Info->NumSegments;
27128c506b8Sjruoho char *InternalName = Info->InternalName;
27228c506b8Sjruoho const char *ExternalName = Info->NextExternalChar;
27328c506b8Sjruoho char *Result = NULL;
27428c506b8Sjruoho UINT32 i;
27528c506b8Sjruoho
27628c506b8Sjruoho
27728c506b8Sjruoho ACPI_FUNCTION_TRACE (NsBuildInternalName);
27828c506b8Sjruoho
27928c506b8Sjruoho
28028c506b8Sjruoho /* Setup the correct prefixes, counts, and pointers */
28128c506b8Sjruoho
28228c506b8Sjruoho if (Info->FullyQualified)
28328c506b8Sjruoho {
284ff4a156dSchristos InternalName[0] = AML_ROOT_PREFIX;
28528c506b8Sjruoho
28628c506b8Sjruoho if (NumSegments <= 1)
28728c506b8Sjruoho {
28828c506b8Sjruoho Result = &InternalName[1];
28928c506b8Sjruoho }
29028c506b8Sjruoho else if (NumSegments == 2)
29128c506b8Sjruoho {
29228c506b8Sjruoho InternalName[1] = AML_DUAL_NAME_PREFIX;
29328c506b8Sjruoho Result = &InternalName[2];
29428c506b8Sjruoho }
29528c506b8Sjruoho else
29628c506b8Sjruoho {
297835858a6Schristos InternalName[1] = AML_MULTI_NAME_PREFIX;
29828c506b8Sjruoho InternalName[2] = (char) NumSegments;
29928c506b8Sjruoho Result = &InternalName[3];
30028c506b8Sjruoho }
30128c506b8Sjruoho }
30228c506b8Sjruoho else
30328c506b8Sjruoho {
30428c506b8Sjruoho /*
30528c506b8Sjruoho * Not fully qualified.
30628c506b8Sjruoho * Handle Carats first, then append the name segments
30728c506b8Sjruoho */
30828c506b8Sjruoho i = 0;
30928c506b8Sjruoho if (Info->NumCarats)
31028c506b8Sjruoho {
31128c506b8Sjruoho for (i = 0; i < Info->NumCarats; i++)
31228c506b8Sjruoho {
313ff4a156dSchristos InternalName[i] = AML_PARENT_PREFIX;
31428c506b8Sjruoho }
31528c506b8Sjruoho }
31628c506b8Sjruoho
31728c506b8Sjruoho if (NumSegments <= 1)
31828c506b8Sjruoho {
31928c506b8Sjruoho Result = &InternalName[i];
32028c506b8Sjruoho }
32128c506b8Sjruoho else if (NumSegments == 2)
32228c506b8Sjruoho {
32328c506b8Sjruoho InternalName[i] = AML_DUAL_NAME_PREFIX;
32428c506b8Sjruoho Result = &InternalName[(ACPI_SIZE) i+1];
32528c506b8Sjruoho }
32628c506b8Sjruoho else
32728c506b8Sjruoho {
328835858a6Schristos InternalName[i] = AML_MULTI_NAME_PREFIX;
32928c506b8Sjruoho InternalName[(ACPI_SIZE) i+1] = (char) NumSegments;
33028c506b8Sjruoho Result = &InternalName[(ACPI_SIZE) i+2];
33128c506b8Sjruoho }
33228c506b8Sjruoho }
33328c506b8Sjruoho
33428c506b8Sjruoho /* Build the name (minus path separators) */
33528c506b8Sjruoho
33628c506b8Sjruoho for (; NumSegments; NumSegments--)
33728c506b8Sjruoho {
33894783addSchristos for (i = 0; i < ACPI_NAMESEG_SIZE; i++)
33928c506b8Sjruoho {
340ff4a156dSchristos if (ACPI_IS_PATH_SEPARATOR (*ExternalName) ||
34128c506b8Sjruoho (*ExternalName == 0))
34228c506b8Sjruoho {
34328c506b8Sjruoho /* Pad the segment with underscore(s) if segment is short */
34428c506b8Sjruoho
34528c506b8Sjruoho Result[i] = '_';
34628c506b8Sjruoho }
34728c506b8Sjruoho else
34828c506b8Sjruoho {
34928c506b8Sjruoho /* Convert the character to uppercase and save it */
35028c506b8Sjruoho
351c72da027Schristos Result[i] = (char) toupper ((int) *ExternalName);
35228c506b8Sjruoho ExternalName++;
35328c506b8Sjruoho }
35428c506b8Sjruoho }
35528c506b8Sjruoho
35628c506b8Sjruoho /* Now we must have a path separator, or the pathname is bad */
35728c506b8Sjruoho
358ff4a156dSchristos if (!ACPI_IS_PATH_SEPARATOR (*ExternalName) &&
35928c506b8Sjruoho (*ExternalName != 0))
36028c506b8Sjruoho {
361ff4a156dSchristos return_ACPI_STATUS (AE_BAD_PATHNAME);
36228c506b8Sjruoho }
36328c506b8Sjruoho
36428c506b8Sjruoho /* Move on the next segment */
36528c506b8Sjruoho
36628c506b8Sjruoho ExternalName++;
36794783addSchristos Result += ACPI_NAMESEG_SIZE;
36828c506b8Sjruoho }
36928c506b8Sjruoho
37028c506b8Sjruoho /* Terminate the string */
37128c506b8Sjruoho
37228c506b8Sjruoho *Result = 0;
37328c506b8Sjruoho
37428c506b8Sjruoho if (Info->FullyQualified)
37528c506b8Sjruoho {
37628c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n",
37728c506b8Sjruoho InternalName, InternalName));
37828c506b8Sjruoho }
37928c506b8Sjruoho else
38028c506b8Sjruoho {
38128c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
38228c506b8Sjruoho InternalName, InternalName));
38328c506b8Sjruoho }
38428c506b8Sjruoho
38528c506b8Sjruoho return_ACPI_STATUS (AE_OK);
38628c506b8Sjruoho }
38728c506b8Sjruoho
38828c506b8Sjruoho
38928c506b8Sjruoho /*******************************************************************************
39028c506b8Sjruoho *
39128c506b8Sjruoho * FUNCTION: AcpiNsInternalizeName
39228c506b8Sjruoho *
39328c506b8Sjruoho * PARAMETERS: *ExternalName - External representation of name
39428c506b8Sjruoho * **Converted Name - Where to return the resulting
395*046a2985Schristos * internal representation of the name
39628c506b8Sjruoho *
39728c506b8Sjruoho * RETURN: Status
39828c506b8Sjruoho *
39928c506b8Sjruoho * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0")
40028c506b8Sjruoho * to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
40128c506b8Sjruoho *
40228c506b8Sjruoho *******************************************************************************/
40328c506b8Sjruoho
40428c506b8Sjruoho ACPI_STATUS
AcpiNsInternalizeName(const char * ExternalName,char ** ConvertedName)40528c506b8Sjruoho AcpiNsInternalizeName (
40628c506b8Sjruoho const char *ExternalName,
40728c506b8Sjruoho char **ConvertedName)
40828c506b8Sjruoho {
40928c506b8Sjruoho char *InternalName;
41028c506b8Sjruoho ACPI_NAMESTRING_INFO Info;
41128c506b8Sjruoho ACPI_STATUS Status;
41228c506b8Sjruoho
41328c506b8Sjruoho
41428c506b8Sjruoho ACPI_FUNCTION_TRACE (NsInternalizeName);
41528c506b8Sjruoho
41628c506b8Sjruoho
41728c506b8Sjruoho if ((!ExternalName) ||
41828c506b8Sjruoho (*ExternalName == 0) ||
41928c506b8Sjruoho (!ConvertedName))
42028c506b8Sjruoho {
42128c506b8Sjruoho return_ACPI_STATUS (AE_BAD_PARAMETER);
42228c506b8Sjruoho }
42328c506b8Sjruoho
42428c506b8Sjruoho /* Get the length of the new internal name */
42528c506b8Sjruoho
42628c506b8Sjruoho Info.ExternalName = ExternalName;
42728c506b8Sjruoho AcpiNsGetInternalNameLength (&Info);
42828c506b8Sjruoho
42928c506b8Sjruoho /* We need a segment to store the internal name */
43028c506b8Sjruoho
43128c506b8Sjruoho InternalName = ACPI_ALLOCATE_ZEROED (Info.Length);
43228c506b8Sjruoho if (!InternalName)
43328c506b8Sjruoho {
43428c506b8Sjruoho return_ACPI_STATUS (AE_NO_MEMORY);
43528c506b8Sjruoho }
43628c506b8Sjruoho
43728c506b8Sjruoho /* Build the name */
43828c506b8Sjruoho
43928c506b8Sjruoho Info.InternalName = InternalName;
44028c506b8Sjruoho Status = AcpiNsBuildInternalName (&Info);
44128c506b8Sjruoho if (ACPI_FAILURE (Status))
44228c506b8Sjruoho {
44328c506b8Sjruoho ACPI_FREE (InternalName);
44428c506b8Sjruoho return_ACPI_STATUS (Status);
44528c506b8Sjruoho }
44628c506b8Sjruoho
44728c506b8Sjruoho *ConvertedName = InternalName;
44828c506b8Sjruoho return_ACPI_STATUS (AE_OK);
44928c506b8Sjruoho }
45028c506b8Sjruoho
45128c506b8Sjruoho
45228c506b8Sjruoho /*******************************************************************************
45328c506b8Sjruoho *
45428c506b8Sjruoho * FUNCTION: AcpiNsExternalizeName
45528c506b8Sjruoho *
45694783addSchristos * PARAMETERS: InternalNameLength - Length of the internal name below
45728c506b8Sjruoho * InternalName - Internal representation of name
45828c506b8Sjruoho * ConvertedNameLength - Where the length is returned
45928c506b8Sjruoho * ConvertedName - Where the resulting external name
46028c506b8Sjruoho * is returned
46128c506b8Sjruoho *
46228c506b8Sjruoho * RETURN: Status
46328c506b8Sjruoho *
46428c506b8Sjruoho * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
46528c506b8Sjruoho * to its external (printable) form (e.g. "\_PR_.CPU0")
46628c506b8Sjruoho *
46728c506b8Sjruoho ******************************************************************************/
46828c506b8Sjruoho
46928c506b8Sjruoho ACPI_STATUS
AcpiNsExternalizeName(UINT32 InternalNameLength,const char * InternalName,UINT32 * ConvertedNameLength,char ** ConvertedName)47028c506b8Sjruoho AcpiNsExternalizeName (
47128c506b8Sjruoho UINT32 InternalNameLength,
47228c506b8Sjruoho const char *InternalName,
47328c506b8Sjruoho UINT32 *ConvertedNameLength,
47428c506b8Sjruoho char **ConvertedName)
47528c506b8Sjruoho {
47628c506b8Sjruoho UINT32 NamesIndex = 0;
47728c506b8Sjruoho UINT32 NumSegments = 0;
47828c506b8Sjruoho UINT32 RequiredLength;
47928c506b8Sjruoho UINT32 PrefixLength = 0;
48028c506b8Sjruoho UINT32 i = 0;
48128c506b8Sjruoho UINT32 j = 0;
48228c506b8Sjruoho
48328c506b8Sjruoho
48428c506b8Sjruoho ACPI_FUNCTION_TRACE (NsExternalizeName);
48528c506b8Sjruoho
48628c506b8Sjruoho
48728c506b8Sjruoho if (!InternalNameLength ||
48828c506b8Sjruoho !InternalName ||
48928c506b8Sjruoho !ConvertedName)
49028c506b8Sjruoho {
49128c506b8Sjruoho return_ACPI_STATUS (AE_BAD_PARAMETER);
49228c506b8Sjruoho }
49328c506b8Sjruoho
49428c506b8Sjruoho /* Check for a prefix (one '\' | one or more '^') */
49528c506b8Sjruoho
49628c506b8Sjruoho switch (InternalName[0])
49728c506b8Sjruoho {
498ff4a156dSchristos case AML_ROOT_PREFIX:
499ff4a156dSchristos
50028c506b8Sjruoho PrefixLength = 1;
50128c506b8Sjruoho break;
50228c506b8Sjruoho
503ff4a156dSchristos case AML_PARENT_PREFIX:
504ff4a156dSchristos
50528c506b8Sjruoho for (i = 0; i < InternalNameLength; i++)
50628c506b8Sjruoho {
507ff4a156dSchristos if (ACPI_IS_PARENT_PREFIX (InternalName[i]))
50828c506b8Sjruoho {
50928c506b8Sjruoho PrefixLength = i + 1;
51028c506b8Sjruoho }
51128c506b8Sjruoho else
51228c506b8Sjruoho {
51328c506b8Sjruoho break;
51428c506b8Sjruoho }
51528c506b8Sjruoho }
51628c506b8Sjruoho
51728c506b8Sjruoho if (i == InternalNameLength)
51828c506b8Sjruoho {
51928c506b8Sjruoho PrefixLength = i;
52028c506b8Sjruoho }
52128c506b8Sjruoho
52228c506b8Sjruoho break;
52328c506b8Sjruoho
52428c506b8Sjruoho default:
525ff4a156dSchristos
52628c506b8Sjruoho break;
52728c506b8Sjruoho }
52828c506b8Sjruoho
52928c506b8Sjruoho /*
53028c506b8Sjruoho * Check for object names. Note that there could be 0-255 of these
53128c506b8Sjruoho * 4-byte elements.
53228c506b8Sjruoho */
53328c506b8Sjruoho if (PrefixLength < InternalNameLength)
53428c506b8Sjruoho {
53528c506b8Sjruoho switch (InternalName[PrefixLength])
53628c506b8Sjruoho {
537835858a6Schristos case AML_MULTI_NAME_PREFIX:
53828c506b8Sjruoho
53928c506b8Sjruoho /* <count> 4-byte names */
54028c506b8Sjruoho
54128c506b8Sjruoho NamesIndex = PrefixLength + 2;
54228c506b8Sjruoho NumSegments = (UINT8)
54328c506b8Sjruoho InternalName[(ACPI_SIZE) PrefixLength + 1];
54428c506b8Sjruoho break;
54528c506b8Sjruoho
54628c506b8Sjruoho case AML_DUAL_NAME_PREFIX:
54728c506b8Sjruoho
54828c506b8Sjruoho /* Two 4-byte names */
54928c506b8Sjruoho
55028c506b8Sjruoho NamesIndex = PrefixLength + 1;
55128c506b8Sjruoho NumSegments = 2;
55228c506b8Sjruoho break;
55328c506b8Sjruoho
55428c506b8Sjruoho case 0:
55528c506b8Sjruoho
55628c506b8Sjruoho /* NullName */
55728c506b8Sjruoho
55828c506b8Sjruoho NamesIndex = 0;
55928c506b8Sjruoho NumSegments = 0;
56028c506b8Sjruoho break;
56128c506b8Sjruoho
56228c506b8Sjruoho default:
56328c506b8Sjruoho
56428c506b8Sjruoho /* one 4-byte name */
56528c506b8Sjruoho
56628c506b8Sjruoho NamesIndex = PrefixLength;
56728c506b8Sjruoho NumSegments = 1;
56828c506b8Sjruoho break;
56928c506b8Sjruoho }
57028c506b8Sjruoho }
57128c506b8Sjruoho
57228c506b8Sjruoho /*
57328c506b8Sjruoho * Calculate the length of ConvertedName, which equals the length
57428c506b8Sjruoho * of the prefix, length of all object names, length of any required
57528c506b8Sjruoho * punctuation ('.') between object names, plus the NULL terminator.
57628c506b8Sjruoho */
57728c506b8Sjruoho RequiredLength = PrefixLength + (4 * NumSegments) +
57828c506b8Sjruoho ((NumSegments > 0) ? (NumSegments - 1) : 0) + 1;
57928c506b8Sjruoho
58028c506b8Sjruoho /*
58128c506b8Sjruoho * Check to see if we're still in bounds. If not, there's a problem
58228c506b8Sjruoho * with InternalName (invalid format).
58328c506b8Sjruoho */
58428c506b8Sjruoho if (RequiredLength > InternalNameLength)
58528c506b8Sjruoho {
58628c506b8Sjruoho ACPI_ERROR ((AE_INFO, "Invalid internal name"));
58728c506b8Sjruoho return_ACPI_STATUS (AE_BAD_PATHNAME);
58828c506b8Sjruoho }
58928c506b8Sjruoho
59028c506b8Sjruoho /* Build the ConvertedName */
59128c506b8Sjruoho
59228c506b8Sjruoho *ConvertedName = ACPI_ALLOCATE_ZEROED (RequiredLength);
59328c506b8Sjruoho if (!(*ConvertedName))
59428c506b8Sjruoho {
59528c506b8Sjruoho return_ACPI_STATUS (AE_NO_MEMORY);
59628c506b8Sjruoho }
59728c506b8Sjruoho
59828c506b8Sjruoho j = 0;
59928c506b8Sjruoho
60028c506b8Sjruoho for (i = 0; i < PrefixLength; i++)
60128c506b8Sjruoho {
60228c506b8Sjruoho (*ConvertedName)[j++] = InternalName[i];
60328c506b8Sjruoho }
60428c506b8Sjruoho
60528c506b8Sjruoho if (NumSegments > 0)
60628c506b8Sjruoho {
60728c506b8Sjruoho for (i = 0; i < NumSegments; i++)
60828c506b8Sjruoho {
60928c506b8Sjruoho if (i > 0)
61028c506b8Sjruoho {
61128c506b8Sjruoho (*ConvertedName)[j++] = '.';
61228c506b8Sjruoho }
61328c506b8Sjruoho
614ff4a156dSchristos /* Copy and validate the 4-char name segment */
615ff4a156dSchristos
61694783addSchristos ACPI_COPY_NAMESEG (&(*ConvertedName)[j],
61771e38f1dSchristos &InternalName[NamesIndex]);
618ff4a156dSchristos AcpiUtRepairName (&(*ConvertedName)[j]);
619ff4a156dSchristos
62094783addSchristos j += ACPI_NAMESEG_SIZE;
62194783addSchristos NamesIndex += ACPI_NAMESEG_SIZE;
62228c506b8Sjruoho }
62328c506b8Sjruoho }
62428c506b8Sjruoho
62528c506b8Sjruoho if (ConvertedNameLength)
62628c506b8Sjruoho {
62728c506b8Sjruoho *ConvertedNameLength = (UINT32) RequiredLength;
62828c506b8Sjruoho }
62928c506b8Sjruoho
63028c506b8Sjruoho return_ACPI_STATUS (AE_OK);
63128c506b8Sjruoho }
63228c506b8Sjruoho
63328c506b8Sjruoho
63428c506b8Sjruoho /*******************************************************************************
63528c506b8Sjruoho *
63628c506b8Sjruoho * FUNCTION: AcpiNsValidateHandle
63728c506b8Sjruoho *
63828c506b8Sjruoho * PARAMETERS: Handle - Handle to be validated and typecast to a
63928c506b8Sjruoho * namespace node.
64028c506b8Sjruoho *
64128c506b8Sjruoho * RETURN: A pointer to a namespace node
64228c506b8Sjruoho *
64328c506b8Sjruoho * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special
64428c506b8Sjruoho * cases for the root node.
64528c506b8Sjruoho *
64628c506b8Sjruoho * NOTE: Real integer handles would allow for more verification
64728c506b8Sjruoho * and keep all pointers within this subsystem - however this introduces
64828c506b8Sjruoho * more overhead and has not been necessary to this point. Drivers
64928c506b8Sjruoho * holding handles are typically notified before a node becomes invalid
65028c506b8Sjruoho * due to a table unload.
65128c506b8Sjruoho *
65228c506b8Sjruoho ******************************************************************************/
65328c506b8Sjruoho
65428c506b8Sjruoho ACPI_NAMESPACE_NODE *
AcpiNsValidateHandle(ACPI_HANDLE Handle)65528c506b8Sjruoho AcpiNsValidateHandle (
65628c506b8Sjruoho ACPI_HANDLE Handle)
65728c506b8Sjruoho {
65828c506b8Sjruoho
65928c506b8Sjruoho ACPI_FUNCTION_ENTRY ();
66028c506b8Sjruoho
66128c506b8Sjruoho
66228c506b8Sjruoho /* Parameter validation */
66328c506b8Sjruoho
66428c506b8Sjruoho if ((!Handle) || (Handle == ACPI_ROOT_OBJECT))
66528c506b8Sjruoho {
66628c506b8Sjruoho return (AcpiGbl_RootNode);
66728c506b8Sjruoho }
66828c506b8Sjruoho
66928c506b8Sjruoho /* We can at least attempt to verify the handle */
67028c506b8Sjruoho
67128c506b8Sjruoho if (ACPI_GET_DESCRIPTOR_TYPE (Handle) != ACPI_DESC_TYPE_NAMED)
67228c506b8Sjruoho {
67328c506b8Sjruoho return (NULL);
67428c506b8Sjruoho }
67528c506b8Sjruoho
67628c506b8Sjruoho return (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle));
67728c506b8Sjruoho }
67828c506b8Sjruoho
67928c506b8Sjruoho
68028c506b8Sjruoho /*******************************************************************************
68128c506b8Sjruoho *
68228c506b8Sjruoho * FUNCTION: AcpiNsTerminate
68328c506b8Sjruoho *
68428c506b8Sjruoho * PARAMETERS: none
68528c506b8Sjruoho *
68628c506b8Sjruoho * RETURN: none
68728c506b8Sjruoho *
68828c506b8Sjruoho * DESCRIPTION: free memory allocated for namespace and ACPI table storage.
68928c506b8Sjruoho *
69028c506b8Sjruoho ******************************************************************************/
69128c506b8Sjruoho
69228c506b8Sjruoho void
AcpiNsTerminate(void)69328c506b8Sjruoho AcpiNsTerminate (
69428c506b8Sjruoho void)
69528c506b8Sjruoho {
696ff4a156dSchristos ACPI_STATUS Status;
69728c506b8Sjruoho
69828c506b8Sjruoho
69928c506b8Sjruoho ACPI_FUNCTION_TRACE (NsTerminate);
70028c506b8Sjruoho
70128c506b8Sjruoho
70228c506b8Sjruoho /*
703ff4a156dSchristos * Free the entire namespace -- all nodes and all objects
704ff4a156dSchristos * attached to the nodes
70528c506b8Sjruoho */
70628c506b8Sjruoho AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
70728c506b8Sjruoho
708ff4a156dSchristos /* Delete any objects attached to the root node */
70928c506b8Sjruoho
710ff4a156dSchristos Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
711ff4a156dSchristos if (ACPI_FAILURE (Status))
71228c506b8Sjruoho {
713ff4a156dSchristos return_VOID;
71428c506b8Sjruoho }
71528c506b8Sjruoho
716ff4a156dSchristos AcpiNsDeleteNode (AcpiGbl_RootNode);
717ff4a156dSchristos (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
718ff4a156dSchristos
71928c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n"));
72028c506b8Sjruoho return_VOID;
72128c506b8Sjruoho }
72228c506b8Sjruoho
72328c506b8Sjruoho
72428c506b8Sjruoho /*******************************************************************************
72528c506b8Sjruoho *
72628c506b8Sjruoho * FUNCTION: AcpiNsOpensScope
72728c506b8Sjruoho *
72828c506b8Sjruoho * PARAMETERS: Type - A valid namespace type
72928c506b8Sjruoho *
73028c506b8Sjruoho * RETURN: NEWSCOPE if the passed type "opens a name scope" according
73128c506b8Sjruoho * to the ACPI specification, else 0
73228c506b8Sjruoho *
73328c506b8Sjruoho ******************************************************************************/
73428c506b8Sjruoho
73528c506b8Sjruoho UINT32
AcpiNsOpensScope(ACPI_OBJECT_TYPE Type)73628c506b8Sjruoho AcpiNsOpensScope (
73728c506b8Sjruoho ACPI_OBJECT_TYPE Type)
73828c506b8Sjruoho {
739ff4a156dSchristos ACPI_FUNCTION_ENTRY ();
74028c506b8Sjruoho
74128c506b8Sjruoho
742ff4a156dSchristos if (Type > ACPI_TYPE_LOCAL_MAX)
74328c506b8Sjruoho {
74428c506b8Sjruoho /* type code out of range */
74528c506b8Sjruoho
74628c506b8Sjruoho ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
747ff4a156dSchristos return (ACPI_NS_NORMAL);
74828c506b8Sjruoho }
74928c506b8Sjruoho
750ff4a156dSchristos return (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE);
75128c506b8Sjruoho }
75228c506b8Sjruoho
75328c506b8Sjruoho
75428c506b8Sjruoho /*******************************************************************************
75528c506b8Sjruoho *
756d0e1da26Schristos * FUNCTION: AcpiNsGetNodeUnlocked
75728c506b8Sjruoho *
75828c506b8Sjruoho * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The
75928c506b8Sjruoho * \ (backslash) and ^ (carat) prefixes, and the
76028c506b8Sjruoho * . (period) to separate segments are supported.
76128c506b8Sjruoho * PrefixNode - Root of subtree to be searched, or NS_ALL for the
76228c506b8Sjruoho * root of the name space. If Name is fully
76328c506b8Sjruoho * qualified (first INT8 is '\'), the passed value
76428c506b8Sjruoho * of Scope will not be accessed.
76528c506b8Sjruoho * Flags - Used to indicate whether to perform upsearch or
76628c506b8Sjruoho * not.
76728c506b8Sjruoho * ReturnNode - Where the Node is returned
76828c506b8Sjruoho *
76928c506b8Sjruoho * DESCRIPTION: Look up a name relative to a given scope and return the
77028c506b8Sjruoho * corresponding Node. NOTE: Scope can be null.
77128c506b8Sjruoho *
772d0e1da26Schristos * MUTEX: Doesn't locks namespace
77328c506b8Sjruoho *
77428c506b8Sjruoho ******************************************************************************/
77528c506b8Sjruoho
77628c506b8Sjruoho ACPI_STATUS
AcpiNsGetNodeUnlocked(ACPI_NAMESPACE_NODE * PrefixNode,const char * Pathname,UINT32 Flags,ACPI_NAMESPACE_NODE ** ReturnNode)777d0e1da26Schristos AcpiNsGetNodeUnlocked (
77828c506b8Sjruoho ACPI_NAMESPACE_NODE *PrefixNode,
77928c506b8Sjruoho const char *Pathname,
78028c506b8Sjruoho UINT32 Flags,
78128c506b8Sjruoho ACPI_NAMESPACE_NODE **ReturnNode)
78228c506b8Sjruoho {
78328c506b8Sjruoho ACPI_GENERIC_STATE ScopeInfo;
78428c506b8Sjruoho ACPI_STATUS Status;
78528c506b8Sjruoho char *InternalPath;
78628c506b8Sjruoho
78728c506b8Sjruoho
788d0e1da26Schristos ACPI_FUNCTION_TRACE_PTR (NsGetNodeUnlocked, ACPI_CAST_PTR (char, Pathname));
78928c506b8Sjruoho
79028c506b8Sjruoho
791ff4a156dSchristos /* Simplest case is a null pathname */
792ff4a156dSchristos
79328c506b8Sjruoho if (!Pathname)
79428c506b8Sjruoho {
79528c506b8Sjruoho *ReturnNode = PrefixNode;
79628c506b8Sjruoho if (!PrefixNode)
79728c506b8Sjruoho {
79828c506b8Sjruoho *ReturnNode = AcpiGbl_RootNode;
79928c506b8Sjruoho }
80071e38f1dSchristos
80128c506b8Sjruoho return_ACPI_STATUS (AE_OK);
80228c506b8Sjruoho }
80328c506b8Sjruoho
804ff4a156dSchristos /* Quick check for a reference to the root */
805ff4a156dSchristos
806ff4a156dSchristos if (ACPI_IS_ROOT_PREFIX (Pathname[0]) && (!Pathname[1]))
807ff4a156dSchristos {
808ff4a156dSchristos *ReturnNode = AcpiGbl_RootNode;
809ff4a156dSchristos return_ACPI_STATUS (AE_OK);
810ff4a156dSchristos }
811ff4a156dSchristos
81228c506b8Sjruoho /* Convert path to internal representation */
81328c506b8Sjruoho
81428c506b8Sjruoho Status = AcpiNsInternalizeName (Pathname, &InternalPath);
81528c506b8Sjruoho if (ACPI_FAILURE (Status))
81628c506b8Sjruoho {
81728c506b8Sjruoho return_ACPI_STATUS (Status);
81828c506b8Sjruoho }
81928c506b8Sjruoho
82028c506b8Sjruoho /* Setup lookup scope (search starting point) */
82128c506b8Sjruoho
82228c506b8Sjruoho ScopeInfo.Scope.Node = PrefixNode;
82328c506b8Sjruoho
82428c506b8Sjruoho /* Lookup the name in the namespace */
82528c506b8Sjruoho
82628c506b8Sjruoho Status = AcpiNsLookup (&ScopeInfo, InternalPath, ACPI_TYPE_ANY,
82728c506b8Sjruoho ACPI_IMODE_EXECUTE, (Flags | ACPI_NS_DONT_OPEN_SCOPE),
82828c506b8Sjruoho NULL, ReturnNode);
82928c506b8Sjruoho if (ACPI_FAILURE (Status))
83028c506b8Sjruoho {
83128c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s, %s\n",
83228c506b8Sjruoho Pathname, AcpiFormatException (Status)));
83328c506b8Sjruoho }
83428c506b8Sjruoho
83528c506b8Sjruoho ACPI_FREE (InternalPath);
83628c506b8Sjruoho return_ACPI_STATUS (Status);
83728c506b8Sjruoho }
838d0e1da26Schristos
839d0e1da26Schristos
840d0e1da26Schristos /*******************************************************************************
841d0e1da26Schristos *
842d0e1da26Schristos * FUNCTION: AcpiNsGetNode
843d0e1da26Schristos *
844d0e1da26Schristos * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The
845d0e1da26Schristos * \ (backslash) and ^ (carat) prefixes, and the
846d0e1da26Schristos * . (period) to separate segments are supported.
847d0e1da26Schristos * PrefixNode - Root of subtree to be searched, or NS_ALL for the
848d0e1da26Schristos * root of the name space. If Name is fully
849d0e1da26Schristos * qualified (first INT8 is '\'), the passed value
850d0e1da26Schristos * of Scope will not be accessed.
851d0e1da26Schristos * Flags - Used to indicate whether to perform upsearch or
852d0e1da26Schristos * not.
853d0e1da26Schristos * ReturnNode - Where the Node is returned
854d0e1da26Schristos *
855d0e1da26Schristos * DESCRIPTION: Look up a name relative to a given scope and return the
856d0e1da26Schristos * corresponding Node. NOTE: Scope can be null.
857d0e1da26Schristos *
858d0e1da26Schristos * MUTEX: Locks namespace
859d0e1da26Schristos *
860d0e1da26Schristos ******************************************************************************/
861d0e1da26Schristos
862d0e1da26Schristos ACPI_STATUS
AcpiNsGetNode(ACPI_NAMESPACE_NODE * PrefixNode,const char * Pathname,UINT32 Flags,ACPI_NAMESPACE_NODE ** ReturnNode)863d0e1da26Schristos AcpiNsGetNode (
864d0e1da26Schristos ACPI_NAMESPACE_NODE *PrefixNode,
865d0e1da26Schristos const char *Pathname,
866d0e1da26Schristos UINT32 Flags,
867d0e1da26Schristos ACPI_NAMESPACE_NODE **ReturnNode)
868d0e1da26Schristos {
869d0e1da26Schristos ACPI_STATUS Status;
870d0e1da26Schristos
871d0e1da26Schristos
872d0e1da26Schristos ACPI_FUNCTION_TRACE_PTR (NsGetNode, ACPI_CAST_PTR (char, Pathname));
873d0e1da26Schristos
874d0e1da26Schristos
875d0e1da26Schristos Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
876d0e1da26Schristos if (ACPI_FAILURE (Status))
877d0e1da26Schristos {
878d0e1da26Schristos return_ACPI_STATUS (Status);
879d0e1da26Schristos }
880d0e1da26Schristos
881d0e1da26Schristos Status = AcpiNsGetNodeUnlocked (PrefixNode, Pathname,
882d0e1da26Schristos Flags, ReturnNode);
883d0e1da26Schristos
884d0e1da26Schristos (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
885d0e1da26Schristos return_ACPI_STATUS (Status);
886d0e1da26Schristos }
887