aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
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,