summaryrefslogtreecommitdiffstats
path: root/drivers/acpi/parser/psargs.c
diff options
context:
space:
mode:
authorLin Ming <ming.m.lin@intel.com>2008-04-10 17:06:42 +0200
committerLen Brown <len.brown@intel.com>2008-04-22 20:29:30 +0200
commitbc7a36ab74e09da7bb63e2477b0740ac992b290e (patch)
treef9384f3f0909e1da6f12fb55643de8de594551dd /drivers/acpi/parser/psargs.c
parentACPICA: Bulletproof disassembler for bad ACPI tables (diff)
downloadlinux-bc7a36ab74e09da7bb63e2477b0740ac992b290e.tar.xz
linux-bc7a36ab74e09da7bb63e2477b0740ac992b290e.zip
ACPICA: Fixes for Unload and DDBHandles
Implemented support for the use of DDBHandles as an Indexed Reference, as per the ACPI spec. http://www.acpica.org/bugzilla/show_bug.cgi?id=486. Implemented support for UserTerm (Method invocation) for the Unload operator as per the ACPI spec. http://www.acpica.org/bugzilla/show_bug.cgi?id=580 Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/parser/psargs.c')
-rw-r--r--drivers/acpi/parser/psargs.c37
1 files changed, 34 insertions, 3 deletions
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c
index 442880f5600e..2a3a948dd114 100644
--- a/drivers/acpi/parser/psargs.c
+++ b/drivers/acpi/parser/psargs.c
@@ -235,6 +235,7 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
union acpi_parse_object *name_op;
union acpi_operand_object *method_desc;
struct acpi_namespace_node *node;
+ u8 *start = parser_state->aml;
ACPI_FUNCTION_TRACE(ps_get_next_namepath);
@@ -267,6 +268,16 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
*/
if (ACPI_SUCCESS(status) &&
possible_method_call && (node->type == ACPI_TYPE_METHOD)) {
+ if (walk_state->op->common.aml_opcode == AML_UNLOAD_OP) {
+ /*
+ * acpi_ps_get_next_namestring has increased the AML pointer,
+ * so we need to restore the saved AML pointer for method call.
+ */
+ walk_state->parser_state.aml = start;
+ walk_state->arg_count = 1;
+ acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
+ return_ACPI_STATUS(AE_OK);
+ }
/* This name is actually a control method invocation */
@@ -678,9 +689,29 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
return_ACPI_STATUS(AE_NO_MEMORY);
}
- status =
- acpi_ps_get_next_namepath(walk_state, parser_state,
- arg, 0);
+ /* To support super_name arg of Unload */
+
+ if (walk_state->op->common.aml_opcode == AML_UNLOAD_OP) {
+ status =
+ acpi_ps_get_next_namepath(walk_state,
+ parser_state, arg,
+ 1);
+
+ /*
+ * If the super_name arg of Unload is a method call,
+ * we have restored the AML pointer, just free this Arg
+ */
+ if (arg->common.aml_opcode ==
+ AML_INT_METHODCALL_OP) {
+ acpi_ps_free_op(arg);
+ arg = NULL;
+ }
+ } else {
+ status =
+ acpi_ps_get_next_namepath(walk_state,
+ parser_state, arg,
+ 0);
+ }
} else {
/* Single complex argument, nothing returned */