xref: /freebsd/sys/contrib/dev/acpica/common/dmextern.c (revision a7a3b383f2f828cd59ad5f58d318da892ad53868)
1f556842eSJung-uk Kim /******************************************************************************
2f556842eSJung-uk Kim  *
3f556842eSJung-uk Kim  * Module Name: dmextern - Support for External() ASL statements
4f556842eSJung-uk Kim  *
5f556842eSJung-uk Kim  *****************************************************************************/
6f556842eSJung-uk Kim 
7d244b227SJung-uk Kim /*
8ec3fc72fSJung-uk Kim  * Copyright (C) 2000 - 2012, Intel Corp.
9f556842eSJung-uk Kim  * All rights reserved.
10f556842eSJung-uk Kim  *
11d244b227SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
12d244b227SJung-uk Kim  * modification, are permitted provided that the following conditions
13d244b227SJung-uk Kim  * are met:
14d244b227SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
15d244b227SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
16d244b227SJung-uk Kim  *    without modification.
17d244b227SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18d244b227SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
19d244b227SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
20d244b227SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
21d244b227SJung-uk Kim  *    binary redistribution.
22d244b227SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
23d244b227SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
24d244b227SJung-uk Kim  *    from this software without specific prior written permission.
25f556842eSJung-uk Kim  *
26d244b227SJung-uk Kim  * Alternatively, this software may be distributed under the terms of the
27d244b227SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
28d244b227SJung-uk Kim  * Software Foundation.
29f556842eSJung-uk Kim  *
30d244b227SJung-uk Kim  * NO WARRANTY
31d244b227SJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32d244b227SJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33d244b227SJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34d244b227SJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35d244b227SJung-uk Kim  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36d244b227SJung-uk Kim  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37d244b227SJung-uk Kim  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38d244b227SJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39d244b227SJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40d244b227SJung-uk Kim  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41d244b227SJung-uk Kim  * POSSIBILITY OF SUCH DAMAGES.
42d244b227SJung-uk Kim  */
43f556842eSJung-uk Kim 
44f556842eSJung-uk Kim #include <contrib/dev/acpica/include/acpi.h>
45f556842eSJung-uk Kim #include <contrib/dev/acpica/include/accommon.h>
46f556842eSJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h>
47f556842eSJung-uk Kim #include <contrib/dev/acpica/include/acnamesp.h>
48f556842eSJung-uk Kim #include <contrib/dev/acpica/include/acdisasm.h>
49f556842eSJung-uk Kim 
50f556842eSJung-uk Kim 
51f556842eSJung-uk Kim /*
52f556842eSJung-uk Kim  * This module is used for application-level code (iASL disassembler) only.
53f556842eSJung-uk Kim  *
54f556842eSJung-uk Kim  * It contains the code to create and emit any necessary External() ASL
55f556842eSJung-uk Kim  * statements for the module being disassembled.
56f556842eSJung-uk Kim  */
57f556842eSJung-uk Kim #define _COMPONENT          ACPI_CA_DISASSEMBLER
58f556842eSJung-uk Kim         ACPI_MODULE_NAME    ("dmextern")
59f556842eSJung-uk Kim 
60f556842eSJung-uk Kim 
61f556842eSJung-uk Kim /*
62f556842eSJung-uk Kim  * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL
63f556842eSJung-uk Kim  * ObjectTypeKeyword. Used to generate typed external declarations
64f556842eSJung-uk Kim  */
65f556842eSJung-uk Kim static const char           *AcpiGbl_DmTypeNames[] =
66f556842eSJung-uk Kim {
67f556842eSJung-uk Kim     /* 00 */ "",                    /* Type ANY */
68f556842eSJung-uk Kim     /* 01 */ ", IntObj",
69f556842eSJung-uk Kim     /* 02 */ ", StrObj",
70f556842eSJung-uk Kim     /* 03 */ ", BuffObj",
71f556842eSJung-uk Kim     /* 04 */ ", PkgObj",
72f556842eSJung-uk Kim     /* 05 */ ", FieldUnitObj",
73f556842eSJung-uk Kim     /* 06 */ ", DeviceObj",
74f556842eSJung-uk Kim     /* 07 */ ", EventObj",
75f556842eSJung-uk Kim     /* 08 */ ", MethodObj",
76f556842eSJung-uk Kim     /* 09 */ ", MutexObj",
77f556842eSJung-uk Kim     /* 10 */ ", OpRegionObj",
78f556842eSJung-uk Kim     /* 11 */ ", PowerResObj",
79f556842eSJung-uk Kim     /* 12 */ ", ProcessorObj",
80f556842eSJung-uk Kim     /* 13 */ ", ThermalZoneObj",
81f556842eSJung-uk Kim     /* 14 */ ", BuffFieldObj",
82f556842eSJung-uk Kim     /* 15 */ ", DDBHandleObj",
83f556842eSJung-uk Kim     /* 16 */ "",                    /* Debug object */
84f556842eSJung-uk Kim     /* 17 */ ", FieldUnitObj",
85f556842eSJung-uk Kim     /* 18 */ ", FieldUnitObj",
86f556842eSJung-uk Kim     /* 19 */ ", FieldUnitObj"
87f556842eSJung-uk Kim };
88f556842eSJung-uk Kim 
89f556842eSJung-uk Kim 
90f556842eSJung-uk Kim /* Local prototypes */
91f556842eSJung-uk Kim 
92f556842eSJung-uk Kim static const char *
93f556842eSJung-uk Kim AcpiDmGetObjectTypeName (
94f556842eSJung-uk Kim     ACPI_OBJECT_TYPE        Type);
95f556842eSJung-uk Kim 
96f556842eSJung-uk Kim static char *
97f556842eSJung-uk Kim AcpiDmNormalizeParentPrefix (
98f556842eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
99f556842eSJung-uk Kim     char                    *Path);
100f556842eSJung-uk Kim 
101f556842eSJung-uk Kim 
102f556842eSJung-uk Kim /*******************************************************************************
103f556842eSJung-uk Kim  *
104f556842eSJung-uk Kim  * FUNCTION:    AcpiDmGetObjectTypeName
105f556842eSJung-uk Kim  *
106f556842eSJung-uk Kim  * PARAMETERS:  Type                - An ACPI_OBJECT_TYPE
107f556842eSJung-uk Kim  *
108f556842eSJung-uk Kim  * RETURN:      Pointer to a string
109f556842eSJung-uk Kim  *
110f556842eSJung-uk Kim  * DESCRIPTION: Map an object type to the ASL object type string.
111f556842eSJung-uk Kim  *
112f556842eSJung-uk Kim  ******************************************************************************/
113f556842eSJung-uk Kim 
114f556842eSJung-uk Kim static const char *
115f556842eSJung-uk Kim AcpiDmGetObjectTypeName (
116f556842eSJung-uk Kim     ACPI_OBJECT_TYPE        Type)
117f556842eSJung-uk Kim {
118f556842eSJung-uk Kim 
119f556842eSJung-uk Kim     if (Type == ACPI_TYPE_LOCAL_SCOPE)
120f556842eSJung-uk Kim     {
121f556842eSJung-uk Kim         Type = ACPI_TYPE_DEVICE;
122f556842eSJung-uk Kim     }
123f556842eSJung-uk Kim 
124f556842eSJung-uk Kim     else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD)
125f556842eSJung-uk Kim     {
126f556842eSJung-uk Kim         return ("");
127f556842eSJung-uk Kim     }
128f556842eSJung-uk Kim 
129f556842eSJung-uk Kim     return (AcpiGbl_DmTypeNames[Type]);
130f556842eSJung-uk Kim }
131f556842eSJung-uk Kim 
132f556842eSJung-uk Kim 
133f556842eSJung-uk Kim /*******************************************************************************
134f556842eSJung-uk Kim  *
135f556842eSJung-uk Kim  * FUNCTION:    AcpiDmNormalizeParentPrefix
136f556842eSJung-uk Kim  *
137f556842eSJung-uk Kim  * PARAMETERS:  Op                  - Parse op
138f556842eSJung-uk Kim  *              Path                - Path with parent prefix
139f556842eSJung-uk Kim  *
140f556842eSJung-uk Kim  * RETURN:      The full pathname to the object (from the namespace root)
141f556842eSJung-uk Kim  *
142f556842eSJung-uk Kim  * DESCRIPTION: Returns the full pathname of a path with parent prefix
143f556842eSJung-uk Kim  *              The caller must free the fullpath returned.
144f556842eSJung-uk Kim  *
145f556842eSJung-uk Kim  ******************************************************************************/
146f556842eSJung-uk Kim 
147f556842eSJung-uk Kim static char *
148f556842eSJung-uk Kim AcpiDmNormalizeParentPrefix (
149f556842eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
150f556842eSJung-uk Kim     char                    *Path)
151f556842eSJung-uk Kim {
152f556842eSJung-uk Kim     ACPI_NAMESPACE_NODE     *Node;
153f556842eSJung-uk Kim     char                    *Fullpath;
154f556842eSJung-uk Kim     char                    *ParentPath;
155f556842eSJung-uk Kim     ACPI_SIZE               Length;
156f556842eSJung-uk Kim 
157f556842eSJung-uk Kim 
158f556842eSJung-uk Kim     /* Search upwards in the parse tree until we reach a namespace node */
159f556842eSJung-uk Kim 
160f556842eSJung-uk Kim     while (Op)
161f556842eSJung-uk Kim     {
162f556842eSJung-uk Kim         if (Op->Common.Node)
163f556842eSJung-uk Kim         {
164f556842eSJung-uk Kim             break;
165f556842eSJung-uk Kim         }
166f556842eSJung-uk Kim 
167f556842eSJung-uk Kim         Op = Op->Common.Parent;
168f556842eSJung-uk Kim     }
169f556842eSJung-uk Kim 
170f556842eSJung-uk Kim     if (!Op)
171f556842eSJung-uk Kim     {
172f556842eSJung-uk Kim         return (NULL);
173f556842eSJung-uk Kim     }
174f556842eSJung-uk Kim 
175f556842eSJung-uk Kim     /*
176f556842eSJung-uk Kim      * Find the actual parent node for the reference:
177f556842eSJung-uk Kim      * Remove all carat prefixes from the input path.
178f556842eSJung-uk Kim      * There may be multiple parent prefixes (For example, ^^^M000)
179f556842eSJung-uk Kim      */
180f556842eSJung-uk Kim     Node = Op->Common.Node;
181f556842eSJung-uk Kim     while (Node && (*Path == (UINT8) AML_PARENT_PREFIX))
182f556842eSJung-uk Kim     {
183a88e22b7SJung-uk Kim         Node = Node->Parent;
184f556842eSJung-uk Kim         Path++;
185f556842eSJung-uk Kim     }
186f556842eSJung-uk Kim 
187f556842eSJung-uk Kim     if (!Node)
188f556842eSJung-uk Kim     {
189f556842eSJung-uk Kim         return (NULL);
190f556842eSJung-uk Kim     }
191f556842eSJung-uk Kim 
192f556842eSJung-uk Kim     /* Get the full pathname for the parent node */
193f556842eSJung-uk Kim 
194f556842eSJung-uk Kim     ParentPath = AcpiNsGetExternalPathname (Node);
195f556842eSJung-uk Kim     if (!ParentPath)
196f556842eSJung-uk Kim     {
197f556842eSJung-uk Kim         return (NULL);
198f556842eSJung-uk Kim     }
199f556842eSJung-uk Kim 
200f556842eSJung-uk Kim     Length = (ACPI_STRLEN (ParentPath) + ACPI_STRLEN (Path) + 1);
2018c8be05fSJung-uk Kim     if (ParentPath[1])
2028c8be05fSJung-uk Kim     {
2038c8be05fSJung-uk Kim         /*
2048c8be05fSJung-uk Kim          * If ParentPath is not just a simple '\', increment the length
2058c8be05fSJung-uk Kim          * for the required dot separator (ParentPath.Path)
2068c8be05fSJung-uk Kim          */
2078c8be05fSJung-uk Kim         Length++;
2088c8be05fSJung-uk Kim     }
2098c8be05fSJung-uk Kim 
210f556842eSJung-uk Kim     Fullpath = ACPI_ALLOCATE_ZEROED (Length);
211f556842eSJung-uk Kim     if (!Fullpath)
212f556842eSJung-uk Kim     {
213f556842eSJung-uk Kim         goto Cleanup;
214f556842eSJung-uk Kim     }
215f556842eSJung-uk Kim 
216f556842eSJung-uk Kim     /*
217f556842eSJung-uk Kim      * Concatenate parent fullpath and path. For example,
218f556842eSJung-uk Kim      * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT"
219f556842eSJung-uk Kim      *
220f556842eSJung-uk Kim      * Copy the parent path
221f556842eSJung-uk Kim      */
222f556842eSJung-uk Kim     ACPI_STRCAT (Fullpath, ParentPath);
223f556842eSJung-uk Kim 
224f556842eSJung-uk Kim     /* Add dot separator (don't need dot if parent fullpath is a single "\") */
225f556842eSJung-uk Kim 
226f556842eSJung-uk Kim     if (ParentPath[1])
227f556842eSJung-uk Kim     {
228f556842eSJung-uk Kim         ACPI_STRCAT (Fullpath, ".");
229f556842eSJung-uk Kim     }
230f556842eSJung-uk Kim 
231f556842eSJung-uk Kim     /* Copy child path (carat parent prefix(es) were skipped above) */
232f556842eSJung-uk Kim 
233f556842eSJung-uk Kim     ACPI_STRCAT (Fullpath, Path);
234f556842eSJung-uk Kim 
235f556842eSJung-uk Kim Cleanup:
236f556842eSJung-uk Kim     ACPI_FREE (ParentPath);
237f556842eSJung-uk Kim     return (Fullpath);
238f556842eSJung-uk Kim }
239f556842eSJung-uk Kim 
240f556842eSJung-uk Kim 
241f556842eSJung-uk Kim /*******************************************************************************
242f556842eSJung-uk Kim  *
243709fac06SJung-uk Kim  * FUNCTION:    AcpiDmAddToExternalFileList
244709fac06SJung-uk Kim  *
245709fac06SJung-uk Kim  * PARAMETERS:  PathList            - Single path or list separated by comma
246709fac06SJung-uk Kim  *
247709fac06SJung-uk Kim  * RETURN:      None
248709fac06SJung-uk Kim  *
249709fac06SJung-uk Kim  * DESCRIPTION: Add external files to global list
250709fac06SJung-uk Kim  *
251709fac06SJung-uk Kim  ******************************************************************************/
252709fac06SJung-uk Kim 
253709fac06SJung-uk Kim ACPI_STATUS
254709fac06SJung-uk Kim AcpiDmAddToExternalFileList (
255709fac06SJung-uk Kim     char                    *PathList)
256709fac06SJung-uk Kim {
257709fac06SJung-uk Kim     ACPI_EXTERNAL_FILE      *ExternalFile;
258709fac06SJung-uk Kim     char                    *Path;
259709fac06SJung-uk Kim     char                    *TmpPath;
260709fac06SJung-uk Kim 
261709fac06SJung-uk Kim 
262709fac06SJung-uk Kim     if (!PathList)
263709fac06SJung-uk Kim     {
264709fac06SJung-uk Kim         return (AE_OK);
265709fac06SJung-uk Kim     }
266709fac06SJung-uk Kim 
267709fac06SJung-uk Kim     Path = strtok (PathList, ",");
268709fac06SJung-uk Kim 
269709fac06SJung-uk Kim     while (Path)
270709fac06SJung-uk Kim     {
271709fac06SJung-uk Kim         TmpPath = ACPI_ALLOCATE_ZEROED (ACPI_STRLEN (Path) + 1);
272709fac06SJung-uk Kim         if (!TmpPath)
273709fac06SJung-uk Kim         {
274709fac06SJung-uk Kim             return (AE_NO_MEMORY);
275709fac06SJung-uk Kim         }
276709fac06SJung-uk Kim 
277709fac06SJung-uk Kim         ACPI_STRCPY (TmpPath, Path);
278709fac06SJung-uk Kim 
279709fac06SJung-uk Kim         ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE));
280709fac06SJung-uk Kim         if (!ExternalFile)
281709fac06SJung-uk Kim         {
282709fac06SJung-uk Kim             ACPI_FREE (TmpPath);
283709fac06SJung-uk Kim             return (AE_NO_MEMORY);
284709fac06SJung-uk Kim         }
285709fac06SJung-uk Kim 
286709fac06SJung-uk Kim         ExternalFile->Path = TmpPath;
287709fac06SJung-uk Kim 
288709fac06SJung-uk Kim         if (AcpiGbl_ExternalFileList)
289709fac06SJung-uk Kim         {
290709fac06SJung-uk Kim             ExternalFile->Next = AcpiGbl_ExternalFileList;
291709fac06SJung-uk Kim         }
292709fac06SJung-uk Kim 
293709fac06SJung-uk Kim         AcpiGbl_ExternalFileList = ExternalFile;
294709fac06SJung-uk Kim         Path = strtok (NULL, ",");
295709fac06SJung-uk Kim     }
296709fac06SJung-uk Kim 
297709fac06SJung-uk Kim     return (AE_OK);
298709fac06SJung-uk Kim }
299709fac06SJung-uk Kim 
300709fac06SJung-uk Kim 
301709fac06SJung-uk Kim /*******************************************************************************
302709fac06SJung-uk Kim  *
303709fac06SJung-uk Kim  * FUNCTION:    AcpiDmClearExternalFileList
304709fac06SJung-uk Kim  *
305709fac06SJung-uk Kim  * PARAMETERS:  None
306709fac06SJung-uk Kim  *
307709fac06SJung-uk Kim  * RETURN:      None
308709fac06SJung-uk Kim  *
309709fac06SJung-uk Kim  * DESCRIPTION: Clear the external file list
310709fac06SJung-uk Kim  *
311709fac06SJung-uk Kim  ******************************************************************************/
312709fac06SJung-uk Kim 
313709fac06SJung-uk Kim void
314709fac06SJung-uk Kim AcpiDmClearExternalFileList (
315709fac06SJung-uk Kim     void)
316709fac06SJung-uk Kim {
317709fac06SJung-uk Kim     ACPI_EXTERNAL_FILE      *NextExternal;
318709fac06SJung-uk Kim 
319709fac06SJung-uk Kim 
320709fac06SJung-uk Kim     while (AcpiGbl_ExternalFileList)
321709fac06SJung-uk Kim     {
322709fac06SJung-uk Kim         NextExternal = AcpiGbl_ExternalFileList->Next;
323709fac06SJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalFileList->Path);
324709fac06SJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalFileList);
325709fac06SJung-uk Kim         AcpiGbl_ExternalFileList = NextExternal;
326709fac06SJung-uk Kim     }
327709fac06SJung-uk Kim }
328709fac06SJung-uk Kim 
329709fac06SJung-uk Kim 
330709fac06SJung-uk Kim /*******************************************************************************
331709fac06SJung-uk Kim  *
332f556842eSJung-uk Kim  * FUNCTION:    AcpiDmAddToExternalList
333f556842eSJung-uk Kim  *
334f556842eSJung-uk Kim  * PARAMETERS:  Op                  - Current parser Op
335f556842eSJung-uk Kim  *              Path                - Internal (AML) path to the object
336f556842eSJung-uk Kim  *              Type                - ACPI object type to be added
337f556842eSJung-uk Kim  *              Value               - Arg count if adding a Method object
338f556842eSJung-uk Kim  *
339f556842eSJung-uk Kim  * RETURN:      None
340f556842eSJung-uk Kim  *
341f556842eSJung-uk Kim  * DESCRIPTION: Insert a new name into the global list of Externals which
342f556842eSJung-uk Kim  *              will in turn be later emitted as an External() declaration
343f556842eSJung-uk Kim  *              in the disassembled output.
344f556842eSJung-uk Kim  *
345f556842eSJung-uk Kim  ******************************************************************************/
346f556842eSJung-uk Kim 
347f556842eSJung-uk Kim void
348f556842eSJung-uk Kim AcpiDmAddToExternalList (
349f556842eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
350f556842eSJung-uk Kim     char                    *Path,
351f556842eSJung-uk Kim     UINT8                   Type,
352f556842eSJung-uk Kim     UINT32                  Value)
353f556842eSJung-uk Kim {
354f556842eSJung-uk Kim     char                    *ExternalPath;
355f556842eSJung-uk Kim     char                    *Fullpath = NULL;
356f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *NewExternal;
357f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *NextExternal;
358f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *PrevExternal = NULL;
359f556842eSJung-uk Kim     ACPI_STATUS             Status;
360f556842eSJung-uk Kim 
361f556842eSJung-uk Kim 
362f556842eSJung-uk Kim     if (!Path)
363f556842eSJung-uk Kim     {
364f556842eSJung-uk Kim         return;
365f556842eSJung-uk Kim     }
366f556842eSJung-uk Kim 
367f556842eSJung-uk Kim     /* Externalize the ACPI path */
368f556842eSJung-uk Kim 
369f556842eSJung-uk Kim     Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path,
370f556842eSJung-uk Kim                 NULL, &ExternalPath);
371f556842eSJung-uk Kim     if (ACPI_FAILURE (Status))
372f556842eSJung-uk Kim     {
373f556842eSJung-uk Kim         return;
374f556842eSJung-uk Kim     }
375f556842eSJung-uk Kim 
376f556842eSJung-uk Kim     /* Get the full pathname from root if "Path" has a parent prefix */
377f556842eSJung-uk Kim 
378f556842eSJung-uk Kim     if (*Path == (UINT8) AML_PARENT_PREFIX)
379f556842eSJung-uk Kim     {
380f556842eSJung-uk Kim         Fullpath = AcpiDmNormalizeParentPrefix (Op, ExternalPath);
381f556842eSJung-uk Kim         if (Fullpath)
382f556842eSJung-uk Kim         {
383f556842eSJung-uk Kim             /* Set new external path */
384f556842eSJung-uk Kim 
385f556842eSJung-uk Kim             ACPI_FREE (ExternalPath);
386f556842eSJung-uk Kim             ExternalPath = Fullpath;
387f556842eSJung-uk Kim         }
388f556842eSJung-uk Kim     }
389f556842eSJung-uk Kim 
390f556842eSJung-uk Kim     /* Check all existing externals to ensure no duplicates */
391f556842eSJung-uk Kim 
392f556842eSJung-uk Kim     NextExternal = AcpiGbl_ExternalList;
393f556842eSJung-uk Kim     while (NextExternal)
394f556842eSJung-uk Kim     {
395f556842eSJung-uk Kim         if (!ACPI_STRCMP (ExternalPath, NextExternal->Path))
396f556842eSJung-uk Kim         {
397f556842eSJung-uk Kim             /* Duplicate method, check that the Value (ArgCount) is the same */
398f556842eSJung-uk Kim 
399f556842eSJung-uk Kim             if ((NextExternal->Type == ACPI_TYPE_METHOD) &&
400f556842eSJung-uk Kim                 (NextExternal->Value != Value))
401f556842eSJung-uk Kim             {
402f556842eSJung-uk Kim                 ACPI_ERROR ((AE_INFO,
403ca3cf4faSJung-uk Kim                     "Argument count mismatch for method %s %u %u",
404f556842eSJung-uk Kim                     NextExternal->Path, NextExternal->Value, Value));
405f556842eSJung-uk Kim             }
406f556842eSJung-uk Kim 
407f556842eSJung-uk Kim             /* Allow upgrade of type from ANY */
408f556842eSJung-uk Kim 
409f556842eSJung-uk Kim             else if (NextExternal->Type == ACPI_TYPE_ANY)
410f556842eSJung-uk Kim             {
411f556842eSJung-uk Kim                 NextExternal->Type = Type;
412f556842eSJung-uk Kim                 NextExternal->Value = Value;
413f556842eSJung-uk Kim             }
414f556842eSJung-uk Kim 
415f556842eSJung-uk Kim             ACPI_FREE (ExternalPath);
416f556842eSJung-uk Kim             return;
417f556842eSJung-uk Kim         }
418f556842eSJung-uk Kim 
419f556842eSJung-uk Kim         NextExternal = NextExternal->Next;
420f556842eSJung-uk Kim     }
421f556842eSJung-uk Kim 
422f556842eSJung-uk Kim     /* Allocate and init a new External() descriptor */
423f556842eSJung-uk Kim 
424f556842eSJung-uk Kim     NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));
425f556842eSJung-uk Kim     if (!NewExternal)
426f556842eSJung-uk Kim     {
427f556842eSJung-uk Kim         ACPI_FREE (ExternalPath);
428f556842eSJung-uk Kim         return;
429f556842eSJung-uk Kim     }
430f556842eSJung-uk Kim 
431f556842eSJung-uk Kim     NewExternal->Path = ExternalPath;
432f556842eSJung-uk Kim     NewExternal->Type = Type;
433f556842eSJung-uk Kim     NewExternal->Value = Value;
434f556842eSJung-uk Kim     NewExternal->Length = (UINT16) ACPI_STRLEN (ExternalPath);
435f556842eSJung-uk Kim 
436f556842eSJung-uk Kim     /* Was the external path with parent prefix normalized to a fullpath? */
437f556842eSJung-uk Kim 
438f556842eSJung-uk Kim     if (Fullpath == ExternalPath)
439f556842eSJung-uk Kim     {
440f556842eSJung-uk Kim         /* Get new internal path */
441f556842eSJung-uk Kim 
442f556842eSJung-uk Kim         Status = AcpiNsInternalizeName (ExternalPath, &Path);
443f556842eSJung-uk Kim         if (ACPI_FAILURE (Status))
444f556842eSJung-uk Kim         {
445f556842eSJung-uk Kim             ACPI_FREE (ExternalPath);
446f556842eSJung-uk Kim             ACPI_FREE (NewExternal);
447f556842eSJung-uk Kim             return;
448f556842eSJung-uk Kim         }
449f556842eSJung-uk Kim 
450f556842eSJung-uk Kim         /* Set flag to indicate External->InternalPath need to be freed */
451f556842eSJung-uk Kim 
452f556842eSJung-uk Kim         NewExternal->Flags |= ACPI_IPATH_ALLOCATED;
453f556842eSJung-uk Kim     }
454f556842eSJung-uk Kim 
455f556842eSJung-uk Kim     NewExternal->InternalPath = Path;
456f556842eSJung-uk Kim 
457*a7a3b383SJung-uk Kim     /* Link the new descriptor into the global list, alphabetically ordered */
458f556842eSJung-uk Kim 
459f556842eSJung-uk Kim     NextExternal = AcpiGbl_ExternalList;
460f556842eSJung-uk Kim     while (NextExternal)
461f556842eSJung-uk Kim     {
462*a7a3b383SJung-uk Kim         if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0)
463f556842eSJung-uk Kim         {
464f556842eSJung-uk Kim             if (PrevExternal)
465f556842eSJung-uk Kim             {
466f556842eSJung-uk Kim                 PrevExternal->Next = NewExternal;
467f556842eSJung-uk Kim             }
468f556842eSJung-uk Kim             else
469f556842eSJung-uk Kim             {
470f556842eSJung-uk Kim                 AcpiGbl_ExternalList = NewExternal;
471f556842eSJung-uk Kim             }
472f556842eSJung-uk Kim 
473f556842eSJung-uk Kim             NewExternal->Next = NextExternal;
474f556842eSJung-uk Kim             return;
475f556842eSJung-uk Kim         }
476f556842eSJung-uk Kim 
477f556842eSJung-uk Kim         PrevExternal = NextExternal;
478f556842eSJung-uk Kim         NextExternal = NextExternal->Next;
479f556842eSJung-uk Kim     }
480f556842eSJung-uk Kim 
481f556842eSJung-uk Kim     if (PrevExternal)
482f556842eSJung-uk Kim     {
483f556842eSJung-uk Kim         PrevExternal->Next = NewExternal;
484f556842eSJung-uk Kim     }
485f556842eSJung-uk Kim     else
486f556842eSJung-uk Kim     {
487f556842eSJung-uk Kim         AcpiGbl_ExternalList = NewExternal;
488f556842eSJung-uk Kim     }
489f556842eSJung-uk Kim }
490f556842eSJung-uk Kim 
491f556842eSJung-uk Kim 
492f556842eSJung-uk Kim /*******************************************************************************
493f556842eSJung-uk Kim  *
494f556842eSJung-uk Kim  * FUNCTION:    AcpiDmAddExternalsToNamespace
495f556842eSJung-uk Kim  *
496f556842eSJung-uk Kim  * PARAMETERS:  None
497f556842eSJung-uk Kim  *
498f556842eSJung-uk Kim  * RETURN:      None
499f556842eSJung-uk Kim  *
500f556842eSJung-uk Kim  * DESCRIPTION: Add all externals to the namespace. Allows externals to be
501f556842eSJung-uk Kim  *              "resolved".
502f556842eSJung-uk Kim  *
503f556842eSJung-uk Kim  ******************************************************************************/
504f556842eSJung-uk Kim 
505f556842eSJung-uk Kim void
506f556842eSJung-uk Kim AcpiDmAddExternalsToNamespace (
507f556842eSJung-uk Kim     void)
508f556842eSJung-uk Kim {
509f556842eSJung-uk Kim     ACPI_STATUS             Status;
510f556842eSJung-uk Kim     ACPI_NAMESPACE_NODE     *Node;
511*a7a3b383SJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc;
512f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *External = AcpiGbl_ExternalList;
513f556842eSJung-uk Kim 
514f556842eSJung-uk Kim 
515f556842eSJung-uk Kim     while (External)
516f556842eSJung-uk Kim     {
517f556842eSJung-uk Kim         /* Add the external name (object) into the namespace */
518f556842eSJung-uk Kim 
519f556842eSJung-uk Kim         Status = AcpiNsLookup (NULL, External->InternalPath, External->Type,
520f556842eSJung-uk Kim                    ACPI_IMODE_LOAD_PASS1,
521f556842eSJung-uk Kim                    ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
522f556842eSJung-uk Kim                    NULL, &Node);
523f556842eSJung-uk Kim 
524f556842eSJung-uk Kim         if (ACPI_FAILURE (Status))
525f556842eSJung-uk Kim         {
526f556842eSJung-uk Kim             ACPI_EXCEPTION ((AE_INFO, Status,
527f556842eSJung-uk Kim                 "while adding external to namespace [%s]",
528f556842eSJung-uk Kim                 External->Path));
529f556842eSJung-uk Kim         }
530*a7a3b383SJung-uk Kim 
531*a7a3b383SJung-uk Kim         else switch (External->Type)
532f556842eSJung-uk Kim         {
533*a7a3b383SJung-uk Kim         case ACPI_TYPE_METHOD:
534*a7a3b383SJung-uk Kim 
535f556842eSJung-uk Kim             /* For methods, we need to save the argument count */
536f556842eSJung-uk Kim 
537*a7a3b383SJung-uk Kim             ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
538*a7a3b383SJung-uk Kim             ObjDesc->Method.ParamCount = (UINT8) External->Value;
539*a7a3b383SJung-uk Kim             Node->Object = ObjDesc;
540*a7a3b383SJung-uk Kim             break;
541*a7a3b383SJung-uk Kim 
542*a7a3b383SJung-uk Kim         case ACPI_TYPE_REGION:
543*a7a3b383SJung-uk Kim 
544*a7a3b383SJung-uk Kim             /* Regions require a region sub-object */
545*a7a3b383SJung-uk Kim 
546*a7a3b383SJung-uk Kim             ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
547*a7a3b383SJung-uk Kim             ObjDesc->Region.Node = Node;
548*a7a3b383SJung-uk Kim             Node->Object = ObjDesc;
549*a7a3b383SJung-uk Kim             break;
550*a7a3b383SJung-uk Kim 
551*a7a3b383SJung-uk Kim         default:
552*a7a3b383SJung-uk Kim             break;
553f556842eSJung-uk Kim         }
554f556842eSJung-uk Kim 
555f556842eSJung-uk Kim         External = External->Next;
556f556842eSJung-uk Kim     }
557f556842eSJung-uk Kim }
558f556842eSJung-uk Kim 
559f556842eSJung-uk Kim 
560f556842eSJung-uk Kim /*******************************************************************************
561f556842eSJung-uk Kim  *
562f556842eSJung-uk Kim  * FUNCTION:    AcpiDmGetExternalMethodCount
563f556842eSJung-uk Kim  *
564f556842eSJung-uk Kim  * PARAMETERS:  None
565f556842eSJung-uk Kim  *
566f556842eSJung-uk Kim  * RETURN:      The number of control method externals in the external list
567f556842eSJung-uk Kim  *
568f556842eSJung-uk Kim  * DESCRIPTION: Return the number of method externals that have been generated.
569f556842eSJung-uk Kim  *              If any control method externals have been found, we must
570f556842eSJung-uk Kim  *              re-parse the entire definition block with the new information
571f556842eSJung-uk Kim  *              (number of arguments for the methods.) This is limitation of
572f556842eSJung-uk Kim  *              AML, we don't know the number of arguments from the control
573f556842eSJung-uk Kim  *              method invocation itself.
574f556842eSJung-uk Kim  *
575f556842eSJung-uk Kim  ******************************************************************************/
576f556842eSJung-uk Kim 
577f556842eSJung-uk Kim UINT32
578f556842eSJung-uk Kim AcpiDmGetExternalMethodCount (
579f556842eSJung-uk Kim     void)
580f556842eSJung-uk Kim {
581f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *External = AcpiGbl_ExternalList;
582f556842eSJung-uk Kim     UINT32                  Count = 0;
583f556842eSJung-uk Kim 
584f556842eSJung-uk Kim 
585f556842eSJung-uk Kim     while (External)
586f556842eSJung-uk Kim     {
587f556842eSJung-uk Kim         if (External->Type == ACPI_TYPE_METHOD)
588f556842eSJung-uk Kim         {
589f556842eSJung-uk Kim             Count++;
590f556842eSJung-uk Kim         }
591f556842eSJung-uk Kim 
592f556842eSJung-uk Kim         External = External->Next;
593f556842eSJung-uk Kim     }
594f556842eSJung-uk Kim 
595f556842eSJung-uk Kim     return (Count);
596f556842eSJung-uk Kim }
597f556842eSJung-uk Kim 
598f556842eSJung-uk Kim 
599f556842eSJung-uk Kim /*******************************************************************************
600f556842eSJung-uk Kim  *
601f556842eSJung-uk Kim  * FUNCTION:    AcpiDmClearExternalList
602f556842eSJung-uk Kim  *
603f556842eSJung-uk Kim  * PARAMETERS:  None
604f556842eSJung-uk Kim  *
605f556842eSJung-uk Kim  * RETURN:      None
606f556842eSJung-uk Kim  *
607f556842eSJung-uk Kim  * DESCRIPTION: Free the entire External info list
608f556842eSJung-uk Kim  *
609f556842eSJung-uk Kim  ******************************************************************************/
610f556842eSJung-uk Kim 
611f556842eSJung-uk Kim void
612f556842eSJung-uk Kim AcpiDmClearExternalList (
613f556842eSJung-uk Kim     void)
614f556842eSJung-uk Kim {
615f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *NextExternal;
616f556842eSJung-uk Kim 
617f556842eSJung-uk Kim 
618f556842eSJung-uk Kim     while (AcpiGbl_ExternalList)
619f556842eSJung-uk Kim     {
620f556842eSJung-uk Kim         NextExternal = AcpiGbl_ExternalList->Next;
621f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList->Path);
622f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList);
623f556842eSJung-uk Kim         AcpiGbl_ExternalList = NextExternal;
624f556842eSJung-uk Kim     }
625f556842eSJung-uk Kim }
626f556842eSJung-uk Kim 
627f556842eSJung-uk Kim 
628f556842eSJung-uk Kim /*******************************************************************************
629f556842eSJung-uk Kim  *
630f556842eSJung-uk Kim  * FUNCTION:    AcpiDmEmitExternals
631f556842eSJung-uk Kim  *
632f556842eSJung-uk Kim  * PARAMETERS:  None
633f556842eSJung-uk Kim  *
634f556842eSJung-uk Kim  * RETURN:      None
635f556842eSJung-uk Kim  *
636f556842eSJung-uk Kim  * DESCRIPTION: Emit an External() ASL statement for each of the externals in
637f556842eSJung-uk Kim  *              the global external info list.
638f556842eSJung-uk Kim  *
639f556842eSJung-uk Kim  ******************************************************************************/
640f556842eSJung-uk Kim 
641f556842eSJung-uk Kim void
642f556842eSJung-uk Kim AcpiDmEmitExternals (
643f556842eSJung-uk Kim     void)
644f556842eSJung-uk Kim {
645f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *NextExternal;
646f556842eSJung-uk Kim 
647f556842eSJung-uk Kim 
648f556842eSJung-uk Kim     if (!AcpiGbl_ExternalList)
649f556842eSJung-uk Kim     {
650f556842eSJung-uk Kim         return;
651f556842eSJung-uk Kim     }
652f556842eSJung-uk Kim 
653f556842eSJung-uk Kim     /*
654f556842eSJung-uk Kim      * Walk the list of externals (unresolved references)
655f556842eSJung-uk Kim      * found during the AML parsing
656f556842eSJung-uk Kim      */
657f556842eSJung-uk Kim     while (AcpiGbl_ExternalList)
658f556842eSJung-uk Kim     {
659f556842eSJung-uk Kim         AcpiOsPrintf ("    External (%s%s",
660f556842eSJung-uk Kim             AcpiGbl_ExternalList->Path,
661f556842eSJung-uk Kim             AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type));
662f556842eSJung-uk Kim 
663f556842eSJung-uk Kim         if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
664f556842eSJung-uk Kim         {
665a88e22b7SJung-uk Kim             AcpiOsPrintf (")    // %u Arguments\n",
666f556842eSJung-uk Kim                 AcpiGbl_ExternalList->Value);
667f556842eSJung-uk Kim         }
668f556842eSJung-uk Kim         else
669f556842eSJung-uk Kim         {
670f556842eSJung-uk Kim             AcpiOsPrintf (")\n");
671f556842eSJung-uk Kim         }
672f556842eSJung-uk Kim 
673f556842eSJung-uk Kim         /* Free this external info block and move on to next external */
674f556842eSJung-uk Kim 
675f556842eSJung-uk Kim         NextExternal = AcpiGbl_ExternalList->Next;
676f556842eSJung-uk Kim         if (AcpiGbl_ExternalList->Flags & ACPI_IPATH_ALLOCATED)
677f556842eSJung-uk Kim         {
678f556842eSJung-uk Kim             ACPI_FREE (AcpiGbl_ExternalList->InternalPath);
679f556842eSJung-uk Kim         }
680f556842eSJung-uk Kim 
681f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList->Path);
682f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList);
683f556842eSJung-uk Kim         AcpiGbl_ExternalList = NextExternal;
684f556842eSJung-uk Kim     }
685f556842eSJung-uk Kim 
686f556842eSJung-uk Kim     AcpiOsPrintf ("\n");
687f556842eSJung-uk Kim }
688f556842eSJung-uk Kim 
689