xref: /freebsd/sys/contrib/dev/acpica/components/namespace/nsnames.c (revision a159c266a93c3c4f229864954c5f963acd8f60f2)
1*a159c266SJung-uk Kim /*******************************************************************************
2*a159c266SJung-uk Kim  *
3*a159c266SJung-uk Kim  * Module Name: nsnames - Name manipulation and search
4*a159c266SJung-uk Kim  *
5*a159c266SJung-uk Kim  ******************************************************************************/
6*a159c266SJung-uk Kim 
7*a159c266SJung-uk Kim /*
8*a159c266SJung-uk Kim  * Copyright (C) 2000 - 2012, Intel Corp.
9*a159c266SJung-uk Kim  * All rights reserved.
10*a159c266SJung-uk Kim  *
11*a159c266SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
12*a159c266SJung-uk Kim  * modification, are permitted provided that the following conditions
13*a159c266SJung-uk Kim  * are met:
14*a159c266SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
15*a159c266SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
16*a159c266SJung-uk Kim  *    without modification.
17*a159c266SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18*a159c266SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
19*a159c266SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
20*a159c266SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
21*a159c266SJung-uk Kim  *    binary redistribution.
22*a159c266SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
23*a159c266SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
24*a159c266SJung-uk Kim  *    from this software without specific prior written permission.
25*a159c266SJung-uk Kim  *
26*a159c266SJung-uk Kim  * Alternatively, this software may be distributed under the terms of the
27*a159c266SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
28*a159c266SJung-uk Kim  * Software Foundation.
29*a159c266SJung-uk Kim  *
30*a159c266SJung-uk Kim  * NO WARRANTY
31*a159c266SJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*a159c266SJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*a159c266SJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34*a159c266SJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35*a159c266SJung-uk Kim  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*a159c266SJung-uk Kim  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*a159c266SJung-uk Kim  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*a159c266SJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39*a159c266SJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40*a159c266SJung-uk Kim  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*a159c266SJung-uk Kim  * POSSIBILITY OF SUCH DAMAGES.
42*a159c266SJung-uk Kim  */
43*a159c266SJung-uk Kim 
44*a159c266SJung-uk Kim #define __NSNAMES_C__
45*a159c266SJung-uk Kim 
46*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h>
47*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h>
48*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h>
49*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acnamesp.h>
50*a159c266SJung-uk Kim 
51*a159c266SJung-uk Kim 
52*a159c266SJung-uk Kim #define _COMPONENT          ACPI_NAMESPACE
53*a159c266SJung-uk Kim         ACPI_MODULE_NAME    ("nsnames")
54*a159c266SJung-uk Kim 
55*a159c266SJung-uk Kim 
56*a159c266SJung-uk Kim /*******************************************************************************
57*a159c266SJung-uk Kim  *
58*a159c266SJung-uk Kim  * FUNCTION:    AcpiNsBuildExternalPath
59*a159c266SJung-uk Kim  *
60*a159c266SJung-uk Kim  * PARAMETERS:  Node            - NS node whose pathname is needed
61*a159c266SJung-uk Kim  *              Size            - Size of the pathname
62*a159c266SJung-uk Kim  *              *NameBuffer     - Where to return the pathname
63*a159c266SJung-uk Kim  *
64*a159c266SJung-uk Kim  * RETURN:      Status
65*a159c266SJung-uk Kim  *              Places the pathname into the NameBuffer, in external format
66*a159c266SJung-uk Kim  *              (name segments separated by path separators)
67*a159c266SJung-uk Kim  *
68*a159c266SJung-uk Kim  * DESCRIPTION: Generate a full pathaname
69*a159c266SJung-uk Kim  *
70*a159c266SJung-uk Kim  ******************************************************************************/
71*a159c266SJung-uk Kim 
72*a159c266SJung-uk Kim ACPI_STATUS
73*a159c266SJung-uk Kim AcpiNsBuildExternalPath (
74*a159c266SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node,
75*a159c266SJung-uk Kim     ACPI_SIZE               Size,
76*a159c266SJung-uk Kim     char                    *NameBuffer)
77*a159c266SJung-uk Kim {
78*a159c266SJung-uk Kim     ACPI_SIZE               Index;
79*a159c266SJung-uk Kim     ACPI_NAMESPACE_NODE     *ParentNode;
80*a159c266SJung-uk Kim 
81*a159c266SJung-uk Kim 
82*a159c266SJung-uk Kim     ACPI_FUNCTION_ENTRY ();
83*a159c266SJung-uk Kim 
84*a159c266SJung-uk Kim 
85*a159c266SJung-uk Kim     /* Special case for root */
86*a159c266SJung-uk Kim 
87*a159c266SJung-uk Kim     Index = Size - 1;
88*a159c266SJung-uk Kim     if (Index < ACPI_NAME_SIZE)
89*a159c266SJung-uk Kim     {
90*a159c266SJung-uk Kim         NameBuffer[0] = AML_ROOT_PREFIX;
91*a159c266SJung-uk Kim         NameBuffer[1] = 0;
92*a159c266SJung-uk Kim         return (AE_OK);
93*a159c266SJung-uk Kim     }
94*a159c266SJung-uk Kim 
95*a159c266SJung-uk Kim     /* Store terminator byte, then build name backwards */
96*a159c266SJung-uk Kim 
97*a159c266SJung-uk Kim     ParentNode = Node;
98*a159c266SJung-uk Kim     NameBuffer[Index] = 0;
99*a159c266SJung-uk Kim 
100*a159c266SJung-uk Kim     while ((Index > ACPI_NAME_SIZE) && (ParentNode != AcpiGbl_RootNode))
101*a159c266SJung-uk Kim     {
102*a159c266SJung-uk Kim         Index -= ACPI_NAME_SIZE;
103*a159c266SJung-uk Kim 
104*a159c266SJung-uk Kim         /* Put the name into the buffer */
105*a159c266SJung-uk Kim 
106*a159c266SJung-uk Kim         ACPI_MOVE_32_TO_32 ((NameBuffer + Index), &ParentNode->Name);
107*a159c266SJung-uk Kim         ParentNode = ParentNode->Parent;
108*a159c266SJung-uk Kim 
109*a159c266SJung-uk Kim         /* Prefix name with the path separator */
110*a159c266SJung-uk Kim 
111*a159c266SJung-uk Kim         Index--;
112*a159c266SJung-uk Kim         NameBuffer[Index] = ACPI_PATH_SEPARATOR;
113*a159c266SJung-uk Kim     }
114*a159c266SJung-uk Kim 
115*a159c266SJung-uk Kim     /* Overwrite final separator with the root prefix character */
116*a159c266SJung-uk Kim 
117*a159c266SJung-uk Kim     NameBuffer[Index] = AML_ROOT_PREFIX;
118*a159c266SJung-uk Kim 
119*a159c266SJung-uk Kim     if (Index != 0)
120*a159c266SJung-uk Kim     {
121*a159c266SJung-uk Kim         ACPI_ERROR ((AE_INFO,
122*a159c266SJung-uk Kim             "Could not construct external pathname; index=%u, size=%u, Path=%s",
123*a159c266SJung-uk Kim             (UINT32) Index, (UINT32) Size, &NameBuffer[Size]));
124*a159c266SJung-uk Kim 
125*a159c266SJung-uk Kim         return (AE_BAD_PARAMETER);
126*a159c266SJung-uk Kim     }
127*a159c266SJung-uk Kim 
128*a159c266SJung-uk Kim     return (AE_OK);
129*a159c266SJung-uk Kim }
130*a159c266SJung-uk Kim 
131*a159c266SJung-uk Kim 
132*a159c266SJung-uk Kim /*******************************************************************************
133*a159c266SJung-uk Kim  *
134*a159c266SJung-uk Kim  * FUNCTION:    AcpiNsGetExternalPathname
135*a159c266SJung-uk Kim  *
136*a159c266SJung-uk Kim  * PARAMETERS:  Node            - Namespace node whose pathname is needed
137*a159c266SJung-uk Kim  *
138*a159c266SJung-uk Kim  * RETURN:      Pointer to storage containing the fully qualified name of
139*a159c266SJung-uk Kim  *              the node, In external format (name segments separated by path
140*a159c266SJung-uk Kim  *              separators.)
141*a159c266SJung-uk Kim  *
142*a159c266SJung-uk Kim  * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually
143*a159c266SJung-uk Kim  *              for error and debug statements.
144*a159c266SJung-uk Kim  *
145*a159c266SJung-uk Kim  ******************************************************************************/
146*a159c266SJung-uk Kim 
147*a159c266SJung-uk Kim char *
148*a159c266SJung-uk Kim AcpiNsGetExternalPathname (
149*a159c266SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node)
150*a159c266SJung-uk Kim {
151*a159c266SJung-uk Kim     ACPI_STATUS             Status;
152*a159c266SJung-uk Kim     char                    *NameBuffer;
153*a159c266SJung-uk Kim     ACPI_SIZE               Size;
154*a159c266SJung-uk Kim 
155*a159c266SJung-uk Kim 
156*a159c266SJung-uk Kim     ACPI_FUNCTION_TRACE_PTR (NsGetExternalPathname, Node);
157*a159c266SJung-uk Kim 
158*a159c266SJung-uk Kim 
159*a159c266SJung-uk Kim     /* Calculate required buffer size based on depth below root */
160*a159c266SJung-uk Kim 
161*a159c266SJung-uk Kim     Size = AcpiNsGetPathnameLength (Node);
162*a159c266SJung-uk Kim     if (!Size)
163*a159c266SJung-uk Kim     {
164*a159c266SJung-uk Kim         return_PTR (NULL);
165*a159c266SJung-uk Kim     }
166*a159c266SJung-uk Kim 
167*a159c266SJung-uk Kim     /* Allocate a buffer to be returned to caller */
168*a159c266SJung-uk Kim 
169*a159c266SJung-uk Kim     NameBuffer = ACPI_ALLOCATE_ZEROED (Size);
170*a159c266SJung-uk Kim     if (!NameBuffer)
171*a159c266SJung-uk Kim     {
172*a159c266SJung-uk Kim         ACPI_ERROR ((AE_INFO, "Could not allocate %u bytes", (UINT32) Size));
173*a159c266SJung-uk Kim         return_PTR (NULL);
174*a159c266SJung-uk Kim     }
175*a159c266SJung-uk Kim 
176*a159c266SJung-uk Kim     /* Build the path in the allocated buffer */
177*a159c266SJung-uk Kim 
178*a159c266SJung-uk Kim     Status = AcpiNsBuildExternalPath (Node, Size, NameBuffer);
179*a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
180*a159c266SJung-uk Kim     {
181*a159c266SJung-uk Kim         ACPI_FREE (NameBuffer);
182*a159c266SJung-uk Kim         return_PTR (NULL);
183*a159c266SJung-uk Kim     }
184*a159c266SJung-uk Kim 
185*a159c266SJung-uk Kim     return_PTR (NameBuffer);
186*a159c266SJung-uk Kim }
187*a159c266SJung-uk Kim 
188*a159c266SJung-uk Kim 
189*a159c266SJung-uk Kim /*******************************************************************************
190*a159c266SJung-uk Kim  *
191*a159c266SJung-uk Kim  * FUNCTION:    AcpiNsGetPathnameLength
192*a159c266SJung-uk Kim  *
193*a159c266SJung-uk Kim  * PARAMETERS:  Node        - Namespace node
194*a159c266SJung-uk Kim  *
195*a159c266SJung-uk Kim  * RETURN:      Length of path, including prefix
196*a159c266SJung-uk Kim  *
197*a159c266SJung-uk Kim  * DESCRIPTION: Get the length of the pathname string for this node
198*a159c266SJung-uk Kim  *
199*a159c266SJung-uk Kim  ******************************************************************************/
200*a159c266SJung-uk Kim 
201*a159c266SJung-uk Kim ACPI_SIZE
202*a159c266SJung-uk Kim AcpiNsGetPathnameLength (
203*a159c266SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node)
204*a159c266SJung-uk Kim {
205*a159c266SJung-uk Kim     ACPI_SIZE               Size;
206*a159c266SJung-uk Kim     ACPI_NAMESPACE_NODE     *NextNode;
207*a159c266SJung-uk Kim 
208*a159c266SJung-uk Kim 
209*a159c266SJung-uk Kim     ACPI_FUNCTION_ENTRY ();
210*a159c266SJung-uk Kim 
211*a159c266SJung-uk Kim 
212*a159c266SJung-uk Kim     /*
213*a159c266SJung-uk Kim      * Compute length of pathname as 5 * number of name segments.
214*a159c266SJung-uk Kim      * Go back up the parent tree to the root
215*a159c266SJung-uk Kim      */
216*a159c266SJung-uk Kim     Size = 0;
217*a159c266SJung-uk Kim     NextNode = Node;
218*a159c266SJung-uk Kim 
219*a159c266SJung-uk Kim     while (NextNode && (NextNode != AcpiGbl_RootNode))
220*a159c266SJung-uk Kim     {
221*a159c266SJung-uk Kim         if (ACPI_GET_DESCRIPTOR_TYPE (NextNode) != ACPI_DESC_TYPE_NAMED)
222*a159c266SJung-uk Kim         {
223*a159c266SJung-uk Kim             ACPI_ERROR ((AE_INFO,
224*a159c266SJung-uk Kim                 "Invalid Namespace Node (%p) while traversing namespace",
225*a159c266SJung-uk Kim                 NextNode));
226*a159c266SJung-uk Kim             return 0;
227*a159c266SJung-uk Kim         }
228*a159c266SJung-uk Kim         Size += ACPI_PATH_SEGMENT_LENGTH;
229*a159c266SJung-uk Kim         NextNode = NextNode->Parent;
230*a159c266SJung-uk Kim     }
231*a159c266SJung-uk Kim 
232*a159c266SJung-uk Kim     if (!Size)
233*a159c266SJung-uk Kim     {
234*a159c266SJung-uk Kim         Size = 1; /* Root node case */
235*a159c266SJung-uk Kim     }
236*a159c266SJung-uk Kim 
237*a159c266SJung-uk Kim     return (Size + 1);  /* +1 for null string terminator */
238*a159c266SJung-uk Kim }
239*a159c266SJung-uk Kim 
240*a159c266SJung-uk Kim 
241*a159c266SJung-uk Kim /*******************************************************************************
242*a159c266SJung-uk Kim  *
243*a159c266SJung-uk Kim  * FUNCTION:    AcpiNsHandleToPathname
244*a159c266SJung-uk Kim  *
245*a159c266SJung-uk Kim  * PARAMETERS:  TargetHandle            - Handle of named object whose name is
246*a159c266SJung-uk Kim  *                                        to be found
247*a159c266SJung-uk Kim  *              Buffer                  - Where the pathname is returned
248*a159c266SJung-uk Kim  *
249*a159c266SJung-uk Kim  * RETURN:      Status, Buffer is filled with pathname if status is AE_OK
250*a159c266SJung-uk Kim  *
251*a159c266SJung-uk Kim  * DESCRIPTION: Build and return a full namespace pathname
252*a159c266SJung-uk Kim  *
253*a159c266SJung-uk Kim  ******************************************************************************/
254*a159c266SJung-uk Kim 
255*a159c266SJung-uk Kim ACPI_STATUS
256*a159c266SJung-uk Kim AcpiNsHandleToPathname (
257*a159c266SJung-uk Kim     ACPI_HANDLE             TargetHandle,
258*a159c266SJung-uk Kim     ACPI_BUFFER             *Buffer)
259*a159c266SJung-uk Kim {
260*a159c266SJung-uk Kim     ACPI_STATUS             Status;
261*a159c266SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node;
262*a159c266SJung-uk Kim     ACPI_SIZE               RequiredSize;
263*a159c266SJung-uk Kim 
264*a159c266SJung-uk Kim 
265*a159c266SJung-uk Kim     ACPI_FUNCTION_TRACE_PTR (NsHandleToPathname, TargetHandle);
266*a159c266SJung-uk Kim 
267*a159c266SJung-uk Kim 
268*a159c266SJung-uk Kim     Node = AcpiNsValidateHandle (TargetHandle);
269*a159c266SJung-uk Kim     if (!Node)
270*a159c266SJung-uk Kim     {
271*a159c266SJung-uk Kim         return_ACPI_STATUS (AE_BAD_PARAMETER);
272*a159c266SJung-uk Kim     }
273*a159c266SJung-uk Kim 
274*a159c266SJung-uk Kim     /* Determine size required for the caller buffer */
275*a159c266SJung-uk Kim 
276*a159c266SJung-uk Kim     RequiredSize = AcpiNsGetPathnameLength (Node);
277*a159c266SJung-uk Kim     if (!RequiredSize)
278*a159c266SJung-uk Kim     {
279*a159c266SJung-uk Kim         return_ACPI_STATUS (AE_BAD_PARAMETER);
280*a159c266SJung-uk Kim     }
281*a159c266SJung-uk Kim 
282*a159c266SJung-uk Kim     /* Validate/Allocate/Clear caller buffer */
283*a159c266SJung-uk Kim 
284*a159c266SJung-uk Kim     Status = AcpiUtInitializeBuffer (Buffer, RequiredSize);
285*a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
286*a159c266SJung-uk Kim     {
287*a159c266SJung-uk Kim         return_ACPI_STATUS (Status);
288*a159c266SJung-uk Kim     }
289*a159c266SJung-uk Kim 
290*a159c266SJung-uk Kim     /* Build the path in the caller buffer */
291*a159c266SJung-uk Kim 
292*a159c266SJung-uk Kim     Status = AcpiNsBuildExternalPath (Node, RequiredSize, Buffer->Pointer);
293*a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
294*a159c266SJung-uk Kim     {
295*a159c266SJung-uk Kim         return_ACPI_STATUS (Status);
296*a159c266SJung-uk Kim     }
297*a159c266SJung-uk Kim 
298*a159c266SJung-uk Kim     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s [%X]\n",
299*a159c266SJung-uk Kim         (char *) Buffer->Pointer, (UINT32) RequiredSize));
300*a159c266SJung-uk Kim     return_ACPI_STATUS (AE_OK);
301*a159c266SJung-uk Kim }
302*a159c266SJung-uk Kim 
303*a159c266SJung-uk Kim 
304