diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/dispatcher/dsutils.c | 113 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dswexec.c | 11 | ||||
-rw-r--r-- | drivers/acpi/executer/exutils.c | 3 | ||||
-rw-r--r-- | drivers/acpi/parser/psloop.c | 23 | ||||
-rw-r--r-- | drivers/acpi/parser/psopcode.c | 26 | ||||
-rw-r--r-- | drivers/acpi/parser/pstree.c | 2 |
6 files changed, 170 insertions, 8 deletions
diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c index d2a8cfdaec22..36518b4a79c2 100644 --- a/drivers/acpi/dispatcher/dsutils.c +++ b/drivers/acpi/dispatcher/dsutils.c | |||
@@ -472,7 +472,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, | |||
472 | /* A valid name must be looked up in the namespace */ | 472 | /* A valid name must be looked up in the namespace */ |
473 | 473 | ||
474 | if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) && | 474 | if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) && |
475 | (arg->common.value.string)) { | 475 | (arg->common.value.string) && |
476 | !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) { | ||
476 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", | 477 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", |
477 | arg)); | 478 | arg)); |
478 | 479 | ||
@@ -595,7 +596,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, | |||
595 | } else { | 596 | } else { |
596 | /* Check for null name case */ | 597 | /* Check for null name case */ |
597 | 598 | ||
598 | if (arg->common.aml_opcode == AML_INT_NAMEPATH_OP) { | 599 | if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) && |
600 | !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) { | ||
599 | /* | 601 | /* |
600 | * If the name is null, this means that this is an | 602 | * If the name is null, this means that this is an |
601 | * optional result parameter that was not specified | 603 | * optional result parameter that was not specified |
@@ -617,7 +619,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, | |||
617 | return_ACPI_STATUS(AE_NOT_IMPLEMENTED); | 619 | return_ACPI_STATUS(AE_NOT_IMPLEMENTED); |
618 | } | 620 | } |
619 | 621 | ||
620 | if (op_info->flags & AML_HAS_RETVAL) { | 622 | if ((op_info->flags & AML_HAS_RETVAL) |
623 | || (arg->common.flags & ACPI_PARSEOP_IN_STACK)) { | ||
621 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | 624 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, |
622 | "Argument previously created, already stacked\n")); | 625 | "Argument previously created, already stacked\n")); |
623 | 626 | ||
@@ -759,3 +762,107 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, | |||
759 | ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", index)); | 762 | ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", index)); |
760 | return_ACPI_STATUS(status); | 763 | return_ACPI_STATUS(status); |
761 | } | 764 | } |
765 | |||
766 | /***************************************************************************** | ||
767 | * | ||
768 | * FUNCTION: acpi_ds_evaluate_name_path | ||
769 | * | ||
770 | * PARAMETERS: walk_state - Current state of the parse tree walk, | ||
771 | * the opcode of current operation should be | ||
772 | * AML_INT_NAMEPATH_OP | ||
773 | * | ||
774 | * RETURN: Status | ||
775 | * | ||
776 | * DESCRIPTION: Translate the -name_path- parse tree object to the equivalent | ||
777 | * interpreter object, convert it to value, if needed, duplicate | ||
778 | * it, if needed, and push it onto the current result stack. | ||
779 | * | ||
780 | ****************************************************************************/ | ||
781 | |||
782 | acpi_status acpi_ds_evaluate_name_path(struct acpi_walk_state *walk_state) | ||
783 | { | ||
784 | acpi_status status = AE_OK; | ||
785 | union acpi_parse_object *op = walk_state->op; | ||
786 | union acpi_operand_object **operand = &walk_state->operands[0]; | ||
787 | union acpi_operand_object *new_obj_desc; | ||
788 | u8 type; | ||
789 | |||
790 | ACPI_FUNCTION_TRACE_PTR(ds_evaluate_name_path, walk_state); | ||
791 | |||
792 | if (!op->common.parent) { | ||
793 | |||
794 | /* This happens after certain exception processing */ | ||
795 | |||
796 | goto exit; | ||
797 | } | ||
798 | |||
799 | if ((op->common.parent->common.aml_opcode == AML_PACKAGE_OP) || | ||
800 | (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP) || | ||
801 | (op->common.parent->common.aml_opcode == AML_REF_OF_OP)) { | ||
802 | |||
803 | /* TBD: Should we specify this feature as a bit of op_info->Flags of these opcodes? */ | ||
804 | |||
805 | goto exit; | ||
806 | } | ||
807 | |||
808 | status = acpi_ds_create_operand(walk_state, op, 0); | ||
809 | if (ACPI_FAILURE(status)) { | ||
810 | goto exit; | ||
811 | } | ||
812 | |||
813 | if (op->common.flags & ACPI_PARSEOP_TARGET) { | ||
814 | new_obj_desc = *operand; | ||
815 | goto push_result; | ||
816 | } | ||
817 | |||
818 | type = ACPI_GET_OBJECT_TYPE(*operand); | ||
819 | |||
820 | status = acpi_ex_resolve_to_value(operand, walk_state); | ||
821 | if (ACPI_FAILURE(status)) { | ||
822 | goto exit; | ||
823 | } | ||
824 | |||
825 | if (type == ACPI_TYPE_INTEGER) { | ||
826 | |||
827 | /* It was incremented by acpi_ex_resolve_to_value */ | ||
828 | |||
829 | acpi_ut_remove_reference(*operand); | ||
830 | |||
831 | status = | ||
832 | acpi_ut_copy_iobject_to_iobject(*operand, &new_obj_desc, | ||
833 | walk_state); | ||
834 | if (ACPI_FAILURE(status)) { | ||
835 | goto exit; | ||
836 | } | ||
837 | } else { | ||
838 | /* | ||
839 | * The object either was anew created or is | ||
840 | * a Namespace node - don't decrement it. | ||
841 | */ | ||
842 | new_obj_desc = *operand; | ||
843 | } | ||
844 | |||
845 | /* Cleanup for name-path operand */ | ||
846 | |||
847 | status = acpi_ds_obj_stack_pop(1, walk_state); | ||
848 | if (ACPI_FAILURE(status)) { | ||
849 | walk_state->result_obj = new_obj_desc; | ||
850 | goto exit; | ||
851 | } | ||
852 | |||
853 | push_result: | ||
854 | |||
855 | walk_state->result_obj = new_obj_desc; | ||
856 | |||
857 | status = acpi_ds_result_push(walk_state->result_obj, walk_state); | ||
858 | if (ACPI_SUCCESS(status)) { | ||
859 | |||
860 | /* Force to take it from stack */ | ||
861 | |||
862 | op->common.flags |= ACPI_PARSEOP_IN_STACK; | ||
863 | } | ||
864 | |||
865 | exit: | ||
866 | |||
867 | return_ACPI_STATUS(status); | ||
868 | } | ||
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c index 12b148587e3d..514b9d2eb3a7 100644 --- a/drivers/acpi/dispatcher/dswexec.c +++ b/drivers/acpi/dispatcher/dswexec.c | |||
@@ -375,10 +375,17 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) | |||
375 | /* Decode the Opcode Class */ | 375 | /* Decode the Opcode Class */ |
376 | 376 | ||
377 | switch (op_class) { | 377 | switch (op_class) { |
378 | case AML_CLASS_ARGUMENT: /* constants, literals, etc. - do nothing */ | 378 | case AML_CLASS_ARGUMENT: /* Constants, literals, etc. */ |
379 | |||
380 | if (walk_state->opcode == AML_INT_NAMEPATH_OP) { | ||
381 | status = acpi_ds_evaluate_name_path(walk_state); | ||
382 | if (ACPI_FAILURE(status)) { | ||
383 | goto cleanup; | ||
384 | } | ||
385 | } | ||
379 | break; | 386 | break; |
380 | 387 | ||
381 | case AML_CLASS_EXECUTE: /* most operators with arguments */ | 388 | case AML_CLASS_EXECUTE: /* Most operators with arguments */ |
382 | 389 | ||
383 | /* Build resolved operand stack */ | 390 | /* Build resolved operand stack */ |
384 | 391 | ||
diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c index c0837af0acb1..c40b191f70b5 100644 --- a/drivers/acpi/executer/exutils.c +++ b/drivers/acpi/executer/exutils.c | |||
@@ -217,9 +217,10 @@ void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc) | |||
217 | 217 | ||
218 | /* | 218 | /* |
219 | * Object must be a valid number and we must be executing | 219 | * Object must be a valid number and we must be executing |
220 | * a control method | 220 | * a control method. NS node could be there for AML_INT_NAMEPATH_OP. |
221 | */ | 221 | */ |
222 | if ((!obj_desc) || | 222 | if ((!obj_desc) || |
223 | (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) || | ||
223 | (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) { | 224 | (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) { |
224 | return; | 225 | return; |
225 | } | 226 | } |
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c index 266dd0c10218..4348b0530398 100644 --- a/drivers/acpi/parser/psloop.c +++ b/drivers/acpi/parser/psloop.c | |||
@@ -182,6 +182,7 @@ acpi_ps_build_named_op(struct acpi_walk_state *walk_state, | |||
182 | ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state); | 182 | ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state); |
183 | 183 | ||
184 | unnamed_op->common.value.arg = NULL; | 184 | unnamed_op->common.value.arg = NULL; |
185 | unnamed_op->common.arg_list_length = 0; | ||
185 | unnamed_op->common.aml_opcode = walk_state->opcode; | 186 | unnamed_op->common.aml_opcode = walk_state->opcode; |
186 | 187 | ||
187 | /* | 188 | /* |
@@ -280,6 +281,9 @@ acpi_ps_create_op(struct acpi_walk_state *walk_state, | |||
280 | acpi_status status = AE_OK; | 281 | acpi_status status = AE_OK; |
281 | union acpi_parse_object *op; | 282 | union acpi_parse_object *op; |
282 | union acpi_parse_object *named_op = NULL; | 283 | union acpi_parse_object *named_op = NULL; |
284 | union acpi_parse_object *parent_scope; | ||
285 | u8 argument_count; | ||
286 | const struct acpi_opcode_info *op_info; | ||
283 | 287 | ||
284 | ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state); | 288 | ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state); |
285 | 289 | ||
@@ -320,8 +324,23 @@ acpi_ps_create_op(struct acpi_walk_state *walk_state, | |||
320 | op->named.length = 0; | 324 | op->named.length = 0; |
321 | } | 325 | } |
322 | 326 | ||
323 | acpi_ps_append_arg(acpi_ps_get_parent_scope | 327 | parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state)); |
324 | (&(walk_state->parser_state)), op); | 328 | acpi_ps_append_arg(parent_scope, op); |
329 | |||
330 | if (parent_scope) { | ||
331 | op_info = | ||
332 | acpi_ps_get_opcode_info(parent_scope->common.aml_opcode); | ||
333 | if (op_info->flags & AML_HAS_TARGET) { | ||
334 | argument_count = | ||
335 | acpi_ps_get_argument_count(op_info->type); | ||
336 | if (parent_scope->common.arg_list_length > | ||
337 | argument_count) { | ||
338 | op->common.flags |= ACPI_PARSEOP_TARGET; | ||
339 | } | ||
340 | } else if (parent_scope->common.aml_opcode == AML_INCREMENT_OP) { | ||
341 | op->common.flags |= ACPI_PARSEOP_TARGET; | ||
342 | } | ||
343 | } | ||
325 | 344 | ||
326 | if (walk_state->descending_callback != NULL) { | 345 | if (walk_state->descending_callback != NULL) { |
327 | /* | 346 | /* |
diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c index 9296e86761d7..3bf8105d6348 100644 --- a/drivers/acpi/parser/psopcode.c +++ b/drivers/acpi/parser/psopcode.c | |||
@@ -49,6 +49,8 @@ | |||
49 | #define _COMPONENT ACPI_PARSER | 49 | #define _COMPONENT ACPI_PARSER |
50 | ACPI_MODULE_NAME("psopcode") | 50 | ACPI_MODULE_NAME("psopcode") |
51 | 51 | ||
52 | const u8 acpi_gbl_argument_count[] = { 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 6 }; | ||
53 | |||
52 | /******************************************************************************* | 54 | /******************************************************************************* |
53 | * | 55 | * |
54 | * NAME: acpi_gbl_aml_op_info | 56 | * NAME: acpi_gbl_aml_op_info |
@@ -59,6 +61,7 @@ ACPI_MODULE_NAME("psopcode") | |||
59 | * the operand type. | 61 | * the operand type. |
60 | * | 62 | * |
61 | ******************************************************************************/ | 63 | ******************************************************************************/ |
64 | |||
62 | /* | 65 | /* |
63 | * Summary of opcode types/flags | 66 | * Summary of opcode types/flags |
64 | * | 67 | * |
@@ -176,6 +179,7 @@ ACPI_MODULE_NAME("psopcode") | |||
176 | AML_CREATE_QWORD_FIELD_OP | 179 | AML_CREATE_QWORD_FIELD_OP |
177 | 180 | ||
178 | ******************************************************************************/ | 181 | ******************************************************************************/ |
182 | |||
179 | /* | 183 | /* |
180 | * Master Opcode information table. A summary of everything we know about each | 184 | * Master Opcode information table. A summary of everything we know about each |
181 | * opcode, all in one place. | 185 | * opcode, all in one place. |
@@ -779,3 +783,25 @@ char *acpi_ps_get_opcode_name(u16 opcode) | |||
779 | 783 | ||
780 | #endif | 784 | #endif |
781 | } | 785 | } |
786 | |||
787 | /******************************************************************************* | ||
788 | * | ||
789 | * FUNCTION: acpi_ps_get_argument_count | ||
790 | * | ||
791 | * PARAMETERS: op_type - Type associated with the AML opcode | ||
792 | * | ||
793 | * RETURN: Argument count | ||
794 | * | ||
795 | * DESCRIPTION: Obtain the number of expected arguments for an AML opcode | ||
796 | * | ||
797 | ******************************************************************************/ | ||
798 | |||
799 | u8 acpi_ps_get_argument_count(u32 op_type) | ||
800 | { | ||
801 | |||
802 | if (op_type <= AML_TYPE_EXEC_6A_0T_1R) { | ||
803 | return (acpi_gbl_argument_count[op_type]); | ||
804 | } | ||
805 | |||
806 | return (0); | ||
807 | } | ||
diff --git a/drivers/acpi/parser/pstree.c b/drivers/acpi/parser/pstree.c index 966e7ea2a0c4..0e1a3226665d 100644 --- a/drivers/acpi/parser/pstree.c +++ b/drivers/acpi/parser/pstree.c | |||
@@ -171,6 +171,8 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg) | |||
171 | while (arg) { | 171 | while (arg) { |
172 | arg->common.parent = op; | 172 | arg->common.parent = op; |
173 | arg = arg->common.next; | 173 | arg = arg->common.next; |
174 | |||
175 | op->common.arg_list_length++; | ||
174 | } | 176 | } |
175 | } | 177 | } |
176 | 178 | ||