diff options
author | Len Brown <len.brown@intel.com> | 2009-01-09 00:13:17 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-01-09 03:30:47 -0500 |
commit | 95b482a8d31116f3f5c2a5089569393234d06385 (patch) | |
tree | f32aec8673a285a9d188948be97af3034ee06e93 /drivers/acpi/namespace | |
parent | 6620e0c49f577454b772fb381543d60ae53eb885 (diff) |
ACPICA: create acpica/ directory
also, delete sleep/ and delete ACPI_CFLAGS from Makefile
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/namespace')
-rw-r--r-- | drivers/acpi/namespace/Makefile | 12 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsaccess.c | 676 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsalloc.c | 497 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsdump.c | 709 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsdumpdv.c | 141 | ||||
-rw-r--r-- | drivers/acpi/namespace/nseval.c | 278 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsinit.c | 593 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsload.c | 315 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsnames.c | 265 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsobject.c | 441 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsparse.c | 204 | ||||
-rw-r--r-- | drivers/acpi/namespace/nspredef.c | 1065 | ||||
-rw-r--r-- | drivers/acpi/namespace/nssearch.c | 415 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsutils.c | 997 | ||||
-rw-r--r-- | drivers/acpi/namespace/nswalk.c | 296 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsxfeval.c | 812 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsxfname.c | 360 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsxfobj.c | 287 |
18 files changed, 0 insertions, 8363 deletions
diff --git a/drivers/acpi/namespace/Makefile b/drivers/acpi/namespace/Makefile deleted file mode 100644 index 371a2daf837f..000000000000 --- a/drivers/acpi/namespace/Makefile +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for all Linux ACPI interpreter subdirectories | ||
3 | # | ||
4 | |||
5 | obj-y := nsaccess.o nsload.o nssearch.o nsxfeval.o \ | ||
6 | nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \ | ||
7 | nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \ | ||
8 | nsparse.o nspredef.o | ||
9 | |||
10 | obj-$(ACPI_FUTURE_USAGE) += nsdumpdv.o | ||
11 | |||
12 | EXTRA_CFLAGS += $(ACPI_CFLAGS) | ||
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c deleted file mode 100644 index 7954640e69cb..000000000000 --- a/drivers/acpi/namespace/nsaccess.c +++ /dev/null | |||
@@ -1,676 +0,0 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: nsaccess - Top-level functions for accessing ACPI namespace | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2008, 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 <acpi/acpi.h> | ||
45 | #include <acpi/accommon.h> | ||
46 | #include <acpi/amlcode.h> | ||
47 | #include <acpi/acnamesp.h> | ||
48 | #include <acpi/acdispat.h> | ||
49 | |||
50 | #define _COMPONENT ACPI_NAMESPACE | ||
51 | ACPI_MODULE_NAME("nsaccess") | ||
52 | |||
53 | /******************************************************************************* | ||
54 | * | ||
55 | * FUNCTION: acpi_ns_root_initialize | ||
56 | * | ||
57 | * PARAMETERS: None | ||
58 | * | ||
59 | * RETURN: Status | ||
60 | * | ||
61 | * DESCRIPTION: Allocate and initialize the default root named objects | ||
62 | * | ||
63 | * MUTEX: Locks namespace for entire execution | ||
64 | * | ||
65 | ******************************************************************************/ | ||
66 | acpi_status acpi_ns_root_initialize(void) | ||
67 | { | ||
68 | acpi_status status; | ||
69 | const struct acpi_predefined_names *init_val = NULL; | ||
70 | struct acpi_namespace_node *new_node; | ||
71 | union acpi_operand_object *obj_desc; | ||
72 | acpi_string val = NULL; | ||
73 | |||
74 | ACPI_FUNCTION_TRACE(ns_root_initialize); | ||
75 | |||
76 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
77 | if (ACPI_FAILURE(status)) { | ||
78 | return_ACPI_STATUS(status); | ||
79 | } | ||
80 | |||
81 | /* | ||
82 | * The global root ptr is initially NULL, so a non-NULL value indicates | ||
83 | * that acpi_ns_root_initialize() has already been called; just return. | ||
84 | */ | ||
85 | if (acpi_gbl_root_node) { | ||
86 | status = AE_OK; | ||
87 | goto unlock_and_exit; | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * Tell the rest of the subsystem that the root is initialized | ||
92 | * (This is OK because the namespace is locked) | ||
93 | */ | ||
94 | acpi_gbl_root_node = &acpi_gbl_root_node_struct; | ||
95 | |||
96 | /* Enter the pre-defined names in the name table */ | ||
97 | |||
98 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
99 | "Entering predefined entries into namespace\n")); | ||
100 | |||
101 | for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) { | ||
102 | |||
103 | /* _OSI is optional for now, will be permanent later */ | ||
104 | |||
105 | if (!ACPI_STRCMP(init_val->name, "_OSI") | ||
106 | && !acpi_gbl_create_osi_method) { | ||
107 | continue; | ||
108 | } | ||
109 | |||
110 | status = acpi_ns_lookup(NULL, init_val->name, init_val->type, | ||
111 | ACPI_IMODE_LOAD_PASS2, | ||
112 | ACPI_NS_NO_UPSEARCH, NULL, &new_node); | ||
113 | |||
114 | if (ACPI_FAILURE(status) || (!new_node)) { /* Must be on same line for code converter */ | ||
115 | ACPI_EXCEPTION((AE_INFO, status, | ||
116 | "Could not create predefined name %s", | ||
117 | init_val->name)); | ||
118 | } | ||
119 | |||
120 | /* | ||
121 | * Name entered successfully. | ||
122 | * If entry in pre_defined_names[] specifies an | ||
123 | * initial value, create the initial value. | ||
124 | */ | ||
125 | if (init_val->val) { | ||
126 | status = acpi_os_predefined_override(init_val, &val); | ||
127 | if (ACPI_FAILURE(status)) { | ||
128 | ACPI_ERROR((AE_INFO, | ||
129 | "Could not override predefined %s", | ||
130 | init_val->name)); | ||
131 | } | ||
132 | |||
133 | if (!val) { | ||
134 | val = init_val->val; | ||
135 | } | ||
136 | |||
137 | /* | ||
138 | * Entry requests an initial value, allocate a | ||
139 | * descriptor for it. | ||
140 | */ | ||
141 | obj_desc = | ||
142 | acpi_ut_create_internal_object(init_val->type); | ||
143 | if (!obj_desc) { | ||
144 | status = AE_NO_MEMORY; | ||
145 | goto unlock_and_exit; | ||
146 | } | ||
147 | |||
148 | /* | ||
149 | * Convert value string from table entry to | ||
150 | * internal representation. Only types actually | ||
151 | * used for initial values are implemented here. | ||
152 | */ | ||
153 | switch (init_val->type) { | ||
154 | case ACPI_TYPE_METHOD: | ||
155 | obj_desc->method.param_count = | ||
156 | (u8) ACPI_TO_INTEGER(val); | ||
157 | obj_desc->common.flags |= AOPOBJ_DATA_VALID; | ||
158 | |||
159 | #if defined (ACPI_ASL_COMPILER) | ||
160 | |||
161 | /* Save the parameter count for the i_aSL compiler */ | ||
162 | |||
163 | new_node->value = obj_desc->method.param_count; | ||
164 | #else | ||
165 | /* Mark this as a very SPECIAL method */ | ||
166 | |||
167 | obj_desc->method.method_flags = | ||
168 | AML_METHOD_INTERNAL_ONLY; | ||
169 | obj_desc->method.implementation = | ||
170 | acpi_ut_osi_implementation; | ||
171 | #endif | ||
172 | break; | ||
173 | |||
174 | case ACPI_TYPE_INTEGER: | ||
175 | |||
176 | obj_desc->integer.value = ACPI_TO_INTEGER(val); | ||
177 | break; | ||
178 | |||
179 | case ACPI_TYPE_STRING: | ||
180 | |||
181 | /* | ||
182 | * Build an object around the static string | ||
183 | */ | ||
184 | obj_desc->string.length = | ||
185 | (u32) ACPI_STRLEN(val); | ||
186 | obj_desc->string.pointer = val; | ||
187 | obj_desc->common.flags |= AOPOBJ_STATIC_POINTER; | ||
188 | break; | ||
189 | |||
190 | case ACPI_TYPE_MUTEX: | ||
191 | |||
192 | obj_desc->mutex.node = new_node; | ||
193 | obj_desc->mutex.sync_level = | ||
194 | (u8) (ACPI_TO_INTEGER(val) - 1); | ||
195 | |||
196 | /* Create a mutex */ | ||
197 | |||
198 | status = | ||
199 | acpi_os_create_mutex(&obj_desc->mutex. | ||
200 | os_mutex); | ||
201 | if (ACPI_FAILURE(status)) { | ||
202 | acpi_ut_remove_reference(obj_desc); | ||
203 | goto unlock_and_exit; | ||
204 | } | ||
205 | |||
206 | /* Special case for ACPI Global Lock */ | ||
207 | |||
208 | if (ACPI_STRCMP(init_val->name, "_GL_") == 0) { | ||
209 | acpi_gbl_global_lock_mutex = obj_desc; | ||
210 | |||
211 | /* Create additional counting semaphore for global lock */ | ||
212 | |||
213 | status = | ||
214 | acpi_os_create_semaphore(1, 0, | ||
215 | &acpi_gbl_global_lock_semaphore); | ||
216 | if (ACPI_FAILURE(status)) { | ||
217 | acpi_ut_remove_reference | ||
218 | (obj_desc); | ||
219 | goto unlock_and_exit; | ||
220 | } | ||
221 | } | ||
222 | break; | ||
223 | |||
224 | default: | ||
225 | |||
226 | ACPI_ERROR((AE_INFO, | ||
227 | "Unsupported initial type value %X", | ||
228 | init_val->type)); | ||
229 | acpi_ut_remove_reference(obj_desc); | ||
230 | obj_desc = NULL; | ||
231 | continue; | ||
232 | } | ||
233 | |||
234 | /* Store pointer to value descriptor in the Node */ | ||
235 | |||
236 | status = acpi_ns_attach_object(new_node, obj_desc, | ||
237 | ACPI_GET_OBJECT_TYPE | ||
238 | (obj_desc)); | ||
239 | |||
240 | /* Remove local reference to the object */ | ||
241 | |||
242 | acpi_ut_remove_reference(obj_desc); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | unlock_and_exit: | ||
247 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
248 | |||
249 | /* Save a handle to "_GPE", it is always present */ | ||
250 | |||
251 | if (ACPI_SUCCESS(status)) { | ||
252 | status = acpi_ns_get_node(NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH, | ||
253 | &acpi_gbl_fadt_gpe_device); | ||
254 | } | ||
255 | |||
256 | return_ACPI_STATUS(status); | ||
257 | } | ||
258 | |||
259 | /******************************************************************************* | ||
260 | * | ||
261 | * FUNCTION: acpi_ns_lookup | ||
262 | * | ||
263 | * PARAMETERS: scope_info - Current scope info block | ||
264 | * Pathname - Search pathname, in internal format | ||
265 | * (as represented in the AML stream) | ||
266 | * Type - Type associated with name | ||
267 | * interpreter_mode - IMODE_LOAD_PASS2 => add name if not found | ||
268 | * Flags - Flags describing the search restrictions | ||
269 | * walk_state - Current state of the walk | ||
270 | * return_node - Where the Node is placed (if found | ||
271 | * or created successfully) | ||
272 | * | ||
273 | * RETURN: Status | ||
274 | * | ||
275 | * DESCRIPTION: Find or enter the passed name in the name space. | ||
276 | * Log an error if name not found in Exec mode. | ||
277 | * | ||
278 | * MUTEX: Assumes namespace is locked. | ||
279 | * | ||
280 | ******************************************************************************/ | ||
281 | |||
282 | acpi_status | ||
283 | acpi_ns_lookup(union acpi_generic_state *scope_info, | ||
284 | char *pathname, | ||
285 | acpi_object_type type, | ||
286 | acpi_interpreter_mode interpreter_mode, | ||
287 | u32 flags, | ||
288 | struct acpi_walk_state *walk_state, | ||
289 | struct acpi_namespace_node **return_node) | ||
290 | { | ||
291 | acpi_status status; | ||
292 | char *path = pathname; | ||
293 | struct acpi_namespace_node *prefix_node; | ||
294 | struct acpi_namespace_node *current_node = NULL; | ||
295 | struct acpi_namespace_node *this_node = NULL; | ||
296 | u32 num_segments; | ||
297 | u32 num_carats; | ||
298 | acpi_name simple_name; | ||
299 | acpi_object_type type_to_check_for; | ||
300 | acpi_object_type this_search_type; | ||
301 | u32 search_parent_flag = ACPI_NS_SEARCH_PARENT; | ||
302 | u32 local_flags; | ||
303 | |||
304 | ACPI_FUNCTION_TRACE(ns_lookup); | ||
305 | |||
306 | if (!return_node) { | ||
307 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
308 | } | ||
309 | |||
310 | local_flags = flags & ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_SEARCH_PARENT); | ||
311 | *return_node = ACPI_ENTRY_NOT_FOUND; | ||
312 | acpi_gbl_ns_lookup_count++; | ||
313 | |||
314 | if (!acpi_gbl_root_node) { | ||
315 | return_ACPI_STATUS(AE_NO_NAMESPACE); | ||
316 | } | ||
317 | |||
318 | /* | ||
319 | * Get the prefix scope. | ||
320 | * A null scope means use the root scope | ||
321 | */ | ||
322 | if ((!scope_info) || (!scope_info->scope.node)) { | ||
323 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
324 | "Null scope prefix, using root node (%p)\n", | ||
325 | acpi_gbl_root_node)); | ||
326 | |||
327 | prefix_node = acpi_gbl_root_node; | ||
328 | } else { | ||
329 | prefix_node = scope_info->scope.node; | ||
330 | if (ACPI_GET_DESCRIPTOR_TYPE(prefix_node) != | ||
331 | ACPI_DESC_TYPE_NAMED) { | ||
332 | ACPI_ERROR((AE_INFO, "%p is not a namespace node [%s]", | ||
333 | prefix_node, | ||
334 | acpi_ut_get_descriptor_name(prefix_node))); | ||
335 | return_ACPI_STATUS(AE_AML_INTERNAL); | ||
336 | } | ||
337 | |||
338 | if (!(flags & ACPI_NS_PREFIX_IS_SCOPE)) { | ||
339 | /* | ||
340 | * This node might not be a actual "scope" node (such as a | ||
341 | * Device/Method, etc.) It could be a Package or other object node. | ||
342 | * Backup up the tree to find the containing scope node. | ||
343 | */ | ||
344 | while (!acpi_ns_opens_scope(prefix_node->type) && | ||
345 | prefix_node->type != ACPI_TYPE_ANY) { | ||
346 | prefix_node = | ||
347 | acpi_ns_get_parent_node(prefix_node); | ||
348 | } | ||
349 | } | ||
350 | } | ||
351 | |||
352 | /* Save type TBD: may be no longer necessary */ | ||
353 | |||
354 | type_to_check_for = type; | ||
355 | |||
356 | /* | ||
357 | * Begin examination of the actual pathname | ||
358 | */ | ||
359 | if (!pathname) { | ||
360 | |||
361 | /* A Null name_path is allowed and refers to the root */ | ||
362 | |||
363 | num_segments = 0; | ||
364 | this_node = acpi_gbl_root_node; | ||
365 | path = ""; | ||
366 | |||
367 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
368 | "Null Pathname (Zero segments), Flags=%X\n", | ||
369 | flags)); | ||
370 | } else { | ||
371 | /* | ||
372 | * Name pointer is valid (and must be in internal name format) | ||
373 | * | ||
374 | * Check for scope prefixes: | ||
375 | * | ||
376 | * As represented in the AML stream, a namepath consists of an | ||
377 | * optional scope prefix followed by a name segment part. | ||
378 | * | ||
379 | * If present, the scope prefix is either a Root Prefix (in | ||
380 | * which case the name is fully qualified), or one or more | ||
381 | * Parent Prefixes (in which case the name's scope is relative | ||
382 | * to the current scope). | ||
383 | */ | ||
384 | if (*path == (u8) AML_ROOT_PREFIX) { | ||
385 | |||
386 | /* Pathname is fully qualified, start from the root */ | ||
387 | |||
388 | this_node = acpi_gbl_root_node; | ||
389 | search_parent_flag = ACPI_NS_NO_UPSEARCH; | ||
390 | |||
391 | /* Point to name segment part */ | ||
392 | |||
393 | path++; | ||
394 | |||
395 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
396 | "Path is absolute from root [%p]\n", | ||
397 | this_node)); | ||
398 | } else { | ||
399 | /* Pathname is relative to current scope, start there */ | ||
400 | |||
401 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
402 | "Searching relative to prefix scope [%4.4s] (%p)\n", | ||
403 | acpi_ut_get_node_name(prefix_node), | ||
404 | prefix_node)); | ||
405 | |||
406 | /* | ||
407 | * Handle multiple Parent Prefixes (carat) by just getting | ||
408 | * the parent node for each prefix instance. | ||
409 | */ | ||
410 | this_node = prefix_node; | ||
411 | num_carats = 0; | ||
412 | while (*path == (u8) AML_PARENT_PREFIX) { | ||
413 | |||
414 | /* Name is fully qualified, no search rules apply */ | ||
415 | |||
416 | search_parent_flag = ACPI_NS_NO_UPSEARCH; | ||
417 | /* | ||
418 | * Point past this prefix to the name segment | ||
419 | * part or the next Parent Prefix | ||
420 | */ | ||
421 | path++; | ||
422 | |||
423 | /* Backup to the parent node */ | ||
424 | |||
425 | num_carats++; | ||
426 | this_node = acpi_ns_get_parent_node(this_node); | ||
427 | if (!this_node) { | ||
428 | |||
429 | /* Current scope has no parent scope */ | ||
430 | |||
431 | ACPI_ERROR((AE_INFO, | ||
432 | "ACPI path has too many parent prefixes (^) - reached beyond root node")); | ||
433 | return_ACPI_STATUS(AE_NOT_FOUND); | ||
434 | } | ||
435 | } | ||
436 | |||
437 | if (search_parent_flag == ACPI_NS_NO_UPSEARCH) { | ||
438 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
439 | "Search scope is [%4.4s], path has %d carat(s)\n", | ||
440 | acpi_ut_get_node_name | ||
441 | (this_node), num_carats)); | ||
442 | } | ||
443 | } | ||
444 | |||
445 | /* | ||
446 | * Determine the number of ACPI name segments in this pathname. | ||
447 | * | ||
448 | * The segment part consists of either: | ||
449 | * - A Null name segment (0) | ||
450 | * - A dual_name_prefix followed by two 4-byte name segments | ||
451 | * - A multi_name_prefix followed by a byte indicating the | ||
452 | * number of segments and the segments themselves. | ||
453 | * - A single 4-byte name segment | ||
454 | * | ||
455 | * Examine the name prefix opcode, if any, to determine the number of | ||
456 | * segments. | ||
457 | */ | ||
458 | switch (*path) { | ||
459 | case 0: | ||
460 | /* | ||
461 | * Null name after a root or parent prefixes. We already | ||
462 | * have the correct target node and there are no name segments. | ||
463 | */ | ||
464 | num_segments = 0; | ||
465 | type = this_node->type; | ||
466 | |||
467 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
468 | "Prefix-only Pathname (Zero name segments), Flags=%X\n", | ||
469 | flags)); | ||
470 | break; | ||
471 | |||
472 | case AML_DUAL_NAME_PREFIX: | ||
473 | |||
474 | /* More than one name_seg, search rules do not apply */ | ||
475 | |||
476 | search_parent_flag = ACPI_NS_NO_UPSEARCH; | ||
477 | |||
478 | /* Two segments, point to first name segment */ | ||
479 | |||
480 | num_segments = 2; | ||
481 | path++; | ||
482 | |||
483 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
484 | "Dual Pathname (2 segments, Flags=%X)\n", | ||
485 | flags)); | ||
486 | break; | ||
487 | |||
488 | case AML_MULTI_NAME_PREFIX_OP: | ||
489 | |||
490 | /* More than one name_seg, search rules do not apply */ | ||
491 | |||
492 | search_parent_flag = ACPI_NS_NO_UPSEARCH; | ||
493 | |||
494 | /* Extract segment count, point to first name segment */ | ||
495 | |||
496 | path++; | ||
497 | num_segments = (u32) (u8) * path; | ||
498 | path++; | ||
499 | |||
500 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
501 | "Multi Pathname (%d Segments, Flags=%X)\n", | ||
502 | num_segments, flags)); | ||
503 | break; | ||
504 | |||
505 | default: | ||
506 | /* | ||
507 | * Not a Null name, no Dual or Multi prefix, hence there is | ||
508 | * only one name segment and Pathname is already pointing to it. | ||
509 | */ | ||
510 | num_segments = 1; | ||
511 | |||
512 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
513 | "Simple Pathname (1 segment, Flags=%X)\n", | ||
514 | flags)); | ||
515 | break; | ||
516 | } | ||
517 | |||
518 | ACPI_DEBUG_EXEC(acpi_ns_print_pathname(num_segments, path)); | ||
519 | } | ||
520 | |||
521 | /* | ||
522 | * Search namespace for each segment of the name. Loop through and | ||
523 | * verify (or add to the namespace) each name segment. | ||
524 | * | ||
525 | * The object type is significant only at the last name | ||
526 | * segment. (We don't care about the types along the path, only | ||
527 | * the type of the final target object.) | ||
528 | */ | ||
529 | this_search_type = ACPI_TYPE_ANY; | ||
530 | current_node = this_node; | ||
531 | while (num_segments && current_node) { | ||
532 | num_segments--; | ||
533 | if (!num_segments) { | ||
534 | /* | ||
535 | * This is the last segment, enable typechecking | ||
536 | */ | ||
537 | this_search_type = type; | ||
538 | |||
539 | /* | ||
540 | * Only allow automatic parent search (search rules) if the caller | ||
541 | * requested it AND we have a single, non-fully-qualified name_seg | ||
542 | */ | ||
543 | if ((search_parent_flag != ACPI_NS_NO_UPSEARCH) && | ||
544 | (flags & ACPI_NS_SEARCH_PARENT)) { | ||
545 | local_flags |= ACPI_NS_SEARCH_PARENT; | ||
546 | } | ||
547 | |||
548 | /* Set error flag according to caller */ | ||
549 | |||
550 | if (flags & ACPI_NS_ERROR_IF_FOUND) { | ||
551 | local_flags |= ACPI_NS_ERROR_IF_FOUND; | ||
552 | } | ||
553 | } | ||
554 | |||
555 | /* Extract one ACPI name from the front of the pathname */ | ||
556 | |||
557 | ACPI_MOVE_32_TO_32(&simple_name, path); | ||
558 | |||
559 | /* Try to find the single (4 character) ACPI name */ | ||
560 | |||
561 | status = | ||
562 | acpi_ns_search_and_enter(simple_name, walk_state, | ||
563 | current_node, interpreter_mode, | ||
564 | this_search_type, local_flags, | ||
565 | &this_node); | ||
566 | if (ACPI_FAILURE(status)) { | ||
567 | if (status == AE_NOT_FOUND) { | ||
568 | |||
569 | /* Name not found in ACPI namespace */ | ||
570 | |||
571 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
572 | "Name [%4.4s] not found in scope [%4.4s] %p\n", | ||
573 | (char *)&simple_name, | ||
574 | (char *)¤t_node->name, | ||
575 | current_node)); | ||
576 | } | ||
577 | |||
578 | *return_node = this_node; | ||
579 | return_ACPI_STATUS(status); | ||
580 | } | ||
581 | |||
582 | /* More segments to follow? */ | ||
583 | |||
584 | if (num_segments > 0) { | ||
585 | /* | ||
586 | * If we have an alias to an object that opens a scope (such as a | ||
587 | * device or processor), we need to dereference the alias here so that | ||
588 | * we can access any children of the original node (via the remaining | ||
589 | * segments). | ||
590 | */ | ||
591 | if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) { | ||
592 | if (!this_node->object) { | ||
593 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
594 | } | ||
595 | |||
596 | if (acpi_ns_opens_scope | ||
597 | (((struct acpi_namespace_node *)this_node-> | ||
598 | object)->type)) { | ||
599 | this_node = | ||
600 | (struct acpi_namespace_node *) | ||
601 | this_node->object; | ||
602 | } | ||
603 | } | ||
604 | } | ||
605 | |||
606 | /* Special handling for the last segment (num_segments == 0) */ | ||
607 | |||
608 | else { | ||
609 | /* | ||
610 | * Sanity typecheck of the target object: | ||
611 | * | ||
612 | * If 1) This is the last segment (num_segments == 0) | ||
613 | * 2) And we are looking for a specific type | ||
614 | * (Not checking for TYPE_ANY) | ||
615 | * 3) Which is not an alias | ||
616 | * 4) Which is not a local type (TYPE_SCOPE) | ||
617 | * 5) And the type of target object is known (not TYPE_ANY) | ||
618 | * 6) And target object does not match what we are looking for | ||
619 | * | ||
620 | * Then we have a type mismatch. Just warn and ignore it. | ||
621 | */ | ||
622 | if ((type_to_check_for != ACPI_TYPE_ANY) && | ||
623 | (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) && | ||
624 | (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS) | ||
625 | && (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE) | ||
626 | && (this_node->type != ACPI_TYPE_ANY) | ||
627 | && (this_node->type != type_to_check_for)) { | ||
628 | |||
629 | /* Complain about a type mismatch */ | ||
630 | |||
631 | ACPI_WARNING((AE_INFO, | ||
632 | "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)", | ||
633 | ACPI_CAST_PTR(char, &simple_name), | ||
634 | acpi_ut_get_type_name(this_node-> | ||
635 | type), | ||
636 | acpi_ut_get_type_name | ||
637 | (type_to_check_for))); | ||
638 | } | ||
639 | |||
640 | /* | ||
641 | * If this is the last name segment and we are not looking for a | ||
642 | * specific type, but the type of found object is known, use that type | ||
643 | * to (later) see if it opens a scope. | ||
644 | */ | ||
645 | if (type == ACPI_TYPE_ANY) { | ||
646 | type = this_node->type; | ||
647 | } | ||
648 | } | ||
649 | |||
650 | /* Point to next name segment and make this node current */ | ||
651 | |||
652 | path += ACPI_NAME_SIZE; | ||
653 | current_node = this_node; | ||
654 | } | ||
655 | |||
656 | /* | ||
657 | * Always check if we need to open a new scope | ||
658 | */ | ||
659 | if (!(flags & ACPI_NS_DONT_OPEN_SCOPE) && (walk_state)) { | ||
660 | /* | ||
661 | * If entry is a type which opens a scope, push the new scope on the | ||
662 | * scope stack. | ||
663 | */ | ||
664 | if (acpi_ns_opens_scope(type)) { | ||
665 | status = | ||
666 | acpi_ds_scope_stack_push(this_node, type, | ||
667 | walk_state); | ||
668 | if (ACPI_FAILURE(status)) { | ||
669 | return_ACPI_STATUS(status); | ||
670 | } | ||
671 | } | ||
672 | } | ||
673 | |||
674 | *return_node = this_node; | ||
675 | return_ACPI_STATUS(AE_OK); | ||
676 | } | ||
diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c deleted file mode 100644 index cb2afbf4e457..000000000000 --- a/drivers/acpi/namespace/nsalloc.c +++ /dev/null | |||
@@ -1,497 +0,0 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: nsalloc - Namespace allocation and deletion utilities | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2008, 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 <acpi/acpi.h> | ||
45 | #include <acpi/accommon.h> | ||
46 | #include <acpi/acnamesp.h> | ||
47 | |||
48 | #define _COMPONENT ACPI_NAMESPACE | ||
49 | ACPI_MODULE_NAME("nsalloc") | ||
50 | |||
51 | /******************************************************************************* | ||
52 | * | ||
53 | * FUNCTION: acpi_ns_create_node | ||
54 | * | ||
55 | * PARAMETERS: Name - Name of the new node (4 char ACPI name) | ||
56 | * | ||
57 | * RETURN: New namespace node (Null on failure) | ||
58 | * | ||
59 | * DESCRIPTION: Create a namespace node | ||
60 | * | ||
61 | ******************************************************************************/ | ||
62 | struct acpi_namespace_node *acpi_ns_create_node(u32 name) | ||
63 | { | ||
64 | struct acpi_namespace_node *node; | ||
65 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
66 | u32 temp; | ||
67 | #endif | ||
68 | |||
69 | ACPI_FUNCTION_TRACE(ns_create_node); | ||
70 | |||
71 | node = acpi_os_acquire_object(acpi_gbl_namespace_cache); | ||
72 | if (!node) { | ||
73 | return_PTR(NULL); | ||
74 | } | ||
75 | |||
76 | ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++); | ||
77 | |||
78 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
79 | temp = | ||
80 | acpi_gbl_ns_node_list->total_allocated - | ||
81 | acpi_gbl_ns_node_list->total_freed; | ||
82 | if (temp > acpi_gbl_ns_node_list->max_occupied) { | ||
83 | acpi_gbl_ns_node_list->max_occupied = temp; | ||
84 | } | ||
85 | #endif | ||
86 | |||
87 | node->name.integer = name; | ||
88 | ACPI_SET_DESCRIPTOR_TYPE(node, ACPI_DESC_TYPE_NAMED); | ||
89 | return_PTR(node); | ||
90 | } | ||
91 | |||
92 | /******************************************************************************* | ||
93 | * | ||
94 | * FUNCTION: acpi_ns_delete_node | ||
95 | * | ||
96 | * PARAMETERS: Node - Node to be deleted | ||
97 | * | ||
98 | * RETURN: None | ||
99 | * | ||
100 | * DESCRIPTION: Delete a namespace node | ||
101 | * | ||
102 | ******************************************************************************/ | ||
103 | |||
104 | void acpi_ns_delete_node(struct acpi_namespace_node *node) | ||
105 | { | ||
106 | struct acpi_namespace_node *parent_node; | ||
107 | struct acpi_namespace_node *prev_node; | ||
108 | struct acpi_namespace_node *next_node; | ||
109 | |||
110 | ACPI_FUNCTION_TRACE_PTR(ns_delete_node, node); | ||
111 | |||
112 | parent_node = acpi_ns_get_parent_node(node); | ||
113 | |||
114 | prev_node = NULL; | ||
115 | next_node = parent_node->child; | ||
116 | |||
117 | /* Find the node that is the previous peer in the parent's child list */ | ||
118 | |||
119 | while (next_node != node) { | ||
120 | prev_node = next_node; | ||
121 | next_node = prev_node->peer; | ||
122 | } | ||
123 | |||
124 | if (prev_node) { | ||
125 | |||
126 | /* Node is not first child, unlink it */ | ||
127 | |||
128 | prev_node->peer = next_node->peer; | ||
129 | if (next_node->flags & ANOBJ_END_OF_PEER_LIST) { | ||
130 | prev_node->flags |= ANOBJ_END_OF_PEER_LIST; | ||
131 | } | ||
132 | } else { | ||
133 | /* Node is first child (has no previous peer) */ | ||
134 | |||
135 | if (next_node->flags & ANOBJ_END_OF_PEER_LIST) { | ||
136 | |||
137 | /* No peers at all */ | ||
138 | |||
139 | parent_node->child = NULL; | ||
140 | } else { /* Link peer list to parent */ | ||
141 | |||
142 | parent_node->child = next_node->peer; | ||
143 | } | ||
144 | } | ||
145 | |||
146 | ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); | ||
147 | |||
148 | /* | ||
149 | * Detach an object if there is one, then delete the node | ||
150 | */ | ||
151 | acpi_ns_detach_object(node); | ||
152 | (void)acpi_os_release_object(acpi_gbl_namespace_cache, node); | ||
153 | return_VOID; | ||
154 | } | ||
155 | |||
156 | /******************************************************************************* | ||
157 | * | ||
158 | * FUNCTION: acpi_ns_install_node | ||
159 | * | ||
160 | * PARAMETERS: walk_state - Current state of the walk | ||
161 | * parent_node - The parent of the new Node | ||
162 | * Node - The new Node to install | ||
163 | * Type - ACPI object type of the new Node | ||
164 | * | ||
165 | * RETURN: None | ||
166 | * | ||
167 | * DESCRIPTION: Initialize a new namespace node and install it amongst | ||
168 | * its peers. | ||
169 | * | ||
170 | * Note: Current namespace lookup is linear search. This appears | ||
171 | * to be sufficient as namespace searches consume only a small | ||
172 | * fraction of the execution time of the ACPI subsystem. | ||
173 | * | ||
174 | ******************************************************************************/ | ||
175 | |||
176 | void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namespace_node *parent_node, /* Parent */ | ||
177 | struct acpi_namespace_node *node, /* New Child */ | ||
178 | acpi_object_type type) | ||
179 | { | ||
180 | acpi_owner_id owner_id = 0; | ||
181 | struct acpi_namespace_node *child_node; | ||
182 | |||
183 | ACPI_FUNCTION_TRACE(ns_install_node); | ||
184 | |||
185 | /* | ||
186 | * Get the owner ID from the Walk state | ||
187 | * The owner ID is used to track table deletion and | ||
188 | * deletion of objects created by methods | ||
189 | */ | ||
190 | if (walk_state) { | ||
191 | owner_id = walk_state->owner_id; | ||
192 | } | ||
193 | |||
194 | /* Link the new entry into the parent and existing children */ | ||
195 | |||
196 | child_node = parent_node->child; | ||
197 | if (!child_node) { | ||
198 | parent_node->child = node; | ||
199 | node->flags |= ANOBJ_END_OF_PEER_LIST; | ||
200 | node->peer = parent_node; | ||
201 | } else { | ||
202 | while (!(child_node->flags & ANOBJ_END_OF_PEER_LIST)) { | ||
203 | child_node = child_node->peer; | ||
204 | } | ||
205 | |||
206 | child_node->peer = node; | ||
207 | |||
208 | /* Clear end-of-list flag */ | ||
209 | |||
210 | child_node->flags &= ~ANOBJ_END_OF_PEER_LIST; | ||
211 | node->flags |= ANOBJ_END_OF_PEER_LIST; | ||
212 | node->peer = parent_node; | ||
213 | } | ||
214 | |||
215 | /* Init the new entry */ | ||
216 | |||
217 | node->owner_id = owner_id; | ||
218 | node->type = (u8) type; | ||
219 | |||
220 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
221 | "%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n", | ||
222 | acpi_ut_get_node_name(node), | ||
223 | acpi_ut_get_type_name(node->type), node, owner_id, | ||
224 | acpi_ut_get_node_name(parent_node), | ||
225 | acpi_ut_get_type_name(parent_node->type), | ||
226 | parent_node)); | ||
227 | |||
228 | return_VOID; | ||
229 | } | ||
230 | |||
231 | /******************************************************************************* | ||
232 | * | ||
233 | * FUNCTION: acpi_ns_delete_children | ||
234 | * | ||
235 | * PARAMETERS: parent_node - Delete this objects children | ||
236 | * | ||
237 | * RETURN: None. | ||
238 | * | ||
239 | * DESCRIPTION: Delete all children of the parent object. In other words, | ||
240 | * deletes a "scope". | ||
241 | * | ||
242 | ******************************************************************************/ | ||
243 | |||
244 | void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) | ||
245 | { | ||
246 | struct acpi_namespace_node *child_node; | ||
247 | struct acpi_namespace_node *next_node; | ||
248 | u8 flags; | ||
249 | |||
250 | ACPI_FUNCTION_TRACE_PTR(ns_delete_children, parent_node); | ||
251 | |||
252 | if (!parent_node) { | ||
253 | return_VOID; | ||
254 | } | ||
255 | |||
256 | /* If no children, all done! */ | ||
257 | |||
258 | child_node = parent_node->child; | ||
259 | if (!child_node) { | ||
260 | return_VOID; | ||
261 | } | ||
262 | |||
263 | /* | ||
264 | * Deallocate all children at this level | ||
265 | */ | ||
266 | do { | ||
267 | |||
268 | /* Get the things we need */ | ||
269 | |||
270 | next_node = child_node->peer; | ||
271 | flags = child_node->flags; | ||
272 | |||
273 | /* Grandchildren should have all been deleted already */ | ||
274 | |||
275 | if (child_node->child) { | ||
276 | ACPI_ERROR((AE_INFO, "Found a grandchild! P=%p C=%p", | ||
277 | parent_node, child_node)); | ||
278 | } | ||
279 | |||
280 | /* Now we can free this child object */ | ||
281 | |||
282 | ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); | ||
283 | |||
284 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
285 | "Object %p, Remaining %X\n", child_node, | ||
286 | acpi_gbl_current_node_count)); | ||
287 | |||
288 | /* | ||
289 | * Detach an object if there is one, then free the child node | ||
290 | */ | ||
291 | acpi_ns_detach_object(child_node); | ||
292 | |||
293 | /* Now we can delete the node */ | ||
294 | |||
295 | (void)acpi_os_release_object(acpi_gbl_namespace_cache, | ||
296 | child_node); | ||
297 | |||
298 | /* And move on to the next child in the list */ | ||
299 | |||
300 | child_node = next_node; | ||
301 | |||
302 | } while (!(flags & ANOBJ_END_OF_PEER_LIST)); | ||
303 | |||
304 | /* Clear the parent's child pointer */ | ||
305 | |||
306 | parent_node->child = NULL; | ||
307 | |||
308 | return_VOID; | ||
309 | } | ||
310 | |||
311 | /******************************************************************************* | ||
312 | * | ||
313 | * FUNCTION: acpi_ns_delete_namespace_subtree | ||
314 | * | ||
315 | * PARAMETERS: parent_node - Root of the subtree to be deleted | ||
316 | * | ||
317 | * RETURN: None. | ||
318 | * | ||
319 | * DESCRIPTION: Delete a subtree of the namespace. This includes all objects | ||
320 | * stored within the subtree. | ||
321 | * | ||
322 | ******************************************************************************/ | ||
323 | |||
324 | void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) | ||
325 | { | ||
326 | struct acpi_namespace_node *child_node = NULL; | ||
327 | u32 level = 1; | ||
328 | |||
329 | ACPI_FUNCTION_TRACE(ns_delete_namespace_subtree); | ||
330 | |||
331 | if (!parent_node) { | ||
332 | return_VOID; | ||
333 | } | ||
334 | |||
335 | /* | ||
336 | * Traverse the tree of objects until we bubble back up | ||
337 | * to where we started. | ||
338 | */ | ||
339 | while (level > 0) { | ||
340 | |||
341 | /* Get the next node in this scope (NULL if none) */ | ||
342 | |||
343 | child_node = | ||
344 | acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, | ||
345 | child_node); | ||
346 | if (child_node) { | ||
347 | |||
348 | /* Found a child node - detach any attached object */ | ||
349 | |||
350 | acpi_ns_detach_object(child_node); | ||
351 | |||
352 | /* Check if this node has any children */ | ||
353 | |||
354 | if (acpi_ns_get_next_node | ||
355 | (ACPI_TYPE_ANY, child_node, NULL)) { | ||
356 | /* | ||
357 | * There is at least one child of this node, | ||
358 | * visit the node | ||
359 | */ | ||
360 | level++; | ||
361 | parent_node = child_node; | ||
362 | child_node = NULL; | ||
363 | } | ||
364 | } else { | ||
365 | /* | ||
366 | * No more children of this parent node. | ||
367 | * Move up to the grandparent. | ||
368 | */ | ||
369 | level--; | ||
370 | |||
371 | /* | ||
372 | * Now delete all of the children of this parent | ||
373 | * all at the same time. | ||
374 | */ | ||
375 | acpi_ns_delete_children(parent_node); | ||
376 | |||
377 | /* New "last child" is this parent node */ | ||
378 | |||
379 | child_node = parent_node; | ||
380 | |||
381 | /* Move up the tree to the grandparent */ | ||
382 | |||
383 | parent_node = acpi_ns_get_parent_node(parent_node); | ||
384 | } | ||
385 | } | ||
386 | |||
387 | return_VOID; | ||
388 | } | ||
389 | |||
390 | /******************************************************************************* | ||
391 | * | ||
392 | * FUNCTION: acpi_ns_delete_namespace_by_owner | ||
393 | * | ||
394 | * PARAMETERS: owner_id - All nodes with this owner will be deleted | ||
395 | * | ||
396 | * RETURN: Status | ||
397 | * | ||
398 | * DESCRIPTION: Delete entries within the namespace that are owned by a | ||
399 | * specific ID. Used to delete entire ACPI tables. All | ||
400 | * reference counts are updated. | ||
401 | * | ||
402 | * MUTEX: Locks namespace during deletion walk. | ||
403 | * | ||
404 | ******************************************************************************/ | ||
405 | |||
406 | void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id) | ||
407 | { | ||
408 | struct acpi_namespace_node *child_node; | ||
409 | struct acpi_namespace_node *deletion_node; | ||
410 | struct acpi_namespace_node *parent_node; | ||
411 | u32 level; | ||
412 | acpi_status status; | ||
413 | |||
414 | ACPI_FUNCTION_TRACE_U32(ns_delete_namespace_by_owner, owner_id); | ||
415 | |||
416 | if (owner_id == 0) { | ||
417 | return_VOID; | ||
418 | } | ||
419 | |||
420 | /* Lock namespace for possible update */ | ||
421 | |||
422 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
423 | if (ACPI_FAILURE(status)) { | ||
424 | return_VOID; | ||
425 | } | ||
426 | |||
427 | deletion_node = NULL; | ||
428 | parent_node = acpi_gbl_root_node; | ||
429 | child_node = NULL; | ||
430 | level = 1; | ||
431 | |||
432 | /* | ||
433 | * Traverse the tree of nodes until we bubble back up | ||
434 | * to where we started. | ||
435 | */ | ||
436 | while (level > 0) { | ||
437 | /* | ||
438 | * Get the next child of this parent node. When child_node is NULL, | ||
439 | * the first child of the parent is returned | ||
440 | */ | ||
441 | child_node = | ||
442 | acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, | ||
443 | child_node); | ||
444 | |||
445 | if (deletion_node) { | ||
446 | acpi_ns_delete_children(deletion_node); | ||
447 | acpi_ns_delete_node(deletion_node); | ||
448 | deletion_node = NULL; | ||
449 | } | ||
450 | |||
451 | if (child_node) { | ||
452 | if (child_node->owner_id == owner_id) { | ||
453 | |||
454 | /* Found a matching child node - detach any attached object */ | ||
455 | |||
456 | acpi_ns_detach_object(child_node); | ||
457 | } | ||
458 | |||
459 | /* Check if this node has any children */ | ||
460 | |||
461 | if (acpi_ns_get_next_node | ||
462 | (ACPI_TYPE_ANY, child_node, NULL)) { | ||
463 | /* | ||
464 | * There is at least one child of this node, | ||
465 | * visit the node | ||
466 | */ | ||
467 | level++; | ||
468 | parent_node = child_node; | ||
469 | child_node = NULL; | ||
470 | } else if (child_node->owner_id == owner_id) { | ||
471 | deletion_node = child_node; | ||
472 | } | ||
473 | } else { | ||
474 | /* | ||
475 | * No more children of this parent node. | ||
476 | * Move up to the grandparent. | ||
477 | */ | ||
478 | level--; | ||
479 | if (level != 0) { | ||
480 | if (parent_node->owner_id == owner_id) { | ||
481 | deletion_node = parent_node; | ||
482 | } | ||
483 | } | ||
484 | |||
485 | /* New "last child" is this parent node */ | ||
486 | |||
487 | child_node = parent_node; | ||
488 | |||
489 | /* Move up the tree to the grandparent */ | ||
490 | |||
491 | parent_node = acpi_ns_get_parent_node(parent_node); | ||
492 | } | ||
493 | } | ||
494 | |||
495 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
496 | return_VOID; | ||
497 | } | ||
diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c deleted file mode 100644 index 48f02e659f24..000000000000 --- a/drivers/acpi/namespace/nsdump.c +++ /dev/null | |||
@@ -1,709 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: nsdump - table dumping routines for debug | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2008, 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 <acpi/acpi.h> | ||
45 | #include <acpi/accommon.h> | ||
46 | #include <acpi/acnamesp.h> | ||
47 | |||
48 | #define _COMPONENT ACPI_NAMESPACE | ||
49 | ACPI_MODULE_NAME("nsdump") | ||
50 | |||
51 | /* Local prototypes */ | ||
52 | #ifdef ACPI_OBSOLETE_FUNCTIONS | ||
53 | void acpi_ns_dump_root_devices(void); | ||
54 | |||
55 | static acpi_status | ||
56 | acpi_ns_dump_one_device(acpi_handle obj_handle, | ||
57 | u32 level, void *context, void **return_value); | ||
58 | #endif | ||
59 | |||
60 | #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) | ||
61 | /******************************************************************************* | ||
62 | * | ||
63 | * FUNCTION: acpi_ns_print_pathname | ||
64 | * | ||
65 | * PARAMETERS: num_segments - Number of ACPI name segments | ||
66 | * Pathname - The compressed (internal) path | ||
67 | * | ||
68 | * RETURN: None | ||
69 | * | ||
70 | * DESCRIPTION: Print an object's full namespace pathname | ||
71 | * | ||
72 | ******************************************************************************/ | ||
73 | |||
74 | void acpi_ns_print_pathname(u32 num_segments, char *pathname) | ||
75 | { | ||
76 | u32 i; | ||
77 | |||
78 | ACPI_FUNCTION_NAME(ns_print_pathname); | ||
79 | |||
80 | if (!(acpi_dbg_level & ACPI_LV_NAMES) | ||
81 | || !(acpi_dbg_layer & ACPI_NAMESPACE)) { | ||
82 | return; | ||
83 | } | ||
84 | |||
85 | /* Print the entire name */ | ||
86 | |||
87 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "[")); | ||
88 | |||
89 | while (num_segments) { | ||
90 | for (i = 0; i < 4; i++) { | ||
91 | ACPI_IS_PRINT(pathname[i]) ? | ||
92 | acpi_os_printf("%c", pathname[i]) : | ||
93 | acpi_os_printf("?"); | ||
94 | } | ||
95 | |||
96 | pathname += ACPI_NAME_SIZE; | ||
97 | num_segments--; | ||
98 | if (num_segments) { | ||
99 | acpi_os_printf("."); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | acpi_os_printf("]\n"); | ||
104 | } | ||
105 | |||
106 | /******************************************************************************* | ||
107 | * | ||
108 | * FUNCTION: acpi_ns_dump_pathname | ||
109 | * | ||
110 | * PARAMETERS: Handle - Object | ||
111 | * Msg - Prefix message | ||
112 | * Level - Desired debug level | ||
113 | * Component - Caller's component ID | ||
114 | * | ||
115 | * RETURN: None | ||
116 | * | ||
117 | * DESCRIPTION: Print an object's full namespace pathname | ||
118 | * Manages allocation/freeing of a pathname buffer | ||
119 | * | ||
120 | ******************************************************************************/ | ||
121 | |||
122 | void | ||
123 | acpi_ns_dump_pathname(acpi_handle handle, char *msg, u32 level, u32 component) | ||
124 | { | ||
125 | |||
126 | ACPI_FUNCTION_TRACE(ns_dump_pathname); | ||
127 | |||
128 | /* Do this only if the requested debug level and component are enabled */ | ||
129 | |||
130 | if (!(acpi_dbg_level & level) || !(acpi_dbg_layer & component)) { | ||
131 | return_VOID; | ||
132 | } | ||
133 | |||
134 | /* Convert handle to a full pathname and print it (with supplied message) */ | ||
135 | |||
136 | acpi_ns_print_node_pathname(handle, msg); | ||
137 | acpi_os_printf("\n"); | ||
138 | return_VOID; | ||
139 | } | ||
140 | |||
141 | /******************************************************************************* | ||
142 | * | ||
143 | * FUNCTION: acpi_ns_dump_one_object | ||
144 | * | ||
145 | * PARAMETERS: obj_handle - Node to be dumped | ||
146 | * Level - Nesting level of the handle | ||
147 | * Context - Passed into walk_namespace | ||
148 | * return_value - Not used | ||
149 | * | ||
150 | * RETURN: Status | ||
151 | * | ||
152 | * DESCRIPTION: Dump a single Node | ||
153 | * This procedure is a user_function called by acpi_ns_walk_namespace. | ||
154 | * | ||
155 | ******************************************************************************/ | ||
156 | |||
157 | acpi_status | ||
158 | acpi_ns_dump_one_object(acpi_handle obj_handle, | ||
159 | u32 level, void *context, void **return_value) | ||
160 | { | ||
161 | struct acpi_walk_info *info = (struct acpi_walk_info *)context; | ||
162 | struct acpi_namespace_node *this_node; | ||
163 | union acpi_operand_object *obj_desc = NULL; | ||
164 | acpi_object_type obj_type; | ||
165 | acpi_object_type type; | ||
166 | u32 bytes_to_dump; | ||
167 | u32 dbg_level; | ||
168 | u32 i; | ||
169 | |||
170 | ACPI_FUNCTION_NAME(ns_dump_one_object); | ||
171 | |||
172 | /* Is output enabled? */ | ||
173 | |||
174 | if (!(acpi_dbg_level & info->debug_level)) { | ||
175 | return (AE_OK); | ||
176 | } | ||
177 | |||
178 | if (!obj_handle) { | ||
179 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Null object handle\n")); | ||
180 | return (AE_OK); | ||
181 | } | ||
182 | |||
183 | this_node = acpi_ns_map_handle_to_node(obj_handle); | ||
184 | type = this_node->type; | ||
185 | |||
186 | /* Check if the owner matches */ | ||
187 | |||
188 | if ((info->owner_id != ACPI_OWNER_ID_MAX) && | ||
189 | (info->owner_id != this_node->owner_id)) { | ||
190 | return (AE_OK); | ||
191 | } | ||
192 | |||
193 | if (!(info->display_type & ACPI_DISPLAY_SHORT)) { | ||
194 | |||
195 | /* Indent the object according to the level */ | ||
196 | |||
197 | acpi_os_printf("%2d%*s", (u32) level - 1, (int)level * 2, " "); | ||
198 | |||
199 | /* Check the node type and name */ | ||
200 | |||
201 | if (type > ACPI_TYPE_LOCAL_MAX) { | ||
202 | ACPI_WARNING((AE_INFO, "Invalid ACPI Object Type %08X", | ||
203 | type)); | ||
204 | } | ||
205 | |||
206 | if (!acpi_ut_valid_acpi_name(this_node->name.integer)) { | ||
207 | this_node->name.integer = | ||
208 | acpi_ut_repair_name(this_node->name.ascii); | ||
209 | |||
210 | ACPI_WARNING((AE_INFO, "Invalid ACPI Name %08X", | ||
211 | this_node->name.integer)); | ||
212 | } | ||
213 | |||
214 | acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node)); | ||
215 | } | ||
216 | |||
217 | /* | ||
218 | * Now we can print out the pertinent information | ||
219 | */ | ||
220 | acpi_os_printf(" %-12s %p %2.2X ", | ||
221 | acpi_ut_get_type_name(type), this_node, | ||
222 | this_node->owner_id); | ||
223 | |||
224 | dbg_level = acpi_dbg_level; | ||
225 | acpi_dbg_level = 0; | ||
226 | obj_desc = acpi_ns_get_attached_object(this_node); | ||
227 | acpi_dbg_level = dbg_level; | ||
228 | |||
229 | /* Temp nodes are those nodes created by a control method */ | ||
230 | |||
231 | if (this_node->flags & ANOBJ_TEMPORARY) { | ||
232 | acpi_os_printf("(T) "); | ||
233 | } | ||
234 | |||
235 | switch (info->display_type & ACPI_DISPLAY_MASK) { | ||
236 | case ACPI_DISPLAY_SUMMARY: | ||
237 | |||
238 | if (!obj_desc) { | ||
239 | |||
240 | /* No attached object, we are done */ | ||
241 | |||
242 | acpi_os_printf("\n"); | ||
243 | return (AE_OK); | ||
244 | } | ||
245 | |||
246 | switch (type) { | ||
247 | case ACPI_TYPE_PROCESSOR: | ||
248 | |||
249 | acpi_os_printf("ID %X Len %.4X Addr %p\n", | ||
250 | obj_desc->processor.proc_id, | ||
251 | obj_desc->processor.length, | ||
252 | ACPI_CAST_PTR(void, | ||
253 | obj_desc->processor. | ||
254 | address)); | ||
255 | break; | ||
256 | |||
257 | case ACPI_TYPE_DEVICE: | ||
258 | |||
259 | acpi_os_printf("Notify Object: %p\n", obj_desc); | ||
260 | break; | ||
261 | |||
262 | case ACPI_TYPE_METHOD: | ||
263 | |||
264 | acpi_os_printf("Args %X Len %.4X Aml %p\n", | ||
265 | (u32) obj_desc->method.param_count, | ||
266 | obj_desc->method.aml_length, | ||
267 | obj_desc->method.aml_start); | ||
268 | break; | ||
269 | |||
270 | case ACPI_TYPE_INTEGER: | ||
271 | |||
272 | acpi_os_printf("= %8.8X%8.8X\n", | ||
273 | ACPI_FORMAT_UINT64(obj_desc->integer. | ||
274 | value)); | ||
275 | break; | ||
276 | |||
277 | case ACPI_TYPE_PACKAGE: | ||
278 | |||
279 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { | ||
280 | acpi_os_printf("Elements %.2X\n", | ||
281 | obj_desc->package.count); | ||
282 | } else { | ||
283 | acpi_os_printf("[Length not yet evaluated]\n"); | ||
284 | } | ||
285 | break; | ||
286 | |||
287 | case ACPI_TYPE_BUFFER: | ||
288 | |||
289 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { | ||
290 | acpi_os_printf("Len %.2X", | ||
291 | obj_desc->buffer.length); | ||
292 | |||
293 | /* Dump some of the buffer */ | ||
294 | |||
295 | if (obj_desc->buffer.length > 0) { | ||
296 | acpi_os_printf(" ="); | ||
297 | for (i = 0; | ||
298 | (i < obj_desc->buffer.length | ||
299 | && i < 12); i++) { | ||
300 | acpi_os_printf(" %.2hX", | ||
301 | obj_desc->buffer. | ||
302 | pointer[i]); | ||
303 | } | ||
304 | } | ||
305 | acpi_os_printf("\n"); | ||
306 | } else { | ||
307 | acpi_os_printf("[Length not yet evaluated]\n"); | ||
308 | } | ||
309 | break; | ||
310 | |||
311 | case ACPI_TYPE_STRING: | ||
312 | |||
313 | acpi_os_printf("Len %.2X ", obj_desc->string.length); | ||
314 | acpi_ut_print_string(obj_desc->string.pointer, 32); | ||
315 | acpi_os_printf("\n"); | ||
316 | break; | ||
317 | |||
318 | case ACPI_TYPE_REGION: | ||
319 | |||
320 | acpi_os_printf("[%s]", | ||
321 | acpi_ut_get_region_name(obj_desc->region. | ||
322 | space_id)); | ||
323 | if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { | ||
324 | acpi_os_printf(" Addr %8.8X%8.8X Len %.4X\n", | ||
325 | ACPI_FORMAT_NATIVE_UINT | ||
326 | (obj_desc->region.address), | ||
327 | obj_desc->region.length); | ||
328 | } else { | ||
329 | acpi_os_printf | ||
330 | (" [Address/Length not yet evaluated]\n"); | ||
331 | } | ||
332 | break; | ||
333 | |||
334 | case ACPI_TYPE_LOCAL_REFERENCE: | ||
335 | |||
336 | acpi_os_printf("[%s]\n", | ||
337 | acpi_ut_get_reference_name(obj_desc)); | ||
338 | break; | ||
339 | |||
340 | case ACPI_TYPE_BUFFER_FIELD: | ||
341 | |||
342 | if (obj_desc->buffer_field.buffer_obj && | ||
343 | obj_desc->buffer_field.buffer_obj->buffer.node) { | ||
344 | acpi_os_printf("Buf [%4.4s]", | ||
345 | acpi_ut_get_node_name(obj_desc-> | ||
346 | buffer_field. | ||
347 | buffer_obj-> | ||
348 | buffer. | ||
349 | node)); | ||
350 | } | ||
351 | break; | ||
352 | |||
353 | case ACPI_TYPE_LOCAL_REGION_FIELD: | ||
354 | |||
355 | acpi_os_printf("Rgn [%4.4s]", | ||
356 | acpi_ut_get_node_name(obj_desc-> | ||
357 | common_field. | ||
358 | region_obj->region. | ||
359 | node)); | ||
360 | break; | ||
361 | |||
362 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
363 | |||
364 | acpi_os_printf("Rgn [%4.4s] Bnk [%4.4s]", | ||
365 | acpi_ut_get_node_name(obj_desc-> | ||
366 | common_field. | ||
367 | region_obj->region. | ||
368 | node), | ||
369 | acpi_ut_get_node_name(obj_desc-> | ||
370 | bank_field. | ||
371 | bank_obj-> | ||
372 | common_field. | ||
373 | node)); | ||
374 | break; | ||
375 | |||
376 | case ACPI_TYPE_LOCAL_INDEX_FIELD: | ||
377 | |||
378 | acpi_os_printf("Idx [%4.4s] Dat [%4.4s]", | ||
379 | acpi_ut_get_node_name(obj_desc-> | ||
380 | index_field. | ||
381 | index_obj-> | ||
382 | common_field.node), | ||
383 | acpi_ut_get_node_name(obj_desc-> | ||
384 | index_field. | ||
385 | data_obj-> | ||
386 | common_field. | ||
387 | node)); | ||
388 | break; | ||
389 | |||
390 | case ACPI_TYPE_LOCAL_ALIAS: | ||
391 | case ACPI_TYPE_LOCAL_METHOD_ALIAS: | ||
392 | |||
393 | acpi_os_printf("Target %4.4s (%p)\n", | ||
394 | acpi_ut_get_node_name(obj_desc), | ||
395 | obj_desc); | ||
396 | break; | ||
397 | |||
398 | default: | ||
399 | |||
400 | acpi_os_printf("Object %p\n", obj_desc); | ||
401 | break; | ||
402 | } | ||
403 | |||
404 | /* Common field handling */ | ||
405 | |||
406 | switch (type) { | ||
407 | case ACPI_TYPE_BUFFER_FIELD: | ||
408 | case ACPI_TYPE_LOCAL_REGION_FIELD: | ||
409 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
410 | case ACPI_TYPE_LOCAL_INDEX_FIELD: | ||
411 | |||
412 | acpi_os_printf(" Off %.3X Len %.2X Acc %.2hd\n", | ||
413 | (obj_desc->common_field. | ||
414 | base_byte_offset * 8) | ||
415 | + | ||
416 | obj_desc->common_field. | ||
417 | start_field_bit_offset, | ||
418 | obj_desc->common_field.bit_length, | ||
419 | obj_desc->common_field. | ||
420 | access_byte_width); | ||
421 | break; | ||
422 | |||
423 | default: | ||
424 | break; | ||
425 | } | ||
426 | break; | ||
427 | |||
428 | case ACPI_DISPLAY_OBJECTS: | ||
429 | |||
430 | acpi_os_printf("O:%p", obj_desc); | ||
431 | if (!obj_desc) { | ||
432 | |||
433 | /* No attached object, we are done */ | ||
434 | |||
435 | acpi_os_printf("\n"); | ||
436 | return (AE_OK); | ||
437 | } | ||
438 | |||
439 | acpi_os_printf("(R%d)", obj_desc->common.reference_count); | ||
440 | |||
441 | switch (type) { | ||
442 | case ACPI_TYPE_METHOD: | ||
443 | |||
444 | /* Name is a Method and its AML offset/length are set */ | ||
445 | |||
446 | acpi_os_printf(" M:%p-%X\n", obj_desc->method.aml_start, | ||
447 | obj_desc->method.aml_length); | ||
448 | break; | ||
449 | |||
450 | case ACPI_TYPE_INTEGER: | ||
451 | |||
452 | acpi_os_printf(" I:%8.8X8.8%X\n", | ||
453 | ACPI_FORMAT_UINT64(obj_desc->integer. | ||
454 | value)); | ||
455 | break; | ||
456 | |||
457 | case ACPI_TYPE_STRING: | ||
458 | |||
459 | acpi_os_printf(" S:%p-%X\n", obj_desc->string.pointer, | ||
460 | obj_desc->string.length); | ||
461 | break; | ||
462 | |||
463 | case ACPI_TYPE_BUFFER: | ||
464 | |||
465 | acpi_os_printf(" B:%p-%X\n", obj_desc->buffer.pointer, | ||
466 | obj_desc->buffer.length); | ||
467 | break; | ||
468 | |||
469 | default: | ||
470 | |||
471 | acpi_os_printf("\n"); | ||
472 | break; | ||
473 | } | ||
474 | break; | ||
475 | |||
476 | default: | ||
477 | acpi_os_printf("\n"); | ||
478 | break; | ||
479 | } | ||
480 | |||
481 | /* If debug turned off, done */ | ||
482 | |||
483 | if (!(acpi_dbg_level & ACPI_LV_VALUES)) { | ||
484 | return (AE_OK); | ||
485 | } | ||
486 | |||
487 | /* If there is an attached object, display it */ | ||
488 | |||
489 | dbg_level = acpi_dbg_level; | ||
490 | acpi_dbg_level = 0; | ||
491 | obj_desc = acpi_ns_get_attached_object(this_node); | ||
492 | acpi_dbg_level = dbg_level; | ||
493 | |||
494 | /* Dump attached objects */ | ||
495 | |||
496 | while (obj_desc) { | ||
497 | obj_type = ACPI_TYPE_INVALID; | ||
498 | acpi_os_printf("Attached Object %p: ", obj_desc); | ||
499 | |||
500 | /* Decode the type of attached object and dump the contents */ | ||
501 | |||
502 | switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) { | ||
503 | case ACPI_DESC_TYPE_NAMED: | ||
504 | |||
505 | acpi_os_printf("(Ptr to Node)\n"); | ||
506 | bytes_to_dump = sizeof(struct acpi_namespace_node); | ||
507 | ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump); | ||
508 | break; | ||
509 | |||
510 | case ACPI_DESC_TYPE_OPERAND: | ||
511 | |||
512 | obj_type = ACPI_GET_OBJECT_TYPE(obj_desc); | ||
513 | |||
514 | if (obj_type > ACPI_TYPE_LOCAL_MAX) { | ||
515 | acpi_os_printf | ||
516 | ("(Pointer to ACPI Object type %.2X [UNKNOWN])\n", | ||
517 | obj_type); | ||
518 | bytes_to_dump = 32; | ||
519 | } else { | ||
520 | acpi_os_printf | ||
521 | ("(Pointer to ACPI Object type %.2X [%s])\n", | ||
522 | obj_type, acpi_ut_get_type_name(obj_type)); | ||
523 | bytes_to_dump = | ||
524 | sizeof(union acpi_operand_object); | ||
525 | } | ||
526 | |||
527 | ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump); | ||
528 | break; | ||
529 | |||
530 | default: | ||
531 | |||
532 | break; | ||
533 | } | ||
534 | |||
535 | /* If value is NOT an internal object, we are done */ | ||
536 | |||
537 | if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != | ||
538 | ACPI_DESC_TYPE_OPERAND) { | ||
539 | goto cleanup; | ||
540 | } | ||
541 | |||
542 | /* | ||
543 | * Valid object, get the pointer to next level, if any | ||
544 | */ | ||
545 | switch (obj_type) { | ||
546 | case ACPI_TYPE_BUFFER: | ||
547 | case ACPI_TYPE_STRING: | ||
548 | /* | ||
549 | * NOTE: takes advantage of common fields between string/buffer | ||
550 | */ | ||
551 | bytes_to_dump = obj_desc->string.length; | ||
552 | obj_desc = (void *)obj_desc->string.pointer; | ||
553 | acpi_os_printf("(Buffer/String pointer %p length %X)\n", | ||
554 | obj_desc, bytes_to_dump); | ||
555 | ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump); | ||
556 | goto cleanup; | ||
557 | |||
558 | case ACPI_TYPE_BUFFER_FIELD: | ||
559 | obj_desc = | ||
560 | (union acpi_operand_object *)obj_desc->buffer_field. | ||
561 | buffer_obj; | ||
562 | break; | ||
563 | |||
564 | case ACPI_TYPE_PACKAGE: | ||
565 | obj_desc = (void *)obj_desc->package.elements; | ||
566 | break; | ||
567 | |||
568 | case ACPI_TYPE_METHOD: | ||
569 | obj_desc = (void *)obj_desc->method.aml_start; | ||
570 | break; | ||
571 | |||
572 | case ACPI_TYPE_LOCAL_REGION_FIELD: | ||
573 | obj_desc = (void *)obj_desc->field.region_obj; | ||
574 | break; | ||
575 | |||
576 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
577 | obj_desc = (void *)obj_desc->bank_field.region_obj; | ||
578 | break; | ||
579 | |||
580 | case ACPI_TYPE_LOCAL_INDEX_FIELD: | ||
581 | obj_desc = (void *)obj_desc->index_field.index_obj; | ||
582 | break; | ||
583 | |||
584 | default: | ||
585 | goto cleanup; | ||
586 | } | ||
587 | |||
588 | obj_type = ACPI_TYPE_INVALID; /* Terminate loop after next pass */ | ||
589 | } | ||
590 | |||
591 | cleanup: | ||
592 | acpi_os_printf("\n"); | ||
593 | return (AE_OK); | ||
594 | } | ||
595 | |||
596 | #ifdef ACPI_FUTURE_USAGE | ||
597 | /******************************************************************************* | ||
598 | * | ||
599 | * FUNCTION: acpi_ns_dump_objects | ||
600 | * | ||
601 | * PARAMETERS: Type - Object type to be dumped | ||
602 | * display_type - 0 or ACPI_DISPLAY_SUMMARY | ||
603 | * max_depth - Maximum depth of dump. Use ACPI_UINT32_MAX | ||
604 | * for an effectively unlimited depth. | ||
605 | * owner_id - Dump only objects owned by this ID. Use | ||
606 | * ACPI_UINT32_MAX to match all owners. | ||
607 | * start_handle - Where in namespace to start/end search | ||
608 | * | ||
609 | * RETURN: None | ||
610 | * | ||
611 | * DESCRIPTION: Dump typed objects within the loaded namespace. | ||
612 | * Uses acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object. | ||
613 | * | ||
614 | ******************************************************************************/ | ||
615 | |||
616 | void | ||
617 | acpi_ns_dump_objects(acpi_object_type type, | ||
618 | u8 display_type, | ||
619 | u32 max_depth, | ||
620 | acpi_owner_id owner_id, acpi_handle start_handle) | ||
621 | { | ||
622 | struct acpi_walk_info info; | ||
623 | |||
624 | ACPI_FUNCTION_ENTRY(); | ||
625 | |||
626 | info.debug_level = ACPI_LV_TABLES; | ||
627 | info.owner_id = owner_id; | ||
628 | info.display_type = display_type; | ||
629 | |||
630 | (void)acpi_ns_walk_namespace(type, start_handle, max_depth, | ||
631 | ACPI_NS_WALK_NO_UNLOCK | | ||
632 | ACPI_NS_WALK_TEMP_NODES, | ||
633 | acpi_ns_dump_one_object, (void *)&info, | ||
634 | NULL); | ||
635 | } | ||
636 | #endif /* ACPI_FUTURE_USAGE */ | ||
637 | |||
638 | /******************************************************************************* | ||
639 | * | ||
640 | * FUNCTION: acpi_ns_dump_entry | ||
641 | * | ||
642 | * PARAMETERS: Handle - Node to be dumped | ||
643 | * debug_level - Output level | ||
644 | * | ||
645 | * RETURN: None | ||
646 | * | ||
647 | * DESCRIPTION: Dump a single Node | ||
648 | * | ||
649 | ******************************************************************************/ | ||
650 | |||
651 | void acpi_ns_dump_entry(acpi_handle handle, u32 debug_level) | ||
652 | { | ||
653 | struct acpi_walk_info info; | ||
654 | |||
655 | ACPI_FUNCTION_ENTRY(); | ||
656 | |||
657 | info.debug_level = debug_level; | ||
658 | info.owner_id = ACPI_OWNER_ID_MAX; | ||
659 | info.display_type = ACPI_DISPLAY_SUMMARY; | ||
660 | |||
661 | (void)acpi_ns_dump_one_object(handle, 1, &info, NULL); | ||
662 | } | ||
663 | |||
664 | #ifdef ACPI_ASL_COMPILER | ||
665 | /******************************************************************************* | ||
666 | * | ||
667 | * FUNCTION: acpi_ns_dump_tables | ||
668 | * | ||
669 | * PARAMETERS: search_base - Root of subtree to be dumped, or | ||
670 | * NS_ALL to dump the entire namespace | ||
671 | * max_depth - Maximum depth of dump. Use INT_MAX | ||
672 | * for an effectively unlimited depth. | ||
673 | * | ||
674 | * RETURN: None | ||
675 | * | ||
676 | * DESCRIPTION: Dump the name space, or a portion of it. | ||
677 | * | ||
678 | ******************************************************************************/ | ||
679 | |||
680 | void acpi_ns_dump_tables(acpi_handle search_base, u32 max_depth) | ||
681 | { | ||
682 | acpi_handle search_handle = search_base; | ||
683 | |||
684 | ACPI_FUNCTION_TRACE(ns_dump_tables); | ||
685 | |||
686 | if (!acpi_gbl_root_node) { | ||
687 | /* | ||
688 | * If the name space has not been initialized, | ||
689 | * there is nothing to dump. | ||
690 | */ | ||
691 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, | ||
692 | "namespace not initialized!\n")); | ||
693 | return_VOID; | ||
694 | } | ||
695 | |||
696 | if (ACPI_NS_ALL == search_base) { | ||
697 | |||
698 | /* Entire namespace */ | ||
699 | |||
700 | search_handle = acpi_gbl_root_node; | ||
701 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "\\\n")); | ||
702 | } | ||
703 | |||
704 | acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_OBJECTS, max_depth, | ||
705 | ACPI_OWNER_ID_MAX, search_handle); | ||
706 | return_VOID; | ||
707 | } | ||
708 | #endif /* _ACPI_ASL_COMPILER */ | ||
709 | #endif /* defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) */ | ||
diff --git a/drivers/acpi/namespace/nsdumpdv.c b/drivers/acpi/namespace/nsdumpdv.c deleted file mode 100644 index cc3df78258ed..000000000000 --- a/drivers/acpi/namespace/nsdumpdv.c +++ /dev/null | |||
@@ -1,141 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: nsdump - table dumping routines for debug | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2008, 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 <acpi/acpi.h> | ||
45 | #include <acpi/accommon.h> | ||
46 | |||
47 | /* TBD: This entire module is apparently obsolete and should be removed */ | ||
48 | |||
49 | #define _COMPONENT ACPI_NAMESPACE | ||
50 | ACPI_MODULE_NAME("nsdumpdv") | ||
51 | #ifdef ACPI_OBSOLETE_FUNCTIONS | ||
52 | #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) | ||
53 | #include <acpi/acnamesp.h> | ||
54 | /******************************************************************************* | ||
55 | * | ||
56 | * FUNCTION: acpi_ns_dump_one_device | ||
57 | * | ||
58 | * PARAMETERS: Handle - Node to be dumped | ||
59 | * Level - Nesting level of the handle | ||
60 | * Context - Passed into walk_namespace | ||
61 | * return_value - Not used | ||
62 | * | ||
63 | * RETURN: Status | ||
64 | * | ||
65 | * DESCRIPTION: Dump a single Node that represents a device | ||
66 | * This procedure is a user_function called by acpi_ns_walk_namespace. | ||
67 | * | ||
68 | ******************************************************************************/ | ||
69 | static acpi_status | ||
70 | acpi_ns_dump_one_device(acpi_handle obj_handle, | ||
71 | u32 level, void *context, void **return_value) | ||
72 | { | ||
73 | struct acpi_buffer buffer; | ||
74 | struct acpi_device_info *info; | ||
75 | acpi_status status; | ||
76 | u32 i; | ||
77 | |||
78 | ACPI_FUNCTION_NAME(ns_dump_one_device); | ||
79 | |||
80 | status = | ||
81 | acpi_ns_dump_one_object(obj_handle, level, context, return_value); | ||
82 | |||
83 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | ||
84 | status = acpi_get_object_info(obj_handle, &buffer); | ||
85 | if (ACPI_SUCCESS(status)) { | ||
86 | info = buffer.pointer; | ||
87 | for (i = 0; i < level; i++) { | ||
88 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, " ")); | ||
89 | } | ||
90 | |||
91 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, | ||
92 | " HID: %s, ADR: %8.8X%8.8X, Status: %X\n", | ||
93 | info->hardware_id.value, | ||
94 | ACPI_FORMAT_UINT64(info->address), | ||
95 | info->current_status)); | ||
96 | ACPI_FREE(info); | ||
97 | } | ||
98 | |||
99 | return (status); | ||
100 | } | ||
101 | |||
102 | /******************************************************************************* | ||
103 | * | ||
104 | * FUNCTION: acpi_ns_dump_root_devices | ||
105 | * | ||
106 | * PARAMETERS: None | ||
107 | * | ||
108 | * RETURN: None | ||
109 | * | ||
110 | * DESCRIPTION: Dump all objects of type "device" | ||
111 | * | ||
112 | ******************************************************************************/ | ||
113 | |||
114 | void acpi_ns_dump_root_devices(void) | ||
115 | { | ||
116 | acpi_handle sys_bus_handle; | ||
117 | acpi_status status; | ||
118 | |||
119 | ACPI_FUNCTION_NAME(ns_dump_root_devices); | ||
120 | |||
121 | /* Only dump the table if tracing is enabled */ | ||
122 | |||
123 | if (!(ACPI_LV_TABLES & acpi_dbg_level)) { | ||
124 | return; | ||
125 | } | ||
126 | |||
127 | status = acpi_get_handle(NULL, ACPI_NS_SYSTEM_BUS, &sys_bus_handle); | ||
128 | if (ACPI_FAILURE(status)) { | ||
129 | return; | ||
130 | } | ||
131 | |||
132 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, | ||
133 | "Display of all devices in the namespace:\n")); | ||
134 | |||
135 | status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, sys_bus_handle, | ||
136 | ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, | ||
137 | acpi_ns_dump_one_device, NULL, NULL); | ||
138 | } | ||
139 | |||
140 | #endif | ||
141 | #endif | ||
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c deleted file mode 100644 index a8d7764c73b7..000000000000 --- a/drivers/acpi/namespace/nseval.c +++ /dev/null | |||
@@ -1,278 +0,0 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: nseval - Object evaluation, includes control method execution | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2008, 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 <acpi/acpi.h> | ||
45 | #include <acpi/accommon.h> | ||
46 | #include <acpi/acparser.h> | ||
47 | #include <acpi/acinterp.h> | ||
48 | #include <acpi/acnamesp.h> | ||
49 | |||
50 | #define _COMPONENT ACPI_NAMESPACE | ||
51 | ACPI_MODULE_NAME("nseval") | ||
52 | |||
53 | /******************************************************************************* | ||
54 | * | ||
55 | * FUNCTION: acpi_ns_evaluate | ||
56 | * | ||
57 | * PARAMETERS: Info - Evaluation info block, contains: | ||
58 | * prefix_node - Prefix or Method/Object Node to execute | ||
59 | * Pathname - Name of method to execute, If NULL, the | ||
60 | * Node is the object to execute | ||
61 | * Parameters - List of parameters to pass to the method, | ||
62 | * terminated by NULL. Params itself may be | ||
63 | * NULL if no parameters are being passed. | ||
64 | * return_object - Where to put method's return value (if | ||
65 | * any). If NULL, no value is returned. | ||
66 | * parameter_type - Type of Parameter list | ||
67 | * return_object - Where to put method's return value (if | ||
68 | * any). If NULL, no value is returned. | ||
69 | * Flags - ACPI_IGNORE_RETURN_VALUE to delete return | ||
70 | * | ||
71 | * RETURN: Status | ||
72 | * | ||
73 | * DESCRIPTION: Execute a control method or return the current value of an | ||
74 | * ACPI namespace object. | ||
75 | * | ||
76 | * MUTEX: Locks interpreter | ||
77 | * | ||
78 | ******************************************************************************/ | ||
79 | acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | ||
80 | { | ||
81 | acpi_status status; | ||
82 | struct acpi_namespace_node *node; | ||
83 | |||
84 | ACPI_FUNCTION_TRACE(ns_evaluate); | ||
85 | |||
86 | if (!info) { | ||
87 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
88 | } | ||
89 | |||
90 | /* Initialize the return value to an invalid object */ | ||
91 | |||
92 | info->return_object = NULL; | ||
93 | info->param_count = 0; | ||
94 | |||
95 | /* | ||
96 | * Get the actual namespace node for the target object. Handles these cases: | ||
97 | * | ||
98 | * 1) Null node, Pathname (absolute path) | ||
99 | * 2) Node, Pathname (path relative to Node) | ||
100 | * 3) Node, Null Pathname | ||
101 | */ | ||
102 | status = acpi_ns_get_node(info->prefix_node, info->pathname, | ||
103 | ACPI_NS_NO_UPSEARCH, &info->resolved_node); | ||
104 | if (ACPI_FAILURE(status)) { | ||
105 | return_ACPI_STATUS(status); | ||
106 | } | ||
107 | |||
108 | /* | ||
109 | * For a method alias, we must grab the actual method node so that proper | ||
110 | * scoping context will be established before execution. | ||
111 | */ | ||
112 | if (acpi_ns_get_type(info->resolved_node) == | ||
113 | ACPI_TYPE_LOCAL_METHOD_ALIAS) { | ||
114 | info->resolved_node = | ||
115 | ACPI_CAST_PTR(struct acpi_namespace_node, | ||
116 | info->resolved_node->object); | ||
117 | } | ||
118 | |||
119 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n", info->pathname, | ||
120 | info->resolved_node, | ||
121 | acpi_ns_get_attached_object(info->resolved_node))); | ||
122 | |||
123 | node = info->resolved_node; | ||
124 | |||
125 | /* | ||
126 | * Two major cases here: | ||
127 | * | ||
128 | * 1) The object is a control method -- execute it | ||
129 | * 2) The object is not a method -- just return it's current value | ||
130 | */ | ||
131 | if (acpi_ns_get_type(info->resolved_node) == ACPI_TYPE_METHOD) { | ||
132 | /* | ||
133 | * 1) Object is a control method - execute it | ||
134 | */ | ||
135 | |||
136 | /* Verify that there is a method object associated with this node */ | ||
137 | |||
138 | info->obj_desc = | ||
139 | acpi_ns_get_attached_object(info->resolved_node); | ||
140 | if (!info->obj_desc) { | ||
141 | ACPI_ERROR((AE_INFO, | ||
142 | "Control method has no attached sub-object")); | ||
143 | return_ACPI_STATUS(AE_NULL_OBJECT); | ||
144 | } | ||
145 | |||
146 | /* Count the number of arguments being passed to the method */ | ||
147 | |||
148 | if (info->parameters) { | ||
149 | while (info->parameters[info->param_count]) { | ||
150 | if (info->param_count > ACPI_METHOD_MAX_ARG) { | ||
151 | return_ACPI_STATUS(AE_LIMIT); | ||
152 | } | ||
153 | info->param_count++; | ||
154 | } | ||
155 | } | ||
156 | |||
157 | |||
158 | ACPI_DUMP_PATHNAME(info->resolved_node, "Execute Method:", | ||
159 | ACPI_LV_INFO, _COMPONENT); | ||
160 | |||
161 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
162 | "Method at AML address %p Length %X\n", | ||
163 | info->obj_desc->method.aml_start + 1, | ||
164 | info->obj_desc->method.aml_length - 1)); | ||
165 | |||
166 | /* | ||
167 | * Any namespace deletion must acquire both the namespace and | ||
168 | * interpreter locks to ensure that no thread is using the portion of | ||
169 | * the namespace that is being deleted. | ||
170 | * | ||
171 | * Execute the method via the interpreter. The interpreter is locked | ||
172 | * here before calling into the AML parser | ||
173 | */ | ||
174 | acpi_ex_enter_interpreter(); | ||
175 | status = acpi_ps_execute_method(info); | ||
176 | acpi_ex_exit_interpreter(); | ||
177 | } else { | ||
178 | /* | ||
179 | * 2) Object is not a method, return its current value | ||
180 | * | ||
181 | * Disallow certain object types. For these, "evaluation" is undefined. | ||
182 | */ | ||
183 | switch (info->resolved_node->type) { | ||
184 | case ACPI_TYPE_DEVICE: | ||
185 | case ACPI_TYPE_EVENT: | ||
186 | case ACPI_TYPE_MUTEX: | ||
187 | case ACPI_TYPE_REGION: | ||
188 | case ACPI_TYPE_THERMAL: | ||
189 | case ACPI_TYPE_LOCAL_SCOPE: | ||
190 | |||
191 | ACPI_ERROR((AE_INFO, | ||
192 | "[%4.4s] Evaluation of object type [%s] is not supported", | ||
193 | info->resolved_node->name.ascii, | ||
194 | acpi_ut_get_type_name(info->resolved_node-> | ||
195 | type))); | ||
196 | |||
197 | return_ACPI_STATUS(AE_TYPE); | ||
198 | |||
199 | default: | ||
200 | break; | ||
201 | } | ||
202 | |||
203 | /* | ||
204 | * Objects require additional resolution steps (e.g., the Node may be | ||
205 | * a field that must be read, etc.) -- we can't just grab the object | ||
206 | * out of the node. | ||
207 | * | ||
208 | * Use resolve_node_to_value() to get the associated value. | ||
209 | * | ||
210 | * NOTE: we can get away with passing in NULL for a walk state because | ||
211 | * resolved_node is guaranteed to not be a reference to either a method | ||
212 | * local or a method argument (because this interface is never called | ||
213 | * from a running method.) | ||
214 | * | ||
215 | * Even though we do not directly invoke the interpreter for object | ||
216 | * resolution, we must lock it because we could access an opregion. | ||
217 | * The opregion access code assumes that the interpreter is locked. | ||
218 | */ | ||
219 | acpi_ex_enter_interpreter(); | ||
220 | |||
221 | /* Function has a strange interface */ | ||
222 | |||
223 | status = | ||
224 | acpi_ex_resolve_node_to_value(&info->resolved_node, NULL); | ||
225 | acpi_ex_exit_interpreter(); | ||
226 | |||
227 | /* | ||
228 | * If acpi_ex_resolve_node_to_value() succeeded, the return value was placed | ||
229 | * in resolved_node. | ||
230 | */ | ||
231 | if (ACPI_SUCCESS(status)) { | ||
232 | status = AE_CTRL_RETURN_VALUE; | ||
233 | info->return_object = | ||
234 | ACPI_CAST_PTR(union acpi_operand_object, | ||
235 | info->resolved_node); | ||
236 | |||
237 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
238 | "Returning object %p [%s]\n", | ||
239 | info->return_object, | ||
240 | acpi_ut_get_object_type_name(info-> | ||
241 | return_object))); | ||
242 | } | ||
243 | } | ||
244 | |||
245 | /* | ||
246 | * Check input argument count against the ASL-defined count for a method. | ||
247 | * Also check predefined names: argument count and return value against | ||
248 | * the ACPI specification. Some incorrect return value types are repaired. | ||
249 | */ | ||
250 | (void)acpi_ns_check_predefined_names(node, info->param_count, | ||
251 | status, &info->return_object); | ||
252 | |||
253 | /* Check if there is a return value that must be dealt with */ | ||
254 | |||
255 | if (status == AE_CTRL_RETURN_VALUE) { | ||
256 | |||
257 | /* If caller does not want the return value, delete it */ | ||
258 | |||
259 | if (info->flags & ACPI_IGNORE_RETURN_VALUE) { | ||
260 | acpi_ut_remove_reference(info->return_object); | ||
261 | info->return_object = NULL; | ||
262 | } | ||
263 | |||
264 | /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */ | ||
265 | |||
266 | status = AE_OK; | ||
267 | } | ||
268 | |||
269 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
270 | "*** Completed evaluation of object %s ***\n", | ||
271 | info->pathname)); | ||
272 | |||
273 | /* | ||
274 | * Namespace was unlocked by the handling acpi_ns* function, so we | ||
275 | * just return | ||
276 | */ | ||
277 | return_ACPI_STATUS(status); | ||
278 | } | ||
diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c deleted file mode 100644 index fe470c4b38f7..000000000000 --- a/drivers/acpi/namespace/nsinit.c +++ /dev/null | |||
@@ -1,593 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: nsinit - namespace initialization | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2008, 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 <acpi/acpi.h> | ||
45 | #include <acpi/accommon.h> | ||
46 | #include <acpi/acnamesp.h> | ||
47 | #include <acpi/acdispat.h> | ||
48 | #include <acpi/acinterp.h> | ||
49 | #include <linux/nmi.h> | ||
50 | |||
51 | #define _COMPONENT ACPI_NAMESPACE | ||
52 | ACPI_MODULE_NAME("nsinit") | ||
53 | |||
54 | /* Local prototypes */ | ||
55 | static acpi_status | ||
56 | acpi_ns_init_one_object(acpi_handle obj_handle, | ||
57 | u32 level, void *context, void **return_value); | ||
58 | |||
59 | static acpi_status | ||
60 | acpi_ns_init_one_device(acpi_handle obj_handle, | ||
61 | u32 nesting_level, void *context, void **return_value); | ||
62 | |||
63 | static acpi_status | ||
64 | acpi_ns_find_ini_methods(acpi_handle obj_handle, | ||
65 | u32 nesting_level, void *context, void **return_value); | ||
66 | |||
67 | /******************************************************************************* | ||
68 | * | ||
69 | * FUNCTION: acpi_ns_initialize_objects | ||
70 | * | ||
71 | * PARAMETERS: None | ||
72 | * | ||
73 | * RETURN: Status | ||
74 | * | ||
75 | * DESCRIPTION: Walk the entire namespace and perform any necessary | ||
76 | * initialization on the objects found therein | ||
77 | * | ||
78 | ******************************************************************************/ | ||
79 | |||
80 | acpi_status acpi_ns_initialize_objects(void) | ||
81 | { | ||
82 | acpi_status status; | ||
83 | struct acpi_init_walk_info info; | ||
84 | |||
85 | ACPI_FUNCTION_TRACE(ns_initialize_objects); | ||
86 | |||
87 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
88 | "**** Starting initialization of namespace objects ****\n")); | ||
89 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | ||
90 | "Completing Region/Field/Buffer/Package initialization:")); | ||
91 | |||
92 | /* Set all init info to zero */ | ||
93 | |||
94 | ACPI_MEMSET(&info, 0, sizeof(struct acpi_init_walk_info)); | ||
95 | |||
96 | /* Walk entire namespace from the supplied root */ | ||
97 | |||
98 | status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, | ||
99 | ACPI_UINT32_MAX, acpi_ns_init_one_object, | ||
100 | &info, NULL); | ||
101 | if (ACPI_FAILURE(status)) { | ||
102 | ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); | ||
103 | } | ||
104 | |||
105 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | ||
106 | "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd Buffers %hd/%hd Packages (%hd nodes)\n", | ||
107 | info.op_region_init, info.op_region_count, | ||
108 | info.field_init, info.field_count, | ||
109 | info.buffer_init, info.buffer_count, | ||
110 | info.package_init, info.package_count, | ||
111 | info.object_count)); | ||
112 | |||
113 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
114 | "%hd Control Methods found\n", info.method_count)); | ||
115 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
116 | "%hd Op Regions found\n", info.op_region_count)); | ||
117 | |||
118 | return_ACPI_STATUS(AE_OK); | ||
119 | } | ||
120 | |||
121 | /******************************************************************************* | ||
122 | * | ||
123 | * FUNCTION: acpi_ns_initialize_devices | ||
124 | * | ||
125 | * PARAMETERS: None | ||
126 | * | ||
127 | * RETURN: acpi_status | ||
128 | * | ||
129 | * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices. | ||
130 | * This means running _INI on all present devices. | ||
131 | * | ||
132 | * Note: We install PCI config space handler on region access, | ||
133 | * not here. | ||
134 | * | ||
135 | ******************************************************************************/ | ||
136 | |||
137 | acpi_status acpi_ns_initialize_devices(void) | ||
138 | { | ||
139 | acpi_status status; | ||
140 | struct acpi_device_walk_info info; | ||
141 | |||
142 | ACPI_FUNCTION_TRACE(ns_initialize_devices); | ||
143 | |||
144 | /* Init counters */ | ||
145 | |||
146 | info.device_count = 0; | ||
147 | info.num_STA = 0; | ||
148 | info.num_INI = 0; | ||
149 | |||
150 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | ||
151 | "Initializing Device/Processor/Thermal objects by executing _INI methods:")); | ||
152 | |||
153 | /* Tree analysis: find all subtrees that contain _INI methods */ | ||
154 | |||
155 | status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, | ||
156 | ACPI_UINT32_MAX, FALSE, | ||
157 | acpi_ns_find_ini_methods, &info, NULL); | ||
158 | if (ACPI_FAILURE(status)) { | ||
159 | goto error_exit; | ||
160 | } | ||
161 | |||
162 | /* Allocate the evaluation information block */ | ||
163 | |||
164 | info.evaluate_info = | ||
165 | ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); | ||
166 | if (!info.evaluate_info) { | ||
167 | status = AE_NO_MEMORY; | ||
168 | goto error_exit; | ||
169 | } | ||
170 | |||
171 | /* Walk namespace to execute all _INIs on present devices */ | ||
172 | |||
173 | status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, | ||
174 | ACPI_UINT32_MAX, FALSE, | ||
175 | acpi_ns_init_one_device, &info, NULL); | ||
176 | |||
177 | ACPI_FREE(info.evaluate_info); | ||
178 | if (ACPI_FAILURE(status)) { | ||
179 | goto error_exit; | ||
180 | } | ||
181 | |||
182 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | ||
183 | "\nExecuted %hd _INI methods requiring %hd _STA executions (examined %hd objects)\n", | ||
184 | info.num_INI, info.num_STA, info.device_count)); | ||
185 | |||
186 | return_ACPI_STATUS(status); | ||
187 | |||
188 | error_exit: | ||
189 | ACPI_EXCEPTION((AE_INFO, status, "During device initialization")); | ||
190 | return_ACPI_STATUS(status); | ||
191 | } | ||
192 | |||
193 | /******************************************************************************* | ||
194 | * | ||
195 | * FUNCTION: acpi_ns_init_one_object | ||
196 | * | ||
197 | * PARAMETERS: obj_handle - Node | ||
198 | * Level - Current nesting level | ||
199 | * Context - Points to a init info struct | ||
200 | * return_value - Not used | ||
201 | * | ||
202 | * RETURN: Status | ||
203 | * | ||
204 | * DESCRIPTION: Callback from acpi_walk_namespace. Invoked for every object | ||
205 | * within the namespace. | ||
206 | * | ||
207 | * Currently, the only objects that require initialization are: | ||
208 | * 1) Methods | ||
209 | * 2) Op Regions | ||
210 | * | ||
211 | ******************************************************************************/ | ||
212 | |||
213 | static acpi_status | ||
214 | acpi_ns_init_one_object(acpi_handle obj_handle, | ||
215 | u32 level, void *context, void **return_value) | ||
216 | { | ||
217 | acpi_object_type type; | ||
218 | acpi_status status = AE_OK; | ||
219 | struct acpi_init_walk_info *info = | ||
220 | (struct acpi_init_walk_info *)context; | ||
221 | struct acpi_namespace_node *node = | ||
222 | (struct acpi_namespace_node *)obj_handle; | ||
223 | union acpi_operand_object *obj_desc; | ||
224 | |||
225 | ACPI_FUNCTION_NAME(ns_init_one_object); | ||
226 | |||
227 | info->object_count++; | ||
228 | |||
229 | /* And even then, we are only interested in a few object types */ | ||
230 | |||
231 | type = acpi_ns_get_type(obj_handle); | ||
232 | obj_desc = acpi_ns_get_attached_object(node); | ||
233 | if (!obj_desc) { | ||
234 | return (AE_OK); | ||
235 | } | ||
236 | |||
237 | /* Increment counters for object types we are looking for */ | ||
238 | |||
239 | switch (type) { | ||
240 | case ACPI_TYPE_REGION: | ||
241 | info->op_region_count++; | ||
242 | break; | ||
243 | |||
244 | case ACPI_TYPE_BUFFER_FIELD: | ||
245 | info->field_count++; | ||
246 | break; | ||
247 | |||
248 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
249 | info->field_count++; | ||
250 | break; | ||
251 | |||
252 | case ACPI_TYPE_BUFFER: | ||
253 | info->buffer_count++; | ||
254 | break; | ||
255 | |||
256 | case ACPI_TYPE_PACKAGE: | ||
257 | info->package_count++; | ||
258 | break; | ||
259 | |||
260 | default: | ||
261 | |||
262 | /* No init required, just exit now */ | ||
263 | return (AE_OK); | ||
264 | } | ||
265 | |||
266 | /* | ||
267 | * If the object is already initialized, nothing else to do | ||
268 | */ | ||
269 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { | ||
270 | return (AE_OK); | ||
271 | } | ||
272 | |||
273 | /* | ||
274 | * Must lock the interpreter before executing AML code | ||
275 | */ | ||
276 | acpi_ex_enter_interpreter(); | ||
277 | |||
278 | /* | ||
279 | * Each of these types can contain executable AML code within the | ||
280 | * declaration. | ||
281 | */ | ||
282 | switch (type) { | ||
283 | case ACPI_TYPE_REGION: | ||
284 | |||
285 | info->op_region_init++; | ||
286 | status = acpi_ds_get_region_arguments(obj_desc); | ||
287 | break; | ||
288 | |||
289 | case ACPI_TYPE_BUFFER_FIELD: | ||
290 | |||
291 | info->field_init++; | ||
292 | status = acpi_ds_get_buffer_field_arguments(obj_desc); | ||
293 | break; | ||
294 | |||
295 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
296 | |||
297 | info->field_init++; | ||
298 | status = acpi_ds_get_bank_field_arguments(obj_desc); | ||
299 | break; | ||
300 | |||
301 | case ACPI_TYPE_BUFFER: | ||
302 | |||
303 | info->buffer_init++; | ||
304 | status = acpi_ds_get_buffer_arguments(obj_desc); | ||
305 | break; | ||
306 | |||
307 | case ACPI_TYPE_PACKAGE: | ||
308 | |||
309 | info->package_init++; | ||
310 | status = acpi_ds_get_package_arguments(obj_desc); | ||
311 | break; | ||
312 | |||
313 | default: | ||
314 | /* No other types can get here */ | ||
315 | break; | ||
316 | } | ||
317 | |||
318 | if (ACPI_FAILURE(status)) { | ||
319 | ACPI_EXCEPTION((AE_INFO, status, | ||
320 | "Could not execute arguments for [%4.4s] (%s)", | ||
321 | acpi_ut_get_node_name(node), | ||
322 | acpi_ut_get_type_name(type))); | ||
323 | } | ||
324 | |||
325 | /* | ||
326 | * Print a dot for each object unless we are going to print the entire | ||
327 | * pathname | ||
328 | */ | ||
329 | if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) { | ||
330 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, ".")); | ||
331 | } | ||
332 | |||
333 | /* | ||
334 | * We ignore errors from above, and always return OK, since we don't want | ||
335 | * to abort the walk on any single error. | ||
336 | */ | ||
337 | acpi_ex_exit_interpreter(); | ||
338 | return (AE_OK); | ||
339 | } | ||
340 | |||
341 | /******************************************************************************* | ||
342 | * | ||
343 | * FUNCTION: acpi_ns_find_ini_methods | ||
344 | * | ||
345 | * PARAMETERS: acpi_walk_callback | ||
346 | * | ||
347 | * RETURN: acpi_status | ||
348 | * | ||
349 | * DESCRIPTION: Called during namespace walk. Finds objects named _INI under | ||
350 | * device/processor/thermal objects, and marks the entire subtree | ||
351 | * with a SUBTREE_HAS_INI flag. This flag is used during the | ||
352 | * subsequent device initialization walk to avoid entire subtrees | ||
353 | * that do not contain an _INI. | ||
354 | * | ||
355 | ******************************************************************************/ | ||
356 | |||
357 | static acpi_status | ||
358 | acpi_ns_find_ini_methods(acpi_handle obj_handle, | ||
359 | u32 nesting_level, void *context, void **return_value) | ||
360 | { | ||
361 | struct acpi_device_walk_info *info = | ||
362 | ACPI_CAST_PTR(struct acpi_device_walk_info, context); | ||
363 | struct acpi_namespace_node *node; | ||
364 | struct acpi_namespace_node *parent_node; | ||
365 | |||
366 | /* Keep count of device/processor/thermal objects */ | ||
367 | |||
368 | node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle); | ||
369 | if ((node->type == ACPI_TYPE_DEVICE) || | ||
370 | (node->type == ACPI_TYPE_PROCESSOR) || | ||
371 | (node->type == ACPI_TYPE_THERMAL)) { | ||
372 | info->device_count++; | ||
373 | return (AE_OK); | ||
374 | } | ||
375 | |||
376 | /* We are only looking for methods named _INI */ | ||
377 | |||
378 | if (!ACPI_COMPARE_NAME(node->name.ascii, METHOD_NAME__INI)) { | ||
379 | return (AE_OK); | ||
380 | } | ||
381 | |||
382 | /* | ||
383 | * The only _INI methods that we care about are those that are | ||
384 | * present under Device, Processor, and Thermal objects. | ||
385 | */ | ||
386 | parent_node = acpi_ns_get_parent_node(node); | ||
387 | switch (parent_node->type) { | ||
388 | case ACPI_TYPE_DEVICE: | ||
389 | case ACPI_TYPE_PROCESSOR: | ||
390 | case ACPI_TYPE_THERMAL: | ||
391 | |||
392 | /* Mark parent and bubble up the INI present flag to the root */ | ||
393 | |||
394 | while (parent_node) { | ||
395 | parent_node->flags |= ANOBJ_SUBTREE_HAS_INI; | ||
396 | parent_node = acpi_ns_get_parent_node(parent_node); | ||
397 | } | ||
398 | break; | ||
399 | |||
400 | default: | ||
401 | break; | ||
402 | } | ||
403 | |||
404 | return (AE_OK); | ||
405 | } | ||
406 | |||
407 | /******************************************************************************* | ||
408 | * | ||
409 | * FUNCTION: acpi_ns_init_one_device | ||
410 | * | ||
411 | * PARAMETERS: acpi_walk_callback | ||
412 | * | ||
413 | * RETURN: acpi_status | ||
414 | * | ||
415 | * DESCRIPTION: This is called once per device soon after ACPI is enabled | ||
416 | * to initialize each device. It determines if the device is | ||
417 | * present, and if so, calls _INI. | ||
418 | * | ||
419 | ******************************************************************************/ | ||
420 | |||
421 | static acpi_status | ||
422 | acpi_ns_init_one_device(acpi_handle obj_handle, | ||
423 | u32 nesting_level, void *context, void **return_value) | ||
424 | { | ||
425 | struct acpi_device_walk_info *walk_info = | ||
426 | ACPI_CAST_PTR(struct acpi_device_walk_info, context); | ||
427 | struct acpi_evaluate_info *info = walk_info->evaluate_info; | ||
428 | u32 flags; | ||
429 | acpi_status status; | ||
430 | struct acpi_namespace_node *device_node; | ||
431 | |||
432 | ACPI_FUNCTION_TRACE(ns_init_one_device); | ||
433 | |||
434 | /* We are interested in Devices, Processors and thermal_zones only */ | ||
435 | |||
436 | device_node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle); | ||
437 | if ((device_node->type != ACPI_TYPE_DEVICE) && | ||
438 | (device_node->type != ACPI_TYPE_PROCESSOR) && | ||
439 | (device_node->type != ACPI_TYPE_THERMAL)) { | ||
440 | return_ACPI_STATUS(AE_OK); | ||
441 | } | ||
442 | |||
443 | /* | ||
444 | * Because of an earlier namespace analysis, all subtrees that contain an | ||
445 | * _INI method are tagged. | ||
446 | * | ||
447 | * If this device subtree does not contain any _INI methods, we | ||
448 | * can exit now and stop traversing this entire subtree. | ||
449 | */ | ||
450 | if (!(device_node->flags & ANOBJ_SUBTREE_HAS_INI)) { | ||
451 | return_ACPI_STATUS(AE_CTRL_DEPTH); | ||
452 | } | ||
453 | |||
454 | /* | ||
455 | * Run _STA to determine if this device is present and functioning. We | ||
456 | * must know this information for two important reasons (from ACPI spec): | ||
457 | * | ||
458 | * 1) We can only run _INI if the device is present. | ||
459 | * 2) We must abort the device tree walk on this subtree if the device is | ||
460 | * not present and is not functional (we will not examine the children) | ||
461 | * | ||
462 | * The _STA method is not required to be present under the device, we | ||
463 | * assume the device is present if _STA does not exist. | ||
464 | */ | ||
465 | ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname | ||
466 | (ACPI_TYPE_METHOD, device_node, METHOD_NAME__STA)); | ||
467 | |||
468 | status = acpi_ut_execute_STA(device_node, &flags); | ||
469 | if (ACPI_FAILURE(status)) { | ||
470 | |||
471 | /* Ignore error and move on to next device */ | ||
472 | |||
473 | return_ACPI_STATUS(AE_OK); | ||
474 | } | ||
475 | |||
476 | /* | ||
477 | * Flags == -1 means that _STA was not found. In this case, we assume that | ||
478 | * the device is both present and functional. | ||
479 | * | ||
480 | * From the ACPI spec, description of _STA: | ||
481 | * | ||
482 | * "If a device object (including the processor object) does not have an | ||
483 | * _STA object, then OSPM assumes that all of the above bits are set (in | ||
484 | * other words, the device is present, ..., and functioning)" | ||
485 | */ | ||
486 | if (flags != ACPI_UINT32_MAX) { | ||
487 | walk_info->num_STA++; | ||
488 | } | ||
489 | |||
490 | /* | ||
491 | * Examine the PRESENT and FUNCTIONING status bits | ||
492 | * | ||
493 | * Note: ACPI spec does not seem to specify behavior for the present but | ||
494 | * not functioning case, so we assume functioning if present. | ||
495 | */ | ||
496 | if (!(flags & ACPI_STA_DEVICE_PRESENT)) { | ||
497 | |||
498 | /* Device is not present, we must examine the Functioning bit */ | ||
499 | |||
500 | if (flags & ACPI_STA_DEVICE_FUNCTIONING) { | ||
501 | /* | ||
502 | * Device is not present but is "functioning". In this case, | ||
503 | * we will not run _INI, but we continue to examine the children | ||
504 | * of this device. | ||
505 | * | ||
506 | * From the ACPI spec, description of _STA: (Note - no mention | ||
507 | * of whether to run _INI or not on the device in question) | ||
508 | * | ||
509 | * "_STA may return bit 0 clear (not present) with bit 3 set | ||
510 | * (device is functional). This case is used to indicate a valid | ||
511 | * device for which no device driver should be loaded (for example, | ||
512 | * a bridge device.) Children of this device may be present and | ||
513 | * valid. OSPM should continue enumeration below a device whose | ||
514 | * _STA returns this bit combination" | ||
515 | */ | ||
516 | return_ACPI_STATUS(AE_OK); | ||
517 | } else { | ||
518 | /* | ||
519 | * Device is not present and is not functioning. We must abort the | ||
520 | * walk of this subtree immediately -- don't look at the children | ||
521 | * of such a device. | ||
522 | * | ||
523 | * From the ACPI spec, description of _INI: | ||
524 | * | ||
525 | * "If the _STA method indicates that the device is not present, | ||
526 | * OSPM will not run the _INI and will not examine the children | ||
527 | * of the device for _INI methods" | ||
528 | */ | ||
529 | return_ACPI_STATUS(AE_CTRL_DEPTH); | ||
530 | } | ||
531 | } | ||
532 | |||
533 | /* | ||
534 | * The device is present or is assumed present if no _STA exists. | ||
535 | * Run the _INI if it exists (not required to exist) | ||
536 | * | ||
537 | * Note: We know there is an _INI within this subtree, but it may not be | ||
538 | * under this particular device, it may be lower in the branch. | ||
539 | */ | ||
540 | ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname | ||
541 | (ACPI_TYPE_METHOD, device_node, METHOD_NAME__INI)); | ||
542 | |||
543 | info->prefix_node = device_node; | ||
544 | info->pathname = METHOD_NAME__INI; | ||
545 | info->parameters = NULL; | ||
546 | info->flags = ACPI_IGNORE_RETURN_VALUE; | ||
547 | |||
548 | /* | ||
549 | * Some hardware relies on this being executed as atomically | ||
550 | * as possible (without an NMI being received in the middle of | ||
551 | * this) - so disable NMIs and initialize the device: | ||
552 | */ | ||
553 | acpi_nmi_disable(); | ||
554 | status = acpi_ns_evaluate(info); | ||
555 | acpi_nmi_enable(); | ||
556 | |||
557 | if (ACPI_SUCCESS(status)) { | ||
558 | walk_info->num_INI++; | ||
559 | |||
560 | if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && | ||
561 | (!(acpi_dbg_level & ACPI_LV_INFO))) { | ||
562 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, ".")); | ||
563 | } | ||
564 | } | ||
565 | #ifdef ACPI_DEBUG_OUTPUT | ||
566 | else if (status != AE_NOT_FOUND) { | ||
567 | |||
568 | /* Ignore error and move on to next device */ | ||
569 | |||
570 | char *scope_name = | ||
571 | acpi_ns_get_external_pathname(info->resolved_node); | ||
572 | |||
573 | ACPI_EXCEPTION((AE_INFO, status, "during %s._INI execution", | ||
574 | scope_name)); | ||
575 | ACPI_FREE(scope_name); | ||
576 | } | ||
577 | #endif | ||
578 | |||
579 | /* Ignore errors from above */ | ||
580 | |||
581 | status = AE_OK; | ||
582 | |||
583 | /* | ||
584 | * The _INI method has been run if present; call the Global Initialization | ||
585 | * Handler for this device. | ||
586 | */ | ||
587 | if (acpi_gbl_init_handler) { | ||
588 | status = | ||
589 | acpi_gbl_init_handler(device_node, ACPI_INIT_DEVICE_INI); | ||
590 | } | ||
591 | |||
592 | return_ACPI_STATUS(status); | ||
593 | } | ||
diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c deleted file mode 100644 index a6e92b31a06f..000000000000 --- a/drivers/acpi/namespace/nsload.c +++ /dev/null | |||
@@ -1,315 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: nsload - namespace loading/expanding/contracting procedures | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2008, 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 <acpi/acpi.h> | ||
45 | #include <acpi/accommon.h> | ||
46 | #include <acpi/acnamesp.h> | ||
47 | #include <acpi/acdispat.h> | ||
48 | #include <acpi/actables.h> | ||
49 | |||
50 | #define _COMPONENT ACPI_NAMESPACE | ||
51 | ACPI_MODULE_NAME("nsload") | ||
52 | |||
53 | /* Local prototypes */ | ||
54 | #ifdef ACPI_FUTURE_IMPLEMENTATION | ||
55 | acpi_status acpi_ns_unload_namespace(acpi_handle handle); | ||
56 | |||
57 | static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle); | ||
58 | #endif | ||
59 | |||
60 | #ifndef ACPI_NO_METHOD_EXECUTION | ||
61 | /******************************************************************************* | ||
62 | * | ||
63 | * FUNCTION: acpi_ns_load_table | ||
64 | * | ||
65 | * PARAMETERS: table_index - Index for table to be loaded | ||
66 | * Node - Owning NS node | ||
67 | * | ||
68 | * RETURN: Status | ||
69 | * | ||
70 | * DESCRIPTION: Load one ACPI table into the namespace | ||
71 | * | ||
72 | ******************************************************************************/ | ||
73 | |||
74 | acpi_status | ||
75 | acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node) | ||
76 | { | ||
77 | acpi_status status; | ||
78 | |||
79 | ACPI_FUNCTION_TRACE(ns_load_table); | ||
80 | |||
81 | /* | ||
82 | * Parse the table and load the namespace with all named | ||
83 | * objects found within. Control methods are NOT parsed | ||
84 | * at this time. In fact, the control methods cannot be | ||
85 | * parsed until the entire namespace is loaded, because | ||
86 | * if a control method makes a forward reference (call) | ||
87 | * to another control method, we can't continue parsing | ||
88 | * because we don't know how many arguments to parse next! | ||
89 | */ | ||
90 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
91 | if (ACPI_FAILURE(status)) { | ||
92 | return_ACPI_STATUS(status); | ||
93 | } | ||
94 | |||
95 | /* If table already loaded into namespace, just return */ | ||
96 | |||
97 | if (acpi_tb_is_table_loaded(table_index)) { | ||
98 | status = AE_ALREADY_EXISTS; | ||
99 | goto unlock; | ||
100 | } | ||
101 | |||
102 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
103 | "**** Loading table into namespace ****\n")); | ||
104 | |||
105 | status = acpi_tb_allocate_owner_id(table_index); | ||
106 | if (ACPI_FAILURE(status)) { | ||
107 | goto unlock; | ||
108 | } | ||
109 | |||
110 | status = acpi_ns_parse_table(table_index, node); | ||
111 | if (ACPI_SUCCESS(status)) { | ||
112 | acpi_tb_set_table_loaded_flag(table_index, TRUE); | ||
113 | } else { | ||
114 | (void)acpi_tb_release_owner_id(table_index); | ||
115 | } | ||
116 | |||
117 | unlock: | ||
118 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
119 | |||
120 | if (ACPI_FAILURE(status)) { | ||
121 | return_ACPI_STATUS(status); | ||
122 | } | ||
123 | |||
124 | /* | ||
125 | * Now we can parse the control methods. We always parse | ||
126 | * them here for a sanity check, and if configured for | ||
127 | * just-in-time parsing, we delete the control method | ||
128 | * parse trees. | ||
129 | */ | ||
130 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
131 | "**** Begin Table Method Parsing and Object Initialization ****\n")); | ||
132 | |||
133 | status = acpi_ds_initialize_objects(table_index, node); | ||
134 | |||
135 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
136 | "**** Completed Table Method Parsing and Object Initialization ****\n")); | ||
137 | |||
138 | return_ACPI_STATUS(status); | ||
139 | } | ||
140 | |||
141 | #ifdef ACPI_OBSOLETE_FUNCTIONS | ||
142 | /******************************************************************************* | ||
143 | * | ||
144 | * FUNCTION: acpi_load_namespace | ||
145 | * | ||
146 | * PARAMETERS: None | ||
147 | * | ||
148 | * RETURN: Status | ||
149 | * | ||
150 | * DESCRIPTION: Load the name space from what ever is pointed to by DSDT. | ||
151 | * (DSDT points to either the BIOS or a buffer.) | ||
152 | * | ||
153 | ******************************************************************************/ | ||
154 | |||
155 | acpi_status acpi_ns_load_namespace(void) | ||
156 | { | ||
157 | acpi_status status; | ||
158 | |||
159 | ACPI_FUNCTION_TRACE(acpi_load_name_space); | ||
160 | |||
161 | /* There must be at least a DSDT installed */ | ||
162 | |||
163 | if (acpi_gbl_DSDT == NULL) { | ||
164 | ACPI_ERROR((AE_INFO, "DSDT is not in memory")); | ||
165 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | * Load the namespace. The DSDT is required, | ||
170 | * but the SSDT and PSDT tables are optional. | ||
171 | */ | ||
172 | status = acpi_ns_load_table_by_type(ACPI_TABLE_ID_DSDT); | ||
173 | if (ACPI_FAILURE(status)) { | ||
174 | return_ACPI_STATUS(status); | ||
175 | } | ||
176 | |||
177 | /* Ignore exceptions from these */ | ||
178 | |||
179 | (void)acpi_ns_load_table_by_type(ACPI_TABLE_ID_SSDT); | ||
180 | (void)acpi_ns_load_table_by_type(ACPI_TABLE_ID_PSDT); | ||
181 | |||
182 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | ||
183 | "ACPI Namespace successfully loaded at root %p\n", | ||
184 | acpi_gbl_root_node)); | ||
185 | |||
186 | return_ACPI_STATUS(status); | ||
187 | } | ||
188 | #endif | ||
189 | |||
190 | #ifdef ACPI_FUTURE_IMPLEMENTATION | ||
191 | /******************************************************************************* | ||
192 | * | ||
193 | * FUNCTION: acpi_ns_delete_subtree | ||
194 | * | ||
195 | * PARAMETERS: start_handle - Handle in namespace where search begins | ||
196 | * | ||
197 | * RETURNS Status | ||
198 | * | ||
199 | * DESCRIPTION: Walks the namespace starting at the given handle and deletes | ||
200 | * all objects, entries, and scopes in the entire subtree. | ||
201 | * | ||
202 | * Namespace/Interpreter should be locked or the subsystem should | ||
203 | * be in shutdown before this routine is called. | ||
204 | * | ||
205 | ******************************************************************************/ | ||
206 | |||
207 | static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle) | ||
208 | { | ||
209 | acpi_status status; | ||
210 | acpi_handle child_handle; | ||
211 | acpi_handle parent_handle; | ||
212 | acpi_handle next_child_handle; | ||
213 | acpi_handle dummy; | ||
214 | u32 level; | ||
215 | |||
216 | ACPI_FUNCTION_TRACE(ns_delete_subtree); | ||
217 | |||
218 | parent_handle = start_handle; | ||
219 | child_handle = NULL; | ||
220 | level = 1; | ||
221 | |||
222 | /* | ||
223 | * Traverse the tree of objects until we bubble back up | ||
224 | * to where we started. | ||
225 | */ | ||
226 | while (level > 0) { | ||
227 | |||
228 | /* Attempt to get the next object in this scope */ | ||
229 | |||
230 | status = acpi_get_next_object(ACPI_TYPE_ANY, parent_handle, | ||
231 | child_handle, &next_child_handle); | ||
232 | |||
233 | child_handle = next_child_handle; | ||
234 | |||
235 | /* Did we get a new object? */ | ||
236 | |||
237 | if (ACPI_SUCCESS(status)) { | ||
238 | |||
239 | /* Check if this object has any children */ | ||
240 | |||
241 | if (ACPI_SUCCESS | ||
242 | (acpi_get_next_object | ||
243 | (ACPI_TYPE_ANY, child_handle, NULL, &dummy))) { | ||
244 | /* | ||
245 | * There is at least one child of this object, | ||
246 | * visit the object | ||
247 | */ | ||
248 | level++; | ||
249 | parent_handle = child_handle; | ||
250 | child_handle = NULL; | ||
251 | } | ||
252 | } else { | ||
253 | /* | ||
254 | * No more children in this object, go back up to | ||
255 | * the object's parent | ||
256 | */ | ||
257 | level--; | ||
258 | |||
259 | /* Delete all children now */ | ||
260 | |||
261 | acpi_ns_delete_children(child_handle); | ||
262 | |||
263 | child_handle = parent_handle; | ||
264 | status = acpi_get_parent(parent_handle, &parent_handle); | ||
265 | if (ACPI_FAILURE(status)) { | ||
266 | return_ACPI_STATUS(status); | ||
267 | } | ||
268 | } | ||
269 | } | ||
270 | |||
271 | /* Now delete the starting object, and we are done */ | ||
272 | |||
273 | acpi_ns_delete_node(child_handle); | ||
274 | |||
275 | return_ACPI_STATUS(AE_OK); | ||
276 | } | ||
277 | |||
278 | /******************************************************************************* | ||
279 | * | ||
280 | * FUNCTION: acpi_ns_unload_name_space | ||
281 | * | ||
282 | * PARAMETERS: Handle - Root of namespace subtree to be deleted | ||
283 | * | ||
284 | * RETURN: Status | ||
285 | * | ||
286 | * DESCRIPTION: Shrinks the namespace, typically in response to an undocking | ||
287 | * event. Deletes an entire subtree starting from (and | ||
288 | * including) the given handle. | ||
289 | * | ||
290 | ******************************************************************************/ | ||
291 | |||
292 | acpi_status acpi_ns_unload_namespace(acpi_handle handle) | ||
293 | { | ||
294 | acpi_status status; | ||
295 | |||
296 | ACPI_FUNCTION_TRACE(ns_unload_name_space); | ||
297 | |||
298 | /* Parameter validation */ | ||
299 | |||
300 | if (!acpi_gbl_root_node) { | ||
301 | return_ACPI_STATUS(AE_NO_NAMESPACE); | ||
302 | } | ||
303 | |||
304 | if (!handle) { | ||
305 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
306 | } | ||
307 | |||
308 | /* This function does the real work */ | ||
309 | |||
310 | status = acpi_ns_delete_subtree(handle); | ||
311 | |||
312 | return_ACPI_STATUS(status); | ||
313 | } | ||
314 | #endif | ||
315 | #endif | ||
diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c deleted file mode 100644 index b7e301848ba7..000000000000 --- a/drivers/acpi/namespace/nsnames.c +++ /dev/null | |||
@@ -1,265 +0,0 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: nsnames - Name manipulation and search | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2008, 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 <acpi/acpi.h> | ||
45 | #include <acpi/accommon.h> | ||
46 | #include <acpi/amlcode.h> | ||
47 | #include <acpi/acnamesp.h> | ||
48 | |||
49 | #define _COMPONENT ACPI_NAMESPACE | ||
50 | ACPI_MODULE_NAME("nsnames") | ||
51 | |||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * FUNCTION: acpi_ns_build_external_path | ||
55 | * | ||
56 | * PARAMETERS: Node - NS node whose pathname is needed | ||
57 | * Size - Size of the pathname | ||
58 | * *name_buffer - Where to return the pathname | ||
59 | * | ||
60 | * RETURN: Status | ||
61 | * Places the pathname into the name_buffer, in external format | ||
62 | * (name segments separated by path separators) | ||
63 | * | ||
64 | * DESCRIPTION: Generate a full pathaname | ||
65 | * | ||
66 | ******************************************************************************/ | ||
67 | acpi_status | ||
68 | acpi_ns_build_external_path(struct acpi_namespace_node *node, | ||
69 | acpi_size size, char *name_buffer) | ||
70 | { | ||
71 | acpi_size index; | ||
72 | struct acpi_namespace_node *parent_node; | ||
73 | |||
74 | ACPI_FUNCTION_ENTRY(); | ||
75 | |||
76 | /* Special case for root */ | ||
77 | |||
78 | index = size - 1; | ||
79 | if (index < ACPI_NAME_SIZE) { | ||
80 | name_buffer[0] = AML_ROOT_PREFIX; | ||
81 | name_buffer[1] = 0; | ||
82 | return (AE_OK); | ||
83 | } | ||
84 | |||
85 | /* Store terminator byte, then build name backwards */ | ||
86 | |||
87 | parent_node = node; | ||
88 | name_buffer[index] = 0; | ||
89 | |||
90 | while ((index > ACPI_NAME_SIZE) && (parent_node != acpi_gbl_root_node)) { | ||
91 | index -= ACPI_NAME_SIZE; | ||
92 | |||
93 | /* Put the name into the buffer */ | ||
94 | |||
95 | ACPI_MOVE_32_TO_32((name_buffer + index), &parent_node->name); | ||
96 | parent_node = acpi_ns_get_parent_node(parent_node); | ||
97 | |||
98 | /* Prefix name with the path separator */ | ||
99 | |||
100 | index--; | ||
101 | name_buffer[index] = ACPI_PATH_SEPARATOR; | ||
102 | } | ||
103 | |||
104 | /* Overwrite final separator with the root prefix character */ | ||
105 | |||
106 | name_buffer[index] = AML_ROOT_PREFIX; | ||
107 | |||
108 | if (index != 0) { | ||
109 | ACPI_ERROR((AE_INFO, | ||
110 | "Could not construct external pathname; index=%X, size=%X, Path=%s", | ||
111 | (u32) index, (u32) size, &name_buffer[size])); | ||
112 | |||
113 | return (AE_BAD_PARAMETER); | ||
114 | } | ||
115 | |||
116 | return (AE_OK); | ||
117 | } | ||
118 | |||
119 | /******************************************************************************* | ||
120 | * | ||
121 | * FUNCTION: acpi_ns_get_external_pathname | ||
122 | * | ||
123 | * PARAMETERS: Node - Namespace node whose pathname is needed | ||
124 | * | ||
125 | * RETURN: Pointer to storage containing the fully qualified name of | ||
126 | * the node, In external format (name segments separated by path | ||
127 | * separators.) | ||
128 | * | ||
129 | * DESCRIPTION: Used for debug printing in acpi_ns_search_table(). | ||
130 | * | ||
131 | ******************************************************************************/ | ||
132 | |||
133 | char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) | ||
134 | { | ||
135 | acpi_status status; | ||
136 | char *name_buffer; | ||
137 | acpi_size size; | ||
138 | |||
139 | ACPI_FUNCTION_TRACE_PTR(ns_get_external_pathname, node); | ||
140 | |||
141 | /* Calculate required buffer size based on depth below root */ | ||
142 | |||
143 | size = acpi_ns_get_pathname_length(node); | ||
144 | if (!size) { | ||
145 | return_PTR(NULL); | ||
146 | } | ||
147 | |||
148 | /* Allocate a buffer to be returned to caller */ | ||
149 | |||
150 | name_buffer = ACPI_ALLOCATE_ZEROED(size); | ||
151 | if (!name_buffer) { | ||
152 | ACPI_ERROR((AE_INFO, "Allocation failure")); | ||
153 | return_PTR(NULL); | ||
154 | } | ||
155 | |||
156 | /* Build the path in the allocated buffer */ | ||
157 | |||
158 | status = acpi_ns_build_external_path(node, size, name_buffer); | ||
159 | if (ACPI_FAILURE(status)) { | ||
160 | ACPI_FREE(name_buffer); | ||
161 | return_PTR(NULL); | ||
162 | } | ||
163 | |||
164 | return_PTR(name_buffer); | ||
165 | } | ||
166 | |||
167 | /******************************************************************************* | ||
168 | * | ||
169 | * FUNCTION: acpi_ns_get_pathname_length | ||
170 | * | ||
171 | * PARAMETERS: Node - Namespace node | ||
172 | * | ||
173 | * RETURN: Length of path, including prefix | ||
174 | * | ||
175 | * DESCRIPTION: Get the length of the pathname string for this node | ||
176 | * | ||
177 | ******************************************************************************/ | ||
178 | |||
179 | acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node) | ||
180 | { | ||
181 | acpi_size size; | ||
182 | struct acpi_namespace_node *next_node; | ||
183 | |||
184 | ACPI_FUNCTION_ENTRY(); | ||
185 | |||
186 | /* | ||
187 | * Compute length of pathname as 5 * number of name segments. | ||
188 | * Go back up the parent tree to the root | ||
189 | */ | ||
190 | size = 0; | ||
191 | next_node = node; | ||
192 | |||
193 | while (next_node && (next_node != acpi_gbl_root_node)) { | ||
194 | if (ACPI_GET_DESCRIPTOR_TYPE(next_node) != ACPI_DESC_TYPE_NAMED) { | ||
195 | ACPI_ERROR((AE_INFO, | ||
196 | "Invalid Namespace Node (%p) while traversing namespace", | ||
197 | next_node)); | ||
198 | return 0; | ||
199 | } | ||
200 | size += ACPI_PATH_SEGMENT_LENGTH; | ||
201 | next_node = acpi_ns_get_parent_node(next_node); | ||
202 | } | ||
203 | |||
204 | if (!size) { | ||
205 | size = 1; /* Root node case */ | ||
206 | } | ||
207 | |||
208 | return (size + 1); /* +1 for null string terminator */ | ||
209 | } | ||
210 | |||
211 | /******************************************************************************* | ||
212 | * | ||
213 | * FUNCTION: acpi_ns_handle_to_pathname | ||
214 | * | ||
215 | * PARAMETERS: target_handle - Handle of named object whose name is | ||
216 | * to be found | ||
217 | * Buffer - Where the pathname is returned | ||
218 | * | ||
219 | * RETURN: Status, Buffer is filled with pathname if status is AE_OK | ||
220 | * | ||
221 | * DESCRIPTION: Build and return a full namespace pathname | ||
222 | * | ||
223 | ******************************************************************************/ | ||
224 | |||
225 | acpi_status | ||
226 | acpi_ns_handle_to_pathname(acpi_handle target_handle, | ||
227 | struct acpi_buffer * buffer) | ||
228 | { | ||
229 | acpi_status status; | ||
230 | struct acpi_namespace_node *node; | ||
231 | acpi_size required_size; | ||
232 | |||
233 | ACPI_FUNCTION_TRACE_PTR(ns_handle_to_pathname, target_handle); | ||
234 | |||
235 | node = acpi_ns_map_handle_to_node(target_handle); | ||
236 | if (!node) { | ||
237 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
238 | } | ||
239 | |||
240 | /* Determine size required for the caller buffer */ | ||
241 | |||
242 | required_size = acpi_ns_get_pathname_length(node); | ||
243 | if (!required_size) { | ||
244 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
245 | } | ||
246 | |||
247 | /* Validate/Allocate/Clear caller buffer */ | ||
248 | |||
249 | status = acpi_ut_initialize_buffer(buffer, required_size); | ||
250 | if (ACPI_FAILURE(status)) { | ||
251 | return_ACPI_STATUS(status); | ||
252 | } | ||
253 | |||
254 | /* Build the path in the caller buffer */ | ||
255 | |||
256 | status = | ||
257 | acpi_ns_build_external_path(node, required_size, buffer->pointer); | ||
258 | if (ACPI_FAILURE(status)) { | ||
259 | return_ACPI_STATUS(status); | ||
260 | } | ||
261 | |||
262 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s [%X]\n", | ||
263 | (char *)buffer->pointer, (u32) required_size)); | ||
264 | return_ACPI_STATUS(AE_OK); | ||
265 | } | ||
diff --git a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/namespace/nsobject.c deleted file mode 100644 index ca9edeea27df..000000000000 --- a/drivers/acpi/namespace/nsobject.c +++ /dev/null | |||
@@ -1,441 +0,0 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: nsobject - Utilities for objects attached to namespace | ||
4 | * table entries | ||
5 | * | ||
6 | ******************************************************************************/ | ||
7 | |||
8 | /* | ||
9 | * Copyright (C) 2000 - 2008, Intel Corp. | ||
10 | * All rights reserved. | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or without | ||
13 | * modification, are permitted provided that the following conditions | ||
14 | * are met: | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions, and the following disclaimer, | ||
17 | * without modification. | ||
18 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
19 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
20 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
21 | * including a substantially similar Disclaimer requirement for further | ||
22 | * binary redistribution. | ||
23 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
24 | * of any contributors may be used to endorse or promote products derived | ||
25 | * from this software without specific prior written permission. | ||
26 | * | ||
27 | * Alternatively, this software may be distributed under the terms of the | ||
28 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
29 | * Software Foundation. | ||
30 | * | ||
31 | * NO WARRANTY | ||
32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
33 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
35 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
36 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
37 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
38 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
39 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
40 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
41 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
42 | * POSSIBILITY OF SUCH DAMAGES. | ||
43 | */ | ||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/accommon.h> | ||
47 | #include <acpi/acnamesp.h> | ||
48 | |||
49 | #define _COMPONENT ACPI_NAMESPACE | ||
50 | ACPI_MODULE_NAME("nsobject") | ||
51 | |||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * FUNCTION: acpi_ns_attach_object | ||
55 | * | ||
56 | * PARAMETERS: Node - Parent Node | ||
57 | * Object - Object to be attached | ||
58 | * Type - Type of object, or ACPI_TYPE_ANY if not | ||
59 | * known | ||
60 | * | ||
61 | * RETURN: Status | ||
62 | * | ||
63 | * DESCRIPTION: Record the given object as the value associated with the | ||
64 | * name whose acpi_handle is passed. If Object is NULL | ||
65 | * and Type is ACPI_TYPE_ANY, set the name as having no value. | ||
66 | * Note: Future may require that the Node->Flags field be passed | ||
67 | * as a parameter. | ||
68 | * | ||
69 | * MUTEX: Assumes namespace is locked | ||
70 | * | ||
71 | ******************************************************************************/ | ||
72 | acpi_status | ||
73 | acpi_ns_attach_object(struct acpi_namespace_node *node, | ||
74 | union acpi_operand_object *object, acpi_object_type type) | ||
75 | { | ||
76 | union acpi_operand_object *obj_desc; | ||
77 | union acpi_operand_object *last_obj_desc; | ||
78 | acpi_object_type object_type = ACPI_TYPE_ANY; | ||
79 | |||
80 | ACPI_FUNCTION_TRACE(ns_attach_object); | ||
81 | |||
82 | /* | ||
83 | * Parameter validation | ||
84 | */ | ||
85 | if (!node) { | ||
86 | |||
87 | /* Invalid handle */ | ||
88 | |||
89 | ACPI_ERROR((AE_INFO, "Null NamedObj handle")); | ||
90 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
91 | } | ||
92 | |||
93 | if (!object && (ACPI_TYPE_ANY != type)) { | ||
94 | |||
95 | /* Null object */ | ||
96 | |||
97 | ACPI_ERROR((AE_INFO, | ||
98 | "Null object, but type not ACPI_TYPE_ANY")); | ||
99 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
100 | } | ||
101 | |||
102 | if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { | ||
103 | |||
104 | /* Not a name handle */ | ||
105 | |||
106 | ACPI_ERROR((AE_INFO, "Invalid handle %p [%s]", | ||
107 | node, acpi_ut_get_descriptor_name(node))); | ||
108 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
109 | } | ||
110 | |||
111 | /* Check if this object is already attached */ | ||
112 | |||
113 | if (node->object == object) { | ||
114 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
115 | "Obj %p already installed in NameObj %p\n", | ||
116 | object, node)); | ||
117 | |||
118 | return_ACPI_STATUS(AE_OK); | ||
119 | } | ||
120 | |||
121 | /* If null object, we will just install it */ | ||
122 | |||
123 | if (!object) { | ||
124 | obj_desc = NULL; | ||
125 | object_type = ACPI_TYPE_ANY; | ||
126 | } | ||
127 | |||
128 | /* | ||
129 | * If the source object is a namespace Node with an attached object, | ||
130 | * we will use that (attached) object | ||
131 | */ | ||
132 | else if ((ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) && | ||
133 | ((struct acpi_namespace_node *)object)->object) { | ||
134 | /* | ||
135 | * Value passed is a name handle and that name has a | ||
136 | * non-null value. Use that name's value and type. | ||
137 | */ | ||
138 | obj_desc = ((struct acpi_namespace_node *)object)->object; | ||
139 | object_type = ((struct acpi_namespace_node *)object)->type; | ||
140 | } | ||
141 | |||
142 | /* | ||
143 | * Otherwise, we will use the parameter object, but we must type | ||
144 | * it first | ||
145 | */ | ||
146 | else { | ||
147 | obj_desc = (union acpi_operand_object *)object; | ||
148 | |||
149 | /* Use the given type */ | ||
150 | |||
151 | object_type = type; | ||
152 | } | ||
153 | |||
154 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n", | ||
155 | obj_desc, node, acpi_ut_get_node_name(node))); | ||
156 | |||
157 | /* Detach an existing attached object if present */ | ||
158 | |||
159 | if (node->object) { | ||
160 | acpi_ns_detach_object(node); | ||
161 | } | ||
162 | |||
163 | if (obj_desc) { | ||
164 | /* | ||
165 | * Must increment the new value's reference count | ||
166 | * (if it is an internal object) | ||
167 | */ | ||
168 | acpi_ut_add_reference(obj_desc); | ||
169 | |||
170 | /* | ||
171 | * Handle objects with multiple descriptors - walk | ||
172 | * to the end of the descriptor list | ||
173 | */ | ||
174 | last_obj_desc = obj_desc; | ||
175 | while (last_obj_desc->common.next_object) { | ||
176 | last_obj_desc = last_obj_desc->common.next_object; | ||
177 | } | ||
178 | |||
179 | /* Install the object at the front of the object list */ | ||
180 | |||
181 | last_obj_desc->common.next_object = node->object; | ||
182 | } | ||
183 | |||
184 | node->type = (u8) object_type; | ||
185 | node->object = obj_desc; | ||
186 | |||
187 | return_ACPI_STATUS(AE_OK); | ||
188 | } | ||
189 | |||
190 | /******************************************************************************* | ||
191 | * | ||
192 | * FUNCTION: acpi_ns_detach_object | ||
193 | * | ||
194 | * PARAMETERS: Node - A Namespace node whose object will be detached | ||
195 | * | ||
196 | * RETURN: None. | ||
197 | * | ||
198 | * DESCRIPTION: Detach/delete an object associated with a namespace node. | ||
199 | * if the object is an allocated object, it is freed. | ||
200 | * Otherwise, the field is simply cleared. | ||
201 | * | ||
202 | ******************************************************************************/ | ||
203 | |||
204 | void acpi_ns_detach_object(struct acpi_namespace_node *node) | ||
205 | { | ||
206 | union acpi_operand_object *obj_desc; | ||
207 | |||
208 | ACPI_FUNCTION_TRACE(ns_detach_object); | ||
209 | |||
210 | obj_desc = node->object; | ||
211 | |||
212 | if (!obj_desc || | ||
213 | (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA)) { | ||
214 | return_VOID; | ||
215 | } | ||
216 | |||
217 | /* Clear the entry in all cases */ | ||
218 | |||
219 | node->object = NULL; | ||
220 | if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_OPERAND) { | ||
221 | node->object = obj_desc->common.next_object; | ||
222 | if (node->object && | ||
223 | (ACPI_GET_OBJECT_TYPE(node->object) != | ||
224 | ACPI_TYPE_LOCAL_DATA)) { | ||
225 | node->object = node->object->common.next_object; | ||
226 | } | ||
227 | } | ||
228 | |||
229 | /* Reset the node type to untyped */ | ||
230 | |||
231 | node->type = ACPI_TYPE_ANY; | ||
232 | |||
233 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Node %p [%4.4s] Object %p\n", | ||
234 | node, acpi_ut_get_node_name(node), obj_desc)); | ||
235 | |||
236 | /* Remove one reference on the object (and all subobjects) */ | ||
237 | |||
238 | acpi_ut_remove_reference(obj_desc); | ||
239 | return_VOID; | ||
240 | } | ||
241 | |||
242 | /******************************************************************************* | ||
243 | * | ||
244 | * FUNCTION: acpi_ns_get_attached_object | ||
245 | * | ||
246 | * PARAMETERS: Node - Namespace node | ||
247 | * | ||
248 | * RETURN: Current value of the object field from the Node whose | ||
249 | * handle is passed | ||
250 | * | ||
251 | * DESCRIPTION: Obtain the object attached to a namespace node. | ||
252 | * | ||
253 | ******************************************************************************/ | ||
254 | |||
255 | union acpi_operand_object *acpi_ns_get_attached_object(struct | ||
256 | acpi_namespace_node | ||
257 | *node) | ||
258 | { | ||
259 | ACPI_FUNCTION_TRACE_PTR(ns_get_attached_object, node); | ||
260 | |||
261 | if (!node) { | ||
262 | ACPI_WARNING((AE_INFO, "Null Node ptr")); | ||
263 | return_PTR(NULL); | ||
264 | } | ||
265 | |||
266 | if (!node->object || | ||
267 | ((ACPI_GET_DESCRIPTOR_TYPE(node->object) != ACPI_DESC_TYPE_OPERAND) | ||
268 | && (ACPI_GET_DESCRIPTOR_TYPE(node->object) != | ||
269 | ACPI_DESC_TYPE_NAMED)) | ||
270 | || (ACPI_GET_OBJECT_TYPE(node->object) == ACPI_TYPE_LOCAL_DATA)) { | ||
271 | return_PTR(NULL); | ||
272 | } | ||
273 | |||
274 | return_PTR(node->object); | ||
275 | } | ||
276 | |||
277 | /******************************************************************************* | ||
278 | * | ||
279 | * FUNCTION: acpi_ns_get_secondary_object | ||
280 | * | ||
281 | * PARAMETERS: Node - Namespace node | ||
282 | * | ||
283 | * RETURN: Current value of the object field from the Node whose | ||
284 | * handle is passed. | ||
285 | * | ||
286 | * DESCRIPTION: Obtain a secondary object associated with a namespace node. | ||
287 | * | ||
288 | ******************************************************************************/ | ||
289 | |||
290 | union acpi_operand_object *acpi_ns_get_secondary_object(union | ||
291 | acpi_operand_object | ||
292 | *obj_desc) | ||
293 | { | ||
294 | ACPI_FUNCTION_TRACE_PTR(ns_get_secondary_object, obj_desc); | ||
295 | |||
296 | if ((!obj_desc) || | ||
297 | (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) || | ||
298 | (!obj_desc->common.next_object) || | ||
299 | (ACPI_GET_OBJECT_TYPE(obj_desc->common.next_object) == | ||
300 | ACPI_TYPE_LOCAL_DATA)) { | ||
301 | return_PTR(NULL); | ||
302 | } | ||
303 | |||
304 | return_PTR(obj_desc->common.next_object); | ||
305 | } | ||
306 | |||
307 | /******************************************************************************* | ||
308 | * | ||
309 | * FUNCTION: acpi_ns_attach_data | ||
310 | * | ||
311 | * PARAMETERS: Node - Namespace node | ||
312 | * Handler - Handler to be associated with the data | ||
313 | * Data - Data to be attached | ||
314 | * | ||
315 | * RETURN: Status | ||
316 | * | ||
317 | * DESCRIPTION: Low-level attach data. Create and attach a Data object. | ||
318 | * | ||
319 | ******************************************************************************/ | ||
320 | |||
321 | acpi_status | ||
322 | acpi_ns_attach_data(struct acpi_namespace_node *node, | ||
323 | acpi_object_handler handler, void *data) | ||
324 | { | ||
325 | union acpi_operand_object *prev_obj_desc; | ||
326 | union acpi_operand_object *obj_desc; | ||
327 | union acpi_operand_object *data_desc; | ||
328 | |||
329 | /* We only allow one attachment per handler */ | ||
330 | |||
331 | prev_obj_desc = NULL; | ||
332 | obj_desc = node->object; | ||
333 | while (obj_desc) { | ||
334 | if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) && | ||
335 | (obj_desc->data.handler == handler)) { | ||
336 | return (AE_ALREADY_EXISTS); | ||
337 | } | ||
338 | |||
339 | prev_obj_desc = obj_desc; | ||
340 | obj_desc = obj_desc->common.next_object; | ||
341 | } | ||
342 | |||
343 | /* Create an internal object for the data */ | ||
344 | |||
345 | data_desc = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_DATA); | ||
346 | if (!data_desc) { | ||
347 | return (AE_NO_MEMORY); | ||
348 | } | ||
349 | |||
350 | data_desc->data.handler = handler; | ||
351 | data_desc->data.pointer = data; | ||
352 | |||
353 | /* Install the data object */ | ||
354 | |||
355 | if (prev_obj_desc) { | ||
356 | prev_obj_desc->common.next_object = data_desc; | ||
357 | } else { | ||
358 | node->object = data_desc; | ||
359 | } | ||
360 | |||
361 | return (AE_OK); | ||
362 | } | ||
363 | |||
364 | /******************************************************************************* | ||
365 | * | ||
366 | * FUNCTION: acpi_ns_detach_data | ||
367 | * | ||
368 | * PARAMETERS: Node - Namespace node | ||
369 | * Handler - Handler associated with the data | ||
370 | * | ||
371 | * RETURN: Status | ||
372 | * | ||
373 | * DESCRIPTION: Low-level detach data. Delete the data node, but the caller | ||
374 | * is responsible for the actual data. | ||
375 | * | ||
376 | ******************************************************************************/ | ||
377 | |||
378 | acpi_status | ||
379 | acpi_ns_detach_data(struct acpi_namespace_node * node, | ||
380 | acpi_object_handler handler) | ||
381 | { | ||
382 | union acpi_operand_object *obj_desc; | ||
383 | union acpi_operand_object *prev_obj_desc; | ||
384 | |||
385 | prev_obj_desc = NULL; | ||
386 | obj_desc = node->object; | ||
387 | while (obj_desc) { | ||
388 | if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) && | ||
389 | (obj_desc->data.handler == handler)) { | ||
390 | if (prev_obj_desc) { | ||
391 | prev_obj_desc->common.next_object = | ||
392 | obj_desc->common.next_object; | ||
393 | } else { | ||
394 | node->object = obj_desc->common.next_object; | ||
395 | } | ||
396 | |||
397 | acpi_ut_remove_reference(obj_desc); | ||
398 | return (AE_OK); | ||
399 | } | ||
400 | |||
401 | prev_obj_desc = obj_desc; | ||
402 | obj_desc = obj_desc->common.next_object; | ||
403 | } | ||
404 | |||
405 | return (AE_NOT_FOUND); | ||
406 | } | ||
407 | |||
408 | /******************************************************************************* | ||
409 | * | ||
410 | * FUNCTION: acpi_ns_get_attached_data | ||
411 | * | ||
412 | * PARAMETERS: Node - Namespace node | ||
413 | * Handler - Handler associated with the data | ||
414 | * Data - Where the data is returned | ||
415 | * | ||
416 | * RETURN: Status | ||
417 | * | ||
418 | * DESCRIPTION: Low level interface to obtain data previously associated with | ||
419 | * a namespace node. | ||
420 | * | ||
421 | ******************************************************************************/ | ||
422 | |||
423 | acpi_status | ||
424 | acpi_ns_get_attached_data(struct acpi_namespace_node * node, | ||
425 | acpi_object_handler handler, void **data) | ||
426 | { | ||
427 | union acpi_operand_object *obj_desc; | ||
428 | |||
429 | obj_desc = node->object; | ||
430 | while (obj_desc) { | ||
431 | if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) && | ||
432 | (obj_desc->data.handler == handler)) { | ||
433 | *data = obj_desc->data.pointer; | ||
434 | return (AE_OK); | ||
435 | } | ||
436 | |||
437 | obj_desc = obj_desc->common.next_object; | ||
438 | } | ||
439 | |||
440 | return (AE_NOT_FOUND); | ||
441 | } | ||
diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c deleted file mode 100644 index bcfcf427c909..000000000000 --- a/drivers/acpi/namespace/nsparse.c +++ /dev/null | |||
@@ -1,204 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: nsparse - namespace interface to AML parser | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2008, 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 <acpi/acpi.h> | ||
45 | #include <acpi/accommon.h> | ||
46 | #include <acpi/acnamesp.h> | ||
47 | #include <acpi/acparser.h> | ||
48 | #include <acpi/acdispat.h> | ||
49 | #include <acpi/actables.h> | ||
50 | |||
51 | #define _COMPONENT ACPI_NAMESPACE | ||
52 | ACPI_MODULE_NAME("nsparse") | ||
53 | |||
54 | /******************************************************************************* | ||
55 | * | ||
56 | * FUNCTION: ns_one_complete_parse | ||
57 | * | ||
58 | * PARAMETERS: pass_number - 1 or 2 | ||
59 | * table_desc - The table to be parsed. | ||
60 | * | ||
61 | * RETURN: Status | ||
62 | * | ||
63 | * DESCRIPTION: Perform one complete parse of an ACPI/AML table. | ||
64 | * | ||
65 | ******************************************************************************/ | ||
66 | acpi_status | ||
67 | acpi_ns_one_complete_parse(u32 pass_number, | ||
68 | u32 table_index, | ||
69 | struct acpi_namespace_node *start_node) | ||
70 | { | ||
71 | union acpi_parse_object *parse_root; | ||
72 | acpi_status status; | ||
73 | u32 aml_length; | ||
74 | u8 *aml_start; | ||
75 | struct acpi_walk_state *walk_state; | ||
76 | struct acpi_table_header *table; | ||
77 | acpi_owner_id owner_id; | ||
78 | |||
79 | ACPI_FUNCTION_TRACE(ns_one_complete_parse); | ||
80 | |||
81 | status = acpi_tb_get_owner_id(table_index, &owner_id); | ||
82 | if (ACPI_FAILURE(status)) { | ||
83 | return_ACPI_STATUS(status); | ||
84 | } | ||
85 | |||
86 | /* Create and init a Root Node */ | ||
87 | |||
88 | parse_root = acpi_ps_create_scope_op(); | ||
89 | if (!parse_root) { | ||
90 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
91 | } | ||
92 | |||
93 | /* Create and initialize a new walk state */ | ||
94 | |||
95 | walk_state = acpi_ds_create_walk_state(owner_id, NULL, NULL, NULL); | ||
96 | if (!walk_state) { | ||
97 | acpi_ps_free_op(parse_root); | ||
98 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
99 | } | ||
100 | |||
101 | status = acpi_get_table_by_index(table_index, &table); | ||
102 | if (ACPI_FAILURE(status)) { | ||
103 | acpi_ds_delete_walk_state(walk_state); | ||
104 | acpi_ps_free_op(parse_root); | ||
105 | return_ACPI_STATUS(status); | ||
106 | } | ||
107 | |||
108 | /* Table must consist of at least a complete header */ | ||
109 | |||
110 | if (table->length < sizeof(struct acpi_table_header)) { | ||
111 | status = AE_BAD_HEADER; | ||
112 | } else { | ||
113 | aml_start = (u8 *) table + sizeof(struct acpi_table_header); | ||
114 | aml_length = table->length - sizeof(struct acpi_table_header); | ||
115 | status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, | ||
116 | aml_start, aml_length, NULL, | ||
117 | (u8) pass_number); | ||
118 | } | ||
119 | |||
120 | if (ACPI_FAILURE(status)) { | ||
121 | acpi_ds_delete_walk_state(walk_state); | ||
122 | goto cleanup; | ||
123 | } | ||
124 | |||
125 | /* start_node is the default location to load the table */ | ||
126 | |||
127 | if (start_node && start_node != acpi_gbl_root_node) { | ||
128 | status = | ||
129 | acpi_ds_scope_stack_push(start_node, ACPI_TYPE_METHOD, | ||
130 | walk_state); | ||
131 | if (ACPI_FAILURE(status)) { | ||
132 | acpi_ds_delete_walk_state(walk_state); | ||
133 | goto cleanup; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | /* Parse the AML */ | ||
138 | |||
139 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "*PARSE* pass %d parse\n", | ||
140 | (unsigned)pass_number)); | ||
141 | status = acpi_ps_parse_aml(walk_state); | ||
142 | |||
143 | cleanup: | ||
144 | acpi_ps_delete_parse_tree(parse_root); | ||
145 | return_ACPI_STATUS(status); | ||
146 | } | ||
147 | |||
148 | /******************************************************************************* | ||
149 | * | ||
150 | * FUNCTION: acpi_ns_parse_table | ||
151 | * | ||
152 | * PARAMETERS: table_desc - An ACPI table descriptor for table to parse | ||
153 | * start_node - Where to enter the table into the namespace | ||
154 | * | ||
155 | * RETURN: Status | ||
156 | * | ||
157 | * DESCRIPTION: Parse AML within an ACPI table and return a tree of ops | ||
158 | * | ||
159 | ******************************************************************************/ | ||
160 | |||
161 | acpi_status | ||
162 | acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node) | ||
163 | { | ||
164 | acpi_status status; | ||
165 | |||
166 | ACPI_FUNCTION_TRACE(ns_parse_table); | ||
167 | |||
168 | /* | ||
169 | * AML Parse, pass 1 | ||
170 | * | ||
171 | * In this pass, we load most of the namespace. Control methods | ||
172 | * are not parsed until later. A parse tree is not created. Instead, | ||
173 | * each Parser Op subtree is deleted when it is finished. This saves | ||
174 | * a great deal of memory, and allows a small cache of parse objects | ||
175 | * to service the entire parse. The second pass of the parse then | ||
176 | * performs another complete parse of the AML. | ||
177 | */ | ||
178 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n")); | ||
179 | status = | ||
180 | acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, table_index, | ||
181 | start_node); | ||
182 | if (ACPI_FAILURE(status)) { | ||
183 | return_ACPI_STATUS(status); | ||
184 | } | ||
185 | |||
186 | /* | ||
187 | * AML Parse, pass 2 | ||
188 | * | ||
189 | * In this pass, we resolve forward references and other things | ||
190 | * that could not be completed during the first pass. | ||
191 | * Another complete parse of the AML is performed, but the | ||
192 | * overhead of this is compensated for by the fact that the | ||
193 | * parse objects are all cached. | ||
194 | */ | ||
195 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n")); | ||
196 | status = | ||
197 | acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, table_index, | ||
198 | start_node); | ||
199 | if (ACPI_FAILURE(status)) { | ||
200 | return_ACPI_STATUS(status); | ||
201 | } | ||
202 | |||
203 | return_ACPI_STATUS(status); | ||
204 | } | ||
diff --git a/drivers/acpi/namespace/nspredef.c b/drivers/acpi/namespace/nspredef.c deleted file mode 100644 index 1e682d03f620..000000000000 --- a/drivers/acpi/namespace/nspredef.c +++ /dev/null | |||
@@ -1,1065 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: nspredef - Validation of ACPI predefined methods and objects | ||
4 | * $Revision: 1.1 $ | ||
5 | * | ||
6 | *****************************************************************************/ | ||
7 | |||
8 | /* | ||
9 | * Copyright (C) 2000 - 2008, Intel Corp. | ||
10 | * All rights reserved. | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or without | ||
13 | * modification, are permitted provided that the following conditions | ||
14 | * are met: | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions, and the following disclaimer, | ||
17 | * without modification. | ||
18 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
19 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
20 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
21 | * including a substantially similar Disclaimer requirement for further | ||
22 | * binary redistribution. | ||
23 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
24 | * of any contributors may be used to endorse or promote products derived | ||
25 | * from this software without specific prior written permission. | ||
26 | * | ||
27 | * Alternatively, this software may be distributed under the terms of the | ||
28 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
29 | * Software Foundation. | ||
30 | * | ||
31 | * NO WARRANTY | ||
32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
33 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
35 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
36 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
37 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
38 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
39 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
40 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
41 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
42 | * POSSIBILITY OF SUCH DAMAGES. | ||
43 | */ | ||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/accommon.h> | ||
47 | #include <acpi/acnamesp.h> | ||
48 | #include <acpi/acpredef.h> | ||
49 | |||
50 | #define _COMPONENT ACPI_NAMESPACE | ||
51 | ACPI_MODULE_NAME("nspredef") | ||
52 | |||
53 | /******************************************************************************* | ||
54 | * | ||
55 | * This module validates predefined ACPI objects that appear in the namespace, | ||
56 | * at the time they are evaluated (via acpi_evaluate_object). The purpose of this | ||
57 | * validation is to detect problems with BIOS-exposed predefined ACPI objects | ||
58 | * before the results are returned to the ACPI-related drivers. | ||
59 | * | ||
60 | * There are several areas that are validated: | ||
61 | * | ||
62 | * 1) The number of input arguments as defined by the method/object in the | ||
63 | * ASL is validated against the ACPI specification. | ||
64 | * 2) The type of the return object (if any) is validated against the ACPI | ||
65 | * specification. | ||
66 | * 3) For returned package objects, the count of package elements is | ||
67 | * validated, as well as the type of each package element. Nested | ||
68 | * packages are supported. | ||
69 | * | ||
70 | * For any problems found, a warning message is issued. | ||
71 | * | ||
72 | ******************************************************************************/ | ||
73 | /* Local prototypes */ | ||
74 | static acpi_status | ||
75 | acpi_ns_check_package(char *pathname, | ||
76 | union acpi_operand_object **return_object_ptr, | ||
77 | const union acpi_predefined_info *predefined); | ||
78 | |||
79 | static acpi_status | ||
80 | acpi_ns_check_package_elements(char *pathname, | ||
81 | union acpi_operand_object **elements, | ||
82 | u8 type1, u32 count1, u8 type2, u32 count2); | ||
83 | |||
84 | static acpi_status | ||
85 | acpi_ns_check_object_type(char *pathname, | ||
86 | union acpi_operand_object **return_object_ptr, | ||
87 | u32 expected_btypes, u32 package_index); | ||
88 | |||
89 | static acpi_status | ||
90 | acpi_ns_check_reference(char *pathname, | ||
91 | union acpi_operand_object *return_object); | ||
92 | |||
93 | static acpi_status | ||
94 | acpi_ns_repair_object(u32 expected_btypes, | ||
95 | u32 package_index, | ||
96 | union acpi_operand_object **return_object_ptr); | ||
97 | |||
98 | /* | ||
99 | * Names for the types that can be returned by the predefined objects. | ||
100 | * Used for warning messages. Must be in the same order as the ACPI_RTYPEs | ||
101 | */ | ||
102 | static const char *acpi_rtype_names[] = { | ||
103 | "/Integer", | ||
104 | "/String", | ||
105 | "/Buffer", | ||
106 | "/Package", | ||
107 | "/Reference", | ||
108 | }; | ||
109 | |||
110 | #define ACPI_NOT_PACKAGE ACPI_UINT32_MAX | ||
111 | |||
112 | /******************************************************************************* | ||
113 | * | ||
114 | * FUNCTION: acpi_ns_check_predefined_names | ||
115 | * | ||
116 | * PARAMETERS: Node - Namespace node for the method/object | ||
117 | * return_object_ptr - Pointer to the object returned from the | ||
118 | * evaluation of a method or object | ||
119 | * | ||
120 | * RETURN: Status | ||
121 | * | ||
122 | * DESCRIPTION: Check an ACPI name for a match in the predefined name list. | ||
123 | * | ||
124 | ******************************************************************************/ | ||
125 | |||
126 | acpi_status | ||
127 | acpi_ns_check_predefined_names(struct acpi_namespace_node *node, | ||
128 | u32 user_param_count, | ||
129 | acpi_status return_status, | ||
130 | union acpi_operand_object **return_object_ptr) | ||
131 | { | ||
132 | union acpi_operand_object *return_object = *return_object_ptr; | ||
133 | acpi_status status = AE_OK; | ||
134 | const union acpi_predefined_info *predefined; | ||
135 | char *pathname; | ||
136 | |||
137 | /* Match the name for this method/object against the predefined list */ | ||
138 | |||
139 | predefined = acpi_ns_check_for_predefined_name(node); | ||
140 | |||
141 | /* Get the full pathname to the object, for use in error messages */ | ||
142 | |||
143 | pathname = acpi_ns_get_external_pathname(node); | ||
144 | if (!pathname) { | ||
145 | pathname = ACPI_CAST_PTR(char, predefined->info.name); | ||
146 | } | ||
147 | |||
148 | /* | ||
149 | * Check that the parameter count for this method matches the ASL | ||
150 | * definition. For predefined names, ensure that both the caller and | ||
151 | * the method itself are in accordance with the ACPI specification. | ||
152 | */ | ||
153 | acpi_ns_check_parameter_count(pathname, node, user_param_count, | ||
154 | predefined); | ||
155 | |||
156 | /* If not a predefined name, we cannot validate the return object */ | ||
157 | |||
158 | if (!predefined) { | ||
159 | goto exit; | ||
160 | } | ||
161 | |||
162 | /* If the method failed, we cannot validate the return object */ | ||
163 | |||
164 | if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) { | ||
165 | goto exit; | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | * Only validate the return value on the first successful evaluation of | ||
170 | * the method. This ensures that any warnings will only be emitted during | ||
171 | * the very first evaluation of the method/object. | ||
172 | */ | ||
173 | if (node->flags & ANOBJ_EVALUATED) { | ||
174 | goto exit; | ||
175 | } | ||
176 | |||
177 | /* Mark the node as having been successfully evaluated */ | ||
178 | |||
179 | node->flags |= ANOBJ_EVALUATED; | ||
180 | |||
181 | /* | ||
182 | * If there is no return value, check if we require a return value for | ||
183 | * this predefined name. Either one return value is expected, or none, | ||
184 | * for both methods and other objects. | ||
185 | * | ||
186 | * Exit now if there is no return object. Warning if one was expected. | ||
187 | */ | ||
188 | if (!return_object) { | ||
189 | if ((predefined->info.expected_btypes) && | ||
190 | (!(predefined->info.expected_btypes & ACPI_RTYPE_NONE))) { | ||
191 | ACPI_ERROR((AE_INFO, | ||
192 | "%s: Missing expected return value", | ||
193 | pathname)); | ||
194 | |||
195 | status = AE_AML_NO_RETURN_VALUE; | ||
196 | } | ||
197 | goto exit; | ||
198 | } | ||
199 | |||
200 | /* | ||
201 | * We have a return value, but if one wasn't expected, just exit, this is | ||
202 | * not a problem | ||
203 | * | ||
204 | * For example, if the "Implicit Return" feature is enabled, methods will | ||
205 | * always return a value | ||
206 | */ | ||
207 | if (!predefined->info.expected_btypes) { | ||
208 | goto exit; | ||
209 | } | ||
210 | |||
211 | /* | ||
212 | * Check that the type of the return object is what is expected for | ||
213 | * this predefined name | ||
214 | */ | ||
215 | status = acpi_ns_check_object_type(pathname, return_object_ptr, | ||
216 | predefined->info.expected_btypes, | ||
217 | ACPI_NOT_PACKAGE); | ||
218 | if (ACPI_FAILURE(status)) { | ||
219 | goto exit; | ||
220 | } | ||
221 | |||
222 | /* For returned Package objects, check the type of all sub-objects */ | ||
223 | |||
224 | if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_PACKAGE) { | ||
225 | status = | ||
226 | acpi_ns_check_package(pathname, return_object_ptr, | ||
227 | predefined); | ||
228 | } | ||
229 | |||
230 | exit: | ||
231 | if (pathname != predefined->info.name) { | ||
232 | ACPI_FREE(pathname); | ||
233 | } | ||
234 | |||
235 | return (status); | ||
236 | } | ||
237 | |||
238 | /******************************************************************************* | ||
239 | * | ||
240 | * FUNCTION: acpi_ns_check_parameter_count | ||
241 | * | ||
242 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | ||
243 | * Node - Namespace node for the method/object | ||
244 | * user_param_count - Number of args passed in by the caller | ||
245 | * Predefined - Pointer to entry in predefined name table | ||
246 | * | ||
247 | * RETURN: None | ||
248 | * | ||
249 | * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a | ||
250 | * predefined name is what is expected (i.e., what is defined in | ||
251 | * the ACPI specification for this predefined name.) | ||
252 | * | ||
253 | ******************************************************************************/ | ||
254 | |||
255 | void | ||
256 | acpi_ns_check_parameter_count(char *pathname, | ||
257 | struct acpi_namespace_node *node, | ||
258 | u32 user_param_count, | ||
259 | const union acpi_predefined_info *predefined) | ||
260 | { | ||
261 | u32 param_count; | ||
262 | u32 required_params_current; | ||
263 | u32 required_params_old; | ||
264 | |||
265 | /* Methods have 0-7 parameters. All other types have zero. */ | ||
266 | |||
267 | param_count = 0; | ||
268 | if (node->type == ACPI_TYPE_METHOD) { | ||
269 | param_count = node->object->method.param_count; | ||
270 | } | ||
271 | |||
272 | /* Argument count check for non-predefined methods/objects */ | ||
273 | |||
274 | if (!predefined) { | ||
275 | /* | ||
276 | * Warning if too few or too many arguments have been passed by the | ||
277 | * caller. An incorrect number of arguments may not cause the method | ||
278 | * to fail. However, the method will fail if there are too few | ||
279 | * arguments and the method attempts to use one of the missing ones. | ||
280 | */ | ||
281 | if (user_param_count < param_count) { | ||
282 | ACPI_WARNING((AE_INFO, | ||
283 | "%s: Insufficient arguments - needs %d, found %d", | ||
284 | pathname, param_count, user_param_count)); | ||
285 | } else if (user_param_count > param_count) { | ||
286 | ACPI_WARNING((AE_INFO, | ||
287 | "%s: Excess arguments - needs %d, found %d", | ||
288 | pathname, param_count, user_param_count)); | ||
289 | } | ||
290 | return; | ||
291 | } | ||
292 | |||
293 | /* Allow two different legal argument counts (_SCP, etc.) */ | ||
294 | |||
295 | required_params_current = predefined->info.param_count & 0x0F; | ||
296 | required_params_old = predefined->info.param_count >> 4; | ||
297 | |||
298 | if (user_param_count != ACPI_UINT32_MAX) { | ||
299 | |||
300 | /* Validate the user-supplied parameter count */ | ||
301 | |||
302 | if ((user_param_count != required_params_current) && | ||
303 | (user_param_count != required_params_old)) { | ||
304 | ACPI_WARNING((AE_INFO, | ||
305 | "%s: Parameter count mismatch - caller passed %d, ACPI requires %d", | ||
306 | pathname, user_param_count, | ||
307 | required_params_current)); | ||
308 | } | ||
309 | } | ||
310 | |||
311 | /* | ||
312 | * Only validate the argument count on the first successful evaluation of | ||
313 | * the method. This ensures that any warnings will only be emitted during | ||
314 | * the very first evaluation of the method/object. | ||
315 | */ | ||
316 | if (node->flags & ANOBJ_EVALUATED) { | ||
317 | return; | ||
318 | } | ||
319 | |||
320 | /* | ||
321 | * Check that the ASL-defined parameter count is what is expected for | ||
322 | * this predefined name. | ||
323 | */ | ||
324 | if ((param_count != required_params_current) && | ||
325 | (param_count != required_params_old)) { | ||
326 | ACPI_WARNING((AE_INFO, | ||
327 | "%s: Parameter count mismatch - ASL declared %d, ACPI requires %d", | ||
328 | pathname, param_count, required_params_current)); | ||
329 | } | ||
330 | } | ||
331 | |||
332 | /******************************************************************************* | ||
333 | * | ||
334 | * FUNCTION: acpi_ns_check_for_predefined_name | ||
335 | * | ||
336 | * PARAMETERS: Node - Namespace node for the method/object | ||
337 | * | ||
338 | * RETURN: Pointer to entry in predefined table. NULL indicates not found. | ||
339 | * | ||
340 | * DESCRIPTION: Check an object name against the predefined object list. | ||
341 | * | ||
342 | ******************************************************************************/ | ||
343 | |||
344 | const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct | ||
345 | acpi_namespace_node | ||
346 | *node) | ||
347 | { | ||
348 | const union acpi_predefined_info *this_name; | ||
349 | |||
350 | /* Quick check for a predefined name, first character must be underscore */ | ||
351 | |||
352 | if (node->name.ascii[0] != '_') { | ||
353 | return (NULL); | ||
354 | } | ||
355 | |||
356 | /* Search info table for a predefined method/object name */ | ||
357 | |||
358 | this_name = predefined_names; | ||
359 | while (this_name->info.name[0]) { | ||
360 | if (ACPI_COMPARE_NAME(node->name.ascii, this_name->info.name)) { | ||
361 | |||
362 | /* Return pointer to this table entry */ | ||
363 | |||
364 | return (this_name); | ||
365 | } | ||
366 | |||
367 | /* | ||
368 | * Skip next entry in the table if this name returns a Package | ||
369 | * (next entry contains the package info) | ||
370 | */ | ||
371 | if (this_name->info.expected_btypes & ACPI_RTYPE_PACKAGE) { | ||
372 | this_name++; | ||
373 | } | ||
374 | |||
375 | this_name++; | ||
376 | } | ||
377 | |||
378 | return (NULL); | ||
379 | } | ||
380 | |||
381 | /******************************************************************************* | ||
382 | * | ||
383 | * FUNCTION: acpi_ns_check_package | ||
384 | * | ||
385 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | ||
386 | * return_object_ptr - Pointer to the object returned from the | ||
387 | * evaluation of a method or object | ||
388 | * Predefined - Pointer to entry in predefined name table | ||
389 | * | ||
390 | * RETURN: Status | ||
391 | * | ||
392 | * DESCRIPTION: Check a returned package object for the correct count and | ||
393 | * correct type of all sub-objects. | ||
394 | * | ||
395 | ******************************************************************************/ | ||
396 | |||
397 | static acpi_status | ||
398 | acpi_ns_check_package(char *pathname, | ||
399 | union acpi_operand_object **return_object_ptr, | ||
400 | const union acpi_predefined_info *predefined) | ||
401 | { | ||
402 | union acpi_operand_object *return_object = *return_object_ptr; | ||
403 | const union acpi_predefined_info *package; | ||
404 | union acpi_operand_object *sub_package; | ||
405 | union acpi_operand_object **elements; | ||
406 | union acpi_operand_object **sub_elements; | ||
407 | acpi_status status; | ||
408 | u32 expected_count; | ||
409 | u32 count; | ||
410 | u32 i; | ||
411 | u32 j; | ||
412 | |||
413 | ACPI_FUNCTION_NAME(ns_check_package); | ||
414 | |||
415 | /* The package info for this name is in the next table entry */ | ||
416 | |||
417 | package = predefined + 1; | ||
418 | |||
419 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
420 | "%s Validating return Package of Type %X, Count %X\n", | ||
421 | pathname, package->ret_info.type, | ||
422 | return_object->package.count)); | ||
423 | |||
424 | /* Extract package count and elements array */ | ||
425 | |||
426 | elements = return_object->package.elements; | ||
427 | count = return_object->package.count; | ||
428 | |||
429 | /* The package must have at least one element, else invalid */ | ||
430 | |||
431 | if (!count) { | ||
432 | ACPI_WARNING((AE_INFO, | ||
433 | "%s: Return Package has no elements (empty)", | ||
434 | pathname)); | ||
435 | |||
436 | return (AE_AML_OPERAND_VALUE); | ||
437 | } | ||
438 | |||
439 | /* | ||
440 | * Decode the type of the expected package contents | ||
441 | * | ||
442 | * PTYPE1 packages contain no subpackages | ||
443 | * PTYPE2 packages contain sub-packages | ||
444 | */ | ||
445 | switch (package->ret_info.type) { | ||
446 | case ACPI_PTYPE1_FIXED: | ||
447 | |||
448 | /* | ||
449 | * The package count is fixed and there are no sub-packages | ||
450 | * | ||
451 | * If package is too small, exit. | ||
452 | * If package is larger than expected, issue warning but continue | ||
453 | */ | ||
454 | expected_count = | ||
455 | package->ret_info.count1 + package->ret_info.count2; | ||
456 | if (count < expected_count) { | ||
457 | goto package_too_small; | ||
458 | } else if (count > expected_count) { | ||
459 | ACPI_WARNING((AE_INFO, | ||
460 | "%s: Return Package is larger than needed - " | ||
461 | "found %u, expected %u", pathname, count, | ||
462 | expected_count)); | ||
463 | } | ||
464 | |||
465 | /* Validate all elements of the returned package */ | ||
466 | |||
467 | status = acpi_ns_check_package_elements(pathname, elements, | ||
468 | package->ret_info. | ||
469 | object_type1, | ||
470 | package->ret_info. | ||
471 | count1, | ||
472 | package->ret_info. | ||
473 | object_type2, | ||
474 | package->ret_info. | ||
475 | count2); | ||
476 | if (ACPI_FAILURE(status)) { | ||
477 | return (status); | ||
478 | } | ||
479 | break; | ||
480 | |||
481 | case ACPI_PTYPE1_VAR: | ||
482 | |||
483 | /* | ||
484 | * The package count is variable, there are no sub-packages, and all | ||
485 | * elements must be of the same type | ||
486 | */ | ||
487 | for (i = 0; i < count; i++) { | ||
488 | status = acpi_ns_check_object_type(pathname, elements, | ||
489 | package->ret_info. | ||
490 | object_type1, i); | ||
491 | if (ACPI_FAILURE(status)) { | ||
492 | return (status); | ||
493 | } | ||
494 | elements++; | ||
495 | } | ||
496 | break; | ||
497 | |||
498 | case ACPI_PTYPE1_OPTION: | ||
499 | |||
500 | /* | ||
501 | * The package count is variable, there are no sub-packages. There are | ||
502 | * a fixed number of required elements, and a variable number of | ||
503 | * optional elements. | ||
504 | * | ||
505 | * Check if package is at least as large as the minimum required | ||
506 | */ | ||
507 | expected_count = package->ret_info3.count; | ||
508 | if (count < expected_count) { | ||
509 | goto package_too_small; | ||
510 | } | ||
511 | |||
512 | /* Variable number of sub-objects */ | ||
513 | |||
514 | for (i = 0; i < count; i++) { | ||
515 | if (i < package->ret_info3.count) { | ||
516 | |||
517 | /* These are the required package elements (0, 1, or 2) */ | ||
518 | |||
519 | status = | ||
520 | acpi_ns_check_object_type(pathname, | ||
521 | elements, | ||
522 | package-> | ||
523 | ret_info3. | ||
524 | object_type[i], | ||
525 | i); | ||
526 | if (ACPI_FAILURE(status)) { | ||
527 | return (status); | ||
528 | } | ||
529 | } else { | ||
530 | /* These are the optional package elements */ | ||
531 | |||
532 | status = | ||
533 | acpi_ns_check_object_type(pathname, | ||
534 | elements, | ||
535 | package-> | ||
536 | ret_info3. | ||
537 | tail_object_type, | ||
538 | i); | ||
539 | if (ACPI_FAILURE(status)) { | ||
540 | return (status); | ||
541 | } | ||
542 | } | ||
543 | elements++; | ||
544 | } | ||
545 | break; | ||
546 | |||
547 | case ACPI_PTYPE2_PKG_COUNT: | ||
548 | |||
549 | /* First element is the (Integer) count of sub-packages to follow */ | ||
550 | |||
551 | status = acpi_ns_check_object_type(pathname, elements, | ||
552 | ACPI_RTYPE_INTEGER, 0); | ||
553 | if (ACPI_FAILURE(status)) { | ||
554 | return (status); | ||
555 | } | ||
556 | |||
557 | /* | ||
558 | * Count cannot be larger than the parent package length, but allow it | ||
559 | * to be smaller. The >= accounts for the Integer above. | ||
560 | */ | ||
561 | expected_count = (u32) (*elements)->integer.value; | ||
562 | if (expected_count >= count) { | ||
563 | goto package_too_small; | ||
564 | } | ||
565 | |||
566 | count = expected_count; | ||
567 | elements++; | ||
568 | |||
569 | /* Now we can walk the sub-packages */ | ||
570 | |||
571 | /*lint -fallthrough */ | ||
572 | |||
573 | case ACPI_PTYPE2: | ||
574 | case ACPI_PTYPE2_FIXED: | ||
575 | case ACPI_PTYPE2_MIN: | ||
576 | case ACPI_PTYPE2_COUNT: | ||
577 | |||
578 | /* | ||
579 | * These types all return a single package that consists of a variable | ||
580 | * number of sub-packages | ||
581 | */ | ||
582 | for (i = 0; i < count; i++) { | ||
583 | sub_package = *elements; | ||
584 | sub_elements = sub_package->package.elements; | ||
585 | |||
586 | /* Each sub-object must be of type Package */ | ||
587 | |||
588 | status = | ||
589 | acpi_ns_check_object_type(pathname, &sub_package, | ||
590 | ACPI_RTYPE_PACKAGE, i); | ||
591 | if (ACPI_FAILURE(status)) { | ||
592 | return (status); | ||
593 | } | ||
594 | |||
595 | /* Examine the different types of sub-packages */ | ||
596 | |||
597 | switch (package->ret_info.type) { | ||
598 | case ACPI_PTYPE2: | ||
599 | case ACPI_PTYPE2_PKG_COUNT: | ||
600 | |||
601 | /* Each subpackage has a fixed number of elements */ | ||
602 | |||
603 | expected_count = | ||
604 | package->ret_info.count1 + | ||
605 | package->ret_info.count2; | ||
606 | if (sub_package->package.count != | ||
607 | expected_count) { | ||
608 | count = sub_package->package.count; | ||
609 | goto package_too_small; | ||
610 | } | ||
611 | |||
612 | status = | ||
613 | acpi_ns_check_package_elements(pathname, | ||
614 | sub_elements, | ||
615 | package-> | ||
616 | ret_info. | ||
617 | object_type1, | ||
618 | package-> | ||
619 | ret_info. | ||
620 | count1, | ||
621 | package-> | ||
622 | ret_info. | ||
623 | object_type2, | ||
624 | package-> | ||
625 | ret_info. | ||
626 | count2); | ||
627 | if (ACPI_FAILURE(status)) { | ||
628 | return (status); | ||
629 | } | ||
630 | break; | ||
631 | |||
632 | case ACPI_PTYPE2_FIXED: | ||
633 | |||
634 | /* Each sub-package has a fixed length */ | ||
635 | |||
636 | expected_count = package->ret_info2.count; | ||
637 | if (sub_package->package.count < expected_count) { | ||
638 | count = sub_package->package.count; | ||
639 | goto package_too_small; | ||
640 | } | ||
641 | |||
642 | /* Check the type of each sub-package element */ | ||
643 | |||
644 | for (j = 0; j < expected_count; j++) { | ||
645 | status = | ||
646 | acpi_ns_check_object_type(pathname, | ||
647 | &sub_elements[j], | ||
648 | package->ret_info2.object_type[j], j); | ||
649 | if (ACPI_FAILURE(status)) { | ||
650 | return (status); | ||
651 | } | ||
652 | } | ||
653 | break; | ||
654 | |||
655 | case ACPI_PTYPE2_MIN: | ||
656 | |||
657 | /* Each sub-package has a variable but minimum length */ | ||
658 | |||
659 | expected_count = package->ret_info.count1; | ||
660 | if (sub_package->package.count < expected_count) { | ||
661 | count = sub_package->package.count; | ||
662 | goto package_too_small; | ||
663 | } | ||
664 | |||
665 | /* Check the type of each sub-package element */ | ||
666 | |||
667 | status = | ||
668 | acpi_ns_check_package_elements(pathname, | ||
669 | sub_elements, | ||
670 | package-> | ||
671 | ret_info. | ||
672 | object_type1, | ||
673 | sub_package-> | ||
674 | package. | ||
675 | count, 0, 0); | ||
676 | if (ACPI_FAILURE(status)) { | ||
677 | return (status); | ||
678 | } | ||
679 | break; | ||
680 | |||
681 | case ACPI_PTYPE2_COUNT: | ||
682 | |||
683 | /* First element is the (Integer) count of elements to follow */ | ||
684 | |||
685 | status = | ||
686 | acpi_ns_check_object_type(pathname, | ||
687 | sub_elements, | ||
688 | ACPI_RTYPE_INTEGER, | ||
689 | 0); | ||
690 | if (ACPI_FAILURE(status)) { | ||
691 | return (status); | ||
692 | } | ||
693 | |||
694 | /* Make sure package is large enough for the Count */ | ||
695 | |||
696 | expected_count = | ||
697 | (u32) (*sub_elements)->integer.value; | ||
698 | if (sub_package->package.count < expected_count) { | ||
699 | count = sub_package->package.count; | ||
700 | goto package_too_small; | ||
701 | } | ||
702 | |||
703 | /* Check the type of each sub-package element */ | ||
704 | |||
705 | status = | ||
706 | acpi_ns_check_package_elements(pathname, | ||
707 | (sub_elements | ||
708 | + 1), | ||
709 | package-> | ||
710 | ret_info. | ||
711 | object_type1, | ||
712 | (expected_count | ||
713 | - 1), 0, 0); | ||
714 | if (ACPI_FAILURE(status)) { | ||
715 | return (status); | ||
716 | } | ||
717 | break; | ||
718 | |||
719 | default: | ||
720 | break; | ||
721 | } | ||
722 | |||
723 | elements++; | ||
724 | } | ||
725 | break; | ||
726 | |||
727 | default: | ||
728 | |||
729 | /* Should not get here if predefined info table is correct */ | ||
730 | |||
731 | ACPI_WARNING((AE_INFO, | ||
732 | "%s: Invalid internal return type in table entry: %X", | ||
733 | pathname, package->ret_info.type)); | ||
734 | |||
735 | return (AE_AML_INTERNAL); | ||
736 | } | ||
737 | |||
738 | return (AE_OK); | ||
739 | |||
740 | package_too_small: | ||
741 | |||
742 | /* Error exit for the case with an incorrect package count */ | ||
743 | |||
744 | ACPI_WARNING((AE_INFO, "%s: Return Package is too small - " | ||
745 | "found %u, expected %u", pathname, count, | ||
746 | expected_count)); | ||
747 | |||
748 | return (AE_AML_OPERAND_VALUE); | ||
749 | } | ||
750 | |||
751 | /******************************************************************************* | ||
752 | * | ||
753 | * FUNCTION: acpi_ns_check_package_elements | ||
754 | * | ||
755 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | ||
756 | * Elements - Pointer to the package elements array | ||
757 | * Type1 - Object type for first group | ||
758 | * Count1 - Count for first group | ||
759 | * Type2 - Object type for second group | ||
760 | * Count2 - Count for second group | ||
761 | * | ||
762 | * RETURN: Status | ||
763 | * | ||
764 | * DESCRIPTION: Check that all elements of a package are of the correct object | ||
765 | * type. Supports up to two groups of different object types. | ||
766 | * | ||
767 | ******************************************************************************/ | ||
768 | |||
769 | static acpi_status | ||
770 | acpi_ns_check_package_elements(char *pathname, | ||
771 | union acpi_operand_object **elements, | ||
772 | u8 type1, u32 count1, u8 type2, u32 count2) | ||
773 | { | ||
774 | union acpi_operand_object **this_element = elements; | ||
775 | acpi_status status; | ||
776 | u32 i; | ||
777 | |||
778 | /* | ||
779 | * Up to two groups of package elements are supported by the data | ||
780 | * structure. All elements in each group must be of the same type. | ||
781 | * The second group can have a count of zero. | ||
782 | */ | ||
783 | for (i = 0; i < count1; i++) { | ||
784 | status = acpi_ns_check_object_type(pathname, this_element, | ||
785 | type1, i); | ||
786 | if (ACPI_FAILURE(status)) { | ||
787 | return (status); | ||
788 | } | ||
789 | this_element++; | ||
790 | } | ||
791 | |||
792 | for (i = 0; i < count2; i++) { | ||
793 | status = acpi_ns_check_object_type(pathname, this_element, | ||
794 | type2, (i + count1)); | ||
795 | if (ACPI_FAILURE(status)) { | ||
796 | return (status); | ||
797 | } | ||
798 | this_element++; | ||
799 | } | ||
800 | |||
801 | return (AE_OK); | ||
802 | } | ||
803 | |||
804 | /******************************************************************************* | ||
805 | * | ||
806 | * FUNCTION: acpi_ns_check_object_type | ||
807 | * | ||
808 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | ||
809 | * return_object_ptr - Pointer to the object returned from the | ||
810 | * evaluation of a method or object | ||
811 | * expected_btypes - Bitmap of expected return type(s) | ||
812 | * package_index - Index of object within parent package (if | ||
813 | * applicable - ACPI_NOT_PACKAGE otherwise) | ||
814 | * | ||
815 | * RETURN: Status | ||
816 | * | ||
817 | * DESCRIPTION: Check the type of the return object against the expected object | ||
818 | * type(s). Use of Btype allows multiple expected object types. | ||
819 | * | ||
820 | ******************************************************************************/ | ||
821 | |||
822 | static acpi_status | ||
823 | acpi_ns_check_object_type(char *pathname, | ||
824 | union acpi_operand_object **return_object_ptr, | ||
825 | u32 expected_btypes, u32 package_index) | ||
826 | { | ||
827 | union acpi_operand_object *return_object = *return_object_ptr; | ||
828 | acpi_status status = AE_OK; | ||
829 | u32 return_btype; | ||
830 | char type_buffer[48]; /* Room for 5 types */ | ||
831 | u32 this_rtype; | ||
832 | u32 i; | ||
833 | u32 j; | ||
834 | |||
835 | /* | ||
836 | * If we get a NULL return_object here, it is a NULL package element, | ||
837 | * and this is always an error. | ||
838 | */ | ||
839 | if (!return_object) { | ||
840 | goto type_error_exit; | ||
841 | } | ||
842 | |||
843 | /* A Namespace node should not get here, but make sure */ | ||
844 | |||
845 | if (ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) { | ||
846 | ACPI_WARNING((AE_INFO, | ||
847 | "%s: Invalid return type - Found a Namespace node [%4.4s] type %s", | ||
848 | pathname, return_object->node.name.ascii, | ||
849 | acpi_ut_get_type_name(return_object->node.type))); | ||
850 | return (AE_AML_OPERAND_TYPE); | ||
851 | } | ||
852 | |||
853 | /* | ||
854 | * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type. | ||
855 | * The bitmapped type allows multiple possible return types. | ||
856 | * | ||
857 | * Note, the cases below must handle all of the possible types returned | ||
858 | * from all of the predefined names (including elements of returned | ||
859 | * packages) | ||
860 | */ | ||
861 | switch (ACPI_GET_OBJECT_TYPE(return_object)) { | ||
862 | case ACPI_TYPE_INTEGER: | ||
863 | return_btype = ACPI_RTYPE_INTEGER; | ||
864 | break; | ||
865 | |||
866 | case ACPI_TYPE_BUFFER: | ||
867 | return_btype = ACPI_RTYPE_BUFFER; | ||
868 | break; | ||
869 | |||
870 | case ACPI_TYPE_STRING: | ||
871 | return_btype = ACPI_RTYPE_STRING; | ||
872 | break; | ||
873 | |||
874 | case ACPI_TYPE_PACKAGE: | ||
875 | return_btype = ACPI_RTYPE_PACKAGE; | ||
876 | break; | ||
877 | |||
878 | case ACPI_TYPE_LOCAL_REFERENCE: | ||
879 | return_btype = ACPI_RTYPE_REFERENCE; | ||
880 | break; | ||
881 | |||
882 | default: | ||
883 | /* Not one of the supported objects, must be incorrect */ | ||
884 | |||
885 | goto type_error_exit; | ||
886 | } | ||
887 | |||
888 | /* Is the object one of the expected types? */ | ||
889 | |||
890 | if (!(return_btype & expected_btypes)) { | ||
891 | |||
892 | /* Type mismatch -- attempt repair of the returned object */ | ||
893 | |||
894 | status = acpi_ns_repair_object(expected_btypes, package_index, | ||
895 | return_object_ptr); | ||
896 | if (ACPI_SUCCESS(status)) { | ||
897 | return (status); | ||
898 | } | ||
899 | goto type_error_exit; | ||
900 | } | ||
901 | |||
902 | /* For reference objects, check that the reference type is correct */ | ||
903 | |||
904 | if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_LOCAL_REFERENCE) { | ||
905 | status = acpi_ns_check_reference(pathname, return_object); | ||
906 | } | ||
907 | |||
908 | return (status); | ||
909 | |||
910 | type_error_exit: | ||
911 | |||
912 | /* Create a string with all expected types for this predefined object */ | ||
913 | |||
914 | j = 1; | ||
915 | type_buffer[0] = 0; | ||
916 | this_rtype = ACPI_RTYPE_INTEGER; | ||
917 | |||
918 | for (i = 0; i < ACPI_NUM_RTYPES; i++) { | ||
919 | |||
920 | /* If one of the expected types, concatenate the name of this type */ | ||
921 | |||
922 | if (expected_btypes & this_rtype) { | ||
923 | ACPI_STRCAT(type_buffer, &acpi_rtype_names[i][j]); | ||
924 | j = 0; /* Use name separator from now on */ | ||
925 | } | ||
926 | this_rtype <<= 1; /* Next Rtype */ | ||
927 | } | ||
928 | |||
929 | if (package_index == ACPI_NOT_PACKAGE) { | ||
930 | ACPI_WARNING((AE_INFO, | ||
931 | "%s: Return type mismatch - found %s, expected %s", | ||
932 | pathname, | ||
933 | acpi_ut_get_object_type_name(return_object), | ||
934 | type_buffer)); | ||
935 | } else { | ||
936 | ACPI_WARNING((AE_INFO, | ||
937 | "%s: Return Package type mismatch at index %u - " | ||
938 | "found %s, expected %s", pathname, package_index, | ||
939 | acpi_ut_get_object_type_name(return_object), | ||
940 | type_buffer)); | ||
941 | } | ||
942 | |||
943 | return (AE_AML_OPERAND_TYPE); | ||
944 | } | ||
945 | |||
946 | /******************************************************************************* | ||
947 | * | ||
948 | * FUNCTION: acpi_ns_check_reference | ||
949 | * | ||
950 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | ||
951 | * return_object - Object returned from the evaluation of a | ||
952 | * method or object | ||
953 | * | ||
954 | * RETURN: Status | ||
955 | * | ||
956 | * DESCRIPTION: Check a returned reference object for the correct reference | ||
957 | * type. The only reference type that can be returned from a | ||
958 | * predefined method is a named reference. All others are invalid. | ||
959 | * | ||
960 | ******************************************************************************/ | ||
961 | |||
962 | static acpi_status | ||
963 | acpi_ns_check_reference(char *pathname, | ||
964 | union acpi_operand_object *return_object) | ||
965 | { | ||
966 | |||
967 | /* | ||
968 | * Check the reference object for the correct reference type (opcode). | ||
969 | * The only type of reference that can be converted to an union acpi_object is | ||
970 | * a reference to a named object (reference class: NAME) | ||
971 | */ | ||
972 | if (return_object->reference.class == ACPI_REFCLASS_NAME) { | ||
973 | return (AE_OK); | ||
974 | } | ||
975 | |||
976 | ACPI_WARNING((AE_INFO, | ||
977 | "%s: Return type mismatch - unexpected reference object type [%s] %2.2X", | ||
978 | pathname, acpi_ut_get_reference_name(return_object), | ||
979 | return_object->reference.class)); | ||
980 | |||
981 | return (AE_AML_OPERAND_TYPE); | ||
982 | } | ||
983 | |||
984 | /******************************************************************************* | ||
985 | * | ||
986 | * FUNCTION: acpi_ns_repair_object | ||
987 | * | ||
988 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | ||
989 | * package_index - Used to determine if target is in a package | ||
990 | * return_object_ptr - Pointer to the object returned from the | ||
991 | * evaluation of a method or object | ||
992 | * | ||
993 | * RETURN: Status. AE_OK if repair was successful. | ||
994 | * | ||
995 | * DESCRIPTION: Attempt to repair/convert a return object of a type that was | ||
996 | * not expected. | ||
997 | * | ||
998 | ******************************************************************************/ | ||
999 | |||
1000 | static acpi_status | ||
1001 | acpi_ns_repair_object(u32 expected_btypes, | ||
1002 | u32 package_index, | ||
1003 | union acpi_operand_object **return_object_ptr) | ||
1004 | { | ||
1005 | union acpi_operand_object *return_object = *return_object_ptr; | ||
1006 | union acpi_operand_object *new_object; | ||
1007 | acpi_size length; | ||
1008 | |||
1009 | switch (ACPI_GET_OBJECT_TYPE(return_object)) { | ||
1010 | case ACPI_TYPE_BUFFER: | ||
1011 | |||
1012 | if (!(expected_btypes & ACPI_RTYPE_STRING)) { | ||
1013 | return (AE_AML_OPERAND_TYPE); | ||
1014 | } | ||
1015 | |||
1016 | /* | ||
1017 | * Have a Buffer, expected a String, convert. Use a to_string | ||
1018 | * conversion, no transform performed on the buffer data. The best | ||
1019 | * example of this is the _BIF method, where the string data from | ||
1020 | * the battery is often (incorrectly) returned as buffer object(s). | ||
1021 | */ | ||
1022 | length = 0; | ||
1023 | while ((length < return_object->buffer.length) && | ||
1024 | (return_object->buffer.pointer[length])) { | ||
1025 | length++; | ||
1026 | } | ||
1027 | |||
1028 | /* Allocate a new string object */ | ||
1029 | |||
1030 | new_object = acpi_ut_create_string_object(length); | ||
1031 | if (!new_object) { | ||
1032 | return (AE_NO_MEMORY); | ||
1033 | } | ||
1034 | |||
1035 | /* | ||
1036 | * Copy the raw buffer data with no transform. String is already NULL | ||
1037 | * terminated at Length+1. | ||
1038 | */ | ||
1039 | ACPI_MEMCPY(new_object->string.pointer, | ||
1040 | return_object->buffer.pointer, length); | ||
1041 | |||
1042 | /* Install the new return object */ | ||
1043 | |||
1044 | acpi_ut_remove_reference(return_object); | ||
1045 | *return_object_ptr = new_object; | ||
1046 | |||
1047 | /* | ||
1048 | * If the object is a package element, we need to: | ||
1049 | * 1. Decrement the reference count of the orignal object, it was | ||
1050 | * incremented when building the package | ||
1051 | * 2. Increment the reference count of the new object, it will be | ||
1052 | * decremented when releasing the package | ||
1053 | */ | ||
1054 | if (package_index != ACPI_NOT_PACKAGE) { | ||
1055 | acpi_ut_remove_reference(return_object); | ||
1056 | acpi_ut_add_reference(new_object); | ||
1057 | } | ||
1058 | return (AE_OK); | ||
1059 | |||
1060 | default: | ||
1061 | break; | ||
1062 | } | ||
1063 | |||
1064 | return (AE_AML_OPERAND_TYPE); | ||
1065 | } | ||
diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c deleted file mode 100644 index a76c731e3ba5..000000000000 --- a/drivers/acpi/namespace/nssearch.c +++ /dev/null | |||
@@ -1,415 +0,0 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: nssearch - Namespace search | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2008, 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 <acpi/acpi.h> | ||
45 | #include <acpi/accommon.h> | ||
46 | #include <acpi/acnamesp.h> | ||
47 | |||
48 | #define _COMPONENT ACPI_NAMESPACE | ||
49 | ACPI_MODULE_NAME("nssearch") | ||
50 | |||
51 | /* Local prototypes */ | ||
52 | static acpi_status | ||
53 | acpi_ns_search_parent_tree(u32 target_name, | ||
54 | struct acpi_namespace_node *node, | ||
55 | acpi_object_type type, | ||
56 | struct acpi_namespace_node **return_node); | ||
57 | |||
58 | /******************************************************************************* | ||
59 | * | ||
60 | * FUNCTION: acpi_ns_search_one_scope | ||
61 | * | ||
62 | * PARAMETERS: target_name - Ascii ACPI name to search for | ||
63 | * parent_node - Starting node where search will begin | ||
64 | * Type - Object type to match | ||
65 | * return_node - Where the matched Named obj is returned | ||
66 | * | ||
67 | * RETURN: Status | ||
68 | * | ||
69 | * DESCRIPTION: Search a single level of the namespace. Performs a | ||
70 | * simple search of the specified level, and does not add | ||
71 | * entries or search parents. | ||
72 | * | ||
73 | * | ||
74 | * Named object lists are built (and subsequently dumped) in the | ||
75 | * order in which the names are encountered during the namespace load; | ||
76 | * | ||
77 | * All namespace searching is linear in this implementation, but | ||
78 | * could be easily modified to support any improved search | ||
79 | * algorithm. However, the linear search was chosen for simplicity | ||
80 | * and because the trees are small and the other interpreter | ||
81 | * execution overhead is relatively high. | ||
82 | * | ||
83 | * Note: CPU execution analysis has shown that the AML interpreter spends | ||
84 | * a very small percentage of its time searching the namespace. Therefore, | ||
85 | * the linear search seems to be sufficient, as there would seem to be | ||
86 | * little value in improving the search. | ||
87 | * | ||
88 | ******************************************************************************/ | ||
89 | |||
90 | acpi_status | ||
91 | acpi_ns_search_one_scope(u32 target_name, | ||
92 | struct acpi_namespace_node *parent_node, | ||
93 | acpi_object_type type, | ||
94 | struct acpi_namespace_node **return_node) | ||
95 | { | ||
96 | struct acpi_namespace_node *node; | ||
97 | |||
98 | ACPI_FUNCTION_TRACE(ns_search_one_scope); | ||
99 | |||
100 | #ifdef ACPI_DEBUG_OUTPUT | ||
101 | if (ACPI_LV_NAMES & acpi_dbg_level) { | ||
102 | char *scope_name; | ||
103 | |||
104 | scope_name = acpi_ns_get_external_pathname(parent_node); | ||
105 | if (scope_name) { | ||
106 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
107 | "Searching %s (%p) For [%4.4s] (%s)\n", | ||
108 | scope_name, parent_node, | ||
109 | ACPI_CAST_PTR(char, &target_name), | ||
110 | acpi_ut_get_type_name(type))); | ||
111 | |||
112 | ACPI_FREE(scope_name); | ||
113 | } | ||
114 | } | ||
115 | #endif | ||
116 | |||
117 | /* | ||
118 | * Search for name at this namespace level, which is to say that we | ||
119 | * must search for the name among the children of this object | ||
120 | */ | ||
121 | node = parent_node->child; | ||
122 | while (node) { | ||
123 | |||
124 | /* Check for match against the name */ | ||
125 | |||
126 | if (node->name.integer == target_name) { | ||
127 | |||
128 | /* Resolve a control method alias if any */ | ||
129 | |||
130 | if (acpi_ns_get_type(node) == | ||
131 | ACPI_TYPE_LOCAL_METHOD_ALIAS) { | ||
132 | node = | ||
133 | ACPI_CAST_PTR(struct acpi_namespace_node, | ||
134 | node->object); | ||
135 | } | ||
136 | |||
137 | /* Found matching entry */ | ||
138 | |||
139 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
140 | "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n", | ||
141 | ACPI_CAST_PTR(char, &target_name), | ||
142 | acpi_ut_get_type_name(node->type), | ||
143 | node, | ||
144 | acpi_ut_get_node_name(parent_node), | ||
145 | parent_node)); | ||
146 | |||
147 | *return_node = node; | ||
148 | return_ACPI_STATUS(AE_OK); | ||
149 | } | ||
150 | |||
151 | /* | ||
152 | * The last entry in the list points back to the parent, | ||
153 | * so a flag is used to indicate the end-of-list | ||
154 | */ | ||
155 | if (node->flags & ANOBJ_END_OF_PEER_LIST) { | ||
156 | |||
157 | /* Searched entire list, we are done */ | ||
158 | |||
159 | break; | ||
160 | } | ||
161 | |||
162 | /* Didn't match name, move on to the next peer object */ | ||
163 | |||
164 | node = node->peer; | ||
165 | } | ||
166 | |||
167 | /* Searched entire namespace level, not found */ | ||
168 | |||
169 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
170 | "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n", | ||
171 | ACPI_CAST_PTR(char, &target_name), | ||
172 | acpi_ut_get_type_name(type), | ||
173 | acpi_ut_get_node_name(parent_node), parent_node, | ||
174 | parent_node->child)); | ||
175 | |||
176 | return_ACPI_STATUS(AE_NOT_FOUND); | ||
177 | } | ||
178 | |||
179 | /******************************************************************************* | ||
180 | * | ||
181 | * FUNCTION: acpi_ns_search_parent_tree | ||
182 | * | ||
183 | * PARAMETERS: target_name - Ascii ACPI name to search for | ||
184 | * Node - Starting node where search will begin | ||
185 | * Type - Object type to match | ||
186 | * return_node - Where the matched Node is returned | ||
187 | * | ||
188 | * RETURN: Status | ||
189 | * | ||
190 | * DESCRIPTION: Called when a name has not been found in the current namespace | ||
191 | * level. Before adding it or giving up, ACPI scope rules require | ||
192 | * searching enclosing scopes in cases identified by acpi_ns_local(). | ||
193 | * | ||
194 | * "A name is located by finding the matching name in the current | ||
195 | * name space, and then in the parent name space. If the parent | ||
196 | * name space does not contain the name, the search continues | ||
197 | * recursively until either the name is found or the name space | ||
198 | * does not have a parent (the root of the name space). This | ||
199 | * indicates that the name is not found" (From ACPI Specification, | ||
200 | * section 5.3) | ||
201 | * | ||
202 | ******************************************************************************/ | ||
203 | |||
204 | static acpi_status | ||
205 | acpi_ns_search_parent_tree(u32 target_name, | ||
206 | struct acpi_namespace_node *node, | ||
207 | acpi_object_type type, | ||
208 | struct acpi_namespace_node **return_node) | ||
209 | { | ||
210 | acpi_status status; | ||
211 | struct acpi_namespace_node *parent_node; | ||
212 | |||
213 | ACPI_FUNCTION_TRACE(ns_search_parent_tree); | ||
214 | |||
215 | parent_node = acpi_ns_get_parent_node(node); | ||
216 | |||
217 | /* | ||
218 | * If there is no parent (i.e., we are at the root) or type is "local", | ||
219 | * we won't be searching the parent tree. | ||
220 | */ | ||
221 | if (!parent_node) { | ||
222 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "[%4.4s] has no parent\n", | ||
223 | ACPI_CAST_PTR(char, &target_name))); | ||
224 | return_ACPI_STATUS(AE_NOT_FOUND); | ||
225 | } | ||
226 | |||
227 | if (acpi_ns_local(type)) { | ||
228 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
229 | "[%4.4s] type [%s] must be local to this scope (no parent search)\n", | ||
230 | ACPI_CAST_PTR(char, &target_name), | ||
231 | acpi_ut_get_type_name(type))); | ||
232 | return_ACPI_STATUS(AE_NOT_FOUND); | ||
233 | } | ||
234 | |||
235 | /* Search the parent tree */ | ||
236 | |||
237 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
238 | "Searching parent [%4.4s] for [%4.4s]\n", | ||
239 | acpi_ut_get_node_name(parent_node), | ||
240 | ACPI_CAST_PTR(char, &target_name))); | ||
241 | |||
242 | /* | ||
243 | * Search parents until target is found or we have backed up to the root | ||
244 | */ | ||
245 | while (parent_node) { | ||
246 | /* | ||
247 | * Search parent scope. Use TYPE_ANY because we don't care about the | ||
248 | * object type at this point, we only care about the existence of | ||
249 | * the actual name we are searching for. Typechecking comes later. | ||
250 | */ | ||
251 | status = | ||
252 | acpi_ns_search_one_scope(target_name, parent_node, | ||
253 | ACPI_TYPE_ANY, return_node); | ||
254 | if (ACPI_SUCCESS(status)) { | ||
255 | return_ACPI_STATUS(status); | ||
256 | } | ||
257 | |||
258 | /* Not found here, go up another level (until we reach the root) */ | ||
259 | |||
260 | parent_node = acpi_ns_get_parent_node(parent_node); | ||
261 | } | ||
262 | |||
263 | /* Not found in parent tree */ | ||
264 | |||
265 | return_ACPI_STATUS(AE_NOT_FOUND); | ||
266 | } | ||
267 | |||
268 | /******************************************************************************* | ||
269 | * | ||
270 | * FUNCTION: acpi_ns_search_and_enter | ||
271 | * | ||
272 | * PARAMETERS: target_name - Ascii ACPI name to search for (4 chars) | ||
273 | * walk_state - Current state of the walk | ||
274 | * Node - Starting node where search will begin | ||
275 | * interpreter_mode - Add names only in ACPI_MODE_LOAD_PASS_x. | ||
276 | * Otherwise,search only. | ||
277 | * Type - Object type to match | ||
278 | * Flags - Flags describing the search restrictions | ||
279 | * return_node - Where the Node is returned | ||
280 | * | ||
281 | * RETURN: Status | ||
282 | * | ||
283 | * DESCRIPTION: Search for a name segment in a single namespace level, | ||
284 | * optionally adding it if it is not found. If the passed | ||
285 | * Type is not Any and the type previously stored in the | ||
286 | * entry was Any (i.e. unknown), update the stored type. | ||
287 | * | ||
288 | * In ACPI_IMODE_EXECUTE, search only. | ||
289 | * In other modes, search and add if not found. | ||
290 | * | ||
291 | ******************************************************************************/ | ||
292 | |||
293 | acpi_status | ||
294 | acpi_ns_search_and_enter(u32 target_name, | ||
295 | struct acpi_walk_state *walk_state, | ||
296 | struct acpi_namespace_node *node, | ||
297 | acpi_interpreter_mode interpreter_mode, | ||
298 | acpi_object_type type, | ||
299 | u32 flags, struct acpi_namespace_node **return_node) | ||
300 | { | ||
301 | acpi_status status; | ||
302 | struct acpi_namespace_node *new_node; | ||
303 | |||
304 | ACPI_FUNCTION_TRACE(ns_search_and_enter); | ||
305 | |||
306 | /* Parameter validation */ | ||
307 | |||
308 | if (!node || !target_name || !return_node) { | ||
309 | ACPI_ERROR((AE_INFO, | ||
310 | "Null parameter: Node %p Name %X ReturnNode %p", | ||
311 | node, target_name, return_node)); | ||
312 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
313 | } | ||
314 | |||
315 | /* | ||
316 | * Name must consist of valid ACPI characters. We will repair the name if | ||
317 | * necessary because we don't want to abort because of this, but we want | ||
318 | * all namespace names to be printable. A warning message is appropriate. | ||
319 | * | ||
320 | * This issue came up because there are in fact machines that exhibit | ||
321 | * this problem, and we want to be able to enable ACPI support for them, | ||
322 | * even though there are a few bad names. | ||
323 | */ | ||
324 | if (!acpi_ut_valid_acpi_name(target_name)) { | ||
325 | target_name = | ||
326 | acpi_ut_repair_name(ACPI_CAST_PTR(char, &target_name)); | ||
327 | |||
328 | /* Report warning only if in strict mode or debug mode */ | ||
329 | |||
330 | if (!acpi_gbl_enable_interpreter_slack) { | ||
331 | ACPI_WARNING((AE_INFO, | ||
332 | "Found bad character(s) in name, repaired: [%4.4s]\n", | ||
333 | ACPI_CAST_PTR(char, &target_name))); | ||
334 | } else { | ||
335 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
336 | "Found bad character(s) in name, repaired: [%4.4s]\n", | ||
337 | ACPI_CAST_PTR(char, &target_name))); | ||
338 | } | ||
339 | } | ||
340 | |||
341 | /* Try to find the name in the namespace level specified by the caller */ | ||
342 | |||
343 | *return_node = ACPI_ENTRY_NOT_FOUND; | ||
344 | status = acpi_ns_search_one_scope(target_name, node, type, return_node); | ||
345 | if (status != AE_NOT_FOUND) { | ||
346 | /* | ||
347 | * If we found it AND the request specifies that a find is an error, | ||
348 | * return the error | ||
349 | */ | ||
350 | if ((status == AE_OK) && (flags & ACPI_NS_ERROR_IF_FOUND)) { | ||
351 | status = AE_ALREADY_EXISTS; | ||
352 | } | ||
353 | |||
354 | /* Either found it or there was an error: finished either way */ | ||
355 | |||
356 | return_ACPI_STATUS(status); | ||
357 | } | ||
358 | |||
359 | /* | ||
360 | * The name was not found. If we are NOT performing the first pass | ||
361 | * (name entry) of loading the namespace, search the parent tree (all the | ||
362 | * way to the root if necessary.) We don't want to perform the parent | ||
363 | * search when the namespace is actually being loaded. We want to perform | ||
364 | * the search when namespace references are being resolved (load pass 2) | ||
365 | * and during the execution phase. | ||
366 | */ | ||
367 | if ((interpreter_mode != ACPI_IMODE_LOAD_PASS1) && | ||
368 | (flags & ACPI_NS_SEARCH_PARENT)) { | ||
369 | /* | ||
370 | * Not found at this level - search parent tree according to the | ||
371 | * ACPI specification | ||
372 | */ | ||
373 | status = | ||
374 | acpi_ns_search_parent_tree(target_name, node, type, | ||
375 | return_node); | ||
376 | if (ACPI_SUCCESS(status)) { | ||
377 | return_ACPI_STATUS(status); | ||
378 | } | ||
379 | } | ||
380 | |||
381 | /* In execute mode, just search, never add names. Exit now */ | ||
382 | |||
383 | if (interpreter_mode == ACPI_IMODE_EXECUTE) { | ||
384 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
385 | "%4.4s Not found in %p [Not adding]\n", | ||
386 | ACPI_CAST_PTR(char, &target_name), node)); | ||
387 | |||
388 | return_ACPI_STATUS(AE_NOT_FOUND); | ||
389 | } | ||
390 | |||
391 | /* Create the new named object */ | ||
392 | |||
393 | new_node = acpi_ns_create_node(target_name); | ||
394 | if (!new_node) { | ||
395 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
396 | } | ||
397 | #ifdef ACPI_ASL_COMPILER | ||
398 | /* | ||
399 | * Node is an object defined by an External() statement | ||
400 | */ | ||
401 | if (flags & ACPI_NS_EXTERNAL) { | ||
402 | new_node->flags |= ANOBJ_IS_EXTERNAL; | ||
403 | } | ||
404 | #endif | ||
405 | |||
406 | if (flags & ACPI_NS_TEMPORARY) { | ||
407 | new_node->flags |= ANOBJ_TEMPORARY; | ||
408 | } | ||
409 | |||
410 | /* Install the new object into the parent's list of children */ | ||
411 | |||
412 | acpi_ns_install_node(walk_state, node, new_node, type); | ||
413 | *return_node = new_node; | ||
414 | return_ACPI_STATUS(AE_OK); | ||
415 | } | ||
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c deleted file mode 100644 index a443d2805d2c..000000000000 --- a/drivers/acpi/namespace/nsutils.c +++ /dev/null | |||
@@ -1,997 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing | ||
4 | * parents and siblings and Scope manipulation | ||
5 | * | ||
6 | *****************************************************************************/ | ||
7 | |||
8 | /* | ||
9 | * Copyright (C) 2000 - 2008, Intel Corp. | ||
10 | * All rights reserved. | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or without | ||
13 | * modification, are permitted provided that the following conditions | ||
14 | * are met: | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions, and the following disclaimer, | ||
17 | * without modification. | ||
18 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
19 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
20 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
21 | * including a substantially similar Disclaimer requirement for further | ||
22 | * binary redistribution. | ||
23 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
24 | * of any contributors may be used to endorse or promote products derived | ||
25 | * from this software without specific prior written permission. | ||
26 | * | ||
27 | * Alternatively, this software may be distributed under the terms of the | ||
28 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
29 | * Software Foundation. | ||
30 | * | ||
31 | * NO WARRANTY | ||
32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
33 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
35 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
36 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
37 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
38 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
39 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
40 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
41 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
42 | * POSSIBILITY OF SUCH DAMAGES. | ||
43 | */ | ||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/accommon.h> | ||
47 | #include <acpi/acnamesp.h> | ||
48 | #include <acpi/amlcode.h> | ||
49 | #include <acpi/actables.h> | ||
50 | |||
51 | #define _COMPONENT ACPI_NAMESPACE | ||
52 | ACPI_MODULE_NAME("nsutils") | ||
53 | |||
54 | /* Local prototypes */ | ||
55 | static u8 acpi_ns_valid_path_separator(char sep); | ||
56 | |||
57 | #ifdef ACPI_OBSOLETE_FUNCTIONS | ||
58 | acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search); | ||
59 | #endif | ||
60 | |||
61 | /******************************************************************************* | ||
62 | * | ||
63 | * FUNCTION: acpi_ns_report_error | ||
64 | * | ||
65 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
66 | * line_number - Caller's line number (for error output) | ||
67 | * internal_name - Name or path of the namespace node | ||
68 | * lookup_status - Exception code from NS lookup | ||
69 | * | ||
70 | * RETURN: None | ||
71 | * | ||
72 | * DESCRIPTION: Print warning message with full pathname | ||
73 | * | ||
74 | ******************************************************************************/ | ||
75 | |||
76 | void | ||
77 | acpi_ns_report_error(const char *module_name, | ||
78 | u32 line_number, | ||
79 | const char *internal_name, acpi_status lookup_status) | ||
80 | { | ||
81 | acpi_status status; | ||
82 | u32 bad_name; | ||
83 | char *name = NULL; | ||
84 | |||
85 | acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); | ||
86 | |||
87 | if (lookup_status == AE_BAD_CHARACTER) { | ||
88 | |||
89 | /* There is a non-ascii character in the name */ | ||
90 | |||
91 | ACPI_MOVE_32_TO_32(&bad_name, internal_name); | ||
92 | acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name); | ||
93 | } else { | ||
94 | /* Convert path to external format */ | ||
95 | |||
96 | status = acpi_ns_externalize_name(ACPI_UINT32_MAX, | ||
97 | internal_name, NULL, &name); | ||
98 | |||
99 | /* Print target name */ | ||
100 | |||
101 | if (ACPI_SUCCESS(status)) { | ||
102 | acpi_os_printf("[%s]", name); | ||
103 | } else { | ||
104 | acpi_os_printf("[COULD NOT EXTERNALIZE NAME]"); | ||
105 | } | ||
106 | |||
107 | if (name) { | ||
108 | ACPI_FREE(name); | ||
109 | } | ||
110 | } | ||
111 | |||
112 | acpi_os_printf(" Namespace lookup failure, %s\n", | ||
113 | acpi_format_exception(lookup_status)); | ||
114 | } | ||
115 | |||
116 | /******************************************************************************* | ||
117 | * | ||
118 | * FUNCTION: acpi_ns_report_method_error | ||
119 | * | ||
120 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
121 | * line_number - Caller's line number (for error output) | ||
122 | * Message - Error message to use on failure | ||
123 | * prefix_node - Prefix relative to the path | ||
124 | * Path - Path to the node (optional) | ||
125 | * method_status - Execution status | ||
126 | * | ||
127 | * RETURN: None | ||
128 | * | ||
129 | * DESCRIPTION: Print warning message with full pathname | ||
130 | * | ||
131 | ******************************************************************************/ | ||
132 | |||
133 | void | ||
134 | acpi_ns_report_method_error(const char *module_name, | ||
135 | u32 line_number, | ||
136 | const char *message, | ||
137 | struct acpi_namespace_node *prefix_node, | ||
138 | const char *path, acpi_status method_status) | ||
139 | { | ||
140 | acpi_status status; | ||
141 | struct acpi_namespace_node *node = prefix_node; | ||
142 | |||
143 | acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); | ||
144 | |||
145 | if (path) { | ||
146 | status = | ||
147 | acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH, | ||
148 | &node); | ||
149 | if (ACPI_FAILURE(status)) { | ||
150 | acpi_os_printf("[Could not get node by pathname]"); | ||
151 | } | ||
152 | } | ||
153 | |||
154 | acpi_ns_print_node_pathname(node, message); | ||
155 | acpi_os_printf(", %s\n", acpi_format_exception(method_status)); | ||
156 | } | ||
157 | |||
158 | /******************************************************************************* | ||
159 | * | ||
160 | * FUNCTION: acpi_ns_print_node_pathname | ||
161 | * | ||
162 | * PARAMETERS: Node - Object | ||
163 | * Message - Prefix message | ||
164 | * | ||
165 | * DESCRIPTION: Print an object's full namespace pathname | ||
166 | * Manages allocation/freeing of a pathname buffer | ||
167 | * | ||
168 | ******************************************************************************/ | ||
169 | |||
170 | void | ||
171 | acpi_ns_print_node_pathname(struct acpi_namespace_node *node, | ||
172 | const char *message) | ||
173 | { | ||
174 | struct acpi_buffer buffer; | ||
175 | acpi_status status; | ||
176 | |||
177 | if (!node) { | ||
178 | acpi_os_printf("[NULL NAME]"); | ||
179 | return; | ||
180 | } | ||
181 | |||
182 | /* Convert handle to full pathname and print it (with supplied message) */ | ||
183 | |||
184 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | ||
185 | |||
186 | status = acpi_ns_handle_to_pathname(node, &buffer); | ||
187 | if (ACPI_SUCCESS(status)) { | ||
188 | if (message) { | ||
189 | acpi_os_printf("%s ", message); | ||
190 | } | ||
191 | |||
192 | acpi_os_printf("[%s] (Node %p)", (char *)buffer.pointer, node); | ||
193 | ACPI_FREE(buffer.pointer); | ||
194 | } | ||
195 | } | ||
196 | |||
197 | /******************************************************************************* | ||
198 | * | ||
199 | * FUNCTION: acpi_ns_valid_root_prefix | ||
200 | * | ||
201 | * PARAMETERS: Prefix - Character to be checked | ||
202 | * | ||
203 | * RETURN: TRUE if a valid prefix | ||
204 | * | ||
205 | * DESCRIPTION: Check if a character is a valid ACPI Root prefix | ||
206 | * | ||
207 | ******************************************************************************/ | ||
208 | |||
209 | u8 acpi_ns_valid_root_prefix(char prefix) | ||
210 | { | ||
211 | |||
212 | return ((u8) (prefix == '\\')); | ||
213 | } | ||
214 | |||
215 | /******************************************************************************* | ||
216 | * | ||
217 | * FUNCTION: acpi_ns_valid_path_separator | ||
218 | * | ||
219 | * PARAMETERS: Sep - Character to be checked | ||
220 | * | ||
221 | * RETURN: TRUE if a valid path separator | ||
222 | * | ||
223 | * DESCRIPTION: Check if a character is a valid ACPI path separator | ||
224 | * | ||
225 | ******************************************************************************/ | ||
226 | |||
227 | static u8 acpi_ns_valid_path_separator(char sep) | ||
228 | { | ||
229 | |||
230 | return ((u8) (sep == '.')); | ||
231 | } | ||
232 | |||
233 | /******************************************************************************* | ||
234 | * | ||
235 | * FUNCTION: acpi_ns_get_type | ||
236 | * | ||
237 | * PARAMETERS: Node - Parent Node to be examined | ||
238 | * | ||
239 | * RETURN: Type field from Node whose handle is passed | ||
240 | * | ||
241 | * DESCRIPTION: Return the type of a Namespace node | ||
242 | * | ||
243 | ******************************************************************************/ | ||
244 | |||
245 | acpi_object_type acpi_ns_get_type(struct acpi_namespace_node * node) | ||
246 | { | ||
247 | ACPI_FUNCTION_TRACE(ns_get_type); | ||
248 | |||
249 | if (!node) { | ||
250 | ACPI_WARNING((AE_INFO, "Null Node parameter")); | ||
251 | return_UINT32(ACPI_TYPE_ANY); | ||
252 | } | ||
253 | |||
254 | return_UINT32((acpi_object_type) node->type); | ||
255 | } | ||
256 | |||
257 | /******************************************************************************* | ||
258 | * | ||
259 | * FUNCTION: acpi_ns_local | ||
260 | * | ||
261 | * PARAMETERS: Type - A namespace object type | ||
262 | * | ||
263 | * RETURN: LOCAL if names must be found locally in objects of the | ||
264 | * passed type, 0 if enclosing scopes should be searched | ||
265 | * | ||
266 | * DESCRIPTION: Returns scope rule for the given object type. | ||
267 | * | ||
268 | ******************************************************************************/ | ||
269 | |||
270 | u32 acpi_ns_local(acpi_object_type type) | ||
271 | { | ||
272 | ACPI_FUNCTION_TRACE(ns_local); | ||
273 | |||
274 | if (!acpi_ut_valid_object_type(type)) { | ||
275 | |||
276 | /* Type code out of range */ | ||
277 | |||
278 | ACPI_WARNING((AE_INFO, "Invalid Object Type %X", type)); | ||
279 | return_UINT32(ACPI_NS_NORMAL); | ||
280 | } | ||
281 | |||
282 | return_UINT32((u32) acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL); | ||
283 | } | ||
284 | |||
285 | /******************************************************************************* | ||
286 | * | ||
287 | * FUNCTION: acpi_ns_get_internal_name_length | ||
288 | * | ||
289 | * PARAMETERS: Info - Info struct initialized with the | ||
290 | * external name pointer. | ||
291 | * | ||
292 | * RETURN: None | ||
293 | * | ||
294 | * DESCRIPTION: Calculate the length of the internal (AML) namestring | ||
295 | * corresponding to the external (ASL) namestring. | ||
296 | * | ||
297 | ******************************************************************************/ | ||
298 | |||
299 | void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info) | ||
300 | { | ||
301 | const char *next_external_char; | ||
302 | u32 i; | ||
303 | |||
304 | ACPI_FUNCTION_ENTRY(); | ||
305 | |||
306 | next_external_char = info->external_name; | ||
307 | info->num_carats = 0; | ||
308 | info->num_segments = 0; | ||
309 | info->fully_qualified = FALSE; | ||
310 | |||
311 | /* | ||
312 | * For the internal name, the required length is 4 bytes per segment, plus | ||
313 | * 1 each for root_prefix, multi_name_prefix_op, segment count, trailing null | ||
314 | * (which is not really needed, but no there's harm in putting it there) | ||
315 | * | ||
316 | * strlen() + 1 covers the first name_seg, which has no path separator | ||
317 | */ | ||
318 | if (acpi_ns_valid_root_prefix(*next_external_char)) { | ||
319 | info->fully_qualified = TRUE; | ||
320 | next_external_char++; | ||
321 | |||
322 | /* Skip redundant root_prefix, like \\_SB.PCI0.SBRG.EC0 */ | ||
323 | |||
324 | while (acpi_ns_valid_root_prefix(*next_external_char)) { | ||
325 | next_external_char++; | ||
326 | } | ||
327 | } else { | ||
328 | /* | ||
329 | * Handle Carat prefixes | ||
330 | */ | ||
331 | while (*next_external_char == '^') { | ||
332 | info->num_carats++; | ||
333 | next_external_char++; | ||
334 | } | ||
335 | } | ||
336 | |||
337 | /* | ||
338 | * Determine the number of ACPI name "segments" by counting the number of | ||
339 | * path separators within the string. Start with one segment since the | ||
340 | * segment count is [(# separators) + 1], and zero separators is ok. | ||
341 | */ | ||
342 | if (*next_external_char) { | ||
343 | info->num_segments = 1; | ||
344 | for (i = 0; next_external_char[i]; i++) { | ||
345 | if (acpi_ns_valid_path_separator(next_external_char[i])) { | ||
346 | info->num_segments++; | ||
347 | } | ||
348 | } | ||
349 | } | ||
350 | |||
351 | info->length = (ACPI_NAME_SIZE * info->num_segments) + | ||
352 | 4 + info->num_carats; | ||
353 | |||
354 | info->next_external_char = next_external_char; | ||
355 | } | ||
356 | |||
357 | /******************************************************************************* | ||
358 | * | ||
359 | * FUNCTION: acpi_ns_build_internal_name | ||
360 | * | ||
361 | * PARAMETERS: Info - Info struct fully initialized | ||
362 | * | ||
363 | * RETURN: Status | ||
364 | * | ||
365 | * DESCRIPTION: Construct the internal (AML) namestring | ||
366 | * corresponding to the external (ASL) namestring. | ||
367 | * | ||
368 | ******************************************************************************/ | ||
369 | |||
370 | acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info) | ||
371 | { | ||
372 | u32 num_segments = info->num_segments; | ||
373 | char *internal_name = info->internal_name; | ||
374 | const char *external_name = info->next_external_char; | ||
375 | char *result = NULL; | ||
376 | u32 i; | ||
377 | |||
378 | ACPI_FUNCTION_TRACE(ns_build_internal_name); | ||
379 | |||
380 | /* Setup the correct prefixes, counts, and pointers */ | ||
381 | |||
382 | if (info->fully_qualified) { | ||
383 | internal_name[0] = '\\'; | ||
384 | |||
385 | if (num_segments <= 1) { | ||
386 | result = &internal_name[1]; | ||
387 | } else if (num_segments == 2) { | ||
388 | internal_name[1] = AML_DUAL_NAME_PREFIX; | ||
389 | result = &internal_name[2]; | ||
390 | } else { | ||
391 | internal_name[1] = AML_MULTI_NAME_PREFIX_OP; | ||
392 | internal_name[2] = (char)num_segments; | ||
393 | result = &internal_name[3]; | ||
394 | } | ||
395 | } else { | ||
396 | /* | ||
397 | * Not fully qualified. | ||
398 | * Handle Carats first, then append the name segments | ||
399 | */ | ||
400 | i = 0; | ||
401 | if (info->num_carats) { | ||
402 | for (i = 0; i < info->num_carats; i++) { | ||
403 | internal_name[i] = '^'; | ||
404 | } | ||
405 | } | ||
406 | |||
407 | if (num_segments <= 1) { | ||
408 | result = &internal_name[i]; | ||
409 | } else if (num_segments == 2) { | ||
410 | internal_name[i] = AML_DUAL_NAME_PREFIX; | ||
411 | result = &internal_name[(acpi_size) i + 1]; | ||
412 | } else { | ||
413 | internal_name[i] = AML_MULTI_NAME_PREFIX_OP; | ||
414 | internal_name[(acpi_size) i + 1] = (char)num_segments; | ||
415 | result = &internal_name[(acpi_size) i + 2]; | ||
416 | } | ||
417 | } | ||
418 | |||
419 | /* Build the name (minus path separators) */ | ||
420 | |||
421 | for (; num_segments; num_segments--) { | ||
422 | for (i = 0; i < ACPI_NAME_SIZE; i++) { | ||
423 | if (acpi_ns_valid_path_separator(*external_name) || | ||
424 | (*external_name == 0)) { | ||
425 | |||
426 | /* Pad the segment with underscore(s) if segment is short */ | ||
427 | |||
428 | result[i] = '_'; | ||
429 | } else { | ||
430 | /* Convert the character to uppercase and save it */ | ||
431 | |||
432 | result[i] = | ||
433 | (char)ACPI_TOUPPER((int)*external_name); | ||
434 | external_name++; | ||
435 | } | ||
436 | } | ||
437 | |||
438 | /* Now we must have a path separator, or the pathname is bad */ | ||
439 | |||
440 | if (!acpi_ns_valid_path_separator(*external_name) && | ||
441 | (*external_name != 0)) { | ||
442 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
443 | } | ||
444 | |||
445 | /* Move on the next segment */ | ||
446 | |||
447 | external_name++; | ||
448 | result += ACPI_NAME_SIZE; | ||
449 | } | ||
450 | |||
451 | /* Terminate the string */ | ||
452 | |||
453 | *result = 0; | ||
454 | |||
455 | if (info->fully_qualified) { | ||
456 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
457 | "Returning [%p] (abs) \"\\%s\"\n", | ||
458 | internal_name, internal_name)); | ||
459 | } else { | ||
460 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n", | ||
461 | internal_name, internal_name)); | ||
462 | } | ||
463 | |||
464 | return_ACPI_STATUS(AE_OK); | ||
465 | } | ||
466 | |||
467 | /******************************************************************************* | ||
468 | * | ||
469 | * FUNCTION: acpi_ns_internalize_name | ||
470 | * | ||
471 | * PARAMETERS: *external_name - External representation of name | ||
472 | * **Converted Name - Where to return the resulting | ||
473 | * internal represention of the name | ||
474 | * | ||
475 | * RETURN: Status | ||
476 | * | ||
477 | * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0") | ||
478 | * to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) | ||
479 | * | ||
480 | *******************************************************************************/ | ||
481 | |||
482 | acpi_status | ||
483 | acpi_ns_internalize_name(const char *external_name, char **converted_name) | ||
484 | { | ||
485 | char *internal_name; | ||
486 | struct acpi_namestring_info info; | ||
487 | acpi_status status; | ||
488 | |||
489 | ACPI_FUNCTION_TRACE(ns_internalize_name); | ||
490 | |||
491 | if ((!external_name) || (*external_name == 0) || (!converted_name)) { | ||
492 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
493 | } | ||
494 | |||
495 | /* Get the length of the new internal name */ | ||
496 | |||
497 | info.external_name = external_name; | ||
498 | acpi_ns_get_internal_name_length(&info); | ||
499 | |||
500 | /* We need a segment to store the internal name */ | ||
501 | |||
502 | internal_name = ACPI_ALLOCATE_ZEROED(info.length); | ||
503 | if (!internal_name) { | ||
504 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
505 | } | ||
506 | |||
507 | /* Build the name */ | ||
508 | |||
509 | info.internal_name = internal_name; | ||
510 | status = acpi_ns_build_internal_name(&info); | ||
511 | if (ACPI_FAILURE(status)) { | ||
512 | ACPI_FREE(internal_name); | ||
513 | return_ACPI_STATUS(status); | ||
514 | } | ||
515 | |||
516 | *converted_name = internal_name; | ||
517 | return_ACPI_STATUS(AE_OK); | ||
518 | } | ||
519 | |||
520 | /******************************************************************************* | ||
521 | * | ||
522 | * FUNCTION: acpi_ns_externalize_name | ||
523 | * | ||
524 | * PARAMETERS: internal_name_length - Lenth of the internal name below | ||
525 | * internal_name - Internal representation of name | ||
526 | * converted_name_length - Where the length is returned | ||
527 | * converted_name - Where the resulting external name | ||
528 | * is returned | ||
529 | * | ||
530 | * RETURN: Status | ||
531 | * | ||
532 | * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) | ||
533 | * to its external (printable) form (e.g. "\_PR_.CPU0") | ||
534 | * | ||
535 | ******************************************************************************/ | ||
536 | |||
537 | acpi_status | ||
538 | acpi_ns_externalize_name(u32 internal_name_length, | ||
539 | const char *internal_name, | ||
540 | u32 * converted_name_length, char **converted_name) | ||
541 | { | ||
542 | u32 names_index = 0; | ||
543 | u32 num_segments = 0; | ||
544 | u32 required_length; | ||
545 | u32 prefix_length = 0; | ||
546 | u32 i = 0; | ||
547 | u32 j = 0; | ||
548 | |||
549 | ACPI_FUNCTION_TRACE(ns_externalize_name); | ||
550 | |||
551 | if (!internal_name_length || !internal_name || !converted_name) { | ||
552 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
553 | } | ||
554 | |||
555 | /* | ||
556 | * Check for a prefix (one '\' | one or more '^'). | ||
557 | */ | ||
558 | switch (internal_name[0]) { | ||
559 | case '\\': | ||
560 | prefix_length = 1; | ||
561 | break; | ||
562 | |||
563 | case '^': | ||
564 | for (i = 0; i < internal_name_length; i++) { | ||
565 | if (internal_name[i] == '^') { | ||
566 | prefix_length = i + 1; | ||
567 | } else { | ||
568 | break; | ||
569 | } | ||
570 | } | ||
571 | |||
572 | if (i == internal_name_length) { | ||
573 | prefix_length = i; | ||
574 | } | ||
575 | |||
576 | break; | ||
577 | |||
578 | default: | ||
579 | break; | ||
580 | } | ||
581 | |||
582 | /* | ||
583 | * Check for object names. Note that there could be 0-255 of these | ||
584 | * 4-byte elements. | ||
585 | */ | ||
586 | if (prefix_length < internal_name_length) { | ||
587 | switch (internal_name[prefix_length]) { | ||
588 | case AML_MULTI_NAME_PREFIX_OP: | ||
589 | |||
590 | /* <count> 4-byte names */ | ||
591 | |||
592 | names_index = prefix_length + 2; | ||
593 | num_segments = (u8) | ||
594 | internal_name[(acpi_size) prefix_length + 1]; | ||
595 | break; | ||
596 | |||
597 | case AML_DUAL_NAME_PREFIX: | ||
598 | |||
599 | /* Two 4-byte names */ | ||
600 | |||
601 | names_index = prefix_length + 1; | ||
602 | num_segments = 2; | ||
603 | break; | ||
604 | |||
605 | case 0: | ||
606 | |||
607 | /* null_name */ | ||
608 | |||
609 | names_index = 0; | ||
610 | num_segments = 0; | ||
611 | break; | ||
612 | |||
613 | default: | ||
614 | |||
615 | /* one 4-byte name */ | ||
616 | |||
617 | names_index = prefix_length; | ||
618 | num_segments = 1; | ||
619 | break; | ||
620 | } | ||
621 | } | ||
622 | |||
623 | /* | ||
624 | * Calculate the length of converted_name, which equals the length | ||
625 | * of the prefix, length of all object names, length of any required | ||
626 | * punctuation ('.') between object names, plus the NULL terminator. | ||
627 | */ | ||
628 | required_length = prefix_length + (4 * num_segments) + | ||
629 | ((num_segments > 0) ? (num_segments - 1) : 0) + 1; | ||
630 | |||
631 | /* | ||
632 | * Check to see if we're still in bounds. If not, there's a problem | ||
633 | * with internal_name (invalid format). | ||
634 | */ | ||
635 | if (required_length > internal_name_length) { | ||
636 | ACPI_ERROR((AE_INFO, "Invalid internal name")); | ||
637 | return_ACPI_STATUS(AE_BAD_PATHNAME); | ||
638 | } | ||
639 | |||
640 | /* | ||
641 | * Build converted_name | ||
642 | */ | ||
643 | *converted_name = ACPI_ALLOCATE_ZEROED(required_length); | ||
644 | if (!(*converted_name)) { | ||
645 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
646 | } | ||
647 | |||
648 | j = 0; | ||
649 | |||
650 | for (i = 0; i < prefix_length; i++) { | ||
651 | (*converted_name)[j++] = internal_name[i]; | ||
652 | } | ||
653 | |||
654 | if (num_segments > 0) { | ||
655 | for (i = 0; i < num_segments; i++) { | ||
656 | if (i > 0) { | ||
657 | (*converted_name)[j++] = '.'; | ||
658 | } | ||
659 | |||
660 | (*converted_name)[j++] = internal_name[names_index++]; | ||
661 | (*converted_name)[j++] = internal_name[names_index++]; | ||
662 | (*converted_name)[j++] = internal_name[names_index++]; | ||
663 | (*converted_name)[j++] = internal_name[names_index++]; | ||
664 | } | ||
665 | } | ||
666 | |||
667 | if (converted_name_length) { | ||
668 | *converted_name_length = (u32) required_length; | ||
669 | } | ||
670 | |||
671 | return_ACPI_STATUS(AE_OK); | ||
672 | } | ||
673 | |||
674 | /******************************************************************************* | ||
675 | * | ||
676 | * FUNCTION: acpi_ns_map_handle_to_node | ||
677 | * | ||
678 | * PARAMETERS: Handle - Handle to be converted to an Node | ||
679 | * | ||
680 | * RETURN: A Name table entry pointer | ||
681 | * | ||
682 | * DESCRIPTION: Convert a namespace handle to a real Node | ||
683 | * | ||
684 | * Note: Real integer handles would allow for more verification | ||
685 | * and keep all pointers within this subsystem - however this introduces | ||
686 | * more (and perhaps unnecessary) overhead. | ||
687 | * | ||
688 | ******************************************************************************/ | ||
689 | |||
690 | struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle) | ||
691 | { | ||
692 | |||
693 | ACPI_FUNCTION_ENTRY(); | ||
694 | |||
695 | /* | ||
696 | * Simple implementation | ||
697 | */ | ||
698 | if ((!handle) || (handle == ACPI_ROOT_OBJECT)) { | ||
699 | return (acpi_gbl_root_node); | ||
700 | } | ||
701 | |||
702 | /* We can at least attempt to verify the handle */ | ||
703 | |||
704 | if (ACPI_GET_DESCRIPTOR_TYPE(handle) != ACPI_DESC_TYPE_NAMED) { | ||
705 | return (NULL); | ||
706 | } | ||
707 | |||
708 | return (ACPI_CAST_PTR(struct acpi_namespace_node, handle)); | ||
709 | } | ||
710 | |||
711 | /******************************************************************************* | ||
712 | * | ||
713 | * FUNCTION: acpi_ns_convert_entry_to_handle | ||
714 | * | ||
715 | * PARAMETERS: Node - Node to be converted to a Handle | ||
716 | * | ||
717 | * RETURN: A user handle | ||
718 | * | ||
719 | * DESCRIPTION: Convert a real Node to a namespace handle | ||
720 | * | ||
721 | ******************************************************************************/ | ||
722 | |||
723 | acpi_handle acpi_ns_convert_entry_to_handle(struct acpi_namespace_node *node) | ||
724 | { | ||
725 | |||
726 | /* | ||
727 | * Simple implementation for now; | ||
728 | */ | ||
729 | return ((acpi_handle) node); | ||
730 | |||
731 | /* Example future implementation --------------------- | ||
732 | |||
733 | if (!Node) | ||
734 | { | ||
735 | return (NULL); | ||
736 | } | ||
737 | |||
738 | if (Node == acpi_gbl_root_node) | ||
739 | { | ||
740 | return (ACPI_ROOT_OBJECT); | ||
741 | } | ||
742 | |||
743 | return ((acpi_handle) Node); | ||
744 | ------------------------------------------------------*/ | ||
745 | } | ||
746 | |||
747 | /******************************************************************************* | ||
748 | * | ||
749 | * FUNCTION: acpi_ns_terminate | ||
750 | * | ||
751 | * PARAMETERS: none | ||
752 | * | ||
753 | * RETURN: none | ||
754 | * | ||
755 | * DESCRIPTION: free memory allocated for namespace and ACPI table storage. | ||
756 | * | ||
757 | ******************************************************************************/ | ||
758 | |||
759 | void acpi_ns_terminate(void) | ||
760 | { | ||
761 | union acpi_operand_object *obj_desc; | ||
762 | |||
763 | ACPI_FUNCTION_TRACE(ns_terminate); | ||
764 | |||
765 | /* | ||
766 | * 1) Free the entire namespace -- all nodes and objects | ||
767 | * | ||
768 | * Delete all object descriptors attached to namepsace nodes | ||
769 | */ | ||
770 | acpi_ns_delete_namespace_subtree(acpi_gbl_root_node); | ||
771 | |||
772 | /* Detach any objects attached to the root */ | ||
773 | |||
774 | obj_desc = acpi_ns_get_attached_object(acpi_gbl_root_node); | ||
775 | if (obj_desc) { | ||
776 | acpi_ns_detach_object(acpi_gbl_root_node); | ||
777 | } | ||
778 | |||
779 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n")); | ||
780 | return_VOID; | ||
781 | } | ||
782 | |||
783 | /******************************************************************************* | ||
784 | * | ||
785 | * FUNCTION: acpi_ns_opens_scope | ||
786 | * | ||
787 | * PARAMETERS: Type - A valid namespace type | ||
788 | * | ||
789 | * RETURN: NEWSCOPE if the passed type "opens a name scope" according | ||
790 | * to the ACPI specification, else 0 | ||
791 | * | ||
792 | ******************************************************************************/ | ||
793 | |||
794 | u32 acpi_ns_opens_scope(acpi_object_type type) | ||
795 | { | ||
796 | ACPI_FUNCTION_TRACE_STR(ns_opens_scope, acpi_ut_get_type_name(type)); | ||
797 | |||
798 | if (!acpi_ut_valid_object_type(type)) { | ||
799 | |||
800 | /* type code out of range */ | ||
801 | |||
802 | ACPI_WARNING((AE_INFO, "Invalid Object Type %X", type)); | ||
803 | return_UINT32(ACPI_NS_NORMAL); | ||
804 | } | ||
805 | |||
806 | return_UINT32(((u32) acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE); | ||
807 | } | ||
808 | |||
809 | /******************************************************************************* | ||
810 | * | ||
811 | * FUNCTION: acpi_ns_get_node | ||
812 | * | ||
813 | * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The | ||
814 | * \ (backslash) and ^ (carat) prefixes, and the | ||
815 | * . (period) to separate segments are supported. | ||
816 | * prefix_node - Root of subtree to be searched, or NS_ALL for the | ||
817 | * root of the name space. If Name is fully | ||
818 | * qualified (first s8 is '\'), the passed value | ||
819 | * of Scope will not be accessed. | ||
820 | * Flags - Used to indicate whether to perform upsearch or | ||
821 | * not. | ||
822 | * return_node - Where the Node is returned | ||
823 | * | ||
824 | * DESCRIPTION: Look up a name relative to a given scope and return the | ||
825 | * corresponding Node. NOTE: Scope can be null. | ||
826 | * | ||
827 | * MUTEX: Locks namespace | ||
828 | * | ||
829 | ******************************************************************************/ | ||
830 | |||
831 | acpi_status | ||
832 | acpi_ns_get_node(struct acpi_namespace_node *prefix_node, | ||
833 | const char *pathname, | ||
834 | u32 flags, struct acpi_namespace_node **return_node) | ||
835 | { | ||
836 | union acpi_generic_state scope_info; | ||
837 | acpi_status status; | ||
838 | char *internal_path; | ||
839 | |||
840 | ACPI_FUNCTION_TRACE_PTR(ns_get_node, pathname); | ||
841 | |||
842 | if (!pathname) { | ||
843 | *return_node = prefix_node; | ||
844 | if (!prefix_node) { | ||
845 | *return_node = acpi_gbl_root_node; | ||
846 | } | ||
847 | return_ACPI_STATUS(AE_OK); | ||
848 | } | ||
849 | |||
850 | /* Convert path to internal representation */ | ||
851 | |||
852 | status = acpi_ns_internalize_name(pathname, &internal_path); | ||
853 | if (ACPI_FAILURE(status)) { | ||
854 | return_ACPI_STATUS(status); | ||
855 | } | ||
856 | |||
857 | /* Must lock namespace during lookup */ | ||
858 | |||
859 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
860 | if (ACPI_FAILURE(status)) { | ||
861 | goto cleanup; | ||
862 | } | ||
863 | |||
864 | /* Setup lookup scope (search starting point) */ | ||
865 | |||
866 | scope_info.scope.node = prefix_node; | ||
867 | |||
868 | /* Lookup the name in the namespace */ | ||
869 | |||
870 | status = acpi_ns_lookup(&scope_info, internal_path, ACPI_TYPE_ANY, | ||
871 | ACPI_IMODE_EXECUTE, | ||
872 | (flags | ACPI_NS_DONT_OPEN_SCOPE), NULL, | ||
873 | return_node); | ||
874 | if (ACPI_FAILURE(status)) { | ||
875 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s, %s\n", | ||
876 | pathname, acpi_format_exception(status))); | ||
877 | } | ||
878 | |||
879 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
880 | |||
881 | cleanup: | ||
882 | ACPI_FREE(internal_path); | ||
883 | return_ACPI_STATUS(status); | ||
884 | } | ||
885 | |||
886 | /******************************************************************************* | ||
887 | * | ||
888 | * FUNCTION: acpi_ns_get_parent_node | ||
889 | * | ||
890 | * PARAMETERS: Node - Current table entry | ||
891 | * | ||
892 | * RETURN: Parent entry of the given entry | ||
893 | * | ||
894 | * DESCRIPTION: Obtain the parent entry for a given entry in the namespace. | ||
895 | * | ||
896 | ******************************************************************************/ | ||
897 | |||
898 | struct acpi_namespace_node *acpi_ns_get_parent_node(struct acpi_namespace_node | ||
899 | *node) | ||
900 | { | ||
901 | ACPI_FUNCTION_ENTRY(); | ||
902 | |||
903 | if (!node) { | ||
904 | return (NULL); | ||
905 | } | ||
906 | |||
907 | /* | ||
908 | * Walk to the end of this peer list. The last entry is marked with a flag | ||
909 | * and the peer pointer is really a pointer back to the parent. This saves | ||
910 | * putting a parent back pointer in each and every named object! | ||
911 | */ | ||
912 | while (!(node->flags & ANOBJ_END_OF_PEER_LIST)) { | ||
913 | node = node->peer; | ||
914 | } | ||
915 | |||
916 | return (node->peer); | ||
917 | } | ||
918 | |||
919 | /******************************************************************************* | ||
920 | * | ||
921 | * FUNCTION: acpi_ns_get_next_valid_node | ||
922 | * | ||
923 | * PARAMETERS: Node - Current table entry | ||
924 | * | ||
925 | * RETURN: Next valid Node in the linked node list. NULL if no more valid | ||
926 | * nodes. | ||
927 | * | ||
928 | * DESCRIPTION: Find the next valid node within a name table. | ||
929 | * Useful for implementing NULL-end-of-list loops. | ||
930 | * | ||
931 | ******************************************************************************/ | ||
932 | |||
933 | struct acpi_namespace_node *acpi_ns_get_next_valid_node(struct | ||
934 | acpi_namespace_node | ||
935 | *node) | ||
936 | { | ||
937 | |||
938 | /* If we are at the end of this peer list, return NULL */ | ||
939 | |||
940 | if (node->flags & ANOBJ_END_OF_PEER_LIST) { | ||
941 | return NULL; | ||
942 | } | ||
943 | |||
944 | /* Otherwise just return the next peer */ | ||
945 | |||
946 | return (node->peer); | ||
947 | } | ||
948 | |||
949 | #ifdef ACPI_OBSOLETE_FUNCTIONS | ||
950 | /******************************************************************************* | ||
951 | * | ||
952 | * FUNCTION: acpi_ns_find_parent_name | ||
953 | * | ||
954 | * PARAMETERS: *child_node - Named Obj whose name is to be found | ||
955 | * | ||
956 | * RETURN: The ACPI name | ||
957 | * | ||
958 | * DESCRIPTION: Search for the given obj in its parent scope and return the | ||
959 | * name segment, or "????" if the parent name can't be found | ||
960 | * (which "should not happen"). | ||
961 | * | ||
962 | ******************************************************************************/ | ||
963 | |||
964 | acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node * child_node) | ||
965 | { | ||
966 | struct acpi_namespace_node *parent_node; | ||
967 | |||
968 | ACPI_FUNCTION_TRACE(ns_find_parent_name); | ||
969 | |||
970 | if (child_node) { | ||
971 | |||
972 | /* Valid entry. Get the parent Node */ | ||
973 | |||
974 | parent_node = acpi_ns_get_parent_node(child_node); | ||
975 | if (parent_node) { | ||
976 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
977 | "Parent of %p [%4.4s] is %p [%4.4s]\n", | ||
978 | child_node, | ||
979 | acpi_ut_get_node_name(child_node), | ||
980 | parent_node, | ||
981 | acpi_ut_get_node_name(parent_node))); | ||
982 | |||
983 | if (parent_node->name.integer) { | ||
984 | return_VALUE((acpi_name) parent_node->name. | ||
985 | integer); | ||
986 | } | ||
987 | } | ||
988 | |||
989 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
990 | "Unable to find parent of %p (%4.4s)\n", | ||
991 | child_node, | ||
992 | acpi_ut_get_node_name(child_node))); | ||
993 | } | ||
994 | |||
995 | return_VALUE(ACPI_UNKNOWN_NAME); | ||
996 | } | ||
997 | #endif | ||
diff --git a/drivers/acpi/namespace/nswalk.c b/drivers/acpi/namespace/nswalk.c deleted file mode 100644 index 71b83e9807da..000000000000 --- a/drivers/acpi/namespace/nswalk.c +++ /dev/null | |||
@@ -1,296 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: nswalk - Functions for walking the ACPI namespace | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2008, 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 <acpi/acpi.h> | ||
45 | #include <acpi/accommon.h> | ||
46 | #include <acpi/acnamesp.h> | ||
47 | |||
48 | #define _COMPONENT ACPI_NAMESPACE | ||
49 | ACPI_MODULE_NAME("nswalk") | ||
50 | |||
51 | /******************************************************************************* | ||
52 | * | ||
53 | * FUNCTION: acpi_ns_get_next_node | ||
54 | * | ||
55 | * PARAMETERS: Type - Type of node to be searched for | ||
56 | * parent_node - Parent node whose children we are | ||
57 | * getting | ||
58 | * child_node - Previous child that was found. | ||
59 | * The NEXT child will be returned | ||
60 | * | ||
61 | * RETURN: struct acpi_namespace_node - Pointer to the NEXT child or NULL if | ||
62 | * none is found. | ||
63 | * | ||
64 | * DESCRIPTION: Return the next peer node within the namespace. If Handle | ||
65 | * is valid, Scope is ignored. Otherwise, the first node | ||
66 | * within Scope is returned. | ||
67 | * | ||
68 | ******************************************************************************/ | ||
69 | struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct acpi_namespace_node | ||
70 | *parent_node, struct acpi_namespace_node | ||
71 | *child_node) | ||
72 | { | ||
73 | struct acpi_namespace_node *next_node = NULL; | ||
74 | |||
75 | ACPI_FUNCTION_ENTRY(); | ||
76 | |||
77 | if (!child_node) { | ||
78 | |||
79 | /* It's really the parent's _scope_ that we want */ | ||
80 | |||
81 | next_node = parent_node->child; | ||
82 | } | ||
83 | |||
84 | else { | ||
85 | /* Start search at the NEXT node */ | ||
86 | |||
87 | next_node = acpi_ns_get_next_valid_node(child_node); | ||
88 | } | ||
89 | |||
90 | /* If any type is OK, we are done */ | ||
91 | |||
92 | if (type == ACPI_TYPE_ANY) { | ||
93 | |||
94 | /* next_node is NULL if we are at the end-of-list */ | ||
95 | |||
96 | return (next_node); | ||
97 | } | ||
98 | |||
99 | /* Must search for the node -- but within this scope only */ | ||
100 | |||
101 | while (next_node) { | ||
102 | |||
103 | /* If type matches, we are done */ | ||
104 | |||
105 | if (next_node->type == type) { | ||
106 | return (next_node); | ||
107 | } | ||
108 | |||
109 | /* Otherwise, move on to the next node */ | ||
110 | |||
111 | next_node = acpi_ns_get_next_valid_node(next_node); | ||
112 | } | ||
113 | |||
114 | /* Not found */ | ||
115 | |||
116 | return (NULL); | ||
117 | } | ||
118 | |||
119 | /******************************************************************************* | ||
120 | * | ||
121 | * FUNCTION: acpi_ns_walk_namespace | ||
122 | * | ||
123 | * PARAMETERS: Type - acpi_object_type to search for | ||
124 | * start_node - Handle in namespace where search begins | ||
125 | * max_depth - Depth to which search is to reach | ||
126 | * Flags - Whether to unlock the NS before invoking | ||
127 | * the callback routine | ||
128 | * user_function - Called when an object of "Type" is found | ||
129 | * Context - Passed to user function | ||
130 | * return_value - from the user_function if terminated early. | ||
131 | * Otherwise, returns NULL. | ||
132 | * RETURNS: Status | ||
133 | * | ||
134 | * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, | ||
135 | * starting (and ending) at the node specified by start_handle. | ||
136 | * The user_function is called whenever a node that matches | ||
137 | * the type parameter is found. If the user function returns | ||
138 | * a non-zero value, the search is terminated immediately and this | ||
139 | * value is returned to the caller. | ||
140 | * | ||
141 | * The point of this procedure is to provide a generic namespace | ||
142 | * walk routine that can be called from multiple places to | ||
143 | * provide multiple services; the User Function can be tailored | ||
144 | * to each task, whether it is a print function, a compare | ||
145 | * function, etc. | ||
146 | * | ||
147 | ******************************************************************************/ | ||
148 | |||
149 | acpi_status | ||
150 | acpi_ns_walk_namespace(acpi_object_type type, | ||
151 | acpi_handle start_node, | ||
152 | u32 max_depth, | ||
153 | u32 flags, | ||
154 | acpi_walk_callback user_function, | ||
155 | void *context, void **return_value) | ||
156 | { | ||
157 | acpi_status status; | ||
158 | acpi_status mutex_status; | ||
159 | struct acpi_namespace_node *child_node; | ||
160 | struct acpi_namespace_node *parent_node; | ||
161 | acpi_object_type child_type; | ||
162 | u32 level; | ||
163 | |||
164 | ACPI_FUNCTION_TRACE(ns_walk_namespace); | ||
165 | |||
166 | /* Special case for the namespace Root Node */ | ||
167 | |||
168 | if (start_node == ACPI_ROOT_OBJECT) { | ||
169 | start_node = acpi_gbl_root_node; | ||
170 | } | ||
171 | |||
172 | /* Null child means "get first node" */ | ||
173 | |||
174 | parent_node = start_node; | ||
175 | child_node = NULL; | ||
176 | child_type = ACPI_TYPE_ANY; | ||
177 | level = 1; | ||
178 | |||
179 | /* | ||
180 | * Traverse the tree of nodes until we bubble back up to where we | ||
181 | * started. When Level is zero, the loop is done because we have | ||
182 | * bubbled up to (and passed) the original parent handle (start_entry) | ||
183 | */ | ||
184 | while (level > 0) { | ||
185 | |||
186 | /* Get the next node in this scope. Null if not found */ | ||
187 | |||
188 | status = AE_OK; | ||
189 | child_node = | ||
190 | acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, | ||
191 | child_node); | ||
192 | if (child_node) { | ||
193 | |||
194 | /* Found next child, get the type if we are not searching for ANY */ | ||
195 | |||
196 | if (type != ACPI_TYPE_ANY) { | ||
197 | child_type = child_node->type; | ||
198 | } | ||
199 | |||
200 | /* | ||
201 | * Ignore all temporary namespace nodes (created during control | ||
202 | * method execution) unless told otherwise. These temporary nodes | ||
203 | * can cause a race condition because they can be deleted during the | ||
204 | * execution of the user function (if the namespace is unlocked before | ||
205 | * invocation of the user function.) Only the debugger namespace dump | ||
206 | * will examine the temporary nodes. | ||
207 | */ | ||
208 | if ((child_node->flags & ANOBJ_TEMPORARY) && | ||
209 | !(flags & ACPI_NS_WALK_TEMP_NODES)) { | ||
210 | status = AE_CTRL_DEPTH; | ||
211 | } | ||
212 | |||
213 | /* Type must match requested type */ | ||
214 | |||
215 | else if (child_type == type) { | ||
216 | /* | ||
217 | * Found a matching node, invoke the user callback function. | ||
218 | * Unlock the namespace if flag is set. | ||
219 | */ | ||
220 | if (flags & ACPI_NS_WALK_UNLOCK) { | ||
221 | mutex_status = | ||
222 | acpi_ut_release_mutex | ||
223 | (ACPI_MTX_NAMESPACE); | ||
224 | if (ACPI_FAILURE(mutex_status)) { | ||
225 | return_ACPI_STATUS | ||
226 | (mutex_status); | ||
227 | } | ||
228 | } | ||
229 | |||
230 | status = | ||
231 | user_function(child_node, level, context, | ||
232 | return_value); | ||
233 | |||
234 | if (flags & ACPI_NS_WALK_UNLOCK) { | ||
235 | mutex_status = | ||
236 | acpi_ut_acquire_mutex | ||
237 | (ACPI_MTX_NAMESPACE); | ||
238 | if (ACPI_FAILURE(mutex_status)) { | ||
239 | return_ACPI_STATUS | ||
240 | (mutex_status); | ||
241 | } | ||
242 | } | ||
243 | |||
244 | switch (status) { | ||
245 | case AE_OK: | ||
246 | case AE_CTRL_DEPTH: | ||
247 | |||
248 | /* Just keep going */ | ||
249 | break; | ||
250 | |||
251 | case AE_CTRL_TERMINATE: | ||
252 | |||
253 | /* Exit now, with OK status */ | ||
254 | |||
255 | return_ACPI_STATUS(AE_OK); | ||
256 | |||
257 | default: | ||
258 | |||
259 | /* All others are valid exceptions */ | ||
260 | |||
261 | return_ACPI_STATUS(status); | ||
262 | } | ||
263 | } | ||
264 | |||
265 | /* | ||
266 | * Depth first search: Attempt to go down another level in the | ||
267 | * namespace if we are allowed to. Don't go any further if we have | ||
268 | * reached the caller specified maximum depth or if the user | ||
269 | * function has specified that the maximum depth has been reached. | ||
270 | */ | ||
271 | if ((level < max_depth) && (status != AE_CTRL_DEPTH)) { | ||
272 | if (acpi_ns_get_next_node | ||
273 | (ACPI_TYPE_ANY, child_node, NULL)) { | ||
274 | |||
275 | /* There is at least one child of this node, visit it */ | ||
276 | |||
277 | level++; | ||
278 | parent_node = child_node; | ||
279 | child_node = NULL; | ||
280 | } | ||
281 | } | ||
282 | } else { | ||
283 | /* | ||
284 | * No more children of this node (acpi_ns_get_next_node failed), go | ||
285 | * back upwards in the namespace tree to the node's parent. | ||
286 | */ | ||
287 | level--; | ||
288 | child_node = parent_node; | ||
289 | parent_node = acpi_ns_get_parent_node(parent_node); | ||
290 | } | ||
291 | } | ||
292 | |||
293 | /* Complete walk, not terminated by user function */ | ||
294 | |||
295 | return_ACPI_STATUS(AE_OK); | ||
296 | } | ||
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c deleted file mode 100644 index 598393a04e5f..000000000000 --- a/drivers/acpi/namespace/nsxfeval.c +++ /dev/null | |||
@@ -1,812 +0,0 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: nsxfeval - Public interfaces to the ACPI subsystem | ||
4 | * ACPI Object evaluation interfaces | ||
5 | * | ||
6 | ******************************************************************************/ | ||
7 | |||
8 | /* | ||
9 | * Copyright (C) 2000 - 2008, Intel Corp. | ||
10 | * All rights reserved. | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or without | ||
13 | * modification, are permitted provided that the following conditions | ||
14 | * are met: | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions, and the following disclaimer, | ||
17 | * without modification. | ||
18 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
19 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
20 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
21 | * including a substantially similar Disclaimer requirement for further | ||
22 | * binary redistribution. | ||
23 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
24 | * of any contributors may be used to endorse or promote products derived | ||
25 | * from this software without specific prior written permission. | ||
26 | * | ||
27 | * Alternatively, this software may be distributed under the terms of the | ||
28 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
29 | * Software Foundation. | ||
30 | * | ||
31 | * NO WARRANTY | ||
32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
33 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
35 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
36 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
37 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
38 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
39 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
40 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
41 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
42 | * POSSIBILITY OF SUCH DAMAGES. | ||
43 | */ | ||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/accommon.h> | ||
47 | #include <acpi/acnamesp.h> | ||
48 | #include <acpi/acinterp.h> | ||
49 | |||
50 | #define _COMPONENT ACPI_NAMESPACE | ||
51 | ACPI_MODULE_NAME("nsxfeval") | ||
52 | |||
53 | /* Local prototypes */ | ||
54 | static void acpi_ns_resolve_references(struct acpi_evaluate_info *info); | ||
55 | |||
56 | #ifdef ACPI_FUTURE_USAGE | ||
57 | /******************************************************************************* | ||
58 | * | ||
59 | * FUNCTION: acpi_evaluate_object_typed | ||
60 | * | ||
61 | * PARAMETERS: Handle - Object handle (optional) | ||
62 | * Pathname - Object pathname (optional) | ||
63 | * external_params - List of parameters to pass to method, | ||
64 | * terminated by NULL. May be NULL | ||
65 | * if no parameters are being passed. | ||
66 | * return_buffer - Where to put method's return value (if | ||
67 | * any). If NULL, no value is returned. | ||
68 | * return_type - Expected type of return object | ||
69 | * | ||
70 | * RETURN: Status | ||
71 | * | ||
72 | * DESCRIPTION: Find and evaluate the given object, passing the given | ||
73 | * parameters if necessary. One of "Handle" or "Pathname" must | ||
74 | * be valid (non-null) | ||
75 | * | ||
76 | ******************************************************************************/ | ||
77 | |||
78 | acpi_status | ||
79 | acpi_evaluate_object_typed(acpi_handle handle, | ||
80 | acpi_string pathname, | ||
81 | struct acpi_object_list *external_params, | ||
82 | struct acpi_buffer *return_buffer, | ||
83 | acpi_object_type return_type) | ||
84 | { | ||
85 | acpi_status status; | ||
86 | u8 must_free = FALSE; | ||
87 | |||
88 | ACPI_FUNCTION_TRACE(acpi_evaluate_object_typed); | ||
89 | |||
90 | /* Return buffer must be valid */ | ||
91 | |||
92 | if (!return_buffer) { | ||
93 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
94 | } | ||
95 | |||
96 | if (return_buffer->length == ACPI_ALLOCATE_BUFFER) { | ||
97 | must_free = TRUE; | ||
98 | } | ||
99 | |||
100 | /* Evaluate the object */ | ||
101 | |||
102 | status = | ||
103 | acpi_evaluate_object(handle, pathname, external_params, | ||
104 | return_buffer); | ||
105 | if (ACPI_FAILURE(status)) { | ||
106 | return_ACPI_STATUS(status); | ||
107 | } | ||
108 | |||
109 | /* Type ANY means "don't care" */ | ||
110 | |||
111 | if (return_type == ACPI_TYPE_ANY) { | ||
112 | return_ACPI_STATUS(AE_OK); | ||
113 | } | ||
114 | |||
115 | if (return_buffer->length == 0) { | ||
116 | |||
117 | /* Error because caller specifically asked for a return value */ | ||
118 | |||
119 | ACPI_ERROR((AE_INFO, "No return value")); | ||
120 | return_ACPI_STATUS(AE_NULL_OBJECT); | ||
121 | } | ||
122 | |||
123 | /* Examine the object type returned from evaluate_object */ | ||
124 | |||
125 | if (((union acpi_object *)return_buffer->pointer)->type == return_type) { | ||
126 | return_ACPI_STATUS(AE_OK); | ||
127 | } | ||
128 | |||
129 | /* Return object type does not match requested type */ | ||
130 | |||
131 | ACPI_ERROR((AE_INFO, | ||
132 | "Incorrect return type [%s] requested [%s]", | ||
133 | acpi_ut_get_type_name(((union acpi_object *)return_buffer-> | ||
134 | pointer)->type), | ||
135 | acpi_ut_get_type_name(return_type))); | ||
136 | |||
137 | if (must_free) { | ||
138 | |||
139 | /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */ | ||
140 | |||
141 | ACPI_FREE(return_buffer->pointer); | ||
142 | return_buffer->pointer = NULL; | ||
143 | } | ||
144 | |||
145 | return_buffer->length = 0; | ||
146 | return_ACPI_STATUS(AE_TYPE); | ||
147 | } | ||
148 | |||
149 | ACPI_EXPORT_SYMBOL(acpi_evaluate_object_typed) | ||
150 | #endif /* ACPI_FUTURE_USAGE */ | ||
151 | /******************************************************************************* | ||
152 | * | ||
153 | * FUNCTION: acpi_evaluate_object | ||
154 | * | ||
155 | * PARAMETERS: Handle - Object handle (optional) | ||
156 | * Pathname - Object pathname (optional) | ||
157 | * external_params - List of parameters to pass to method, | ||
158 | * terminated by NULL. May be NULL | ||
159 | * if no parameters are being passed. | ||
160 | * return_buffer - Where to put method's return value (if | ||
161 | * any). If NULL, no value is returned. | ||
162 | * | ||
163 | * RETURN: Status | ||
164 | * | ||
165 | * DESCRIPTION: Find and evaluate the given object, passing the given | ||
166 | * parameters if necessary. One of "Handle" or "Pathname" must | ||
167 | * be valid (non-null) | ||
168 | * | ||
169 | ******************************************************************************/ | ||
170 | acpi_status | ||
171 | acpi_evaluate_object(acpi_handle handle, | ||
172 | acpi_string pathname, | ||
173 | struct acpi_object_list *external_params, | ||
174 | struct acpi_buffer *return_buffer) | ||
175 | { | ||
176 | acpi_status status; | ||
177 | struct acpi_evaluate_info *info; | ||
178 | acpi_size buffer_space_needed; | ||
179 | u32 i; | ||
180 | |||
181 | ACPI_FUNCTION_TRACE(acpi_evaluate_object); | ||
182 | |||
183 | /* Allocate and initialize the evaluation information block */ | ||
184 | |||
185 | info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); | ||
186 | if (!info) { | ||
187 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
188 | } | ||
189 | |||
190 | info->pathname = pathname; | ||
191 | |||
192 | /* Convert and validate the device handle */ | ||
193 | |||
194 | info->prefix_node = acpi_ns_map_handle_to_node(handle); | ||
195 | if (!info->prefix_node) { | ||
196 | status = AE_BAD_PARAMETER; | ||
197 | goto cleanup; | ||
198 | } | ||
199 | |||
200 | /* | ||
201 | * If there are parameters to be passed to a control method, the external | ||
202 | * objects must all be converted to internal objects | ||
203 | */ | ||
204 | if (external_params && external_params->count) { | ||
205 | /* | ||
206 | * Allocate a new parameter block for the internal objects | ||
207 | * Add 1 to count to allow for null terminated internal list | ||
208 | */ | ||
209 | info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size) | ||
210 | external_params-> | ||
211 | count + | ||
212 | 1) * sizeof(void *)); | ||
213 | if (!info->parameters) { | ||
214 | status = AE_NO_MEMORY; | ||
215 | goto cleanup; | ||
216 | } | ||
217 | |||
218 | /* Convert each external object in the list to an internal object */ | ||
219 | |||
220 | for (i = 0; i < external_params->count; i++) { | ||
221 | status = | ||
222 | acpi_ut_copy_eobject_to_iobject(&external_params-> | ||
223 | pointer[i], | ||
224 | &info-> | ||
225 | parameters[i]); | ||
226 | if (ACPI_FAILURE(status)) { | ||
227 | goto cleanup; | ||
228 | } | ||
229 | } | ||
230 | info->parameters[external_params->count] = NULL; | ||
231 | } | ||
232 | |||
233 | /* | ||
234 | * Three major cases: | ||
235 | * 1) Fully qualified pathname | ||
236 | * 2) No handle, not fully qualified pathname (error) | ||
237 | * 3) Valid handle | ||
238 | */ | ||
239 | if ((pathname) && (acpi_ns_valid_root_prefix(pathname[0]))) { | ||
240 | |||
241 | /* The path is fully qualified, just evaluate by name */ | ||
242 | |||
243 | info->prefix_node = NULL; | ||
244 | status = acpi_ns_evaluate(info); | ||
245 | } else if (!handle) { | ||
246 | /* | ||
247 | * A handle is optional iff a fully qualified pathname is specified. | ||
248 | * Since we've already handled fully qualified names above, this is | ||
249 | * an error | ||
250 | */ | ||
251 | if (!pathname) { | ||
252 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
253 | "Both Handle and Pathname are NULL")); | ||
254 | } else { | ||
255 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
256 | "Null Handle with relative pathname [%s]", | ||
257 | pathname)); | ||
258 | } | ||
259 | |||
260 | status = AE_BAD_PARAMETER; | ||
261 | } else { | ||
262 | /* We have a namespace a node and a possible relative path */ | ||
263 | |||
264 | status = acpi_ns_evaluate(info); | ||
265 | } | ||
266 | |||
267 | /* | ||
268 | * If we are expecting a return value, and all went well above, | ||
269 | * copy the return value to an external object. | ||
270 | */ | ||
271 | if (return_buffer) { | ||
272 | if (!info->return_object) { | ||
273 | return_buffer->length = 0; | ||
274 | } else { | ||
275 | if (ACPI_GET_DESCRIPTOR_TYPE(info->return_object) == | ||
276 | ACPI_DESC_TYPE_NAMED) { | ||
277 | /* | ||
278 | * If we received a NS Node as a return object, this means that | ||
279 | * the object we are evaluating has nothing interesting to | ||
280 | * return (such as a mutex, etc.) We return an error because | ||
281 | * these types are essentially unsupported by this interface. | ||
282 | * We don't check up front because this makes it easier to add | ||
283 | * support for various types at a later date if necessary. | ||
284 | */ | ||
285 | status = AE_TYPE; | ||
286 | info->return_object = NULL; /* No need to delete a NS Node */ | ||
287 | return_buffer->length = 0; | ||
288 | } | ||
289 | |||
290 | if (ACPI_SUCCESS(status)) { | ||
291 | |||
292 | /* Dereference Index and ref_of references */ | ||
293 | |||
294 | acpi_ns_resolve_references(info); | ||
295 | |||
296 | /* Get the size of the returned object */ | ||
297 | |||
298 | status = | ||
299 | acpi_ut_get_object_size(info->return_object, | ||
300 | &buffer_space_needed); | ||
301 | if (ACPI_SUCCESS(status)) { | ||
302 | |||
303 | /* Validate/Allocate/Clear caller buffer */ | ||
304 | |||
305 | status = | ||
306 | acpi_ut_initialize_buffer | ||
307 | (return_buffer, | ||
308 | buffer_space_needed); | ||
309 | if (ACPI_FAILURE(status)) { | ||
310 | /* | ||
311 | * Caller's buffer is too small or a new one can't | ||
312 | * be allocated | ||
313 | */ | ||
314 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
315 | "Needed buffer size %X, %s\n", | ||
316 | (u32) | ||
317 | buffer_space_needed, | ||
318 | acpi_format_exception | ||
319 | (status))); | ||
320 | } else { | ||
321 | /* We have enough space for the object, build it */ | ||
322 | |||
323 | status = | ||
324 | acpi_ut_copy_iobject_to_eobject | ||
325 | (info->return_object, | ||
326 | return_buffer); | ||
327 | } | ||
328 | } | ||
329 | } | ||
330 | } | ||
331 | } | ||
332 | |||
333 | if (info->return_object) { | ||
334 | /* | ||
335 | * Delete the internal return object. NOTE: Interpreter must be | ||
336 | * locked to avoid race condition. | ||
337 | */ | ||
338 | acpi_ex_enter_interpreter(); | ||
339 | |||
340 | /* Remove one reference on the return object (should delete it) */ | ||
341 | |||
342 | acpi_ut_remove_reference(info->return_object); | ||
343 | acpi_ex_exit_interpreter(); | ||
344 | } | ||
345 | |||
346 | cleanup: | ||
347 | |||
348 | /* Free the input parameter list (if we created one) */ | ||
349 | |||
350 | if (info->parameters) { | ||
351 | |||
352 | /* Free the allocated parameter block */ | ||
353 | |||
354 | acpi_ut_delete_internal_object_list(info->parameters); | ||
355 | } | ||
356 | |||
357 | ACPI_FREE(info); | ||
358 | return_ACPI_STATUS(status); | ||
359 | } | ||
360 | |||
361 | ACPI_EXPORT_SYMBOL(acpi_evaluate_object) | ||
362 | |||
363 | /******************************************************************************* | ||
364 | * | ||
365 | * FUNCTION: acpi_ns_resolve_references | ||
366 | * | ||
367 | * PARAMETERS: Info - Evaluation info block | ||
368 | * | ||
369 | * RETURN: Info->return_object is replaced with the dereferenced object | ||
370 | * | ||
371 | * DESCRIPTION: Dereference certain reference objects. Called before an | ||
372 | * internal return object is converted to an external union acpi_object. | ||
373 | * | ||
374 | * Performs an automatic dereference of Index and ref_of reference objects. | ||
375 | * These reference objects are not supported by the union acpi_object, so this is a | ||
376 | * last resort effort to return something useful. Also, provides compatibility | ||
377 | * with other ACPI implementations. | ||
378 | * | ||
379 | * NOTE: does not handle references within returned package objects or nested | ||
380 | * references, but this support could be added later if found to be necessary. | ||
381 | * | ||
382 | ******************************************************************************/ | ||
383 | static void acpi_ns_resolve_references(struct acpi_evaluate_info *info) | ||
384 | { | ||
385 | union acpi_operand_object *obj_desc = NULL; | ||
386 | struct acpi_namespace_node *node; | ||
387 | |||
388 | /* We are interested in reference objects only */ | ||
389 | |||
390 | if (ACPI_GET_OBJECT_TYPE(info->return_object) != | ||
391 | ACPI_TYPE_LOCAL_REFERENCE) { | ||
392 | return; | ||
393 | } | ||
394 | |||
395 | /* | ||
396 | * Two types of references are supported - those created by Index and | ||
397 | * ref_of operators. A name reference (AML_NAMEPATH_OP) can be converted | ||
398 | * to an union acpi_object, so it is not dereferenced here. A ddb_handle | ||
399 | * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to | ||
400 | * an union acpi_object. | ||
401 | */ | ||
402 | switch (info->return_object->reference.class) { | ||
403 | case ACPI_REFCLASS_INDEX: | ||
404 | |||
405 | obj_desc = *(info->return_object->reference.where); | ||
406 | break; | ||
407 | |||
408 | case ACPI_REFCLASS_REFOF: | ||
409 | |||
410 | node = info->return_object->reference.object; | ||
411 | if (node) { | ||
412 | obj_desc = node->object; | ||
413 | } | ||
414 | break; | ||
415 | |||
416 | default: | ||
417 | return; | ||
418 | } | ||
419 | |||
420 | /* Replace the existing reference object */ | ||
421 | |||
422 | if (obj_desc) { | ||
423 | acpi_ut_add_reference(obj_desc); | ||
424 | acpi_ut_remove_reference(info->return_object); | ||
425 | info->return_object = obj_desc; | ||
426 | } | ||
427 | |||
428 | return; | ||
429 | } | ||
430 | |||
431 | /******************************************************************************* | ||
432 | * | ||
433 | * FUNCTION: acpi_walk_namespace | ||
434 | * | ||
435 | * PARAMETERS: Type - acpi_object_type to search for | ||
436 | * start_object - Handle in namespace where search begins | ||
437 | * max_depth - Depth to which search is to reach | ||
438 | * user_function - Called when an object of "Type" is found | ||
439 | * Context - Passed to user function | ||
440 | * return_value - Location where return value of | ||
441 | * user_function is put if terminated early | ||
442 | * | ||
443 | * RETURNS Return value from the user_function if terminated early. | ||
444 | * Otherwise, returns NULL. | ||
445 | * | ||
446 | * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, | ||
447 | * starting (and ending) at the object specified by start_handle. | ||
448 | * The user_function is called whenever an object that matches | ||
449 | * the type parameter is found. If the user function returns | ||
450 | * a non-zero value, the search is terminated immediately and this | ||
451 | * value is returned to the caller. | ||
452 | * | ||
453 | * The point of this procedure is to provide a generic namespace | ||
454 | * walk routine that can be called from multiple places to | ||
455 | * provide multiple services; the User Function can be tailored | ||
456 | * to each task, whether it is a print function, a compare | ||
457 | * function, etc. | ||
458 | * | ||
459 | ******************************************************************************/ | ||
460 | |||
461 | acpi_status | ||
462 | acpi_walk_namespace(acpi_object_type type, | ||
463 | acpi_handle start_object, | ||
464 | u32 max_depth, | ||
465 | acpi_walk_callback user_function, | ||
466 | void *context, void **return_value) | ||
467 | { | ||
468 | acpi_status status; | ||
469 | |||
470 | ACPI_FUNCTION_TRACE(acpi_walk_namespace); | ||
471 | |||
472 | /* Parameter validation */ | ||
473 | |||
474 | if ((type > ACPI_TYPE_LOCAL_MAX) || (!max_depth) || (!user_function)) { | ||
475 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
476 | } | ||
477 | |||
478 | /* | ||
479 | * Lock the namespace around the walk. | ||
480 | * The namespace will be unlocked/locked around each call | ||
481 | * to the user function - since this function | ||
482 | * must be allowed to make Acpi calls itself. | ||
483 | */ | ||
484 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
485 | if (ACPI_FAILURE(status)) { | ||
486 | return_ACPI_STATUS(status); | ||
487 | } | ||
488 | |||
489 | status = acpi_ns_walk_namespace(type, start_object, max_depth, | ||
490 | ACPI_NS_WALK_UNLOCK, | ||
491 | user_function, context, return_value); | ||
492 | |||
493 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
494 | return_ACPI_STATUS(status); | ||
495 | } | ||
496 | |||
497 | ACPI_EXPORT_SYMBOL(acpi_walk_namespace) | ||
498 | |||
499 | /******************************************************************************* | ||
500 | * | ||
501 | * FUNCTION: acpi_ns_get_device_callback | ||
502 | * | ||
503 | * PARAMETERS: Callback from acpi_get_device | ||
504 | * | ||
505 | * RETURN: Status | ||
506 | * | ||
507 | * DESCRIPTION: Takes callbacks from walk_namespace and filters out all non- | ||
508 | * present devices, or if they specified a HID, it filters based | ||
509 | * on that. | ||
510 | * | ||
511 | ******************************************************************************/ | ||
512 | static acpi_status | ||
513 | acpi_ns_get_device_callback(acpi_handle obj_handle, | ||
514 | u32 nesting_level, | ||
515 | void *context, void **return_value) | ||
516 | { | ||
517 | struct acpi_get_devices_info *info = context; | ||
518 | acpi_status status; | ||
519 | struct acpi_namespace_node *node; | ||
520 | u32 flags; | ||
521 | struct acpica_device_id hid; | ||
522 | struct acpi_compatible_id_list *cid; | ||
523 | u32 i; | ||
524 | int found; | ||
525 | |||
526 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
527 | if (ACPI_FAILURE(status)) { | ||
528 | return (status); | ||
529 | } | ||
530 | |||
531 | node = acpi_ns_map_handle_to_node(obj_handle); | ||
532 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
533 | if (ACPI_FAILURE(status)) { | ||
534 | return (status); | ||
535 | } | ||
536 | |||
537 | if (!node) { | ||
538 | return (AE_BAD_PARAMETER); | ||
539 | } | ||
540 | |||
541 | /* Run _STA to determine if device is present */ | ||
542 | |||
543 | status = acpi_ut_execute_STA(node, &flags); | ||
544 | if (ACPI_FAILURE(status)) { | ||
545 | return (AE_CTRL_DEPTH); | ||
546 | } | ||
547 | |||
548 | if (!(flags & ACPI_STA_DEVICE_PRESENT) && | ||
549 | !(flags & ACPI_STA_DEVICE_FUNCTIONING)) { | ||
550 | /* | ||
551 | * Don't examine the children of the device only when the | ||
552 | * device is neither present nor functional. See ACPI spec, | ||
553 | * description of _STA for more information. | ||
554 | */ | ||
555 | return (AE_CTRL_DEPTH); | ||
556 | } | ||
557 | |||
558 | /* Filter based on device HID & CID */ | ||
559 | |||
560 | if (info->hid != NULL) { | ||
561 | status = acpi_ut_execute_HID(node, &hid); | ||
562 | if (status == AE_NOT_FOUND) { | ||
563 | return (AE_OK); | ||
564 | } else if (ACPI_FAILURE(status)) { | ||
565 | return (AE_CTRL_DEPTH); | ||
566 | } | ||
567 | |||
568 | if (ACPI_STRNCMP(hid.value, info->hid, sizeof(hid.value)) != 0) { | ||
569 | |||
570 | /* Get the list of Compatible IDs */ | ||
571 | |||
572 | status = acpi_ut_execute_CID(node, &cid); | ||
573 | if (status == AE_NOT_FOUND) { | ||
574 | return (AE_OK); | ||
575 | } else if (ACPI_FAILURE(status)) { | ||
576 | return (AE_CTRL_DEPTH); | ||
577 | } | ||
578 | |||
579 | /* Walk the CID list */ | ||
580 | |||
581 | found = 0; | ||
582 | for (i = 0; i < cid->count; i++) { | ||
583 | if (ACPI_STRNCMP(cid->id[i].value, info->hid, | ||
584 | sizeof(struct | ||
585 | acpi_compatible_id)) == | ||
586 | 0) { | ||
587 | found = 1; | ||
588 | break; | ||
589 | } | ||
590 | } | ||
591 | ACPI_FREE(cid); | ||
592 | if (!found) | ||
593 | return (AE_OK); | ||
594 | } | ||
595 | } | ||
596 | |||
597 | status = info->user_function(obj_handle, nesting_level, info->context, | ||
598 | return_value); | ||
599 | return (status); | ||
600 | } | ||
601 | |||
602 | /******************************************************************************* | ||
603 | * | ||
604 | * FUNCTION: acpi_get_devices | ||
605 | * | ||
606 | * PARAMETERS: HID - HID to search for. Can be NULL. | ||
607 | * user_function - Called when a matching object is found | ||
608 | * Context - Passed to user function | ||
609 | * return_value - Location where return value of | ||
610 | * user_function is put if terminated early | ||
611 | * | ||
612 | * RETURNS Return value from the user_function if terminated early. | ||
613 | * Otherwise, returns NULL. | ||
614 | * | ||
615 | * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, | ||
616 | * starting (and ending) at the object specified by start_handle. | ||
617 | * The user_function is called whenever an object of type | ||
618 | * Device is found. If the user function returns | ||
619 | * a non-zero value, the search is terminated immediately and this | ||
620 | * value is returned to the caller. | ||
621 | * | ||
622 | * This is a wrapper for walk_namespace, but the callback performs | ||
623 | * additional filtering. Please see acpi_ns_get_device_callback. | ||
624 | * | ||
625 | ******************************************************************************/ | ||
626 | |||
627 | acpi_status | ||
628 | acpi_get_devices(const char *HID, | ||
629 | acpi_walk_callback user_function, | ||
630 | void *context, void **return_value) | ||
631 | { | ||
632 | acpi_status status; | ||
633 | struct acpi_get_devices_info info; | ||
634 | |||
635 | ACPI_FUNCTION_TRACE(acpi_get_devices); | ||
636 | |||
637 | /* Parameter validation */ | ||
638 | |||
639 | if (!user_function) { | ||
640 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
641 | } | ||
642 | |||
643 | /* | ||
644 | * We're going to call their callback from OUR callback, so we need | ||
645 | * to know what it is, and their context parameter. | ||
646 | */ | ||
647 | info.hid = HID; | ||
648 | info.context = context; | ||
649 | info.user_function = user_function; | ||
650 | |||
651 | /* | ||
652 | * Lock the namespace around the walk. | ||
653 | * The namespace will be unlocked/locked around each call | ||
654 | * to the user function - since this function | ||
655 | * must be allowed to make Acpi calls itself. | ||
656 | */ | ||
657 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
658 | if (ACPI_FAILURE(status)) { | ||
659 | return_ACPI_STATUS(status); | ||
660 | } | ||
661 | |||
662 | status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
663 | ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, | ||
664 | acpi_ns_get_device_callback, &info, | ||
665 | return_value); | ||
666 | |||
667 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
668 | return_ACPI_STATUS(status); | ||
669 | } | ||
670 | |||
671 | ACPI_EXPORT_SYMBOL(acpi_get_devices) | ||
672 | |||
673 | /******************************************************************************* | ||
674 | * | ||
675 | * FUNCTION: acpi_attach_data | ||
676 | * | ||
677 | * PARAMETERS: obj_handle - Namespace node | ||
678 | * Handler - Handler for this attachment | ||
679 | * Data - Pointer to data to be attached | ||
680 | * | ||
681 | * RETURN: Status | ||
682 | * | ||
683 | * DESCRIPTION: Attach arbitrary data and handler to a namespace node. | ||
684 | * | ||
685 | ******************************************************************************/ | ||
686 | acpi_status | ||
687 | acpi_attach_data(acpi_handle obj_handle, | ||
688 | acpi_object_handler handler, void *data) | ||
689 | { | ||
690 | struct acpi_namespace_node *node; | ||
691 | acpi_status status; | ||
692 | |||
693 | /* Parameter validation */ | ||
694 | |||
695 | if (!obj_handle || !handler || !data) { | ||
696 | return (AE_BAD_PARAMETER); | ||
697 | } | ||
698 | |||
699 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
700 | if (ACPI_FAILURE(status)) { | ||
701 | return (status); | ||
702 | } | ||
703 | |||
704 | /* Convert and validate the handle */ | ||
705 | |||
706 | node = acpi_ns_map_handle_to_node(obj_handle); | ||
707 | if (!node) { | ||
708 | status = AE_BAD_PARAMETER; | ||
709 | goto unlock_and_exit; | ||
710 | } | ||
711 | |||
712 | status = acpi_ns_attach_data(node, handler, data); | ||
713 | |||
714 | unlock_and_exit: | ||
715 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
716 | return (status); | ||
717 | } | ||
718 | |||
719 | ACPI_EXPORT_SYMBOL(acpi_attach_data) | ||
720 | |||
721 | /******************************************************************************* | ||
722 | * | ||
723 | * FUNCTION: acpi_detach_data | ||
724 | * | ||
725 | * PARAMETERS: obj_handle - Namespace node handle | ||
726 | * Handler - Handler used in call to acpi_attach_data | ||
727 | * | ||
728 | * RETURN: Status | ||
729 | * | ||
730 | * DESCRIPTION: Remove data that was previously attached to a node. | ||
731 | * | ||
732 | ******************************************************************************/ | ||
733 | acpi_status | ||
734 | acpi_detach_data(acpi_handle obj_handle, acpi_object_handler handler) | ||
735 | { | ||
736 | struct acpi_namespace_node *node; | ||
737 | acpi_status status; | ||
738 | |||
739 | /* Parameter validation */ | ||
740 | |||
741 | if (!obj_handle || !handler) { | ||
742 | return (AE_BAD_PARAMETER); | ||
743 | } | ||
744 | |||
745 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
746 | if (ACPI_FAILURE(status)) { | ||
747 | return (status); | ||
748 | } | ||
749 | |||
750 | /* Convert and validate the handle */ | ||
751 | |||
752 | node = acpi_ns_map_handle_to_node(obj_handle); | ||
753 | if (!node) { | ||
754 | status = AE_BAD_PARAMETER; | ||
755 | goto unlock_and_exit; | ||
756 | } | ||
757 | |||
758 | status = acpi_ns_detach_data(node, handler); | ||
759 | |||
760 | unlock_and_exit: | ||
761 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
762 | return (status); | ||
763 | } | ||
764 | |||
765 | ACPI_EXPORT_SYMBOL(acpi_detach_data) | ||
766 | |||
767 | /******************************************************************************* | ||
768 | * | ||
769 | * FUNCTION: acpi_get_data | ||
770 | * | ||
771 | * PARAMETERS: obj_handle - Namespace node | ||
772 | * Handler - Handler used in call to attach_data | ||
773 | * Data - Where the data is returned | ||
774 | * | ||
775 | * RETURN: Status | ||
776 | * | ||
777 | * DESCRIPTION: Retrieve data that was previously attached to a namespace node. | ||
778 | * | ||
779 | ******************************************************************************/ | ||
780 | acpi_status | ||
781 | acpi_get_data(acpi_handle obj_handle, acpi_object_handler handler, void **data) | ||
782 | { | ||
783 | struct acpi_namespace_node *node; | ||
784 | acpi_status status; | ||
785 | |||
786 | /* Parameter validation */ | ||
787 | |||
788 | if (!obj_handle || !handler || !data) { | ||
789 | return (AE_BAD_PARAMETER); | ||
790 | } | ||
791 | |||
792 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
793 | if (ACPI_FAILURE(status)) { | ||
794 | return (status); | ||
795 | } | ||
796 | |||
797 | /* Convert and validate the handle */ | ||
798 | |||
799 | node = acpi_ns_map_handle_to_node(obj_handle); | ||
800 | if (!node) { | ||
801 | status = AE_BAD_PARAMETER; | ||
802 | goto unlock_and_exit; | ||
803 | } | ||
804 | |||
805 | status = acpi_ns_get_attached_data(node, handler, data); | ||
806 | |||
807 | unlock_and_exit: | ||
808 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
809 | return (status); | ||
810 | } | ||
811 | |||
812 | ACPI_EXPORT_SYMBOL(acpi_get_data) | ||
diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c deleted file mode 100644 index 7d5bfa9e9fe9..000000000000 --- a/drivers/acpi/namespace/nsxfname.c +++ /dev/null | |||
@@ -1,360 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: nsxfname - Public interfaces to the ACPI subsystem | ||
4 | * ACPI Namespace oriented interfaces | ||
5 | * | ||
6 | *****************************************************************************/ | ||
7 | |||
8 | /* | ||
9 | * Copyright (C) 2000 - 2008, Intel Corp. | ||
10 | * All rights reserved. | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or without | ||
13 | * modification, are permitted provided that the following conditions | ||
14 | * are met: | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions, and the following disclaimer, | ||
17 | * without modification. | ||
18 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
19 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
20 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
21 | * including a substantially similar Disclaimer requirement for further | ||
22 | * binary redistribution. | ||
23 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
24 | * of any contributors may be used to endorse or promote products derived | ||
25 | * from this software without specific prior written permission. | ||
26 | * | ||
27 | * Alternatively, this software may be distributed under the terms of the | ||
28 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
29 | * Software Foundation. | ||
30 | * | ||
31 | * NO WARRANTY | ||
32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
33 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
35 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
36 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
37 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
38 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
39 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
40 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
41 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
42 | * POSSIBILITY OF SUCH DAMAGES. | ||
43 | */ | ||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/accommon.h> | ||
47 | #include <acpi/acnamesp.h> | ||
48 | |||
49 | #define _COMPONENT ACPI_NAMESPACE | ||
50 | ACPI_MODULE_NAME("nsxfname") | ||
51 | |||
52 | /****************************************************************************** | ||
53 | * | ||
54 | * FUNCTION: acpi_get_handle | ||
55 | * | ||
56 | * PARAMETERS: Parent - Object to search under (search scope). | ||
57 | * Pathname - Pointer to an asciiz string containing the | ||
58 | * name | ||
59 | * ret_handle - Where the return handle is returned | ||
60 | * | ||
61 | * RETURN: Status | ||
62 | * | ||
63 | * DESCRIPTION: This routine will search for a caller specified name in the | ||
64 | * name space. The caller can restrict the search region by | ||
65 | * specifying a non NULL parent. The parent value is itself a | ||
66 | * namespace handle. | ||
67 | * | ||
68 | ******************************************************************************/ | ||
69 | acpi_status | ||
70 | acpi_get_handle(acpi_handle parent, | ||
71 | acpi_string pathname, acpi_handle * ret_handle) | ||
72 | { | ||
73 | acpi_status status; | ||
74 | struct acpi_namespace_node *node = NULL; | ||
75 | struct acpi_namespace_node *prefix_node = NULL; | ||
76 | |||
77 | ACPI_FUNCTION_ENTRY(); | ||
78 | |||
79 | /* Parameter Validation */ | ||
80 | |||
81 | if (!ret_handle || !pathname) { | ||
82 | return (AE_BAD_PARAMETER); | ||
83 | } | ||
84 | |||
85 | /* Convert a parent handle to a prefix node */ | ||
86 | |||
87 | if (parent) { | ||
88 | prefix_node = acpi_ns_map_handle_to_node(parent); | ||
89 | if (!prefix_node) { | ||
90 | return (AE_BAD_PARAMETER); | ||
91 | } | ||
92 | } | ||
93 | |||
94 | /* | ||
95 | * Valid cases are: | ||
96 | * 1) Fully qualified pathname | ||
97 | * 2) Parent + Relative pathname | ||
98 | * | ||
99 | * Error for <null Parent + relative path> | ||
100 | */ | ||
101 | if (acpi_ns_valid_root_prefix(pathname[0])) { | ||
102 | |||
103 | /* Pathname is fully qualified (starts with '\') */ | ||
104 | |||
105 | /* Special case for root-only, since we can't search for it */ | ||
106 | |||
107 | if (!ACPI_STRCMP(pathname, ACPI_NS_ROOT_PATH)) { | ||
108 | *ret_handle = | ||
109 | acpi_ns_convert_entry_to_handle(acpi_gbl_root_node); | ||
110 | return (AE_OK); | ||
111 | } | ||
112 | } else if (!prefix_node) { | ||
113 | |||
114 | /* Relative path with null prefix is disallowed */ | ||
115 | |||
116 | return (AE_BAD_PARAMETER); | ||
117 | } | ||
118 | |||
119 | /* Find the Node and convert to a handle */ | ||
120 | |||
121 | status = | ||
122 | acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH, &node); | ||
123 | if (ACPI_SUCCESS(status)) { | ||
124 | *ret_handle = acpi_ns_convert_entry_to_handle(node); | ||
125 | } | ||
126 | |||
127 | return (status); | ||
128 | } | ||
129 | |||
130 | ACPI_EXPORT_SYMBOL(acpi_get_handle) | ||
131 | |||
132 | /****************************************************************************** | ||
133 | * | ||
134 | * FUNCTION: acpi_get_name | ||
135 | * | ||
136 | * PARAMETERS: Handle - Handle to be converted to a pathname | ||
137 | * name_type - Full pathname or single segment | ||
138 | * Buffer - Buffer for returned path | ||
139 | * | ||
140 | * RETURN: Pointer to a string containing the fully qualified Name. | ||
141 | * | ||
142 | * DESCRIPTION: This routine returns the fully qualified name associated with | ||
143 | * the Handle parameter. This and the acpi_pathname_to_handle are | ||
144 | * complementary functions. | ||
145 | * | ||
146 | ******************************************************************************/ | ||
147 | acpi_status | ||
148 | acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer) | ||
149 | { | ||
150 | acpi_status status; | ||
151 | struct acpi_namespace_node *node; | ||
152 | |||
153 | /* Parameter validation */ | ||
154 | |||
155 | if (name_type > ACPI_NAME_TYPE_MAX) { | ||
156 | return (AE_BAD_PARAMETER); | ||
157 | } | ||
158 | |||
159 | status = acpi_ut_validate_buffer(buffer); | ||
160 | if (ACPI_FAILURE(status)) { | ||
161 | return (status); | ||
162 | } | ||
163 | |||
164 | if (name_type == ACPI_FULL_PATHNAME) { | ||
165 | |||
166 | /* Get the full pathname (From the namespace root) */ | ||
167 | |||
168 | status = acpi_ns_handle_to_pathname(handle, buffer); | ||
169 | return (status); | ||
170 | } | ||
171 | |||
172 | /* | ||
173 | * Wants the single segment ACPI name. | ||
174 | * Validate handle and convert to a namespace Node | ||
175 | */ | ||
176 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
177 | if (ACPI_FAILURE(status)) { | ||
178 | return (status); | ||
179 | } | ||
180 | |||
181 | node = acpi_ns_map_handle_to_node(handle); | ||
182 | if (!node) { | ||
183 | status = AE_BAD_PARAMETER; | ||
184 | goto unlock_and_exit; | ||
185 | } | ||
186 | |||
187 | /* Validate/Allocate/Clear caller buffer */ | ||
188 | |||
189 | status = acpi_ut_initialize_buffer(buffer, ACPI_PATH_SEGMENT_LENGTH); | ||
190 | if (ACPI_FAILURE(status)) { | ||
191 | goto unlock_and_exit; | ||
192 | } | ||
193 | |||
194 | /* Just copy the ACPI name from the Node and zero terminate it */ | ||
195 | |||
196 | ACPI_STRNCPY(buffer->pointer, acpi_ut_get_node_name(node), | ||
197 | ACPI_NAME_SIZE); | ||
198 | ((char *)buffer->pointer)[ACPI_NAME_SIZE] = 0; | ||
199 | status = AE_OK; | ||
200 | |||
201 | unlock_and_exit: | ||
202 | |||
203 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
204 | return (status); | ||
205 | } | ||
206 | |||
207 | ACPI_EXPORT_SYMBOL(acpi_get_name) | ||
208 | |||
209 | /****************************************************************************** | ||
210 | * | ||
211 | * FUNCTION: acpi_get_object_info | ||
212 | * | ||
213 | * PARAMETERS: Handle - Object Handle | ||
214 | * Buffer - Where the info is returned | ||
215 | * | ||
216 | * RETURN: Status | ||
217 | * | ||
218 | * DESCRIPTION: Returns information about an object as gleaned from the | ||
219 | * namespace node and possibly by running several standard | ||
220 | * control methods (Such as in the case of a device.) | ||
221 | * | ||
222 | ******************************************************************************/ | ||
223 | acpi_status | ||
224 | acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) | ||
225 | { | ||
226 | acpi_status status; | ||
227 | struct acpi_namespace_node *node; | ||
228 | struct acpi_device_info *info; | ||
229 | struct acpi_device_info *return_info; | ||
230 | struct acpi_compatible_id_list *cid_list = NULL; | ||
231 | acpi_size size; | ||
232 | |||
233 | /* Parameter validation */ | ||
234 | |||
235 | if (!handle || !buffer) { | ||
236 | return (AE_BAD_PARAMETER); | ||
237 | } | ||
238 | |||
239 | status = acpi_ut_validate_buffer(buffer); | ||
240 | if (ACPI_FAILURE(status)) { | ||
241 | return (status); | ||
242 | } | ||
243 | |||
244 | info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_device_info)); | ||
245 | if (!info) { | ||
246 | return (AE_NO_MEMORY); | ||
247 | } | ||
248 | |||
249 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
250 | if (ACPI_FAILURE(status)) { | ||
251 | goto cleanup; | ||
252 | } | ||
253 | |||
254 | node = acpi_ns_map_handle_to_node(handle); | ||
255 | if (!node) { | ||
256 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
257 | status = AE_BAD_PARAMETER; | ||
258 | goto cleanup; | ||
259 | } | ||
260 | |||
261 | /* Init return structure */ | ||
262 | |||
263 | size = sizeof(struct acpi_device_info); | ||
264 | |||
265 | info->type = node->type; | ||
266 | info->name = node->name.integer; | ||
267 | info->valid = 0; | ||
268 | |||
269 | if (node->type == ACPI_TYPE_METHOD) { | ||
270 | info->param_count = node->object->method.param_count; | ||
271 | } | ||
272 | |||
273 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
274 | if (ACPI_FAILURE(status)) { | ||
275 | goto cleanup; | ||
276 | } | ||
277 | |||
278 | /* If not a device, we are all done */ | ||
279 | |||
280 | if (info->type == ACPI_TYPE_DEVICE) { | ||
281 | /* | ||
282 | * Get extra info for ACPI Devices objects only: | ||
283 | * Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods. | ||
284 | * | ||
285 | * Note: none of these methods are required, so they may or may | ||
286 | * not be present for this device. The Info->Valid bitfield is used | ||
287 | * to indicate which methods were found and ran successfully. | ||
288 | */ | ||
289 | |||
290 | /* Execute the Device._HID method */ | ||
291 | |||
292 | status = acpi_ut_execute_HID(node, &info->hardware_id); | ||
293 | if (ACPI_SUCCESS(status)) { | ||
294 | info->valid |= ACPI_VALID_HID; | ||
295 | } | ||
296 | |||
297 | /* Execute the Device._UID method */ | ||
298 | |||
299 | status = acpi_ut_execute_UID(node, &info->unique_id); | ||
300 | if (ACPI_SUCCESS(status)) { | ||
301 | info->valid |= ACPI_VALID_UID; | ||
302 | } | ||
303 | |||
304 | /* Execute the Device._CID method */ | ||
305 | |||
306 | status = acpi_ut_execute_CID(node, &cid_list); | ||
307 | if (ACPI_SUCCESS(status)) { | ||
308 | size += cid_list->size; | ||
309 | info->valid |= ACPI_VALID_CID; | ||
310 | } | ||
311 | |||
312 | /* Execute the Device._STA method */ | ||
313 | |||
314 | status = acpi_ut_execute_STA(node, &info->current_status); | ||
315 | if (ACPI_SUCCESS(status)) { | ||
316 | info->valid |= ACPI_VALID_STA; | ||
317 | } | ||
318 | |||
319 | /* Execute the Device._ADR method */ | ||
320 | |||
321 | status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node, | ||
322 | &info->address); | ||
323 | if (ACPI_SUCCESS(status)) { | ||
324 | info->valid |= ACPI_VALID_ADR; | ||
325 | } | ||
326 | |||
327 | /* Execute the Device._sx_d methods */ | ||
328 | |||
329 | status = acpi_ut_execute_sxds(node, info->highest_dstates); | ||
330 | if (ACPI_SUCCESS(status)) { | ||
331 | info->valid |= ACPI_VALID_SXDS; | ||
332 | } | ||
333 | } | ||
334 | |||
335 | /* Validate/Allocate/Clear caller buffer */ | ||
336 | |||
337 | status = acpi_ut_initialize_buffer(buffer, size); | ||
338 | if (ACPI_FAILURE(status)) { | ||
339 | goto cleanup; | ||
340 | } | ||
341 | |||
342 | /* Populate the return buffer */ | ||
343 | |||
344 | return_info = buffer->pointer; | ||
345 | ACPI_MEMCPY(return_info, info, sizeof(struct acpi_device_info)); | ||
346 | |||
347 | if (cid_list) { | ||
348 | ACPI_MEMCPY(&return_info->compatibility_id, cid_list, | ||
349 | cid_list->size); | ||
350 | } | ||
351 | |||
352 | cleanup: | ||
353 | ACPI_FREE(info); | ||
354 | if (cid_list) { | ||
355 | ACPI_FREE(cid_list); | ||
356 | } | ||
357 | return (status); | ||
358 | } | ||
359 | |||
360 | ACPI_EXPORT_SYMBOL(acpi_get_object_info) | ||
diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c deleted file mode 100644 index 80e6322d59c5..000000000000 --- a/drivers/acpi/namespace/nsxfobj.c +++ /dev/null | |||
@@ -1,287 +0,0 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: nsxfobj - Public interfaces to the ACPI subsystem | ||
4 | * ACPI Object oriented interfaces | ||
5 | * | ||
6 | ******************************************************************************/ | ||
7 | |||
8 | /* | ||
9 | * Copyright (C) 2000 - 2008, Intel Corp. | ||
10 | * All rights reserved. | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or without | ||
13 | * modification, are permitted provided that the following conditions | ||
14 | * are met: | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions, and the following disclaimer, | ||
17 | * without modification. | ||
18 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
19 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
20 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
21 | * including a substantially similar Disclaimer requirement for further | ||
22 | * binary redistribution. | ||
23 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
24 | * of any contributors may be used to endorse or promote products derived | ||
25 | * from this software without specific prior written permission. | ||
26 | * | ||
27 | * Alternatively, this software may be distributed under the terms of the | ||
28 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
29 | * Software Foundation. | ||
30 | * | ||
31 | * NO WARRANTY | ||
32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
33 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
35 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
36 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
37 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
38 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
39 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
40 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
41 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
42 | * POSSIBILITY OF SUCH DAMAGES. | ||
43 | */ | ||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/accommon.h> | ||
47 | #include <acpi/acnamesp.h> | ||
48 | |||
49 | #define _COMPONENT ACPI_NAMESPACE | ||
50 | ACPI_MODULE_NAME("nsxfobj") | ||
51 | |||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * FUNCTION: acpi_get_id | ||
55 | * | ||
56 | * PARAMETERS: Handle - Handle of object whose id is desired | ||
57 | * ret_id - Where the id will be placed | ||
58 | * | ||
59 | * RETURN: Status | ||
60 | * | ||
61 | * DESCRIPTION: This routine returns the owner id associated with a handle | ||
62 | * | ||
63 | ******************************************************************************/ | ||
64 | acpi_status acpi_get_id(acpi_handle handle, acpi_owner_id * ret_id) | ||
65 | { | ||
66 | struct acpi_namespace_node *node; | ||
67 | acpi_status status; | ||
68 | |||
69 | /* Parameter Validation */ | ||
70 | |||
71 | if (!ret_id) { | ||
72 | return (AE_BAD_PARAMETER); | ||
73 | } | ||
74 | |||
75 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
76 | if (ACPI_FAILURE(status)) { | ||
77 | return (status); | ||
78 | } | ||
79 | |||
80 | /* Convert and validate the handle */ | ||
81 | |||
82 | node = acpi_ns_map_handle_to_node(handle); | ||
83 | if (!node) { | ||
84 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
85 | return (AE_BAD_PARAMETER); | ||
86 | } | ||
87 | |||
88 | *ret_id = node->owner_id; | ||
89 | |||
90 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
91 | return (status); | ||
92 | } | ||
93 | |||
94 | ACPI_EXPORT_SYMBOL(acpi_get_id) | ||
95 | |||
96 | /******************************************************************************* | ||
97 | * | ||
98 | * FUNCTION: acpi_get_type | ||
99 | * | ||
100 | * PARAMETERS: Handle - Handle of object whose type is desired | ||
101 | * ret_type - Where the type will be placed | ||
102 | * | ||
103 | * RETURN: Status | ||
104 | * | ||
105 | * DESCRIPTION: This routine returns the type associatd with a particular handle | ||
106 | * | ||
107 | ******************************************************************************/ | ||
108 | acpi_status acpi_get_type(acpi_handle handle, acpi_object_type * ret_type) | ||
109 | { | ||
110 | struct acpi_namespace_node *node; | ||
111 | acpi_status status; | ||
112 | |||
113 | /* Parameter Validation */ | ||
114 | |||
115 | if (!ret_type) { | ||
116 | return (AE_BAD_PARAMETER); | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * Special case for the predefined Root Node | ||
121 | * (return type ANY) | ||
122 | */ | ||
123 | if (handle == ACPI_ROOT_OBJECT) { | ||
124 | *ret_type = ACPI_TYPE_ANY; | ||
125 | return (AE_OK); | ||
126 | } | ||
127 | |||
128 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
129 | if (ACPI_FAILURE(status)) { | ||
130 | return (status); | ||
131 | } | ||
132 | |||
133 | /* Convert and validate the handle */ | ||
134 | |||
135 | node = acpi_ns_map_handle_to_node(handle); | ||
136 | if (!node) { | ||
137 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
138 | return (AE_BAD_PARAMETER); | ||
139 | } | ||
140 | |||
141 | *ret_type = node->type; | ||
142 | |||
143 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
144 | return (status); | ||
145 | } | ||
146 | |||
147 | ACPI_EXPORT_SYMBOL(acpi_get_type) | ||
148 | |||
149 | /******************************************************************************* | ||
150 | * | ||
151 | * FUNCTION: acpi_get_parent | ||
152 | * | ||
153 | * PARAMETERS: Handle - Handle of object whose parent is desired | ||
154 | * ret_handle - Where the parent handle will be placed | ||
155 | * | ||
156 | * RETURN: Status | ||
157 | * | ||
158 | * DESCRIPTION: Returns a handle to the parent of the object represented by | ||
159 | * Handle. | ||
160 | * | ||
161 | ******************************************************************************/ | ||
162 | acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle) | ||
163 | { | ||
164 | struct acpi_namespace_node *node; | ||
165 | acpi_status status; | ||
166 | |||
167 | if (!ret_handle) { | ||
168 | return (AE_BAD_PARAMETER); | ||
169 | } | ||
170 | |||
171 | /* Special case for the predefined Root Node (no parent) */ | ||
172 | |||
173 | if (handle == ACPI_ROOT_OBJECT) { | ||
174 | return (AE_NULL_ENTRY); | ||
175 | } | ||
176 | |||
177 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
178 | if (ACPI_FAILURE(status)) { | ||
179 | return (status); | ||
180 | } | ||
181 | |||
182 | /* Convert and validate the handle */ | ||
183 | |||
184 | node = acpi_ns_map_handle_to_node(handle); | ||
185 | if (!node) { | ||
186 | status = AE_BAD_PARAMETER; | ||
187 | goto unlock_and_exit; | ||
188 | } | ||
189 | |||
190 | /* Get the parent entry */ | ||
191 | |||
192 | *ret_handle = | ||
193 | acpi_ns_convert_entry_to_handle(acpi_ns_get_parent_node(node)); | ||
194 | |||
195 | /* Return exception if parent is null */ | ||
196 | |||
197 | if (!acpi_ns_get_parent_node(node)) { | ||
198 | status = AE_NULL_ENTRY; | ||
199 | } | ||
200 | |||
201 | unlock_and_exit: | ||
202 | |||
203 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
204 | return (status); | ||
205 | } | ||
206 | |||
207 | ACPI_EXPORT_SYMBOL(acpi_get_parent) | ||
208 | |||
209 | /******************************************************************************* | ||
210 | * | ||
211 | * FUNCTION: acpi_get_next_object | ||
212 | * | ||
213 | * PARAMETERS: Type - Type of object to be searched for | ||
214 | * Parent - Parent object whose children we are getting | ||
215 | * last_child - Previous child that was found. | ||
216 | * The NEXT child will be returned | ||
217 | * ret_handle - Where handle to the next object is placed | ||
218 | * | ||
219 | * RETURN: Status | ||
220 | * | ||
221 | * DESCRIPTION: Return the next peer object within the namespace. If Handle is | ||
222 | * valid, Scope is ignored. Otherwise, the first object within | ||
223 | * Scope is returned. | ||
224 | * | ||
225 | ******************************************************************************/ | ||
226 | acpi_status | ||
227 | acpi_get_next_object(acpi_object_type type, | ||
228 | acpi_handle parent, | ||
229 | acpi_handle child, acpi_handle * ret_handle) | ||
230 | { | ||
231 | acpi_status status; | ||
232 | struct acpi_namespace_node *node; | ||
233 | struct acpi_namespace_node *parent_node = NULL; | ||
234 | struct acpi_namespace_node *child_node = NULL; | ||
235 | |||
236 | /* Parameter validation */ | ||
237 | |||
238 | if (type > ACPI_TYPE_EXTERNAL_MAX) { | ||
239 | return (AE_BAD_PARAMETER); | ||
240 | } | ||
241 | |||
242 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
243 | if (ACPI_FAILURE(status)) { | ||
244 | return (status); | ||
245 | } | ||
246 | |||
247 | /* If null handle, use the parent */ | ||
248 | |||
249 | if (!child) { | ||
250 | |||
251 | /* Start search at the beginning of the specified scope */ | ||
252 | |||
253 | parent_node = acpi_ns_map_handle_to_node(parent); | ||
254 | if (!parent_node) { | ||
255 | status = AE_BAD_PARAMETER; | ||
256 | goto unlock_and_exit; | ||
257 | } | ||
258 | } else { | ||
259 | /* Non-null handle, ignore the parent */ | ||
260 | /* Convert and validate the handle */ | ||
261 | |||
262 | child_node = acpi_ns_map_handle_to_node(child); | ||
263 | if (!child_node) { | ||
264 | status = AE_BAD_PARAMETER; | ||
265 | goto unlock_and_exit; | ||
266 | } | ||
267 | } | ||
268 | |||
269 | /* Internal function does the real work */ | ||
270 | |||
271 | node = acpi_ns_get_next_node(type, parent_node, child_node); | ||
272 | if (!node) { | ||
273 | status = AE_NOT_FOUND; | ||
274 | goto unlock_and_exit; | ||
275 | } | ||
276 | |||
277 | if (ret_handle) { | ||
278 | *ret_handle = acpi_ns_convert_entry_to_handle(node); | ||
279 | } | ||
280 | |||
281 | unlock_and_exit: | ||
282 | |||
283 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
284 | return (status); | ||
285 | } | ||
286 | |||
287 | ACPI_EXPORT_SYMBOL(acpi_get_next_object) | ||