aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/parser
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2005-12-16 17:05:00 -0500
committerLen Brown <len.brown@intel.com>2005-12-28 02:54:59 -0500
commitdefba1d8f233c0d5cf3e1ea6aeb898eca7231860 (patch)
treecd8b1b84da8d8a52ad0d44107daaeeee0a0b65f4 /drivers/acpi/parser
parentcb654695f6b912cef7cb3271665b6ee0d416124c (diff)
[ACPI] ACPICA 20051216
Implemented optional support to allow unresolved names within ASL Package objects. A null object is inserted in the package when a named reference cannot be located in the current namespace. Enabled via the interpreter slack flag which Linux has enabled by default (acpi=strict to disable slack). This should eliminate AE_NOT_FOUND exceptions seen on machines that contain such code. Implemented an optimization to the initialization sequence that can improve boot time. During ACPI device initialization, the _STA method is now run if and only if the _INI method exists. The _STA method is used to determine if the device is present; An _INI can only be run if _STA returns present, but it is a waste of time to run the _STA method if the _INI does not exist. (Prototype and assistance from Dong Wei) Implemented use of the C99 uintptr_t for the pointer casting macros if it is available in the current compiler. Otherwise, the default (void *) cast is used as before. Fixed some possible memory leaks found within the execution path of the Break, Continue, If, and CreateField operators. (Valery Podrezov) Fixed a problem introduced in the 20051202 release where an exception is generated during method execution if a control method attempts to declare another method. Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/parser')
-rw-r--r--drivers/acpi/parser/psargs.c198
-rw-r--r--drivers/acpi/parser/psloop.c9
-rw-r--r--drivers/acpi/parser/psparse.c17
3 files changed, 127 insertions, 97 deletions
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c
index 6eae35febccd..e6d4cb9fd303 100644
--- a/drivers/acpi/parser/psargs.c
+++ b/drivers/acpi/parser/psargs.c
@@ -45,6 +45,7 @@
45#include <acpi/acparser.h> 45#include <acpi/acparser.h>
46#include <acpi/amlcode.h> 46#include <acpi/amlcode.h>
47#include <acpi/acnamesp.h> 47#include <acpi/acnamesp.h>
48#include <acpi/acdispat.h>
48 49
49#define _COMPONENT ACPI_PARSER 50#define _COMPONENT ACPI_PARSER
50ACPI_MODULE_NAME("psargs") 51ACPI_MODULE_NAME("psargs")
@@ -211,7 +212,7 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
211 * Arg - Where the namepath will be stored 212 * Arg - Where the namepath will be stored
212 * arg_count - If the namepath points to a control method 213 * arg_count - If the namepath points to a control method
213 * the method's argument is returned here. 214 * the method's argument is returned here.
214 * method_call - Whether the namepath can possibly be the 215 * possible_method_call - Whether the namepath can possibly be the
215 * start of a method call 216 * start of a method call
216 * 217 *
217 * RETURN: Status 218 * RETURN: Status
@@ -227,11 +228,11 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
227acpi_status 228acpi_status
228acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, 229acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
229 struct acpi_parse_state *parser_state, 230 struct acpi_parse_state *parser_state,
230 union acpi_parse_object *arg, u8 method_call) 231 union acpi_parse_object *arg, u8 possible_method_call)
231{ 232{
232 char *path; 233 char *path;
233 union acpi_parse_object *name_op; 234 union acpi_parse_object *name_op;
234 acpi_status status = AE_OK; 235 acpi_status status;
235 union acpi_operand_object *method_desc; 236 union acpi_operand_object *method_desc;
236 struct acpi_namespace_node *node; 237 struct acpi_namespace_node *node;
237 union acpi_generic_state scope_info; 238 union acpi_generic_state scope_info;
@@ -239,114 +240,127 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
239 ACPI_FUNCTION_TRACE("ps_get_next_namepath"); 240 ACPI_FUNCTION_TRACE("ps_get_next_namepath");
240 241
241 path = acpi_ps_get_next_namestring(parser_state); 242 path = acpi_ps_get_next_namestring(parser_state);
243 acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
242 244
243 /* Null path case is allowed */ 245 /* Null path case is allowed, just exit */
244 246
245 if (path) { 247 if (!path) {
246 /* 248 arg->common.value.name = path;
247 * Lookup the name in the internal namespace 249 return_ACPI_STATUS(AE_OK);
248 */ 250 }
249 scope_info.scope.node = NULL;
250 node = parser_state->start_node;
251 if (node) {
252 scope_info.scope.node = node;
253 }
254 251
255 /* 252 /* Setup search scope info */
256 * Lookup object. We don't want to add anything new to the namespace 253
257 * here, however. So we use MODE_EXECUTE. Allow searching of the 254 scope_info.scope.node = NULL;
258 * parent tree, but don't open a new scope -- we just want to lookup the 255 node = parser_state->start_node;
259 * object (MUST BE mode EXECUTE to perform upsearch) 256 if (node) {
260 */ 257 scope_info.scope.node = node;
261 status = acpi_ns_lookup(&scope_info, path, ACPI_TYPE_ANY, 258 }
262 ACPI_IMODE_EXECUTE,
263 ACPI_NS_SEARCH_PARENT |
264 ACPI_NS_DONT_OPEN_SCOPE, NULL, &node);
265 if (ACPI_SUCCESS(status) && method_call) {
266 if (node->type == ACPI_TYPE_METHOD) {
267 /* This name is actually a control method invocation */
268
269 method_desc = acpi_ns_get_attached_object(node);
270 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
271 "Control Method - %p Desc %p Path=%p\n",
272 node, method_desc, path));
273
274 name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP);
275 if (!name_op) {
276 return_ACPI_STATUS(AE_NO_MEMORY);
277 }
278 259
279 /* Change arg into a METHOD CALL and attach name to it */ 260 /*
261 * Lookup the name in the internal namespace. We don't want to add
262 * anything new to the namespace here, however, so we use MODE_EXECUTE.
263 * Allow searching of the parent tree, but don't open a new scope -
264 * we just want to lookup the object (must be mode EXECUTE to perform
265 * the upsearch)
266 */
267 status =
268 acpi_ns_lookup(&scope_info, path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
269 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
270 NULL, &node);
280 271
281 acpi_ps_init_op(arg, AML_INT_METHODCALL_OP); 272 /*
282 name_op->common.value.name = path; 273 * If this name is a control method invocation, we must
274 * setup the method call
275 */
276 if (ACPI_SUCCESS(status) &&
277 possible_method_call && (node->type == ACPI_TYPE_METHOD)) {
278 /* This name is actually a control method invocation */
283 279
284 /* Point METHODCALL/NAME to the METHOD Node */ 280 method_desc = acpi_ns_get_attached_object(node);
281 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
282 "Control Method - %p Desc %p Path=%p\n", node,
283 method_desc, path));
285 284
286 name_op->common.node = node; 285 name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP);
287 acpi_ps_append_arg(arg, name_op); 286 if (!name_op) {
287 return_ACPI_STATUS(AE_NO_MEMORY);
288 }
288 289
289 if (!method_desc) { 290 /* Change Arg into a METHOD CALL and attach name to it */
290 ACPI_REPORT_ERROR(("ps_get_next_namepath: Control Method %p has no attached object\n", node));
291 return_ACPI_STATUS(AE_AML_INTERNAL);
292 }
293 291
294 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 292 acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
295 "Control Method - %p Args %X\n", 293 name_op->common.value.name = path;
296 node,
297 method_desc->method.
298 param_count));
299 294
300 /* Get the number of arguments to expect */ 295 /* Point METHODCALL/NAME to the METHOD Node */
301 296
302 walk_state->arg_count = 297 name_op->common.node = node;
303 method_desc->method.param_count; 298 acpi_ps_append_arg(arg, name_op);
304 return_ACPI_STATUS(AE_OK);
305 }
306 299
307 /* 300 if (!method_desc) {
308 * Else this is normal named object reference. 301 ACPI_REPORT_ERROR(("ps_get_next_namepath: Control Method %p has no attached object\n", node));
309 * Just init the NAMEPATH object with the pathname. 302 return_ACPI_STATUS(AE_AML_INTERNAL);
310 * (See code below)
311 */
312 } 303 }
313 304
314 if (ACPI_FAILURE(status)) { 305 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
315 /* 306 "Control Method - %p Args %X\n",
316 * 1) Any error other than NOT_FOUND is always severe 307 node, method_desc->method.param_count));
317 * 2) NOT_FOUND is only important if we are executing a method. 308
318 * 3) If executing a cond_ref_of opcode, NOT_FOUND is ok. 309 /* Get the number of arguments to expect */
319 */ 310
320 if ((((walk_state-> 311 walk_state->arg_count = method_desc->method.param_count;
321 parse_flags & ACPI_PARSE_MODE_MASK) == 312 return_ACPI_STATUS(AE_OK);
322 ACPI_PARSE_EXECUTE) && (status == AE_NOT_FOUND)
323 && (walk_state->op->common.aml_opcode !=
324 AML_COND_REF_OF_OP))
325 || (status != AE_NOT_FOUND)) {
326 ACPI_REPORT_NSERROR(path, status);
327
328 acpi_os_printf
329 ("search_node %p start_node %p return_node %p\n",
330 scope_info.scope.node,
331 parser_state->start_node, node);
332 } else {
333 /*
334 * We got a NOT_FOUND during table load or we encountered
335 * a cond_ref_of(x) where the target does not exist.
336 * Either case is ok
337 */
338 status = AE_OK;
339 }
340 }
341 } 313 }
342 314
343 /* 315 /*
344 * Regardless of success/failure above, 316 * Special handling if the name was not found during the lookup -
345 * Just initialize the Op with the pathname. 317 * some not_found cases are allowed
346 */ 318 */
347 acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP); 319 if (status == AE_NOT_FOUND) {
348 arg->common.value.name = path; 320 /* 1) not_found is ok during load pass 1/2 (allow forward references) */
321
322 if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) !=
323 ACPI_PARSE_EXECUTE) {
324 status = AE_OK;
325 }
326
327 /* 2) not_found during a cond_ref_of(x) is ok by definition */
328
329 else if (walk_state->op->common.aml_opcode ==
330 AML_COND_REF_OF_OP) {
331 status = AE_OK;
332 }
333
334 /*
335 * 3) not_found while building a Package is ok at this point, we
336 * may flag as an error later if slack mode is not enabled.
337 * (Some ASL code depends on allowing this behavior)
338 */
339 else if ((arg->common.parent) &&
340 ((arg->common.parent->common.aml_opcode ==
341 AML_PACKAGE_OP)
342 || (arg->common.parent->common.aml_opcode ==
343 AML_VAR_PACKAGE_OP))) {
344 status = AE_OK;
345 }
346 }
347
348 /* Final exception check (may have been changed from code above) */
349
350 if (ACPI_FAILURE(status)) {
351 ACPI_REPORT_NSERROR(path, status);
352
353 if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
354 ACPI_PARSE_EXECUTE) {
355 /* Report a control method execution error */
349 356
357 status = acpi_ds_method_error(status, walk_state);
358 }
359 }
360
361 /* Save the namepath */
362
363 arg->common.value.name = path;
350 return_ACPI_STATUS(status); 364 return_ACPI_STATUS(status);
351} 365}
352 366
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c
index 088d33999d90..e81e51b8b3ae 100644
--- a/drivers/acpi/parser/psloop.c
+++ b/drivers/acpi/parser/psloop.c
@@ -704,6 +704,15 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
704 acpi_ps_pop_scope(parser_state, &op, 704 acpi_ps_pop_scope(parser_state, &op,
705 &walk_state->arg_types, 705 &walk_state->arg_types,
706 &walk_state->arg_count); 706 &walk_state->arg_count);
707
708 if (op->common.aml_opcode != AML_WHILE_OP) {
709 status2 =
710 acpi_ds_result_stack_pop
711 (walk_state);
712 if (ACPI_FAILURE(status2)) {
713 return_ACPI_STATUS(status2);
714 }
715 }
707 } 716 }
708 717
709 /* Close this iteration of the While loop */ 718 /* Close this iteration of the While loop */
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
index 7cfa7eb0dfc7..f0979b2956f2 100644
--- a/drivers/acpi/parser/psparse.c
+++ b/drivers/acpi/parser/psparse.c
@@ -333,7 +333,6 @@ acpi_ps_next_parse_state(struct acpi_walk_state *walk_state,
333 333
334 switch (callback_status) { 334 switch (callback_status) {
335 case AE_CTRL_TERMINATE: 335 case AE_CTRL_TERMINATE:
336
337 /* 336 /*
338 * A control method was terminated via a RETURN statement. 337 * A control method was terminated via a RETURN statement.
339 * The walk of this method is complete. 338 * The walk of this method is complete.
@@ -346,13 +345,19 @@ acpi_ps_next_parse_state(struct acpi_walk_state *walk_state,
346 345
347 parser_state->aml = walk_state->aml_last_while; 346 parser_state->aml = walk_state->aml_last_while;
348 walk_state->control_state->common.value = FALSE; 347 walk_state->control_state->common.value = FALSE;
349 status = AE_CTRL_BREAK; 348 status = acpi_ds_result_stack_pop(walk_state);
349 if (ACPI_SUCCESS(status)) {
350 status = AE_CTRL_BREAK;
351 }
350 break; 352 break;
351 353
352 case AE_CTRL_CONTINUE: 354 case AE_CTRL_CONTINUE:
353 355
354 parser_state->aml = walk_state->aml_last_while; 356 parser_state->aml = walk_state->aml_last_while;
355 status = AE_CTRL_CONTINUE; 357 status = acpi_ds_result_stack_pop(walk_state);
358 if (ACPI_SUCCESS(status)) {
359 status = AE_CTRL_CONTINUE;
360 }
356 break; 361 break;
357 362
358 case AE_CTRL_PENDING: 363 case AE_CTRL_PENDING:
@@ -369,16 +374,18 @@ acpi_ps_next_parse_state(struct acpi_walk_state *walk_state,
369#endif 374#endif
370 375
371 case AE_CTRL_TRUE: 376 case AE_CTRL_TRUE:
372
373 /* 377 /*
374 * Predicate of an IF was true, and we are at the matching ELSE. 378 * Predicate of an IF was true, and we are at the matching ELSE.
375 * Just close out this package 379 * Just close out this package
376 */ 380 */
377 parser_state->aml = acpi_ps_get_next_package_end(parser_state); 381 parser_state->aml = acpi_ps_get_next_package_end(parser_state);
382 status = acpi_ds_result_stack_pop(walk_state);
383 if (ACPI_SUCCESS(status)) {
384 status = AE_CTRL_PENDING;
385 }
378 break; 386 break;
379 387
380 case AE_CTRL_FALSE: 388 case AE_CTRL_FALSE:
381
382 /* 389 /*
383 * Either an IF/WHILE Predicate was false or we encountered a BREAK 390 * Either an IF/WHILE Predicate was false or we encountered a BREAK
384 * opcode. In both cases, we do not execute the rest of the 391 * opcode. In both cases, we do not execute the rest of the