aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/dispatcher/dsutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/dispatcher/dsutils.c')
-rw-r--r--drivers/acpi/dispatcher/dsutils.c167
1 files changed, 149 insertions, 18 deletions
diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c
index 71503c036f7c..b398982f0d8b 100644
--- a/drivers/acpi/dispatcher/dsutils.c
+++ b/drivers/acpi/dispatcher/dsutils.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -278,7 +278,9 @@ acpi_ds_is_result_used(union acpi_parse_object * op,
278 AML_VAR_PACKAGE_OP) 278 AML_VAR_PACKAGE_OP)
279 || (op->common.parent->common.aml_opcode == AML_BUFFER_OP) 279 || (op->common.parent->common.aml_opcode == AML_BUFFER_OP)
280 || (op->common.parent->common.aml_opcode == 280 || (op->common.parent->common.aml_opcode ==
281 AML_INT_EVAL_SUBTREE_OP)) { 281 AML_INT_EVAL_SUBTREE_OP)
282 || (op->common.parent->common.aml_opcode ==
283 AML_BANK_FIELD_OP)) {
282 /* 284 /*
283 * These opcodes allow term_arg(s) as operands and therefore 285 * These opcodes allow term_arg(s) as operands and therefore
284 * the operands can be method calls. The result is used. 286 * the operands can be method calls. The result is used.
@@ -472,7 +474,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
472 /* A valid name must be looked up in the namespace */ 474 /* A valid name must be looked up in the namespace */
473 475
474 if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) && 476 if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
475 (arg->common.value.string)) { 477 (arg->common.value.string) &&
478 !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
476 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", 479 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n",
477 arg)); 480 arg));
478 481
@@ -595,7 +598,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
595 } else { 598 } else {
596 /* Check for null name case */ 599 /* Check for null name case */
597 600
598 if (arg->common.aml_opcode == AML_INT_NAMEPATH_OP) { 601 if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
602 !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
599 /* 603 /*
600 * If the name is null, this means that this is an 604 * If the name is null, this means that this is an
601 * optional result parameter that was not specified 605 * optional result parameter that was not specified
@@ -617,7 +621,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
617 return_ACPI_STATUS(AE_NOT_IMPLEMENTED); 621 return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
618 } 622 }
619 623
620 if (op_info->flags & AML_HAS_RETVAL) { 624 if ((op_info->flags & AML_HAS_RETVAL)
625 || (arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
621 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 626 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
622 "Argument previously created, already stacked\n")); 627 "Argument previously created, already stacked\n"));
623 628
@@ -630,9 +635,7 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
630 * Use value that was already previously returned 635 * Use value that was already previously returned
631 * by the evaluation of this argument 636 * by the evaluation of this argument
632 */ 637 */
633 status = 638 status = acpi_ds_result_pop(&obj_desc, walk_state);
634 acpi_ds_result_pop_from_bottom(&obj_desc,
635 walk_state);
636 if (ACPI_FAILURE(status)) { 639 if (ACPI_FAILURE(status)) {
637 /* 640 /*
638 * Only error is underflow, and this indicates 641 * Only error is underflow, and this indicates
@@ -698,27 +701,52 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state,
698{ 701{
699 acpi_status status = AE_OK; 702 acpi_status status = AE_OK;
700 union acpi_parse_object *arg; 703 union acpi_parse_object *arg;
704 union acpi_parse_object *arguments[ACPI_OBJ_NUM_OPERANDS];
701 u32 arg_count = 0; 705 u32 arg_count = 0;
706 u32 index = walk_state->num_operands;
707 u32 i;
702 708
703 ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg); 709 ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg);
704 710
705 /* For all arguments in the list... */ 711 /* Get all arguments in the list */
706 712
707 arg = first_arg; 713 arg = first_arg;
708 while (arg) { 714 while (arg) {
709 status = acpi_ds_create_operand(walk_state, arg, arg_count); 715 if (index >= ACPI_OBJ_NUM_OPERANDS) {
710 if (ACPI_FAILURE(status)) { 716 return_ACPI_STATUS(AE_BAD_DATA);
711 goto cleanup;
712 } 717 }
713 718
714 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 719 arguments[index] = arg;
715 "Arg #%d (%p) done, Arg1=%p\n", arg_count, 720 walk_state->operands[index] = NULL;
716 arg, first_arg));
717 721
718 /* Move on to next argument, if any */ 722 /* Move on to next argument, if any */
719 723
720 arg = arg->common.next; 724 arg = arg->common.next;
721 arg_count++; 725 arg_count++;
726 index++;
727 }
728
729 index--;
730
731 /* It is the appropriate order to get objects from the Result stack */
732
733 for (i = 0; i < arg_count; i++) {
734 arg = arguments[index];
735
736 /* Force the filling of the operand stack in inverse order */
737
738 walk_state->operand_index = (u8) index;
739
740 status = acpi_ds_create_operand(walk_state, arg, index);
741 if (ACPI_FAILURE(status)) {
742 goto cleanup;
743 }
744
745 index--;
746
747 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
748 "Arg #%d (%p) done, Arg1=%p\n", index, arg,
749 first_arg));
722 } 750 }
723 751
724 return_ACPI_STATUS(status); 752 return_ACPI_STATUS(status);
@@ -729,9 +757,112 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state,
729 * pop everything off of the operand stack and delete those 757 * pop everything off of the operand stack and delete those
730 * objects 758 * objects
731 */ 759 */
732 (void)acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state); 760 acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state);
761
762 ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", index));
763 return_ACPI_STATUS(status);
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
782acpi_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:
733 866
734 ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d",
735 (arg_count + 1)));
736 return_ACPI_STATUS(status); 867 return_ACPI_STATUS(status);
737} 868}