diff options
Diffstat (limited to 'drivers/acpi/parser/psargs.c')
-rw-r--r-- | drivers/acpi/parser/psargs.c | 63 |
1 files changed, 43 insertions, 20 deletions
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c index c2b9835c890b..f1e8bf65e24e 100644 --- a/drivers/acpi/parser/psargs.c +++ b/drivers/acpi/parser/psargs.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -230,12 +230,12 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, | |||
230 | struct acpi_parse_state *parser_state, | 230 | struct acpi_parse_state *parser_state, |
231 | union acpi_parse_object *arg, u8 possible_method_call) | 231 | union acpi_parse_object *arg, u8 possible_method_call) |
232 | { | 232 | { |
233 | acpi_status status; | ||
233 | char *path; | 234 | char *path; |
234 | union acpi_parse_object *name_op; | 235 | union acpi_parse_object *name_op; |
235 | acpi_status status; | ||
236 | union acpi_operand_object *method_desc; | 236 | union acpi_operand_object *method_desc; |
237 | struct acpi_namespace_node *node; | 237 | struct acpi_namespace_node *node; |
238 | union acpi_generic_state scope_info; | 238 | u8 *start = parser_state->aml; |
239 | 239 | ||
240 | ACPI_FUNCTION_TRACE(ps_get_next_namepath); | 240 | ACPI_FUNCTION_TRACE(ps_get_next_namepath); |
241 | 241 | ||
@@ -249,25 +249,18 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, | |||
249 | return_ACPI_STATUS(AE_OK); | 249 | return_ACPI_STATUS(AE_OK); |
250 | } | 250 | } |
251 | 251 | ||
252 | /* Setup search scope info */ | ||
253 | |||
254 | scope_info.scope.node = NULL; | ||
255 | node = parser_state->start_node; | ||
256 | if (node) { | ||
257 | scope_info.scope.node = node; | ||
258 | } | ||
259 | |||
260 | /* | 252 | /* |
261 | * Lookup the name in the internal namespace. We don't want to add | 253 | * Lookup the name in the internal namespace, starting with the current |
262 | * anything new to the namespace here, however, so we use MODE_EXECUTE. | 254 | * scope. We don't want to add anything new to the namespace here, |
255 | * however, so we use MODE_EXECUTE. | ||
263 | * Allow searching of the parent tree, but don't open a new scope - | 256 | * 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 | 257 | * we just want to lookup the object (must be mode EXECUTE to perform |
265 | * the upsearch) | 258 | * the upsearch) |
266 | */ | 259 | */ |
267 | status = | 260 | status = acpi_ns_lookup(walk_state->scope_info, path, |
268 | acpi_ns_lookup(&scope_info, path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, | 261 | ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, |
269 | ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, | 262 | ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, |
270 | NULL, &node); | 263 | NULL, &node); |
271 | 264 | ||
272 | /* | 265 | /* |
273 | * If this name is a control method invocation, we must | 266 | * If this name is a control method invocation, we must |
@@ -275,6 +268,16 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, | |||
275 | */ | 268 | */ |
276 | if (ACPI_SUCCESS(status) && | 269 | if (ACPI_SUCCESS(status) && |
277 | possible_method_call && (node->type == ACPI_TYPE_METHOD)) { | 270 | possible_method_call && (node->type == ACPI_TYPE_METHOD)) { |
271 | if (walk_state->op->common.aml_opcode == AML_UNLOAD_OP) { | ||
272 | /* | ||
273 | * acpi_ps_get_next_namestring has increased the AML pointer, | ||
274 | * so we need to restore the saved AML pointer for method call. | ||
275 | */ | ||
276 | walk_state->parser_state.aml = start; | ||
277 | walk_state->arg_count = 1; | ||
278 | acpi_ps_init_op(arg, AML_INT_METHODCALL_OP); | ||
279 | return_ACPI_STATUS(AE_OK); | ||
280 | } | ||
278 | 281 | ||
279 | /* This name is actually a control method invocation */ | 282 | /* This name is actually a control method invocation */ |
280 | 283 | ||
@@ -686,9 +689,29 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, | |||
686 | return_ACPI_STATUS(AE_NO_MEMORY); | 689 | return_ACPI_STATUS(AE_NO_MEMORY); |
687 | } | 690 | } |
688 | 691 | ||
689 | status = | 692 | /* To support super_name arg of Unload */ |
690 | acpi_ps_get_next_namepath(walk_state, parser_state, | 693 | |
691 | arg, 0); | 694 | if (walk_state->op->common.aml_opcode == AML_UNLOAD_OP) { |
695 | status = | ||
696 | acpi_ps_get_next_namepath(walk_state, | ||
697 | parser_state, arg, | ||
698 | 1); | ||
699 | |||
700 | /* | ||
701 | * If the super_name arg of Unload is a method call, | ||
702 | * we have restored the AML pointer, just free this Arg | ||
703 | */ | ||
704 | if (arg->common.aml_opcode == | ||
705 | AML_INT_METHODCALL_OP) { | ||
706 | acpi_ps_free_op(arg); | ||
707 | arg = NULL; | ||
708 | } | ||
709 | } else { | ||
710 | status = | ||
711 | acpi_ps_get_next_namepath(walk_state, | ||
712 | parser_state, arg, | ||
713 | 0); | ||
714 | } | ||
692 | } else { | 715 | } else { |
693 | /* Single complex argument, nothing returned */ | 716 | /* Single complex argument, nothing returned */ |
694 | 717 | ||