diff options
| author | Lin Ming <ming.m.lin@intel.com> | 2008-04-10 11:06:42 -0400 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2008-04-22 14:29:30 -0400 |
| commit | bc7a36ab74e09da7bb63e2477b0740ac992b290e (patch) | |
| tree | f9384f3f0909e1da6f12fb55643de8de594551dd | |
| parent | a6f4a4511e65942b93ded60d746094ec0e58ed8e (diff) | |
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>
| -rw-r--r-- | drivers/acpi/executer/exdump.c | 27 | ||||
| -rw-r--r-- | drivers/acpi/executer/exresolv.c | 13 | ||||
| -rw-r--r-- | drivers/acpi/executer/exstore.c | 23 | ||||
| -rw-r--r-- | drivers/acpi/parser/psargs.c | 37 | ||||
| -rw-r--r-- | drivers/acpi/utilities/utcopy.c | 8 |
5 files changed, 88 insertions, 20 deletions
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index 251d84ba79..ed560e656f 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) | |||
| 895 | } else if (obj_desc->reference.object) { | 895 | } else if (obj_desc->reference.object) { |
| 896 | if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == | 896 | if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == |
| 897 | ACPI_DESC_TYPE_OPERAND) { | 897 | ACPI_DESC_TYPE_OPERAND) { |
| 898 | acpi_os_printf(" Target: %p [%s]\n", | 898 | acpi_os_printf(" Target: %p", |
| 899 | obj_desc->reference.object, | 899 | obj_desc->reference.object); |
| 900 | acpi_ut_get_type_name(((union | 900 | if (obj_desc->reference.opcode == AML_LOAD_OP) { |
| 901 | acpi_operand_object | 901 | /* |
| 902 | *)obj_desc-> | 902 | * For DDBHandle reference, |
| 903 | reference. | 903 | * obj_desc->Reference.Object is the table index |
| 904 | object)->common. | 904 | */ |
| 905 | type)); | 905 | acpi_os_printf(" [DDBHandle]\n"); |
| 906 | } else { | ||
| 907 | acpi_os_printf(" [%s]\n", | ||
| 908 | acpi_ut_get_type_name(((union | ||
| 909 | acpi_operand_object | ||
| 910 | *) | ||
| 911 | obj_desc-> | ||
| 912 | reference. | ||
| 913 | object)-> | ||
| 914 | common. | ||
| 915 | type)); | ||
| 916 | } | ||
| 906 | } else { | 917 | } else { |
| 907 | acpi_os_printf(" Target: %p\n", | 918 | acpi_os_printf(" Target: %p\n", |
| 908 | obj_desc->reference.object); | 919 | obj_desc->reference.object); |
diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c index 9c3cdf61dc..5b5b2ff45e 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, | |||
| 382 | } | 382 | } |
| 383 | 383 | ||
| 384 | /* | 384 | /* |
| 385 | * For reference objects created via the ref_of or Index operators, | 385 | * For reference objects created via the ref_of, Index, or Load/load_table |
| 386 | * we need to get to the base object (as per the ACPI specification | 386 | * operators, we need to get to the base object (as per the ACPI |
| 387 | * of the object_type and size_of operators). This means traversing | 387 | * specification of the object_type and size_of operators). This means |
| 388 | * the list of possibly many nested references. | 388 | * traversing the list of possibly many nested references. |
| 389 | */ | 389 | */ |
| 390 | while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) { | 390 | while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) { |
| 391 | switch (obj_desc->reference.opcode) { | 391 | switch (obj_desc->reference.opcode) { |
| @@ -455,6 +455,11 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, | |||
| 455 | } | 455 | } |
| 456 | break; | 456 | break; |
| 457 | 457 | ||
| 458 | case AML_LOAD_OP: | ||
| 459 | |||
| 460 | type = ACPI_TYPE_DDB_HANDLE; | ||
| 461 | goto exit; | ||
| 462 | |||
| 458 | case AML_LOCAL_OP: | 463 | case AML_LOCAL_OP: |
| 459 | case AML_ARG_OP: | 464 | case AML_ARG_OP: |
| 460 | 465 | ||
diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c index 2408122cb3..725614e277 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, | |||
| 434 | */ | 434 | */ |
| 435 | obj_desc = *(index_desc->reference.where); | 435 | obj_desc = *(index_desc->reference.where); |
| 436 | 436 | ||
| 437 | status = | 437 | if (ACPI_GET_OBJECT_TYPE(source_desc) == |
| 438 | acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, | 438 | ACPI_TYPE_LOCAL_REFERENCE |
| 439 | walk_state); | 439 | && source_desc->reference.opcode == AML_LOAD_OP) { |
| 440 | if (ACPI_FAILURE(status)) { | 440 | |
| 441 | return_ACPI_STATUS(status); | 441 | /* This is a DDBHandle, just add a reference to it */ |
| 442 | |||
| 443 | acpi_ut_add_reference(source_desc); | ||
| 444 | new_desc = source_desc; | ||
| 445 | } else { | ||
| 446 | /* Normal object, copy it */ | ||
| 447 | |||
| 448 | status = | ||
| 449 | acpi_ut_copy_iobject_to_iobject(source_desc, | ||
| 450 | &new_desc, | ||
| 451 | walk_state); | ||
| 452 | if (ACPI_FAILURE(status)) { | ||
| 453 | return_ACPI_STATUS(status); | ||
| 454 | } | ||
| 442 | } | 455 | } |
| 443 | 456 | ||
| 444 | if (obj_desc) { | 457 | if (obj_desc) { |
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c index 442880f560..2a3a948dd1 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, | |||
| 235 | union acpi_parse_object *name_op; | 235 | union acpi_parse_object *name_op; |
| 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 | u8 *start = parser_state->aml; | ||
| 238 | 239 | ||
| 239 | ACPI_FUNCTION_TRACE(ps_get_next_namepath); | 240 | ACPI_FUNCTION_TRACE(ps_get_next_namepath); |
| 240 | 241 | ||
| @@ -267,6 +268,16 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, | |||
| 267 | */ | 268 | */ |
| 268 | if (ACPI_SUCCESS(status) && | 269 | if (ACPI_SUCCESS(status) && |
| 269 | 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 | } | ||
| 270 | 281 | ||
| 271 | /* This name is actually a control method invocation */ | 282 | /* This name is actually a control method invocation */ |
| 272 | 283 | ||
| @@ -678,9 +689,29 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, | |||
| 678 | return_ACPI_STATUS(AE_NO_MEMORY); | 689 | return_ACPI_STATUS(AE_NO_MEMORY); |
| 679 | } | 690 | } |
| 680 | 691 | ||
| 681 | status = | 692 | /* To support super_name arg of Unload */ |
| 682 | acpi_ps_get_next_namepath(walk_state, parser_state, | 693 | |
| 683 | 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 | } | ||
| 684 | } else { | 715 | } else { |
| 685 | /* Single complex argument, nothing returned */ | 716 | /* Single complex argument, nothing returned */ |
| 686 | 717 | ||
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c index b56953d2b5..ba89971473 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, | |||
| 709 | /* | 709 | /* |
| 710 | * We copied the reference object, so we now must add a reference | 710 | * We copied the reference object, so we now must add a reference |
| 711 | * to the object pointed to by the reference | 711 | * to the object pointed to by the reference |
| 712 | * | ||
| 713 | * DDBHandle reference (from Load/load_table is a special reference, | ||
| 714 | * it's Reference.Object is the table index, so does not need to | ||
| 715 | * increase the reference count | ||
| 712 | */ | 716 | */ |
| 717 | if (source_desc->reference.opcode == AML_LOAD_OP) { | ||
| 718 | break; | ||
| 719 | } | ||
| 720 | |||
| 713 | acpi_ut_add_reference(source_desc->reference.object); | 721 | acpi_ut_add_reference(source_desc->reference.object); |
| 714 | break; | 722 | break; |
| 715 | 723 | ||
