aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/parser/psargs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/parser/psargs.c')
-rw-r--r--drivers/acpi/parser/psargs.c198
1 files changed, 106 insertions, 92 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