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