aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/namespace
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2006-05-26 16:36:00 -0400
committerLen Brown <len.brown@intel.com>2006-06-14 02:44:35 -0400
commit4119532c95547821dbe72d6916dfa1b2148475b3 (patch)
tree564eb8f69924fb7dc72e93526faf1547acac7d30 /drivers/acpi/namespace
parentb8d35192c55fb055792ff0641408eaaec7c88988 (diff)
ACPI: ACPICA 20060526
Restructured, flattened, and simplified the internal interfaces for namespace object evaluation - resulting in smaller code, less CPU stack use, and fewer interfaces. (With assistance from Mikhail Kouzmich) Fixed a problem with the CopyObject operator where the first parameter was not typed correctly for the parser, interpreter, compiler, and disassembler. Caused various errors and unexpected behavior. Fixed a problem where a ShiftLeft or ShiftRight of more than 64 bits produced incorrect results with some C compilers. Since the behavior of C compilers when the shift value is larger than the datatype width is apparently not well defined, the interpreter now detects this condition and simply returns zero as expected in all such cases. (BZ 395) Fixed problem reports (Valery Podrezov) integrated: - Update String-to-Integer conversion to match ACPI 3.0A spec http://bugzilla.kernel.org/show_bug.cgi?id=5329 Allow interpreter to handle nested method declarations http://bugzilla.kernel.org/show_bug.cgi?id=5361 Fixed problem reports (Fiodor Suietov) integrated: - acpi_terminate() doesn't free debug memory allocation list objects (BZ 355) - After Core Subsystem shutdown, acpi_subsystem_status() returns AE_OK (BZ 356) - acpi_os_unmap_memory() for RSDP can be invoked inconsistently (BZ 357) - Resource Manager should return AE_TYPE for non-device objects (BZ 358) - Incomplete cleanup branch in AcpiNsEvaluateRelative (BZ 359) - Use acpi_os_free() instead of ACPI_FREE in acpi_rs_set_srs_method_data (BZ 360) - Incomplete cleanup branch in acpi_ps_parse_aml (BZ 361) - Incomplete cleanup branch in acpi_ds_delete_walk_state (BZ 362) - acpi_get_table_header returns AE_NO_ACPI_TABLES until DSDT is loaded (BZ 365) - Status of the Global Initialization Handler call not used (BZ 366) - Incorrect object parameter to Global Initialization Handler (BZ 367) Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/namespace')
-rw-r--r--drivers/acpi/namespace/nsaccess.c6
-rw-r--r--drivers/acpi/namespace/nseval.c485
-rw-r--r--drivers/acpi/namespace/nsinit.c57
-rw-r--r--drivers/acpi/namespace/nssearch.c82
-rw-r--r--drivers/acpi/namespace/nsutils.c63
-rw-r--r--drivers/acpi/namespace/nsxfeval.c119
-rw-r--r--drivers/acpi/namespace/nsxfname.c5
7 files changed, 293 insertions, 524 deletions
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c
index ba8ad569188f..48fadade52e2 100644
--- a/drivers/acpi/namespace/nsaccess.c
+++ b/drivers/acpi/namespace/nsaccess.c
@@ -259,10 +259,8 @@ acpi_status acpi_ns_root_initialize(void)
259 /* Save a handle to "_GPE", it is always present */ 259 /* Save a handle to "_GPE", it is always present */
260 260
261 if (ACPI_SUCCESS(status)) { 261 if (ACPI_SUCCESS(status)) {
262 status = 262 status = acpi_ns_get_node(NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH,
263 acpi_ns_get_node_by_path("\\_GPE", NULL, 263 &acpi_gbl_fadt_gpe_device);
264 ACPI_NS_NO_UPSEARCH,
265 &acpi_gbl_fadt_gpe_device);
266 } 264 }
267 265
268 return_ACPI_STATUS(status); 266 return_ACPI_STATUS(status);
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c
index 4b054062b46a..4b0a4a8c9843 100644
--- a/drivers/acpi/namespace/nseval.c
+++ b/drivers/acpi/namespace/nseval.c
@@ -1,7 +1,6 @@
1/******************************************************************************* 1/*******************************************************************************
2 * 2 *
3 * Module Name: nseval - Object evaluation interfaces -- includes control 3 * Module Name: nseval - Object evaluation, includes control method execution
4 * method lookup and execution.
5 * 4 *
6 ******************************************************************************/ 5 ******************************************************************************/
7 6
@@ -50,196 +49,14 @@
50#define _COMPONENT ACPI_NAMESPACE 49#define _COMPONENT ACPI_NAMESPACE
51ACPI_MODULE_NAME("nseval") 50ACPI_MODULE_NAME("nseval")
52 51
53/* Local prototypes */
54static acpi_status
55acpi_ns_execute_control_method(struct acpi_parameter_info *info);
56
57static acpi_status acpi_ns_get_object_value(struct acpi_parameter_info *info);
58
59/*******************************************************************************
60 *
61 * FUNCTION: acpi_ns_evaluate_relative
62 *
63 * PARAMETERS: Pathname - Name of method to execute, If NULL, the
64 * handle is the object to execute
65 * Info - Method info block, contains:
66 * return_object - Where to put method's return value (if
67 * any). If NULL, no value is returned.
68 * Params - List of parameters to pass to the method,
69 * terminated by NULL. Params itself may be
70 * NULL if no parameters are being passed.
71 *
72 * RETURN: Status
73 *
74 * DESCRIPTION: Evaluate the object or find and execute the requested method
75 *
76 * MUTEX: Locks Namespace
77 *
78 ******************************************************************************/
79
80acpi_status
81acpi_ns_evaluate_relative(char *pathname, struct acpi_parameter_info *info)
82{
83 acpi_status status;
84 struct acpi_namespace_node *node = NULL;
85 union acpi_generic_state *scope_info;
86 char *internal_path = NULL;
87
88 ACPI_FUNCTION_TRACE(ns_evaluate_relative);
89
90 /*
91 * Must have a valid object handle
92 */
93 if (!info || !info->node) {
94 return_ACPI_STATUS(AE_BAD_PARAMETER);
95 }
96
97 /* Build an internal name string for the method */
98
99 status = acpi_ns_internalize_name(pathname, &internal_path);
100 if (ACPI_FAILURE(status)) {
101 return_ACPI_STATUS(status);
102 }
103
104 scope_info = acpi_ut_create_generic_state();
105 if (!scope_info) {
106 goto cleanup1;
107 }
108
109 /* Get the prefix handle and Node */
110
111 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
112 if (ACPI_FAILURE(status)) {
113 goto cleanup;
114 }
115
116 info->node = acpi_ns_map_handle_to_node(info->node);
117 if (!info->node) {
118 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
119 status = AE_BAD_PARAMETER;
120 goto cleanup;
121 }
122
123 /* Lookup the name in the namespace */
124
125 scope_info->scope.node = info->node;
126 status = acpi_ns_lookup(scope_info, internal_path, ACPI_TYPE_ANY,
127 ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
128 &node);
129
130 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
131
132 if (ACPI_FAILURE(status)) {
133 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Object [%s] not found [%s]\n",
134 pathname, acpi_format_exception(status)));
135 goto cleanup;
136 }
137
138 /*
139 * Now that we have a handle to the object, we can attempt to evaluate it.
140 */
141 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n",
142 pathname, node, acpi_ns_get_attached_object(node)));
143
144 info->node = node;
145 status = acpi_ns_evaluate_by_handle(info);
146
147 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
148 "*** Completed eval of object %s ***\n", pathname));
149
150 cleanup:
151 acpi_ut_delete_generic_state(scope_info);
152
153 cleanup1:
154 ACPI_FREE(internal_path);
155 return_ACPI_STATUS(status);
156}
157
158/*******************************************************************************
159 *
160 * FUNCTION: acpi_ns_evaluate_by_name
161 *
162 * PARAMETERS: Pathname - Fully qualified pathname to the object
163 * Info - Method info block, contains:
164 * return_object - Where to put method's return value (if
165 * any). If NULL, no value is returned.
166 * Params - List of parameters to pass to the method,
167 * terminated by NULL. Params itself may be
168 * NULL if no parameters are being passed.
169 *
170 * RETURN: Status
171 *
172 * DESCRIPTION: Evaluate the object or rind and execute the requested method
173 * passing the given parameters
174 *
175 * MUTEX: Locks Namespace
176 *
177 ******************************************************************************/
178
179acpi_status
180acpi_ns_evaluate_by_name(char *pathname, struct acpi_parameter_info *info)
181{
182 acpi_status status;
183 char *internal_path = NULL;
184
185 ACPI_FUNCTION_TRACE(ns_evaluate_by_name);
186
187 /* Build an internal name string for the method */
188
189 status = acpi_ns_internalize_name(pathname, &internal_path);
190 if (ACPI_FAILURE(status)) {
191 return_ACPI_STATUS(status);
192 }
193
194 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
195 if (ACPI_FAILURE(status)) {
196 goto cleanup;
197 }
198
199 /* Lookup the name in the namespace */
200
201 status = acpi_ns_lookup(NULL, internal_path, ACPI_TYPE_ANY,
202 ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
203 &info->node);
204
205 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
206
207 if (ACPI_FAILURE(status)) {
208 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
209 "Object at [%s] was not found, status=%.4X\n",
210 pathname, status));
211 goto cleanup;
212 }
213
214 /*
215 * Now that we have a handle to the object, we can attempt to evaluate it.
216 */
217 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n",
218 pathname, info->node,
219 acpi_ns_get_attached_object(info->node)));
220
221 status = acpi_ns_evaluate_by_handle(info);
222
223 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
224 "*** Completed eval of object %s ***\n", pathname));
225
226 cleanup:
227
228 /* Cleanup */
229
230 if (internal_path) {
231 ACPI_FREE(internal_path);
232 }
233
234 return_ACPI_STATUS(status);
235}
236
237/******************************************************************************* 52/*******************************************************************************
238 * 53 *
239 * FUNCTION: acpi_ns_evaluate_by_handle 54 * FUNCTION: acpi_ns_evaluate
240 * 55 *
241 * PARAMETERS: Info - Method info block, contains: 56 * PARAMETERS: Info - Evaluation info block, contains:
242 * Node - Method/Object Node to execute 57 * prefix_node - Prefix or Method/Object Node to execute
58 * Pathname - Name of method to execute, If NULL, the
59 * Node is the object to execute
243 * Parameters - List of parameters to pass to the method, 60 * Parameters - List of parameters to pass to the method,
244 * terminated by NULL. Params itself may be 61 * terminated by NULL. Params itself may be
245 * NULL if no parameters are being passed. 62 * NULL if no parameters are being passed.
@@ -248,29 +65,21 @@ acpi_ns_evaluate_by_name(char *pathname, struct acpi_parameter_info *info)
248 * parameter_type - Type of Parameter list 65 * parameter_type - Type of Parameter list
249 * return_object - Where to put method's return value (if 66 * return_object - Where to put method's return value (if
250 * any). If NULL, no value is returned. 67 * any). If NULL, no value is returned.
68 * Flags - ACPI_IGNORE_RETURN_VALUE to delete return
251 * 69 *
252 * RETURN: Status 70 * RETURN: Status
253 * 71 *
254 * DESCRIPTION: Evaluate object or execute the requested method passing the 72 * DESCRIPTION: Execute a control method or return the current value of an
255 * given parameters 73 * ACPI namespace object.
256 * 74 *
257 * MUTEX: Locks Namespace 75 * MUTEX: Locks interpreter
258 * 76 *
259 ******************************************************************************/ 77 ******************************************************************************/
260 78acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info)
261acpi_status acpi_ns_evaluate_by_handle(struct acpi_parameter_info *info)
262{ 79{
263 acpi_status status; 80 acpi_status status;
264 81
265 ACPI_FUNCTION_TRACE(ns_evaluate_by_handle); 82 ACPI_FUNCTION_TRACE(ns_evaluate);
266
267 /* Check if namespace has been initialized */
268
269 if (!acpi_gbl_root_node) {
270 return_ACPI_STATUS(AE_NO_NAMESPACE);
271 }
272
273 /* Parameter Validation */
274 83
275 if (!info) { 84 if (!info) {
276 return_ACPI_STATUS(AE_BAD_PARAMETER); 85 return_ACPI_STATUS(AE_BAD_PARAMETER);
@@ -280,203 +89,120 @@ acpi_status acpi_ns_evaluate_by_handle(struct acpi_parameter_info *info)
280 89
281 info->return_object = NULL; 90 info->return_object = NULL;
282 91
283 /* Get the prefix handle and Node */ 92 /*
284 93 * Get the actual namespace node for the target object. Handles these cases:
285 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 94 *
95 * 1) Null node, Pathname (absolute path)
96 * 2) Node, Pathname (path relative to Node)
97 * 3) Node, Null Pathname
98 */
99 status = acpi_ns_get_node(info->prefix_node, info->pathname,
100 ACPI_NS_NO_UPSEARCH, &info->resolved_node);
286 if (ACPI_FAILURE(status)) { 101 if (ACPI_FAILURE(status)) {
287 return_ACPI_STATUS(status); 102 return_ACPI_STATUS(status);
288 } 103 }
289 104
290 info->node = acpi_ns_map_handle_to_node(info->node);
291 if (!info->node) {
292 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
293 return_ACPI_STATUS(AE_BAD_PARAMETER);
294 }
295
296 /* 105 /*
297 * For a method alias, we must grab the actual method node so that proper 106 * For a method alias, we must grab the actual method node so that proper
298 * scoping context will be established before execution. 107 * scoping context will be established before execution.
299 */ 108 */
300 if (acpi_ns_get_type(info->node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) { 109 if (acpi_ns_get_type(info->resolved_node) ==
301 info->node = 110 ACPI_TYPE_LOCAL_METHOD_ALIAS) {
111 info->resolved_node =
302 ACPI_CAST_PTR(struct acpi_namespace_node, 112 ACPI_CAST_PTR(struct acpi_namespace_node,
303 info->node->object); 113 info->resolved_node->object);
304 } 114 }
305 115
116 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n", info->pathname,
117 info->resolved_node,
118 acpi_ns_get_attached_object(info->resolved_node)));
119
306 /* 120 /*
307 * Two major cases here: 121 * Two major cases here:
308 * 1) The object is an actual control method -- execute it.
309 * 2) The object is not a method -- just return it's current value
310 * 122 *
311 * In both cases, the namespace is unlocked by the acpi_ns* procedure 123 * 1) The object is a control method -- execute it
124 * 2) The object is not a method -- just return it's current value
312 */ 125 */
313 if (acpi_ns_get_type(info->node) == ACPI_TYPE_METHOD) { 126 if (acpi_ns_get_type(info->resolved_node) == ACPI_TYPE_METHOD) {
314 /* 127 /*
315 * Case 1) We have an actual control method to execute 128 * 1) Object is a control method - execute it
316 */ 129 */
317 status = acpi_ns_execute_control_method(info);
318 } else {
319 /*
320 * Case 2) Object is NOT a method, just return its current value
321 */
322 status = acpi_ns_get_object_value(info);
323 }
324
325 /*
326 * Check if there is a return value on the stack that must be dealt with
327 */
328 if (status == AE_CTRL_RETURN_VALUE) {
329
330 /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */
331
332 status = AE_OK;
333 }
334
335 /*
336 * Namespace was unlocked by the handling acpi_ns* function, so we
337 * just return
338 */
339 return_ACPI_STATUS(status);
340}
341
342/*******************************************************************************
343 *
344 * FUNCTION: acpi_ns_execute_control_method
345 *
346 * PARAMETERS: Info - Method info block, contains:
347 * Node - Method Node to execute
348 * obj_desc - Method object
349 * Parameters - List of parameters to pass to the method,
350 * terminated by NULL. Params itself may be
351 * NULL if no parameters are being passed.
352 * return_object - Where to put method's return value (if
353 * any). If NULL, no value is returned.
354 * parameter_type - Type of Parameter list
355 * return_object - Where to put method's return value (if
356 * any). If NULL, no value is returned.
357 *
358 * RETURN: Status
359 *
360 * DESCRIPTION: Execute the requested method passing the given parameters
361 *
362 * MUTEX: Assumes namespace is locked
363 *
364 ******************************************************************************/
365
366static acpi_status
367acpi_ns_execute_control_method(struct acpi_parameter_info *info)
368{
369 acpi_status status;
370
371 ACPI_FUNCTION_TRACE(ns_execute_control_method);
372
373 /* Verify that there is a method associated with this object */
374
375 info->obj_desc = acpi_ns_get_attached_object(info->node);
376 if (!info->obj_desc) {
377 ACPI_ERROR((AE_INFO, "No attached method object"));
378 130
379 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 131 /* Verify that there is a method object associated with this node */
380 return_ACPI_STATUS(AE_NULL_OBJECT);
381 }
382
383 ACPI_DUMP_PATHNAME(info->node, "Execute Method:",
384 ACPI_LV_INFO, _COMPONENT);
385
386 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Method at AML address %p Length %X\n",
387 info->obj_desc->method.aml_start + 1,
388 info->obj_desc->method.aml_length - 1));
389
390 /*
391 * Unlock the namespace before execution. This allows namespace access
392 * via the external Acpi* interfaces while a method is being executed.
393 * However, any namespace deletion must acquire both the namespace and
394 * interpreter locks to ensure that no thread is using the portion of the
395 * namespace that is being deleted.
396 */
397 status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
398 if (ACPI_FAILURE(status)) {
399 return_ACPI_STATUS(status);
400 }
401 132
402 /* 133 info->obj_desc =
403 * Execute the method via the interpreter. The interpreter is locked 134 acpi_ns_get_attached_object(info->resolved_node);
404 * here before calling into the AML parser 135 if (!info->obj_desc) {
405 */ 136 ACPI_ERROR((AE_INFO,
406 status = acpi_ex_enter_interpreter(); 137 "Control method has no attached sub-object"));
407 if (ACPI_FAILURE(status)) { 138 return_ACPI_STATUS(AE_NULL_OBJECT);
408 return_ACPI_STATUS(status); 139 }
409 }
410 140
411 status = acpi_ps_execute_method(info); 141 ACPI_DUMP_PATHNAME(info->resolved_node, "Execute Method:",
412 acpi_ex_exit_interpreter(); 142 ACPI_LV_INFO, _COMPONENT);
413 143
414 return_ACPI_STATUS(status); 144 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
415} 145 "Method at AML address %p Length %X\n",
146 info->obj_desc->method.aml_start + 1,
147 info->obj_desc->method.aml_length - 1));
416 148
417/******************************************************************************* 149 /*
418 * 150 * Any namespace deletion must acquire both the namespace and
419 * FUNCTION: acpi_ns_get_object_value 151 * interpreter locks to ensure that no thread is using the portion of
420 * 152 * the namespace that is being deleted.
421 * PARAMETERS: Info - Method info block, contains: 153 *
422 * Node - Object's NS node 154 * Execute the method via the interpreter. The interpreter is locked
423 * return_object - Where to put object value (if 155 * here before calling into the AML parser
424 * any). If NULL, no value is returned. 156 */
425 * 157 status = acpi_ex_enter_interpreter();
426 * RETURN: Status 158 if (ACPI_FAILURE(status)) {
427 * 159 return_ACPI_STATUS(status);
428 * DESCRIPTION: Return the current value of the object 160 }
429 *
430 * MUTEX: Assumes namespace is locked, leaves namespace unlocked
431 *
432 ******************************************************************************/
433 161
434static acpi_status acpi_ns_get_object_value(struct acpi_parameter_info *info) 162 status = acpi_ps_execute_method(info);
435{ 163 acpi_ex_exit_interpreter();
436 acpi_status status = AE_OK; 164 } else {
437 struct acpi_namespace_node *resolved_node = info->node; 165 /*
166 * 2) Object is not a method, return its current value
167 */
438 168
439 ACPI_FUNCTION_TRACE(ns_get_object_value); 169 /*
170 * Objects require additional resolution steps (e.g., the Node may be
171 * a field that must be read, etc.) -- we can't just grab the object
172 * out of the node.
173 *
174 * Use resolve_node_to_value() to get the associated value.
175 *
176 * NOTE: we can get away with passing in NULL for a walk state because
177 * resolved_node is guaranteed to not be a reference to either a method
178 * local or a method argument (because this interface is never called
179 * from a running method.)
180 *
181 * Even though we do not directly invoke the interpreter for object
182 * resolution, we must lock it because we could access an opregion.
183 * The opregion access code assumes that the interpreter is locked.
184 */
185 status = acpi_ex_enter_interpreter();
186 if (ACPI_FAILURE(status)) {
187 return_ACPI_STATUS(status);
188 }
440 189
441 /* 190 /* Function has a strange interface */
442 * Objects require additional resolution steps (e.g., the Node may be a
443 * field that must be read, etc.) -- we can't just grab the object out of
444 * the node.
445 */
446 191
447 /* 192 status =
448 * Use resolve_node_to_value() to get the associated value. This call always 193 acpi_ex_resolve_node_to_value(&info->resolved_node, NULL);
449 * deletes obj_desc (allocated above). 194 acpi_ex_exit_interpreter();
450 *
451 * NOTE: we can get away with passing in NULL for a walk state because
452 * obj_desc is guaranteed to not be a reference to either a method local or
453 * a method argument (because this interface can only be called from the
454 * acpi_evaluate external interface, never called from a running method.)
455 *
456 * Even though we do not directly invoke the interpreter for this, we must
457 * enter it because we could access an opregion. The opregion access code
458 * assumes that the interpreter is locked.
459 *
460 * We must release the namespace lock before entering the intepreter.
461 */
462 status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
463 if (ACPI_FAILURE(status)) {
464 return_ACPI_STATUS(status);
465 }
466 195
467 status = acpi_ex_enter_interpreter();
468 if (ACPI_SUCCESS(status)) {
469 status = acpi_ex_resolve_node_to_value(&resolved_node, NULL);
470 /* 196 /*
471 * If acpi_ex_resolve_node_to_value() succeeded, the return value was placed 197 * If acpi_ex_resolve_node_to_value() succeeded, the return value was placed
472 * in resolved_node. 198 * in resolved_node.
473 */ 199 */
474 acpi_ex_exit_interpreter();
475
476 if (ACPI_SUCCESS(status)) { 200 if (ACPI_SUCCESS(status)) {
477 status = AE_CTRL_RETURN_VALUE; 201 status = AE_CTRL_RETURN_VALUE;
478 info->return_object = ACPI_CAST_PTR 202 info->return_object =
479 (union acpi_operand_object, resolved_node); 203 ACPI_CAST_PTR(union acpi_operand_object,
204 info->resolved_node);
205
480 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, 206 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
481 "Returning object %p [%s]\n", 207 "Returning object %p [%s]\n",
482 info->return_object, 208 info->return_object,
@@ -485,7 +211,30 @@ static acpi_status acpi_ns_get_object_value(struct acpi_parameter_info *info)
485 } 211 }
486 } 212 }
487 213
488 /* Namespace is unlocked */ 214 /*
215 * Check if there is a return value that must be dealt with
216 */
217 if (status == AE_CTRL_RETURN_VALUE) {
218
219 /* If caller does not want the return value, delete it */
489 220
221 if (info->flags & ACPI_IGNORE_RETURN_VALUE) {
222 acpi_ut_remove_reference(info->return_object);
223 info->return_object = NULL;
224 }
225
226 /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */
227
228 status = AE_OK;
229 }
230
231 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
232 "*** Completed evaluation of object %s ***\n",
233 info->pathname));
234
235 /*
236 * Namespace was unlocked by the handling acpi_ns* function, so we
237 * just return
238 */
490 return_ACPI_STATUS(status); 239 return_ACPI_STATUS(status);
491} 240}
diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c
index bf1d8dbc0b86..1c9ca6e05314 100644
--- a/drivers/acpi/namespace/nsinit.c
+++ b/drivers/acpi/namespace/nsinit.c
@@ -154,7 +154,16 @@ acpi_status acpi_ns_initialize_devices(void)
154 ACPI_UINT32_MAX, FALSE, 154 ACPI_UINT32_MAX, FALSE,
155 acpi_ns_find_ini_methods, &info, NULL); 155 acpi_ns_find_ini_methods, &info, NULL);
156 if (ACPI_FAILURE(status)) { 156 if (ACPI_FAILURE(status)) {
157 ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); 157 goto error_exit;
158 }
159
160 /* Allocate the evaluation information block */
161
162 info.evaluate_info =
163 ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
164 if (!info.evaluate_info) {
165 status = AE_NO_MEMORY;
166 goto error_exit;
158 } 167 }
159 168
160 /* Walk namespace to execute all _INIs on present devices */ 169 /* Walk namespace to execute all _INIs on present devices */
@@ -162,8 +171,10 @@ acpi_status acpi_ns_initialize_devices(void)
162 status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 171 status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
163 ACPI_UINT32_MAX, FALSE, 172 ACPI_UINT32_MAX, FALSE,
164 acpi_ns_init_one_device, &info, NULL); 173 acpi_ns_init_one_device, &info, NULL);
174
175 ACPI_FREE(info.evaluate_info);
165 if (ACPI_FAILURE(status)) { 176 if (ACPI_FAILURE(status)) {
166 ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); 177 goto error_exit;
167 } 178 }
168 179
169 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, 180 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
@@ -171,6 +182,10 @@ acpi_status acpi_ns_initialize_devices(void)
171 info.num_INI, info.num_STA, info.device_count)); 182 info.num_INI, info.num_STA, info.device_count));
172 183
173 return_ACPI_STATUS(status); 184 return_ACPI_STATUS(status);
185
186 error_exit:
187 ACPI_EXCEPTION((AE_INFO, status, "During device initialization"));
188 return_ACPI_STATUS(status);
174} 189}
175 190
176/******************************************************************************* 191/*******************************************************************************
@@ -398,9 +413,9 @@ static acpi_status
398acpi_ns_init_one_device(acpi_handle obj_handle, 413acpi_ns_init_one_device(acpi_handle obj_handle,
399 u32 nesting_level, void *context, void **return_value) 414 u32 nesting_level, void *context, void **return_value)
400{ 415{
401 struct acpi_device_walk_info *info = 416 struct acpi_device_walk_info *walk_info =
402 ACPI_CAST_PTR(struct acpi_device_walk_info, context); 417 ACPI_CAST_PTR(struct acpi_device_walk_info, context);
403 struct acpi_parameter_info pinfo; 418 struct acpi_evaluate_info *info = walk_info->evaluate_info;
404 u32 flags; 419 u32 flags;
405 acpi_status status; 420 acpi_status status;
406 struct acpi_namespace_node *device_node; 421 struct acpi_namespace_node *device_node;
@@ -460,7 +475,7 @@ acpi_ns_init_one_device(acpi_handle obj_handle,
460 * other words, the device is present, ..., and functioning)" 475 * other words, the device is present, ..., and functioning)"
461 */ 476 */
462 if (flags != ACPI_UINT32_MAX) { 477 if (flags != ACPI_UINT32_MAX) {
463 info->num_STA++; 478 walk_info->num_STA++;
464 } 479 }
465 480
466 /* 481 /*
@@ -516,20 +531,16 @@ acpi_ns_init_one_device(acpi_handle obj_handle,
516 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname 531 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
517 (ACPI_TYPE_METHOD, device_node, METHOD_NAME__INI)); 532 (ACPI_TYPE_METHOD, device_node, METHOD_NAME__INI));
518 533
519 pinfo.node = device_node; 534 info->prefix_node = device_node;
520 pinfo.parameters = NULL; 535 info->pathname = METHOD_NAME__INI;
521 pinfo.parameter_type = ACPI_PARAM_ARGS; 536 info->parameters = NULL;
537 info->parameter_type = ACPI_PARAM_ARGS;
538 info->flags = ACPI_IGNORE_RETURN_VALUE;
522 539
523 status = acpi_ns_evaluate_relative(METHOD_NAME__INI, &pinfo); 540 status = acpi_ns_evaluate(info);
524 if (ACPI_SUCCESS(status)) { 541 if (ACPI_SUCCESS(status)) {
542 walk_info->num_INI++;
525 543
526 /* Delete any return object (especially if implicit_return is enabled) */
527
528 if (pinfo.return_object) {
529 acpi_ut_remove_reference(pinfo.return_object);
530 }
531
532 info->num_INI++;
533 if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && 544 if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) &&
534 (!(acpi_dbg_level & ACPI_LV_INFO))) { 545 (!(acpi_dbg_level & ACPI_LV_INFO))) {
535 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, ".")); 546 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "."));
@@ -540,20 +551,24 @@ acpi_ns_init_one_device(acpi_handle obj_handle,
540 551
541 /* Ignore error and move on to next device */ 552 /* Ignore error and move on to next device */
542 553
543 char *scope_name = acpi_ns_get_external_pathname(pinfo.node); 554 char *scope_name =
555 acpi_ns_get_external_pathname(info->resolved_node);
544 556
545 ACPI_EXCEPTION((AE_INFO, status, "during %s._INI execution", 557 ACPI_EXCEPTION((AE_INFO, status, "during %s._INI execution",
546 scope_name)); 558 scope_name));
547 ACPI_FREE(scope_name); 559 ACPI_FREE(scope_name);
560 status = AE_OK;
548 } 561 }
549#endif 562#endif
550 563
551 /* If an external initialization handler is present, call it */ 564 /*
552 565 * The _INI method has been run if present; call the Global Initialization
566 * Handler for this device.
567 */
553 if (acpi_gbl_init_handler) { 568 if (acpi_gbl_init_handler) {
554 status = 569 status =
555 acpi_gbl_init_handler(pinfo.node, ACPI_INIT_DEVICE_INI); 570 acpi_gbl_init_handler(device_node, ACPI_INIT_DEVICE_INI);
556 } 571 }
557 572
558 return_ACPI_STATUS(AE_OK); 573 return_ACPI_STATUS(status);
559} 574}
diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c
index d2473476afa5..500e2bbcfaf7 100644
--- a/drivers/acpi/namespace/nssearch.c
+++ b/drivers/acpi/namespace/nssearch.c
@@ -56,16 +56,16 @@ acpi_ns_search_parent_tree(u32 target_name,
56 56
57/******************************************************************************* 57/*******************************************************************************
58 * 58 *
59 * FUNCTION: acpi_ns_search_node 59 * FUNCTION: acpi_ns_search_one_scope
60 * 60 *
61 * PARAMETERS: target_name - Ascii ACPI name to search for 61 * PARAMETERS: target_name - Ascii ACPI name to search for
62 * Node - Starting node where search will begin 62 * parent_node - Starting node where search will begin
63 * Type - Object type to match 63 * Type - Object type to match
64 * return_node - Where the matched Named obj is returned 64 * return_node - Where the matched Named obj is returned
65 * 65 *
66 * RETURN: Status 66 * RETURN: Status
67 * 67 *
68 * DESCRIPTION: Search a single level of the namespace. Performs a 68 * DESCRIPTION: Search a single level of the namespace. Performs a
69 * simple search of the specified level, and does not add 69 * simple search of the specified level, and does not add
70 * entries or search parents. 70 * entries or search parents.
71 * 71 *
@@ -75,32 +75,37 @@ acpi_ns_search_parent_tree(u32 target_name,
75 * 75 *
76 * All namespace searching is linear in this implementation, but 76 * All namespace searching is linear in this implementation, but
77 * could be easily modified to support any improved search 77 * could be easily modified to support any improved search
78 * algorithm. However, the linear search was chosen for simplicity 78 * algorithm. However, the linear search was chosen for simplicity
79 * and because the trees are small and the other interpreter 79 * and because the trees are small and the other interpreter
80 * execution overhead is relatively high. 80 * execution overhead is relatively high.
81 * 81 *
82 * Note: CPU execution analysis has shown that the AML interpreter spends
83 * a very small percentage of its time searching the namespace. Therefore,
84 * the linear search seems to be sufficient, as there would seem to be
85 * little value in improving the search.
86 *
82 ******************************************************************************/ 87 ******************************************************************************/
83 88
84acpi_status 89acpi_status
85acpi_ns_search_node(u32 target_name, 90acpi_ns_search_one_scope(u32 target_name,
86 struct acpi_namespace_node *node, 91 struct acpi_namespace_node *parent_node,
87 acpi_object_type type, 92 acpi_object_type type,
88 struct acpi_namespace_node **return_node) 93 struct acpi_namespace_node **return_node)
89{ 94{
90 struct acpi_namespace_node *next_node; 95 struct acpi_namespace_node *node;
91 96
92 ACPI_FUNCTION_TRACE(ns_search_node); 97 ACPI_FUNCTION_TRACE(ns_search_one_scope);
93 98
94#ifdef ACPI_DEBUG_OUTPUT 99#ifdef ACPI_DEBUG_OUTPUT
95 if (ACPI_LV_NAMES & acpi_dbg_level) { 100 if (ACPI_LV_NAMES & acpi_dbg_level) {
96 char *scope_name; 101 char *scope_name;
97 102
98 scope_name = acpi_ns_get_external_pathname(node); 103 scope_name = acpi_ns_get_external_pathname(parent_node);
99 if (scope_name) { 104 if (scope_name) {
100 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, 105 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
101 "Searching %s (%p) For [%4.4s] (%s)\n", 106 "Searching %s (%p) For [%4.4s] (%s)\n",
102 scope_name, node, ACPI_CAST_PTR(char, 107 scope_name, parent_node,
103 &target_name), 108 ACPI_CAST_PTR(char, &target_name),
104 acpi_ut_get_type_name(type))); 109 acpi_ut_get_type_name(type)));
105 110
106 ACPI_FREE(scope_name); 111 ACPI_FREE(scope_name);
@@ -112,20 +117,20 @@ acpi_ns_search_node(u32 target_name,
112 * Search for name at this namespace level, which is to say that we 117 * Search for name at this namespace level, which is to say that we
113 * must search for the name among the children of this object 118 * must search for the name among the children of this object
114 */ 119 */
115 next_node = node->child; 120 node = parent_node->child;
116 while (next_node) { 121 while (node) {
117 122
118 /* Check for match against the name */ 123 /* Check for match against the name */
119 124
120 if (next_node->name.integer == target_name) { 125 if (node->name.integer == target_name) {
121 126
122 /* Resolve a control method alias if any */ 127 /* Resolve a control method alias if any */
123 128
124 if (acpi_ns_get_type(next_node) == 129 if (acpi_ns_get_type(node) ==
125 ACPI_TYPE_LOCAL_METHOD_ALIAS) { 130 ACPI_TYPE_LOCAL_METHOD_ALIAS) {
126 next_node = 131 node =
127 ACPI_CAST_PTR(struct acpi_namespace_node, 132 ACPI_CAST_PTR(struct acpi_namespace_node,
128 next_node->object); 133 node->object);
129 } 134 }
130 135
131 /* Found matching entry */ 136 /* Found matching entry */
@@ -133,12 +138,12 @@ acpi_ns_search_node(u32 target_name,
133 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, 138 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
134 "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n", 139 "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n",
135 ACPI_CAST_PTR(char, &target_name), 140 ACPI_CAST_PTR(char, &target_name),
136 acpi_ut_get_type_name(next_node-> 141 acpi_ut_get_type_name(node->type),
137 type), 142 node,
138 next_node, 143 acpi_ut_get_node_name(parent_node),
139 acpi_ut_get_node_name(node), node)); 144 parent_node));
140 145
141 *return_node = next_node; 146 *return_node = node;
142 return_ACPI_STATUS(AE_OK); 147 return_ACPI_STATUS(AE_OK);
143 } 148 }
144 149
@@ -146,7 +151,7 @@ acpi_ns_search_node(u32 target_name,
146 * The last entry in the list points back to the parent, 151 * The last entry in the list points back to the parent,
147 * so a flag is used to indicate the end-of-list 152 * so a flag is used to indicate the end-of-list
148 */ 153 */
149 if (next_node->flags & ANOBJ_END_OF_PEER_LIST) { 154 if (node->flags & ANOBJ_END_OF_PEER_LIST) {
150 155
151 /* Searched entire list, we are done */ 156 /* Searched entire list, we are done */
152 157
@@ -155,7 +160,7 @@ acpi_ns_search_node(u32 target_name,
155 160
156 /* Didn't match name, move on to the next peer object */ 161 /* Didn't match name, move on to the next peer object */
157 162
158 next_node = next_node->peer; 163 node = node->peer;
159 } 164 }
160 165
161 /* Searched entire namespace level, not found */ 166 /* Searched entire namespace level, not found */
@@ -164,7 +169,8 @@ acpi_ns_search_node(u32 target_name,
164 "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n", 169 "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n",
165 ACPI_CAST_PTR(char, &target_name), 170 ACPI_CAST_PTR(char, &target_name),
166 acpi_ut_get_type_name(type), 171 acpi_ut_get_type_name(type),
167 acpi_ut_get_node_name(node), node, node->child)); 172 acpi_ut_get_node_name(parent_node), parent_node,
173 parent_node->child));
168 174
169 return_ACPI_STATUS(AE_NOT_FOUND); 175 return_ACPI_STATUS(AE_NOT_FOUND);
170} 176}
@@ -181,14 +187,14 @@ acpi_ns_search_node(u32 target_name,
181 * RETURN: Status 187 * RETURN: Status
182 * 188 *
183 * DESCRIPTION: Called when a name has not been found in the current namespace 189 * DESCRIPTION: Called when a name has not been found in the current namespace
184 * level. Before adding it or giving up, ACPI scope rules require 190 * level. Before adding it or giving up, ACPI scope rules require
185 * searching enclosing scopes in cases identified by acpi_ns_local(). 191 * searching enclosing scopes in cases identified by acpi_ns_local().
186 * 192 *
187 * "A name is located by finding the matching name in the current 193 * "A name is located by finding the matching name in the current
188 * name space, and then in the parent name space. If the parent 194 * name space, and then in the parent name space. If the parent
189 * name space does not contain the name, the search continues 195 * name space does not contain the name, the search continues
190 * recursively until either the name is found or the name space 196 * recursively until either the name is found or the name space
191 * does not have a parent (the root of the name space). This 197 * does not have a parent (the root of the name space). This
192 * indicates that the name is not found" (From ACPI Specification, 198 * indicates that the name is not found" (From ACPI Specification,
193 * section 5.3) 199 * section 5.3)
194 * 200 *
@@ -237,11 +243,12 @@ acpi_ns_search_parent_tree(u32 target_name,
237 */ 243 */
238 while (parent_node) { 244 while (parent_node) {
239 /* 245 /*
240 * Search parent scope. Use TYPE_ANY because we don't care about the 246 * Search parent scope. Use TYPE_ANY because we don't care about the
241 * object type at this point, we only care about the existence of 247 * object type at this point, we only care about the existence of
242 * the actual name we are searching for. Typechecking comes later. 248 * the actual name we are searching for. Typechecking comes later.
243 */ 249 */
244 status = acpi_ns_search_node(target_name, parent_node, 250 status =
251 acpi_ns_search_one_scope(target_name, parent_node,
245 ACPI_TYPE_ANY, return_node); 252 ACPI_TYPE_ANY, return_node);
246 if (ACPI_SUCCESS(status)) { 253 if (ACPI_SUCCESS(status)) {
247 return_ACPI_STATUS(status); 254 return_ACPI_STATUS(status);
@@ -273,7 +280,7 @@ acpi_ns_search_parent_tree(u32 target_name,
273 * RETURN: Status 280 * RETURN: Status
274 * 281 *
275 * DESCRIPTION: Search for a name segment in a single namespace level, 282 * DESCRIPTION: Search for a name segment in a single namespace level,
276 * optionally adding it if it is not found. If the passed 283 * optionally adding it if it is not found. If the passed
277 * Type is not Any and the type previously stored in the 284 * Type is not Any and the type previously stored in the
278 * entry was Any (i.e. unknown), update the stored type. 285 * entry was Any (i.e. unknown), update the stored type.
279 * 286 *
@@ -332,7 +339,7 @@ acpi_ns_search_and_enter(u32 target_name,
332 /* Try to find the name in the namespace level specified by the caller */ 339 /* Try to find the name in the namespace level specified by the caller */
333 340
334 *return_node = ACPI_ENTRY_NOT_FOUND; 341 *return_node = ACPI_ENTRY_NOT_FOUND;
335 status = acpi_ns_search_node(target_name, node, type, return_node); 342 status = acpi_ns_search_one_scope(target_name, node, type, return_node);
336 if (status != AE_NOT_FOUND) { 343 if (status != AE_NOT_FOUND) {
337 /* 344 /*
338 * If we found it AND the request specifies that a find is an error, 345 * If we found it AND the request specifies that a find is an error,
@@ -348,10 +355,10 @@ acpi_ns_search_and_enter(u32 target_name,
348 } 355 }
349 356
350 /* 357 /*
351 * The name was not found. If we are NOT performing the first pass 358 * The name was not found. If we are NOT performing the first pass
352 * (name entry) of loading the namespace, search the parent tree (all the 359 * (name entry) of loading the namespace, search the parent tree (all the
353 * way to the root if necessary.) We don't want to perform the parent 360 * way to the root if necessary.) We don't want to perform the parent
354 * search when the namespace is actually being loaded. We want to perform 361 * search when the namespace is actually being loaded. We want to perform
355 * the search when namespace references are being resolved (load pass 2) 362 * the search when namespace references are being resolved (load pass 2)
356 * and during the execution phase. 363 * and during the execution phase.
357 */ 364 */
@@ -386,6 +393,9 @@ acpi_ns_search_and_enter(u32 target_name,
386 return_ACPI_STATUS(AE_NO_MEMORY); 393 return_ACPI_STATUS(AE_NO_MEMORY);
387 } 394 }
388#ifdef ACPI_ASL_COMPILER 395#ifdef ACPI_ASL_COMPILER
396 /*
397 * Node is an object defined by an External() statement
398 */
389 if (flags & ACPI_NS_EXTERNAL) { 399 if (flags & ACPI_NS_EXTERNAL) {
390 new_node->flags |= ANOBJ_IS_EXTERNAL; 400 new_node->flags |= ANOBJ_IS_EXTERNAL;
391 } 401 }
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c
index d1d55032b455..aa4e799d9a8c 100644
--- a/drivers/acpi/namespace/nsutils.c
+++ b/drivers/acpi/namespace/nsutils.c
@@ -142,8 +142,9 @@ acpi_ns_report_method_error(char *module_name,
142 acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); 142 acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number);
143 143
144 if (path) { 144 if (path) {
145 status = acpi_ns_get_node_by_path(path, prefix_node, 145 status =
146 ACPI_NS_NO_UPSEARCH, &node); 146 acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH,
147 &node);
147 if (ACPI_FAILURE(status)) { 148 if (ACPI_FAILURE(status)) {
148 acpi_os_printf("[Could not get node by pathname]"); 149 acpi_os_printf("[Could not get node by pathname]");
149 } 150 }
@@ -685,13 +686,9 @@ struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle)
685 ACPI_FUNCTION_ENTRY(); 686 ACPI_FUNCTION_ENTRY();
686 687
687 /* 688 /*
688 * Simple implementation. 689 * Simple implementation
689 */ 690 */
690 if (!handle) { 691 if ((!handle) || (handle == ACPI_ROOT_OBJECT)) {
691 return (NULL);
692 }
693
694 if (handle == ACPI_ROOT_OBJECT) {
695 return (acpi_gbl_root_node); 692 return (acpi_gbl_root_node);
696 } 693 }
697 694
@@ -701,7 +698,7 @@ struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle)
701 return (NULL); 698 return (NULL);
702 } 699 }
703 700
704 return ((struct acpi_namespace_node *)handle); 701 return (ACPI_CAST_PTR(struct acpi_namespace_node, handle));
705} 702}
706 703
707/******************************************************************************* 704/*******************************************************************************
@@ -811,12 +808,12 @@ u32 acpi_ns_opens_scope(acpi_object_type type)
811 808
812/******************************************************************************* 809/*******************************************************************************
813 * 810 *
814 * FUNCTION: acpi_ns_get_node_by_path 811 * FUNCTION: acpi_ns_get_node
815 * 812 *
816 * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The 813 * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The
817 * \ (backslash) and ^ (carat) prefixes, and the 814 * \ (backslash) and ^ (carat) prefixes, and the
818 * . (period) to separate segments are supported. 815 * . (period) to separate segments are supported.
819 * start_node - Root of subtree to be searched, or NS_ALL for the 816 * prefix_node - Root of subtree to be searched, or NS_ALL for the
820 * root of the name space. If Name is fully 817 * root of the name space. If Name is fully
821 * qualified (first s8 is '\'), the passed value 818 * qualified (first s8 is '\'), the passed value
822 * of Scope will not be accessed. 819 * of Scope will not be accessed.
@@ -832,24 +829,29 @@ u32 acpi_ns_opens_scope(acpi_object_type type)
832 ******************************************************************************/ 829 ******************************************************************************/
833 830
834acpi_status 831acpi_status
835acpi_ns_get_node_by_path(char *pathname, 832acpi_ns_get_node(struct acpi_namespace_node *prefix_node,
836 struct acpi_namespace_node *start_node, 833 char *pathname,
837 u32 flags, struct acpi_namespace_node **return_node) 834 u32 flags, struct acpi_namespace_node **return_node)
838{ 835{
839 union acpi_generic_state scope_info; 836 union acpi_generic_state scope_info;
840 acpi_status status; 837 acpi_status status;
841 char *internal_path = NULL; 838 char *internal_path;
842 839
843 ACPI_FUNCTION_TRACE_PTR(ns_get_node_by_path, pathname); 840 ACPI_FUNCTION_TRACE_PTR(ns_get_node, pathname);
844 841
845 if (pathname) { 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 }
846 849
847 /* Convert path to internal representation */ 850 /* Convert path to internal representation */
848 851
849 status = acpi_ns_internalize_name(pathname, &internal_path); 852 status = acpi_ns_internalize_name(pathname, &internal_path);
850 if (ACPI_FAILURE(status)) { 853 if (ACPI_FAILURE(status)) {
851 return_ACPI_STATUS(status); 854 return_ACPI_STATUS(status);
852 }
853 } 855 }
854 856
855 /* Must lock namespace during lookup */ 857 /* Must lock namespace during lookup */
@@ -861,26 +863,23 @@ acpi_ns_get_node_by_path(char *pathname,
861 863
862 /* Setup lookup scope (search starting point) */ 864 /* Setup lookup scope (search starting point) */
863 865
864 scope_info.scope.node = start_node; 866 scope_info.scope.node = prefix_node;
865 867
866 /* Lookup the name in the namespace */ 868 /* Lookup the name in the namespace */
867 869
868 status = acpi_ns_lookup(&scope_info, internal_path, 870 status = acpi_ns_lookup(&scope_info, internal_path, ACPI_TYPE_ANY,
869 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 871 ACPI_IMODE_EXECUTE,
870 (flags | ACPI_NS_DONT_OPEN_SCOPE), 872 (flags | ACPI_NS_DONT_OPEN_SCOPE), NULL,
871 NULL, return_node); 873 return_node);
872 if (ACPI_FAILURE(status)) { 874 if (ACPI_FAILURE(status)) {
873 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s, %s\n", 875 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s, %s\n",
874 internal_path, 876 pathname, acpi_format_exception(status)));
875 acpi_format_exception(status)));
876 } 877 }
877 878
878 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 879 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
879 880
880 cleanup: 881 cleanup:
881 if (internal_path) { 882 ACPI_FREE(internal_path);
882 ACPI_FREE(internal_path);
883 }
884 return_ACPI_STATUS(status); 883 return_ACPI_STATUS(status);
885} 884}
886 885
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index 998b29611b19..6d9bd45af30a 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -171,51 +171,61 @@ acpi_evaluate_object(acpi_handle handle,
171{ 171{
172 acpi_status status; 172 acpi_status status;
173 acpi_status status2; 173 acpi_status status2;
174 struct acpi_parameter_info info; 174 struct acpi_evaluate_info *info;
175 acpi_size buffer_space_needed; 175 acpi_size buffer_space_needed;
176 u32 i; 176 u32 i;
177 177
178 ACPI_FUNCTION_TRACE(acpi_evaluate_object); 178 ACPI_FUNCTION_TRACE(acpi_evaluate_object);
179 179
180 info.node = handle; 180 /* Allocate and initialize the evaluation information block */
181 info.parameters = NULL; 181
182 info.return_object = NULL; 182 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
183 info.parameter_type = ACPI_PARAM_ARGS; 183 if (!info) {
184 return_ACPI_STATUS(AE_NO_MEMORY);
185 }
186
187 info->pathname = pathname;
188 info->parameter_type = ACPI_PARAM_ARGS;
189
190 /* Convert and validate the device handle */
191
192 info->prefix_node = acpi_ns_map_handle_to_node(handle);
193 if (!info->prefix_node) {
194 status = AE_BAD_PARAMETER;
195 goto cleanup;
196 }
184 197
185 /* 198 /*
186 * If there are parameters to be passed to the object 199 * If there are parameters to be passed to a control method, the external
187 * (which must be a control method), the external objects 200 * objects must all be converted to internal objects
188 * must be converted to internal objects
189 */ 201 */
190 if (external_params && external_params->count) { 202 if (external_params && external_params->count) {
191 /* 203 /*
192 * Allocate a new parameter block for the internal objects 204 * Allocate a new parameter block for the internal objects
193 * Add 1 to count to allow for null terminated internal list 205 * Add 1 to count to allow for null terminated internal list
194 */ 206 */
195 info.parameters = ACPI_ALLOCATE_ZEROED(((acpi_size) 207 info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size)
196 external_params->count + 208 external_params->
197 1) * sizeof(void *)); 209 count +
198 if (!info.parameters) { 210 1) * sizeof(void *));
199 return_ACPI_STATUS(AE_NO_MEMORY); 211 if (!info->parameters) {
212 status = AE_NO_MEMORY;
213 goto cleanup;
200 } 214 }
201 215
202 /* 216 /* Convert each external object in the list to an internal object */
203 * Convert each external object in the list to an 217
204 * internal object
205 */
206 for (i = 0; i < external_params->count; i++) { 218 for (i = 0; i < external_params->count; i++) {
207 status = 219 status =
208 acpi_ut_copy_eobject_to_iobject(&external_params-> 220 acpi_ut_copy_eobject_to_iobject(&external_params->
209 pointer[i], 221 pointer[i],
210 &info. 222 &info->
211 parameters[i]); 223 parameters[i]);
212 if (ACPI_FAILURE(status)) { 224 if (ACPI_FAILURE(status)) {
213 acpi_ut_delete_internal_object_list(info. 225 goto cleanup;
214 parameters);
215 return_ACPI_STATUS(status);
216 } 226 }
217 } 227 }
218 info.parameters[external_params->count] = NULL; 228 info->parameters[external_params->count] = NULL;
219 } 229 }
220 230
221 /* 231 /*
@@ -228,12 +238,13 @@ acpi_evaluate_object(acpi_handle handle,
228 238
229 /* The path is fully qualified, just evaluate by name */ 239 /* The path is fully qualified, just evaluate by name */
230 240
231 status = acpi_ns_evaluate_by_name(pathname, &info); 241 info->prefix_node = NULL;
242 status = acpi_ns_evaluate(info);
232 } else if (!handle) { 243 } else if (!handle) {
233 /* 244 /*
234 * A handle is optional iff a fully qualified pathname 245 * A handle is optional iff a fully qualified pathname is specified.
235 * is specified. Since we've already handled fully 246 * Since we've already handled fully qualified names above, this is
236 * qualified names above, this is an error 247 * an error
237 */ 248 */
238 if (!pathname) { 249 if (!pathname) {
239 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 250 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -246,22 +257,9 @@ acpi_evaluate_object(acpi_handle handle,
246 257
247 status = AE_BAD_PARAMETER; 258 status = AE_BAD_PARAMETER;
248 } else { 259 } else {
249 /* 260 /* We have a namespace a node and a possible relative path */
250 * We get here if we have a handle -- and if we have a
251 * pathname it is relative. The handle will be validated
252 * in the lower procedures
253 */
254 if (!pathname) {
255 /*
256 * The null pathname case means the handle is for
257 * the actual object to be evaluated
258 */
259 status = acpi_ns_evaluate_by_handle(&info);
260 } else {
261 /* Both a Handle and a relative Pathname */
262 261
263 status = acpi_ns_evaluate_relative(pathname, &info); 262 status = acpi_ns_evaluate(info);
264 }
265 } 263 }
266 264
267 /* 265 /*
@@ -269,10 +267,10 @@ acpi_evaluate_object(acpi_handle handle,
269 * copy the return value to an external object. 267 * copy the return value to an external object.
270 */ 268 */
271 if (return_buffer) { 269 if (return_buffer) {
272 if (!info.return_object) { 270 if (!info->return_object) {
273 return_buffer->length = 0; 271 return_buffer->length = 0;
274 } else { 272 } else {
275 if (ACPI_GET_DESCRIPTOR_TYPE(info.return_object) == 273 if (ACPI_GET_DESCRIPTOR_TYPE(info->return_object) ==
276 ACPI_DESC_TYPE_NAMED) { 274 ACPI_DESC_TYPE_NAMED) {
277 /* 275 /*
278 * If we received a NS Node as a return object, this means that 276 * If we received a NS Node as a return object, this means that
@@ -283,17 +281,16 @@ acpi_evaluate_object(acpi_handle handle,
283 * support for various types at a later date if necessary. 281 * support for various types at a later date if necessary.
284 */ 282 */
285 status = AE_TYPE; 283 status = AE_TYPE;
286 info.return_object = NULL; /* No need to delete a NS Node */ 284 info->return_object = NULL; /* No need to delete a NS Node */
287 return_buffer->length = 0; 285 return_buffer->length = 0;
288 } 286 }
289 287
290 if (ACPI_SUCCESS(status)) { 288 if (ACPI_SUCCESS(status)) {
291 /* 289
292 * Find out how large a buffer is needed 290 /* Get the size of the returned object */
293 * to contain the returned object 291
294 */
295 status = 292 status =
296 acpi_ut_get_object_size(info.return_object, 293 acpi_ut_get_object_size(info->return_object,
297 &buffer_space_needed); 294 &buffer_space_needed);
298 if (ACPI_SUCCESS(status)) { 295 if (ACPI_SUCCESS(status)) {
299 296
@@ -319,7 +316,7 @@ acpi_evaluate_object(acpi_handle handle,
319 316
320 status = 317 status =
321 acpi_ut_copy_iobject_to_eobject 318 acpi_ut_copy_iobject_to_eobject
322 (info.return_object, 319 (info->return_object,
323 return_buffer); 320 return_buffer);
324 } 321 }
325 } 322 }
@@ -327,31 +324,33 @@ acpi_evaluate_object(acpi_handle handle,
327 } 324 }
328 } 325 }
329 326
330 if (info.return_object) { 327 if (info->return_object) {
331 /* 328 /*
332 * Delete the internal return object. NOTE: Interpreter 329 * Delete the internal return object. NOTE: Interpreter must be
333 * must be locked to avoid race condition. 330 * locked to avoid race condition.
334 */ 331 */
335 status2 = acpi_ex_enter_interpreter(); 332 status2 = acpi_ex_enter_interpreter();
336 if (ACPI_SUCCESS(status2)) { 333 if (ACPI_SUCCESS(status2)) {
337 /* 334
338 * Delete the internal return object. (Or at least 335 /* Remove one reference on the return object (should delete it) */
339 * decrement the reference count by one) 336
340 */ 337 acpi_ut_remove_reference(info->return_object);
341 acpi_ut_remove_reference(info.return_object);
342 acpi_ex_exit_interpreter(); 338 acpi_ex_exit_interpreter();
343 } 339 }
344 } 340 }
345 341
342 cleanup:
343
346 /* Free the input parameter list (if we created one) */ 344 /* Free the input parameter list (if we created one) */
347 345
348 if (info.parameters) { 346 if (info->parameters) {
349 347
350 /* Free the allocated parameter block */ 348 /* Free the allocated parameter block */
351 349
352 acpi_ut_delete_internal_object_list(info.parameters); 350 acpi_ut_delete_internal_object_list(info->parameters);
353 } 351 }
354 352
353 ACPI_FREE(info);
355 return_ACPI_STATUS(status); 354 return_ACPI_STATUS(status);
356} 355}
357 356
diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c
index 1303e2b062bb..978213a6c19f 100644
--- a/drivers/acpi/namespace/nsxfname.c
+++ b/drivers/acpi/namespace/nsxfname.c
@@ -112,9 +112,8 @@ acpi_get_handle(acpi_handle parent,
112 /* 112 /*
113 * Find the Node and convert to a handle 113 * Find the Node and convert to a handle
114 */ 114 */
115 status = 115 status = acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH,
116 acpi_ns_get_node_by_path(pathname, prefix_node, ACPI_NS_NO_UPSEARCH, 116 &node);
117 &node);
118 117
119 *ret_handle = NULL; 118 *ret_handle = NULL;
120 if (ACPI_SUCCESS(status)) { 119 if (ACPI_SUCCESS(status)) {