aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLin Ming <ming.m.lin@intel.com>2008-04-10 11:06:42 -0400
committerLen Brown <len.brown@intel.com>2008-04-22 14:29:30 -0400
commitbc7a36ab74e09da7bb63e2477b0740ac992b290e (patch)
treef9384f3f0909e1da6f12fb55643de8de594551dd
parenta6f4a4511e65942b93ded60d746094ec0e58ed8e (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.c27
-rw-r--r--drivers/acpi/executer/exresolv.c13
-rw-r--r--drivers/acpi/executer/exstore.c23
-rw-r--r--drivers/acpi/parser/psargs.c37
-rw-r--r--drivers/acpi/utilities/utcopy.c8
5 files changed, 88 insertions, 20 deletions
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
index 251d84ba79b3..ed560e656f9a 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 9c3cdf61dc34..5b5b2ff45ea2 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 2408122cb3b2..725614e277f8 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 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,
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 b56953d2b59e..ba899714733b 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