aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorLin Ming <ming.m.lin@intel.com>2008-04-10 11:06:41 -0400
committerLen Brown <len.brown@intel.com>2008-04-22 14:29:28 -0400
commit941f48bb465b0b291f8435b1e3de95b0975b84bc (patch)
tree42327b3d29fbaa55827abfe620a94320f86b6eb4 /drivers/acpi
parent9aa6169f471771324b476a90d9392daa06d63a2d (diff)
ACPICA: Implemented full support for deferred execution for the TermArg string arguments for DataTableRegion
This enables forward references and full operand resolution for the three string arguments. Similar to OperationRegion deferred argument execution.) http://www.acpica.org/bugzilla/show_bug.cgi?id=430 Signed-off-by: Lin Ming <ming.m.lin@intel.com> 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')
-rw-r--r--drivers/acpi/dispatcher/dsopcode.c103
-rw-r--r--drivers/acpi/dispatcher/dswexec.c11
-rw-r--r--drivers/acpi/dispatcher/dswload.c29
-rw-r--r--drivers/acpi/executer/excreate.c95
-rw-r--r--drivers/acpi/executer/exmutex.c16
-rw-r--r--drivers/acpi/parser/psloop.c6
-rw-r--r--drivers/acpi/parser/psopcode.c4
7 files changed, 156 insertions, 108 deletions
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
index f0847eed5f3a..a3f29798d1d1 100644
--- a/drivers/acpi/dispatcher/dsopcode.c
+++ b/drivers/acpi/dispatcher/dsopcode.c
@@ -49,6 +49,7 @@
49#include <acpi/acinterp.h> 49#include <acpi/acinterp.h>
50#include <acpi/acnamesp.h> 50#include <acpi/acnamesp.h>
51#include <acpi/acevents.h> 51#include <acpi/acevents.h>
52#include <acpi/actables.h>
52 53
53#define _COMPONENT ACPI_DISPATCHER 54#define _COMPONENT ACPI_DISPATCHER
54ACPI_MODULE_NAME("dsopcode") 55ACPI_MODULE_NAME("dsopcode")
@@ -782,6 +783,108 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,
782 783
783/******************************************************************************* 784/*******************************************************************************
784 * 785 *
786 * FUNCTION: acpi_ds_eval_table_region_operands
787 *
788 * PARAMETERS: walk_state - Current walk
789 * Op - A valid region Op object
790 *
791 * RETURN: Status
792 *
793 * DESCRIPTION: Get region address and length
794 * Called from acpi_ds_exec_end_op during data_table_region parse tree walk
795 *
796 ******************************************************************************/
797
798acpi_status
799acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
800 union acpi_parse_object *op)
801{
802 acpi_status status;
803 union acpi_operand_object *obj_desc;
804 union acpi_operand_object **operand;
805 struct acpi_namespace_node *node;
806 union acpi_parse_object *next_op;
807 acpi_native_uint table_index;
808 struct acpi_table_header *table;
809
810 ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op);
811
812 /*
813 * This is where we evaluate the signature_string and oem_iDString
814 * and oem_table_iDString of the data_table_region declaration
815 */
816 node = op->common.node;
817
818 /* next_op points to signature_string op */
819
820 next_op = op->common.value.arg;
821
822 /*
823 * Evaluate/create the signature_string and oem_iDString
824 * and oem_table_iDString operands
825 */
826 status = acpi_ds_create_operands(walk_state, next_op);
827 if (ACPI_FAILURE(status)) {
828 return_ACPI_STATUS(status);
829 }
830
831 /*
832 * Resolve the signature_string and oem_iDString
833 * and oem_table_iDString operands
834 */
835 status = acpi_ex_resolve_operands(op->common.aml_opcode,
836 ACPI_WALK_OPERANDS, walk_state);
837 if (ACPI_FAILURE(status)) {
838 return_ACPI_STATUS(status);
839 }
840
841 ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
842 acpi_ps_get_opcode_name(op->common.aml_opcode),
843 1, "after AcpiExResolveOperands");
844
845 operand = &walk_state->operands[0];
846
847 /* Find the ACPI table */
848
849 status = acpi_tb_find_table(operand[0]->string.pointer,
850 operand[1]->string.pointer,
851 operand[2]->string.pointer, &table_index);
852 if (ACPI_FAILURE(status)) {
853 return_ACPI_STATUS(status);
854 }
855
856 acpi_ut_remove_reference(operand[0]);
857 acpi_ut_remove_reference(operand[1]);
858 acpi_ut_remove_reference(operand[2]);
859
860 status = acpi_get_table_by_index(table_index, &table);
861 if (ACPI_FAILURE(status)) {
862 return_ACPI_STATUS(status);
863 }
864
865 obj_desc = acpi_ns_get_attached_object(node);
866 if (!obj_desc) {
867 return_ACPI_STATUS(AE_NOT_EXIST);
868 }
869
870 obj_desc->region.address =
871 (acpi_physical_address) ACPI_TO_INTEGER(table);
872 obj_desc->region.length = table->length;
873
874 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
875 obj_desc,
876 ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address),
877 obj_desc->region.length));
878
879 /* Now the address and length are valid for this opregion */
880
881 obj_desc->region.flags |= AOPOBJ_DATA_VALID;
882
883 return_ACPI_STATUS(status);
884}
885
886/*******************************************************************************
887 *
785 * FUNCTION: acpi_ds_eval_data_object_operands 888 * FUNCTION: acpi_ds_eval_data_object_operands
786 * 889 *
787 * PARAMETERS: walk_state - Current walk 890 * PARAMETERS: walk_state - Current walk
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
index 6af4671e51a1..8ba4bb36af9f 100644
--- a/drivers/acpi/dispatcher/dswexec.c
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -641,6 +641,17 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
641 if (ACPI_FAILURE(status)) { 641 if (ACPI_FAILURE(status)) {
642 break; 642 break;
643 } 643 }
644 } else if (op->common.aml_opcode == AML_DATA_REGION_OP) {
645 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
646 "Executing DataTableRegion Strings Op=%p\n",
647 op));
648
649 status =
650 acpi_ds_eval_table_region_operands
651 (walk_state, op);
652 if (ACPI_FAILURE(status)) {
653 break;
654 }
644 } 655 }
645 break; 656 break;
646 657
diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c
index 8ab9d1b29a4c..ec68c1df3932 100644
--- a/drivers/acpi/dispatcher/dswload.c
+++ b/drivers/acpi/dispatcher/dswload.c
@@ -443,6 +443,15 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state)
443 if (ACPI_FAILURE(status)) { 443 if (ACPI_FAILURE(status)) {
444 return_ACPI_STATUS(status); 444 return_ACPI_STATUS(status);
445 } 445 }
446 } else if (op->common.aml_opcode == AML_DATA_REGION_OP) {
447 status =
448 acpi_ex_create_region(op->named.data,
449 op->named.length,
450 REGION_DATA_TABLE,
451 walk_state);
452 if (ACPI_FAILURE(status)) {
453 return_ACPI_STATUS(status);
454 }
446 } 455 }
447 } 456 }
448#endif 457#endif
@@ -823,6 +832,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
823 struct acpi_namespace_node *new_node; 832 struct acpi_namespace_node *new_node;
824#ifndef ACPI_NO_METHOD_EXECUTION 833#ifndef ACPI_NO_METHOD_EXECUTION
825 u32 i; 834 u32 i;
835 u8 region_space;
826#endif 836#endif
827 837
828 ACPI_FUNCTION_TRACE(ds_load2_end_op); 838 ACPI_FUNCTION_TRACE(ds_load2_end_op);
@@ -1003,11 +1013,6 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
1003 status = acpi_ex_create_event(walk_state); 1013 status = acpi_ex_create_event(walk_state);
1004 break; 1014 break;
1005 1015
1006 case AML_DATA_REGION_OP:
1007
1008 status = acpi_ex_create_table_region(walk_state);
1009 break;
1010
1011 case AML_ALIAS_OP: 1016 case AML_ALIAS_OP:
1012 1017
1013 status = acpi_ex_create_alias(walk_state); 1018 status = acpi_ex_create_alias(walk_state);
@@ -1035,6 +1040,15 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
1035 switch (op->common.aml_opcode) { 1040 switch (op->common.aml_opcode) {
1036#ifndef ACPI_NO_METHOD_EXECUTION 1041#ifndef ACPI_NO_METHOD_EXECUTION
1037 case AML_REGION_OP: 1042 case AML_REGION_OP:
1043 case AML_DATA_REGION_OP:
1044
1045 if (op->common.aml_opcode == AML_REGION_OP) {
1046 region_space = (acpi_adr_space_type)
1047 ((op->common.value.arg)->common.value.
1048 integer);
1049 } else {
1050 region_space = REGION_DATA_TABLE;
1051 }
1038 1052
1039 /* 1053 /*
1040 * If we are executing a method, initialize the region 1054 * If we are executing a method, initialize the region
@@ -1043,10 +1057,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
1043 status = 1057 status =
1044 acpi_ex_create_region(op->named.data, 1058 acpi_ex_create_region(op->named.data,
1045 op->named.length, 1059 op->named.length,
1046 (acpi_adr_space_type) 1060 region_space,
1047 ((op->common.value.
1048 arg)->common.value.
1049 integer),
1050 walk_state); 1061 walk_state);
1051 if (ACPI_FAILURE(status)) { 1062 if (ACPI_FAILURE(status)) {
1052 return (status); 1063 return (status);
diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c
index b3914395851b..0396bd4819f1 100644
--- a/drivers/acpi/executer/excreate.c
+++ b/drivers/acpi/executer/excreate.c
@@ -352,101 +352,6 @@ acpi_ex_create_region(u8 * aml_start,
352 352
353/******************************************************************************* 353/*******************************************************************************
354 * 354 *
355 * FUNCTION: acpi_ex_create_table_region
356 *
357 * PARAMETERS: walk_state - Current state
358 *
359 * RETURN: Status
360 *
361 * DESCRIPTION: Create a new data_table_region object
362 *
363 ******************************************************************************/
364
365acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state)
366{
367 acpi_status status;
368 union acpi_operand_object **operand = &walk_state->operands[0];
369 union acpi_operand_object *obj_desc;
370 struct acpi_namespace_node *node;
371 union acpi_operand_object *region_obj2;
372 acpi_native_uint table_index;
373 struct acpi_table_header *table;
374
375 ACPI_FUNCTION_TRACE(ex_create_table_region);
376
377 /* Get the Node from the object stack */
378
379 node = walk_state->op->common.node;
380
381 /*
382 * If the region object is already attached to this node,
383 * just return
384 */
385 if (acpi_ns_get_attached_object(node)) {
386 return_ACPI_STATUS(AE_OK);
387 }
388
389 /* Find the ACPI table */
390
391 status = acpi_tb_find_table(operand[1]->string.pointer,
392 operand[2]->string.pointer,
393 operand[3]->string.pointer, &table_index);
394 if (ACPI_FAILURE(status)) {
395 return_ACPI_STATUS(status);
396 }
397
398 /* Create the region descriptor */
399
400 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION);
401 if (!obj_desc) {
402 return_ACPI_STATUS(AE_NO_MEMORY);
403 }
404
405 region_obj2 = obj_desc->common.next_object;
406 region_obj2->extra.region_context = NULL;
407
408 status = acpi_get_table_by_index(table_index, &table);
409 if (ACPI_FAILURE(status)) {
410 return_ACPI_STATUS(status);
411 }
412
413 /* Init the region from the operands */
414
415 obj_desc->region.space_id = REGION_DATA_TABLE;
416 obj_desc->region.address =
417 (acpi_physical_address) ACPI_TO_INTEGER(table);
418 obj_desc->region.length = table->length;
419 obj_desc->region.node = node;
420 obj_desc->region.flags = AOPOBJ_DATA_VALID;
421
422 /* Install the new region object in the parent Node */
423
424 status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_REGION);
425 if (ACPI_FAILURE(status)) {
426 goto cleanup;
427 }
428
429 status = acpi_ev_initialize_region(obj_desc, FALSE);
430 if (ACPI_FAILURE(status)) {
431 if (status == AE_NOT_EXIST) {
432 status = AE_OK;
433 } else {
434 goto cleanup;
435 }
436 }
437
438 obj_desc->region.flags |= AOPOBJ_SETUP_COMPLETE;
439
440 cleanup:
441
442 /* Remove local reference to the object */
443
444 acpi_ut_remove_reference(obj_desc);
445 return_ACPI_STATUS(status);
446}
447
448/*******************************************************************************
449 *
450 * FUNCTION: acpi_ex_create_processor 355 * FUNCTION: acpi_ex_create_processor
451 * 356 *
452 * PARAMETERS: walk_state - Current state 357 * PARAMETERS: walk_state - Current state
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
index b8d035c00b61..7c70938eef89 100644
--- a/drivers/acpi/executer/exmutex.c
+++ b/drivers/acpi/executer/exmutex.c
@@ -85,6 +85,7 @@ void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc)
85 } else { 85 } else {
86 thread->acquired_mutex_list = obj_desc->mutex.next; 86 thread->acquired_mutex_list = obj_desc->mutex.next;
87 } 87 }
88 return;
88} 89}
89 90
90/******************************************************************************* 91/*******************************************************************************
@@ -298,6 +299,17 @@ acpi_status acpi_ex_release_mutex_object(union acpi_operand_object *obj_desc)
298 return (AE_NOT_ACQUIRED); 299 return (AE_NOT_ACQUIRED);
299 } 300 }
300 301
302 /* No obj_desc->Mutex.owner_thread for Global Lock */
303
304 /*
305 * Mutex to be released must be at the head of acquired list to prevent
306 * deadlock. (The head of the list is the last mutex acquired.)
307 */
308 if (obj_desc->mutex.owner_thread &&
309 (obj_desc != obj_desc->mutex.owner_thread->acquired_mutex_list)) {
310 return (AE_AML_MUTEX_ORDER);
311 }
312
301 /* Match multiple Acquires with multiple Releases */ 313 /* Match multiple Acquires with multiple Releases */
302 314
303 obj_desc->mutex.acquisition_depth--; 315 obj_desc->mutex.acquisition_depth--;
@@ -403,6 +415,9 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
403 } 415 }
404 416
405 status = acpi_ex_release_mutex_object(obj_desc); 417 status = acpi_ex_release_mutex_object(obj_desc);
418 if (ACPI_FAILURE(status)) {
419 return_ACPI_STATUS(status);
420 }
406 421
407 if (obj_desc->mutex.acquisition_depth == 0) { 422 if (obj_desc->mutex.acquisition_depth == 0) {
408 423
@@ -411,6 +426,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
411 walk_state->thread->current_sync_level = 426 walk_state->thread->current_sync_level =
412 obj_desc->mutex.original_sync_level; 427 obj_desc->mutex.original_sync_level;
413 } 428 }
429
414 return_ACPI_STATUS(status); 430 return_ACPI_STATUS(status);
415} 431}
416 432
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c
index 4348b0530398..a079975f671f 100644
--- a/drivers/acpi/parser/psloop.c
+++ b/drivers/acpi/parser/psloop.c
@@ -242,7 +242,8 @@ acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
242 acpi_ps_append_arg(*op, unnamed_op->common.value.arg); 242 acpi_ps_append_arg(*op, unnamed_op->common.value.arg);
243 acpi_gbl_depth++; 243 acpi_gbl_depth++;
244 244
245 if ((*op)->common.aml_opcode == AML_REGION_OP) { 245 if ((*op)->common.aml_opcode == AML_REGION_OP ||
246 (*op)->common.aml_opcode == AML_DATA_REGION_OP) {
246 /* 247 /*
247 * Defer final parsing of an operation_region body, because we don't 248 * Defer final parsing of an operation_region body, because we don't
248 * have enough info in the first pass to parse it correctly (i.e., 249 * have enough info in the first pass to parse it correctly (i.e.,
@@ -1013,7 +1014,8 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
1013 acpi_gbl_depth--; 1014 acpi_gbl_depth--;
1014 } 1015 }
1015 1016
1016 if (op->common.aml_opcode == AML_REGION_OP) { 1017 if (op->common.aml_opcode == AML_REGION_OP ||
1018 op->common.aml_opcode == AML_DATA_REGION_OP) {
1017 /* 1019 /*
1018 * Skip parsing of control method or opregion body, 1020 * Skip parsing of control method or opregion body,
1019 * because we don't have enough info in the first pass 1021 * because we don't have enough info in the first pass
diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c
index 153621d0c464..b273a0a127e6 100644
--- a/drivers/acpi/parser/psopcode.c
+++ b/drivers/acpi/parser/psopcode.c
@@ -624,9 +624,9 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = {
624 AML_TYPE_EXEC_6A_0T_1R, AML_FLAGS_EXEC_6A_0T_1R), 624 AML_TYPE_EXEC_6A_0T_1R, AML_FLAGS_EXEC_6A_0T_1R),
625/* 7C */ ACPI_OP("DataTableRegion", ARGP_DATA_REGION_OP, 625/* 7C */ ACPI_OP("DataTableRegion", ARGP_DATA_REGION_OP,
626 ARGI_DATA_REGION_OP, ACPI_TYPE_REGION, 626 ARGI_DATA_REGION_OP, ACPI_TYPE_REGION,
627 AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, 627 AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_COMPLEX,
628 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | 628 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
629 AML_NSNODE | AML_NAMED), 629 AML_NSNODE | AML_NAMED | AML_DEFER),
630/* 7D */ ACPI_OP("[EvalSubTree]", ARGP_SCOPE_OP, ARGI_SCOPE_OP, 630/* 7D */ ACPI_OP("[EvalSubTree]", ARGP_SCOPE_OP, ARGI_SCOPE_OP,
631 ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, 631 ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT,
632 AML_TYPE_NAMED_NO_OBJ, 632 AML_TYPE_NAMED_NO_OBJ,