diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/dispatcher/dsopcode.c | 103 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dswexec.c | 11 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dswload.c | 29 | ||||
-rw-r--r-- | drivers/acpi/executer/excreate.c | 95 | ||||
-rw-r--r-- | drivers/acpi/executer/exmutex.c | 16 | ||||
-rw-r--r-- | drivers/acpi/parser/psloop.c | 6 | ||||
-rw-r--r-- | drivers/acpi/parser/psopcode.c | 4 |
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 |
54 | ACPI_MODULE_NAME("dsopcode") | 55 | ACPI_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 | |||
798 | acpi_status | ||
799 | acpi_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 | |||
365 | acpi_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, |