From: Lin Ming Date: Thu, 10 Apr 2008 15:06:42 +0000 (+0400) Subject: ACPICA: Fixes for Unload and DDBHandles X-Git-Tag: v2.6.26-rc1~101^2~20 X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=bc7a36ab74e09da7bb63e2477b0740ac992b290e;p=linux-2.6-omap-h63xx.git 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 Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index 251d84ba79b..ed560e656f9 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c @@ -895,14 +895,25 @@ static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc) } else if (obj_desc->reference.object) { if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_OPERAND) { - acpi_os_printf(" Target: %p [%s]\n", - obj_desc->reference.object, - acpi_ut_get_type_name(((union - acpi_operand_object - *)obj_desc-> - reference. - object)->common. - type)); + acpi_os_printf(" Target: %p", + obj_desc->reference.object); + if (obj_desc->reference.opcode == AML_LOAD_OP) { + /* + * For DDBHandle reference, + * obj_desc->Reference.Object is the table index + */ + acpi_os_printf(" [DDBHandle]\n"); + } else { + acpi_os_printf(" [%s]\n", + acpi_ut_get_type_name(((union + acpi_operand_object + *) + obj_desc-> + reference. + object)-> + common. + type)); + } } else { acpi_os_printf(" Target: %p\n", obj_desc->reference.object); diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c index 9c3cdf61dc3..5b5b2ff45ea 100644 --- a/drivers/acpi/executer/exresolv.c +++ b/drivers/acpi/executer/exresolv.c @@ -382,10 +382,10 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, } /* - * For reference objects created via the ref_of or Index operators, - * we need to get to the base object (as per the ACPI specification - * of the object_type and size_of operators). This means traversing - * the list of possibly many nested references. + * For reference objects created via the ref_of, Index, or Load/load_table + * operators, we need to get to the base object (as per the ACPI + * specification of the object_type and size_of operators). This means + * traversing the list of possibly many nested references. */ while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) { switch (obj_desc->reference.opcode) { @@ -455,6 +455,11 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, } break; + case AML_LOAD_OP: + + type = ACPI_TYPE_DDB_HANDLE; + goto exit; + case AML_LOCAL_OP: case AML_ARG_OP: diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c index 2408122cb3b..725614e277f 100644 --- a/drivers/acpi/executer/exstore.c +++ b/drivers/acpi/executer/exstore.c @@ -434,11 +434,24 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, */ obj_desc = *(index_desc->reference.where); - status = - acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, - walk_state); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + if (ACPI_GET_OBJECT_TYPE(source_desc) == + ACPI_TYPE_LOCAL_REFERENCE + && source_desc->reference.opcode == AML_LOAD_OP) { + + /* This is a DDBHandle, just add a reference to it */ + + acpi_ut_add_reference(source_desc); + new_desc = source_desc; + } else { + /* Normal object, copy it */ + + status = + acpi_ut_copy_iobject_to_iobject(source_desc, + &new_desc, + walk_state); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } } if (obj_desc) { diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c index 442880f5600..2a3a948dd11 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 */ diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c index b56953d2b59..ba899714733 100644 --- a/drivers/acpi/utilities/utcopy.c +++ b/drivers/acpi/utilities/utcopy.c @@ -709,7 +709,15 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, /* * We copied the reference object, so we now must add a reference * to the object pointed to by the reference + * + * DDBHandle reference (from Load/load_table is a special reference, + * it's Reference.Object is the table index, so does not need to + * increase the reference count */ + if (source_desc->reference.opcode == AML_LOAD_OP) { + break; + } + acpi_ut_add_reference(source_desc->reference.object); break;