aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2016-12-28 02:29:43 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-01-04 20:48:22 -0500
commitce87e09dd88c61f9088768a7708828423549725c (patch)
tree0fdc74ee15607273bf64a95f6d676b42a768780b
parent74e30f96ad21a338f9492325bc73c452049c2548 (diff)
ACPICA: Parser: Allow method invocations as target operands
ACPICA commit a6cca7a4786cdbfd29cea67e84b5b01a8ae6ff1c Method invocations as target operands are allowed as target operands in the ASL grammar. This change implements support for this. Method must return a reference for this to work properly at runtime, however. Link: https://github.com/acpica/acpica/commit/a6cca7a4 Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/acpi/acpica/psargs.c86
-rw-r--r--drivers/acpi/acpica/psloop.c4
-rw-r--r--drivers/acpi/acpica/psobject.c10
-rw-r--r--drivers/acpi/acpica/pstree.c10
4 files changed, 69 insertions, 41 deletions
diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c
index c29c930ffa08..4e1065e84da8 100644
--- a/drivers/acpi/acpica/psargs.c
+++ b/drivers/acpi/acpica/psargs.c
@@ -269,23 +269,13 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
269 */ 269 */
270 if (ACPI_SUCCESS(status) && 270 if (ACPI_SUCCESS(status) &&
271 possible_method_call && (node->type == ACPI_TYPE_METHOD)) { 271 possible_method_call && (node->type == ACPI_TYPE_METHOD)) {
272 if (walk_state->opcode == AML_UNLOAD_OP) {
273 /*
274 * acpi_ps_get_next_namestring has increased the AML pointer,
275 * so we need to restore the saved AML pointer for method call.
276 */
277 walk_state->parser_state.aml = start;
278 walk_state->arg_count = 1;
279 acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
280 return_ACPI_STATUS(AE_OK);
281 }
282 272
283 /* This name is actually a control method invocation */ 273 /* This name is actually a control method invocation */
284 274
285 method_desc = acpi_ns_get_attached_object(node); 275 method_desc = acpi_ns_get_attached_object(node);
286 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 276 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
287 "Control Method - %p Desc %p Path=%p\n", node, 277 "Control Method invocation %4.4s - %p Desc %p Path=%p\n",
288 method_desc, path)); 278 node->name.ascii, node, method_desc, path));
289 279
290 name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, start); 280 name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, start);
291 if (!name_op) { 281 if (!name_op) {
@@ -719,6 +709,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
719 709
720 ACPI_FUNCTION_TRACE_PTR(ps_get_next_arg, parser_state); 710 ACPI_FUNCTION_TRACE_PTR(ps_get_next_arg, parser_state);
721 711
712 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
713 "Expected argument type ARGP: %s (%2.2X)\n",
714 acpi_ut_get_argument_type_name(arg_type), arg_type));
715
722 switch (arg_type) { 716 switch (arg_type) {
723 case ARGP_BYTEDATA: 717 case ARGP_BYTEDATA:
724 case ARGP_WORDDATA: 718 case ARGP_WORDDATA:
@@ -796,11 +790,14 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
796 } 790 }
797 break; 791 break;
798 792
799 case ARGP_TARGET:
800 case ARGP_SUPERNAME:
801 case ARGP_SIMPLENAME: 793 case ARGP_SIMPLENAME:
802 case ARGP_NAME_OR_REF: 794 case ARGP_NAME_OR_REF:
803 795
796 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
797 "**** SimpleName/NameOrRef: %s (%2.2X)\n",
798 acpi_ut_get_argument_type_name(arg_type),
799 arg_type));
800
804 subop = acpi_ps_peek_opcode(parser_state); 801 subop = acpi_ps_peek_opcode(parser_state);
805 if (subop == 0 || 802 if (subop == 0 ||
806 acpi_ps_is_leading_char(subop) || 803 acpi_ps_is_leading_char(subop) ||
@@ -816,29 +813,41 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
816 return_ACPI_STATUS(AE_NO_MEMORY); 813 return_ACPI_STATUS(AE_NO_MEMORY);
817 } 814 }
818 815
819 /* To support super_name arg of Unload */ 816 status =
820 817 acpi_ps_get_next_namepath(walk_state, parser_state,
821 if (walk_state->opcode == AML_UNLOAD_OP) { 818 arg,
822 status = 819 ACPI_NOT_METHOD_CALL);
823 acpi_ps_get_next_namepath(walk_state, 820 } else {
824 parser_state, arg, 821 /* Single complex argument, nothing returned */
825 ACPI_POSSIBLE_METHOD_CALL); 822
826 823 walk_state->arg_count = 1;
827 /* 824 }
828 * If the super_name argument is a method call, we have 825 break;
829 * already restored the AML pointer, just free this Arg 826
830 */ 827 case ARGP_TARGET:
831 if (arg->common.aml_opcode == 828 case ARGP_SUPERNAME:
832 AML_INT_METHODCALL_OP) { 829
833 acpi_ps_free_op(arg); 830 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
834 arg = NULL; 831 "**** Target/Supername: %s (%2.2X)\n",
835 } 832 acpi_ut_get_argument_type_name(arg_type),
836 } else { 833 arg_type));
837 status = 834
838 acpi_ps_get_next_namepath(walk_state, 835 subop = acpi_ps_peek_opcode(parser_state);
839 parser_state, arg, 836 if (subop == 0) {
840 ACPI_NOT_METHOD_CALL); 837
838 /* NULL target (zero). Convert to a NULL namepath */
839
840 arg =
841 acpi_ps_alloc_op(AML_INT_NAMEPATH_OP,
842 parser_state->aml);
843 if (!arg) {
844 return_ACPI_STATUS(AE_NO_MEMORY);
841 } 845 }
846
847 status =
848 acpi_ps_get_next_namepath(walk_state, parser_state,
849 arg,
850 ACPI_POSSIBLE_METHOD_CALL);
842 } else { 851 } else {
843 /* Single complex argument, nothing returned */ 852 /* Single complex argument, nothing returned */
844 853
@@ -849,6 +858,11 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
849 case ARGP_DATAOBJ: 858 case ARGP_DATAOBJ:
850 case ARGP_TERMARG: 859 case ARGP_TERMARG:
851 860
861 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
862 "**** TermArg/DataObj: %s (%2.2X)\n",
863 acpi_ut_get_argument_type_name(arg_type),
864 arg_type));
865
852 /* Single complex argument, nothing returned */ 866 /* Single complex argument, nothing returned */
853 867
854 walk_state->arg_count = 1; 868 walk_state->arg_count = 1;
diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c
index 6a9f5059f682..ac022b556cd9 100644
--- a/drivers/acpi/acpica/psloop.c
+++ b/drivers/acpi/acpica/psloop.c
@@ -92,6 +92,10 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
92 92
93 ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state); 93 ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state);
94 94
95 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
96 "Get arguments for opcode [%s]\n",
97 op->common.aml_op_name));
98
95 switch (op->common.aml_opcode) { 99 switch (op->common.aml_opcode) {
96 case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ 100 case AML_BYTE_OP: /* AML_BYTEDATA_ARG */
97 case AML_WORD_OP: /* AML_WORDDATA_ARG */ 101 case AML_WORD_OP: /* AML_WORDDATA_ARG */
diff --git a/drivers/acpi/acpica/psobject.c b/drivers/acpi/acpica/psobject.c
index db0e90342e82..4abf007f86c3 100644
--- a/drivers/acpi/acpica/psobject.c
+++ b/drivers/acpi/acpica/psobject.c
@@ -348,7 +348,15 @@ acpi_ps_create_op(struct acpi_walk_state *walk_state,
348 argument_count) { 348 argument_count) {
349 op->common.flags |= ACPI_PARSEOP_TARGET; 349 op->common.flags |= ACPI_PARSEOP_TARGET;
350 } 350 }
351 } else if (parent_scope->common.aml_opcode == AML_INCREMENT_OP) { 351 }
352
353 /*
354 * Special case for both Increment() and Decrement(), where
355 * the lone argument is both a source and a target.
356 */
357 else if ((parent_scope->common.aml_opcode == AML_INCREMENT_OP)
358 || (parent_scope->common.aml_opcode ==
359 AML_DECREMENT_OP)) {
352 op->common.flags |= ACPI_PARSEOP_TARGET; 360 op->common.flags |= ACPI_PARSEOP_TARGET;
353 } 361 }
354 } 362 }
diff --git a/drivers/acpi/acpica/pstree.c b/drivers/acpi/acpica/pstree.c
index 0288cdbda88e..4266e5e445ed 100644
--- a/drivers/acpi/acpica/pstree.c
+++ b/drivers/acpi/acpica/pstree.c
@@ -129,10 +129,10 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg)
129 union acpi_parse_object *prev_arg; 129 union acpi_parse_object *prev_arg;
130 const struct acpi_opcode_info *op_info; 130 const struct acpi_opcode_info *op_info;
131 131
132 ACPI_FUNCTION_ENTRY(); 132 ACPI_FUNCTION_TRACE(ps_append_arg);
133 133
134 if (!op) { 134 if (!op) {
135 return; 135 return_VOID;
136 } 136 }
137 137
138 /* Get the info structure for this opcode */ 138 /* Get the info structure for this opcode */
@@ -144,7 +144,7 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg)
144 144
145 ACPI_ERROR((AE_INFO, "Invalid AML Opcode: 0x%2.2X", 145 ACPI_ERROR((AE_INFO, "Invalid AML Opcode: 0x%2.2X",
146 op->common.aml_opcode)); 146 op->common.aml_opcode));
147 return; 147 return_VOID;
148 } 148 }
149 149
150 /* Check if this opcode requires argument sub-objects */ 150 /* Check if this opcode requires argument sub-objects */
@@ -153,7 +153,7 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg)
153 153
154 /* Has no linked argument objects */ 154 /* Has no linked argument objects */
155 155
156 return; 156 return_VOID;
157 } 157 }
158 158
159 /* Append the argument to the linked argument list */ 159 /* Append the argument to the linked argument list */
@@ -181,6 +181,8 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg)
181 181
182 op->common.arg_list_length++; 182 op->common.arg_list_length++;
183 } 183 }
184
185 return_VOID;
184} 186}
185 187
186/******************************************************************************* 188/*******************************************************************************