GNU Linux-libre 4.19.264-gnu1
[releases.git] / drivers / acpi / acpica / dsutils.c
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /*******************************************************************************
3  *
4  * Module Name: dsutils - Dispatcher utilities
5  *
6  ******************************************************************************/
7
8 #include <acpi/acpi.h>
9 #include "accommon.h"
10 #include "acparser.h"
11 #include "amlcode.h"
12 #include "acdispat.h"
13 #include "acinterp.h"
14 #include "acnamesp.h"
15 #include "acdebug.h"
16
17 #define _COMPONENT          ACPI_DISPATCHER
18 ACPI_MODULE_NAME("dsutils")
19
20 /*******************************************************************************
21  *
22  * FUNCTION:    acpi_ds_clear_implicit_return
23  *
24  * PARAMETERS:  walk_state          - Current State
25  *
26  * RETURN:      None.
27  *
28  * DESCRIPTION: Clear and remove a reference on an implicit return value. Used
29  *              to delete "stale" return values (if enabled, the return value
30  *              from every operator is saved at least momentarily, in case the
31  *              parent method exits.)
32  *
33  ******************************************************************************/
34 void acpi_ds_clear_implicit_return(struct acpi_walk_state *walk_state)
35 {
36         ACPI_FUNCTION_NAME(ds_clear_implicit_return);
37
38         /*
39          * Slack must be enabled for this feature
40          */
41         if (!acpi_gbl_enable_interpreter_slack) {
42                 return;
43         }
44
45         if (walk_state->implicit_return_obj) {
46                 /*
47                  * Delete any "stale" implicit return. However, in
48                  * complex statements, the implicit return value can be
49                  * bubbled up several levels.
50                  */
51                 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
52                                   "Removing reference on stale implicit return obj %p\n",
53                                   walk_state->implicit_return_obj));
54
55                 acpi_ut_remove_reference(walk_state->implicit_return_obj);
56                 walk_state->implicit_return_obj = NULL;
57         }
58 }
59
60 #ifndef ACPI_NO_METHOD_EXECUTION
61 /*******************************************************************************
62  *
63  * FUNCTION:    acpi_ds_do_implicit_return
64  *
65  * PARAMETERS:  return_desc         - The return value
66  *              walk_state          - Current State
67  *              add_reference       - True if a reference should be added to the
68  *                                    return object
69  *
70  * RETURN:      TRUE if implicit return enabled, FALSE otherwise
71  *
72  * DESCRIPTION: Implements the optional "implicit return".  We save the result
73  *              of every ASL operator and control method invocation in case the
74  *              parent method exit. Before storing a new return value, we
75  *              delete the previous return value.
76  *
77  ******************************************************************************/
78
79 u8
80 acpi_ds_do_implicit_return(union acpi_operand_object *return_desc,
81                            struct acpi_walk_state *walk_state, u8 add_reference)
82 {
83         ACPI_FUNCTION_NAME(ds_do_implicit_return);
84
85         /*
86          * Slack must be enabled for this feature, and we must
87          * have a valid return object
88          */
89         if ((!acpi_gbl_enable_interpreter_slack) || (!return_desc)) {
90                 return (FALSE);
91         }
92
93         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
94                           "Result %p will be implicitly returned; Prev=%p\n",
95                           return_desc, walk_state->implicit_return_obj));
96
97         /*
98          * Delete any "stale" implicit return value first. However, in
99          * complex statements, the implicit return value can be
100          * bubbled up several levels, so we don't clear the value if it
101          * is the same as the return_desc.
102          */
103         if (walk_state->implicit_return_obj) {
104                 if (walk_state->implicit_return_obj == return_desc) {
105                         return (TRUE);
106                 }
107                 acpi_ds_clear_implicit_return(walk_state);
108         }
109
110         /* Save the implicit return value, add a reference if requested */
111
112         walk_state->implicit_return_obj = return_desc;
113         if (add_reference) {
114                 acpi_ut_add_reference(return_desc);
115         }
116
117         return (TRUE);
118 }
119
120 /*******************************************************************************
121  *
122  * FUNCTION:    acpi_ds_is_result_used
123  *
124  * PARAMETERS:  op                  - Current Op
125  *              walk_state          - Current State
126  *
127  * RETURN:      TRUE if result is used, FALSE otherwise
128  *
129  * DESCRIPTION: Check if a result object will be used by the parent
130  *
131  ******************************************************************************/
132
133 u8
134 acpi_ds_is_result_used(union acpi_parse_object * op,
135                        struct acpi_walk_state * walk_state)
136 {
137         const struct acpi_opcode_info *parent_info;
138
139         ACPI_FUNCTION_TRACE_PTR(ds_is_result_used, op);
140
141         /* Must have both an Op and a Result Object */
142
143         if (!op) {
144                 ACPI_ERROR((AE_INFO, "Null Op"));
145                 return_UINT8(TRUE);
146         }
147
148         /*
149          * We know that this operator is not a
150          * Return() operator (would not come here.) The following code is the
151          * optional support for a so-called "implicit return". Some AML code
152          * assumes that the last value of the method is "implicitly" returned
153          * to the caller. Just save the last result as the return value.
154          * NOTE: this is optional because the ASL language does not actually
155          * support this behavior.
156          */
157         (void)acpi_ds_do_implicit_return(walk_state->result_obj, walk_state,
158                                          TRUE);
159
160         /*
161          * Now determine if the parent will use the result
162          *
163          * If there is no parent, or the parent is a scope_op, we are executing
164          * at the method level. An executing method typically has no parent,
165          * since each method is parsed separately. A method invoked externally
166          * via execute_control_method has a scope_op as the parent.
167          */
168         if ((!op->common.parent) ||
169             (op->common.parent->common.aml_opcode == AML_SCOPE_OP)) {
170
171                 /* No parent, the return value cannot possibly be used */
172
173                 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
174                                   "At Method level, result of [%s] not used\n",
175                                   acpi_ps_get_opcode_name(op->common.
176                                                           aml_opcode)));
177                 return_UINT8(FALSE);
178         }
179
180         /* Get info on the parent. The root_op is AML_SCOPE */
181
182         parent_info =
183             acpi_ps_get_opcode_info(op->common.parent->common.aml_opcode);
184         if (parent_info->class == AML_CLASS_UNKNOWN) {
185                 ACPI_ERROR((AE_INFO, "Unknown parent opcode Op=%p", op));
186                 return_UINT8(FALSE);
187         }
188
189         /*
190          * Decide what to do with the result based on the parent. If
191          * the parent opcode will not use the result, delete the object.
192          * Otherwise leave it as is, it will be deleted when it is used
193          * as an operand later.
194          */
195         switch (parent_info->class) {
196         case AML_CLASS_CONTROL:
197
198                 switch (op->common.parent->common.aml_opcode) {
199                 case AML_RETURN_OP:
200
201                         /* Never delete the return value associated with a return opcode */
202
203                         goto result_used;
204
205                 case AML_IF_OP:
206                 case AML_WHILE_OP:
207                         /*
208                          * If we are executing the predicate AND this is the predicate op,
209                          * we will use the return value
210                          */
211                         if ((walk_state->control_state->common.state ==
212                              ACPI_CONTROL_PREDICATE_EXECUTING) &&
213                             (walk_state->control_state->control.predicate_op ==
214                              op)) {
215                                 goto result_used;
216                         }
217                         break;
218
219                 default:
220
221                         /* Ignore other control opcodes */
222
223                         break;
224                 }
225
226                 /* The general control opcode returns no result */
227
228                 goto result_not_used;
229
230         case AML_CLASS_CREATE:
231                 /*
232                  * These opcodes allow term_arg(s) as operands and therefore
233                  * the operands can be method calls. The result is used.
234                  */
235                 goto result_used;
236
237         case AML_CLASS_NAMED_OBJECT:
238
239                 if ((op->common.parent->common.aml_opcode == AML_REGION_OP) ||
240                     (op->common.parent->common.aml_opcode == AML_DATA_REGION_OP)
241                     || (op->common.parent->common.aml_opcode == AML_PACKAGE_OP)
242                     || (op->common.parent->common.aml_opcode == AML_BUFFER_OP)
243                     || (op->common.parent->common.aml_opcode ==
244                         AML_VARIABLE_PACKAGE_OP)
245                     || (op->common.parent->common.aml_opcode ==
246                         AML_INT_EVAL_SUBTREE_OP)
247                     || (op->common.parent->common.aml_opcode ==
248                         AML_BANK_FIELD_OP)) {
249                         /*
250                          * These opcodes allow term_arg(s) as operands and therefore
251                          * the operands can be method calls. The result is used.
252                          */
253                         goto result_used;
254                 }
255
256                 goto result_not_used;
257
258         default:
259                 /*
260                  * In all other cases. the parent will actually use the return
261                  * object, so keep it.
262                  */
263                 goto result_used;
264         }
265
266 result_used:
267         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
268                           "Result of [%s] used by Parent [%s] Op=%p\n",
269                           acpi_ps_get_opcode_name(op->common.aml_opcode),
270                           acpi_ps_get_opcode_name(op->common.parent->common.
271                                                   aml_opcode), op));
272
273         return_UINT8(TRUE);
274
275 result_not_used:
276         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
277                           "Result of [%s] not used by Parent [%s] Op=%p\n",
278                           acpi_ps_get_opcode_name(op->common.aml_opcode),
279                           acpi_ps_get_opcode_name(op->common.parent->common.
280                                                   aml_opcode), op));
281
282         return_UINT8(FALSE);
283 }
284
285 /*******************************************************************************
286  *
287  * FUNCTION:    acpi_ds_delete_result_if_not_used
288  *
289  * PARAMETERS:  op              - Current parse Op
290  *              result_obj      - Result of the operation
291  *              walk_state      - Current state
292  *
293  * RETURN:      Status
294  *
295  * DESCRIPTION: Used after interpretation of an opcode. If there is an internal
296  *              result descriptor, check if the parent opcode will actually use
297  *              this result. If not, delete the result now so that it will
298  *              not become orphaned.
299  *
300  ******************************************************************************/
301
302 void
303 acpi_ds_delete_result_if_not_used(union acpi_parse_object *op,
304                                   union acpi_operand_object *result_obj,
305                                   struct acpi_walk_state *walk_state)
306 {
307         union acpi_operand_object *obj_desc;
308         acpi_status status;
309
310         ACPI_FUNCTION_TRACE_PTR(ds_delete_result_if_not_used, result_obj);
311
312         if (!op) {
313                 ACPI_ERROR((AE_INFO, "Null Op"));
314                 return_VOID;
315         }
316
317         if (!result_obj) {
318                 return_VOID;
319         }
320
321         if (!acpi_ds_is_result_used(op, walk_state)) {
322
323                 /* Must pop the result stack (obj_desc should be equal to result_obj) */
324
325                 status = acpi_ds_result_pop(&obj_desc, walk_state);
326                 if (ACPI_SUCCESS(status)) {
327                         acpi_ut_remove_reference(result_obj);
328                 }
329         }
330
331         return_VOID;
332 }
333
334 /*******************************************************************************
335  *
336  * FUNCTION:    acpi_ds_resolve_operands
337  *
338  * PARAMETERS:  walk_state          - Current walk state with operands on stack
339  *
340  * RETURN:      Status
341  *
342  * DESCRIPTION: Resolve all operands to their values. Used to prepare
343  *              arguments to a control method invocation (a call from one
344  *              method to another.)
345  *
346  ******************************************************************************/
347
348 acpi_status acpi_ds_resolve_operands(struct acpi_walk_state *walk_state)
349 {
350         u32 i;
351         acpi_status status = AE_OK;
352
353         ACPI_FUNCTION_TRACE_PTR(ds_resolve_operands, walk_state);
354
355         /*
356          * Attempt to resolve each of the valid operands
357          * Method arguments are passed by reference, not by value. This means
358          * that the actual objects are passed, not copies of the objects.
359          */
360         for (i = 0; i < walk_state->num_operands; i++) {
361                 status =
362                     acpi_ex_resolve_to_value(&walk_state->operands[i],
363                                              walk_state);
364                 if (ACPI_FAILURE(status)) {
365                         break;
366                 }
367         }
368
369         return_ACPI_STATUS(status);
370 }
371
372 /*******************************************************************************
373  *
374  * FUNCTION:    acpi_ds_clear_operands
375  *
376  * PARAMETERS:  walk_state          - Current walk state with operands on stack
377  *
378  * RETURN:      None
379  *
380  * DESCRIPTION: Clear all operands on the current walk state operand stack.
381  *
382  ******************************************************************************/
383
384 void acpi_ds_clear_operands(struct acpi_walk_state *walk_state)
385 {
386         u32 i;
387
388         ACPI_FUNCTION_TRACE_PTR(ds_clear_operands, walk_state);
389
390         /* Remove a reference on each operand on the stack */
391
392         for (i = 0; i < walk_state->num_operands; i++) {
393                 /*
394                  * Remove a reference to all operands, including both
395                  * "Arguments" and "Targets".
396                  */
397                 acpi_ut_remove_reference(walk_state->operands[i]);
398                 walk_state->operands[i] = NULL;
399         }
400
401         walk_state->num_operands = 0;
402         return_VOID;
403 }
404 #endif
405
406 /*******************************************************************************
407  *
408  * FUNCTION:    acpi_ds_create_operand
409  *
410  * PARAMETERS:  walk_state      - Current walk state
411  *              arg             - Parse object for the argument
412  *              arg_index       - Which argument (zero based)
413  *
414  * RETURN:      Status
415  *
416  * DESCRIPTION: Translate a parse tree object that is an argument to an AML
417  *              opcode to the equivalent interpreter object. This may include
418  *              looking up a name or entering a new name into the internal
419  *              namespace.
420  *
421  ******************************************************************************/
422
423 acpi_status
424 acpi_ds_create_operand(struct acpi_walk_state *walk_state,
425                        union acpi_parse_object *arg, u32 arg_index)
426 {
427         acpi_status status = AE_OK;
428         char *name_string;
429         u32 name_length;
430         union acpi_operand_object *obj_desc;
431         union acpi_parse_object *parent_op;
432         u16 opcode;
433         acpi_interpreter_mode interpreter_mode;
434         const struct acpi_opcode_info *op_info;
435
436         ACPI_FUNCTION_TRACE_PTR(ds_create_operand, arg);
437
438         /* A valid name must be looked up in the namespace */
439
440         if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
441             (arg->common.value.string) &&
442             !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
443                 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n",
444                                   arg));
445
446                 /* Get the entire name string from the AML stream */
447
448                 status = acpi_ex_get_name_string(ACPI_TYPE_ANY,
449                                                  arg->common.value.buffer,
450                                                  &name_string, &name_length);
451
452                 if (ACPI_FAILURE(status)) {
453                         return_ACPI_STATUS(status);
454                 }
455
456                 /* All prefixes have been handled, and the name is in name_string */
457
458                 /*
459                  * Special handling for buffer_field declarations. This is a deferred
460                  * opcode that unfortunately defines the field name as the last
461                  * parameter instead of the first. We get here when we are performing
462                  * the deferred execution, so the actual name of the field is already
463                  * in the namespace. We don't want to attempt to look it up again
464                  * because we may be executing in a different scope than where the
465                  * actual opcode exists.
466                  */
467                 if ((walk_state->deferred_node) &&
468                     (walk_state->deferred_node->type == ACPI_TYPE_BUFFER_FIELD)
469                     && (arg_index == (u32)
470                         ((walk_state->opcode == AML_CREATE_FIELD_OP) ? 3 : 2))) {
471                         obj_desc =
472                             ACPI_CAST_PTR(union acpi_operand_object,
473                                           walk_state->deferred_node);
474                         status = AE_OK;
475                 } else {        /* All other opcodes */
476
477                         /*
478                          * Differentiate between a namespace "create" operation
479                          * versus a "lookup" operation (IMODE_LOAD_PASS2 vs.
480                          * IMODE_EXECUTE) in order to support the creation of
481                          * namespace objects during the execution of control methods.
482                          */
483                         parent_op = arg->common.parent;
484                         op_info =
485                             acpi_ps_get_opcode_info(parent_op->common.
486                                                     aml_opcode);
487
488                         if ((op_info->flags & AML_NSNODE) &&
489                             (parent_op->common.aml_opcode !=
490                              AML_INT_METHODCALL_OP)
491                             && (parent_op->common.aml_opcode != AML_REGION_OP)
492                             && (parent_op->common.aml_opcode !=
493                                 AML_INT_NAMEPATH_OP)) {
494
495                                 /* Enter name into namespace if not found */
496
497                                 interpreter_mode = ACPI_IMODE_LOAD_PASS2;
498                         } else {
499                                 /* Return a failure if name not found */
500
501                                 interpreter_mode = ACPI_IMODE_EXECUTE;
502                         }
503
504                         status =
505                             acpi_ns_lookup(walk_state->scope_info, name_string,
506                                            ACPI_TYPE_ANY, interpreter_mode,
507                                            ACPI_NS_SEARCH_PARENT |
508                                            ACPI_NS_DONT_OPEN_SCOPE, walk_state,
509                                            ACPI_CAST_INDIRECT_PTR(struct
510                                                                   acpi_namespace_node,
511                                                                   &obj_desc));
512                         /*
513                          * The only case where we pass through (ignore) a NOT_FOUND
514                          * error is for the cond_ref_of opcode.
515                          */
516                         if (status == AE_NOT_FOUND) {
517                                 if (parent_op->common.aml_opcode ==
518                                     AML_CONDITIONAL_REF_OF_OP) {
519                                         /*
520                                          * For the Conditional Reference op, it's OK if
521                                          * the name is not found;  We just need a way to
522                                          * indicate this to the interpreter, set the
523                                          * object to the root
524                                          */
525                                         obj_desc =
526                                             ACPI_CAST_PTR(union
527                                                                  acpi_operand_object,
528                                                                  acpi_gbl_root_node);
529                                         status = AE_OK;
530                                 } else if (parent_op->common.aml_opcode ==
531                                            AML_EXTERNAL_OP) {
532                                         /*
533                                          * This opcode should never appear here. It is used only
534                                          * by AML disassemblers and is surrounded by an If(0)
535                                          * by the ASL compiler.
536                                          *
537                                          * Therefore, if we see it here, it is a serious error.
538                                          */
539                                         status = AE_AML_BAD_OPCODE;
540                                 } else {
541                                         /*
542                                          * We just plain didn't find it -- which is a
543                                          * very serious error at this point
544                                          */
545                                         status = AE_AML_NAME_NOT_FOUND;
546                                 }
547                         }
548
549                         if (ACPI_FAILURE(status)) {
550                                 ACPI_ERROR_NAMESPACE(walk_state->scope_info,
551                                                      name_string, status);
552                         }
553                 }
554
555                 /* Free the namestring created above */
556
557                 ACPI_FREE(name_string);
558
559                 /* Check status from the lookup */
560
561                 if (ACPI_FAILURE(status)) {
562                         return_ACPI_STATUS(status);
563                 }
564
565                 /* Put the resulting object onto the current object stack */
566
567                 status = acpi_ds_obj_stack_push(obj_desc, walk_state);
568                 if (ACPI_FAILURE(status)) {
569                         return_ACPI_STATUS(status);
570                 }
571
572                 acpi_db_display_argument_object(obj_desc, walk_state);
573         } else {
574                 /* Check for null name case */
575
576                 if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
577                     !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
578                         /*
579                          * If the name is null, this means that this is an
580                          * optional result parameter that was not specified
581                          * in the original ASL. Create a Zero Constant for a
582                          * placeholder. (Store to a constant is a Noop.)
583                          */
584                         opcode = AML_ZERO_OP;   /* Has no arguments! */
585
586                         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
587                                           "Null namepath: Arg=%p\n", arg));
588                 } else {
589                         opcode = arg->common.aml_opcode;
590                 }
591
592                 /* Get the object type of the argument */
593
594                 op_info = acpi_ps_get_opcode_info(opcode);
595                 if (op_info->object_type == ACPI_TYPE_INVALID) {
596                         return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
597                 }
598
599                 if ((op_info->flags & AML_HAS_RETVAL) ||
600                     (arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
601                         /*
602                          * Use value that was already previously returned
603                          * by the evaluation of this argument
604                          */
605                         status = acpi_ds_result_pop(&obj_desc, walk_state);
606                         if (ACPI_FAILURE(status)) {
607                                 /*
608                                  * Only error is underflow, and this indicates
609                                  * a missing or null operand!
610                                  */
611                                 ACPI_EXCEPTION((AE_INFO, status,
612                                                 "Missing or null operand"));
613                                 return_ACPI_STATUS(status);
614                         }
615                 } else {
616                         /* Create an ACPI_INTERNAL_OBJECT for the argument */
617
618                         obj_desc =
619                             acpi_ut_create_internal_object(op_info->
620                                                            object_type);
621                         if (!obj_desc) {
622                                 return_ACPI_STATUS(AE_NO_MEMORY);
623                         }
624
625                         /* Initialize the new object */
626
627                         status =
628                             acpi_ds_init_object_from_op(walk_state, arg, opcode,
629                                                         &obj_desc);
630                         if (ACPI_FAILURE(status)) {
631                                 acpi_ut_delete_object_desc(obj_desc);
632                                 return_ACPI_STATUS(status);
633                         }
634                 }
635
636                 /* Put the operand object on the object stack */
637
638                 status = acpi_ds_obj_stack_push(obj_desc, walk_state);
639                 if (ACPI_FAILURE(status)) {
640                         return_ACPI_STATUS(status);
641                 }
642
643                 acpi_db_display_argument_object(obj_desc, walk_state);
644         }
645
646         return_ACPI_STATUS(AE_OK);
647 }
648
649 /*******************************************************************************
650  *
651  * FUNCTION:    acpi_ds_create_operands
652  *
653  * PARAMETERS:  walk_state          - Current state
654  *              first_arg           - First argument of a parser argument tree
655  *
656  * RETURN:      Status
657  *
658  * DESCRIPTION: Convert an operator's arguments from a parse tree format to
659  *              namespace objects and place those argument object on the object
660  *              stack in preparation for evaluation by the interpreter.
661  *
662  ******************************************************************************/
663
664 acpi_status
665 acpi_ds_create_operands(struct acpi_walk_state *walk_state,
666                         union acpi_parse_object *first_arg)
667 {
668         acpi_status status = AE_OK;
669         union acpi_parse_object *arg;
670         union acpi_parse_object *arguments[ACPI_OBJ_NUM_OPERANDS];
671         u32 arg_count = 0;
672         u32 index = walk_state->num_operands;
673         u32 i;
674
675         ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg);
676
677         /* Get all arguments in the list */
678
679         arg = first_arg;
680         while (arg) {
681                 if (index >= ACPI_OBJ_NUM_OPERANDS) {
682                         return_ACPI_STATUS(AE_BAD_DATA);
683                 }
684
685                 arguments[index] = arg;
686                 walk_state->operands[index] = NULL;
687
688                 /* Move on to next argument, if any */
689
690                 arg = arg->common.next;
691                 arg_count++;
692                 index++;
693         }
694
695         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
696                           "NumOperands %d, ArgCount %d, Index %d\n",
697                           walk_state->num_operands, arg_count, index));
698
699         /* Create the interpreter arguments, in reverse order */
700
701         index--;
702         for (i = 0; i < arg_count; i++) {
703                 arg = arguments[index];
704                 walk_state->operand_index = (u8)index;
705
706                 status = acpi_ds_create_operand(walk_state, arg, index);
707                 if (ACPI_FAILURE(status)) {
708                         goto cleanup;
709                 }
710
711                 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
712                                   "Created Arg #%u (%p) %u args total\n",
713                                   index, arg, arg_count));
714                 index--;
715         }
716
717         return_ACPI_STATUS(status);
718
719 cleanup:
720         /*
721          * We must undo everything done above; meaning that we must
722          * pop everything off of the operand stack and delete those
723          * objects
724          */
725         acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state);
726
727         ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %u", index));
728         return_ACPI_STATUS(status);
729 }
730
731 /*****************************************************************************
732  *
733  * FUNCTION:    acpi_ds_evaluate_name_path
734  *
735  * PARAMETERS:  walk_state      - Current state of the parse tree walk,
736  *                                the opcode of current operation should be
737  *                                AML_INT_NAMEPATH_OP
738  *
739  * RETURN:      Status
740  *
741  * DESCRIPTION: Translate the -name_path- parse tree object to the equivalent
742  *              interpreter object, convert it to value, if needed, duplicate
743  *              it, if needed, and push it onto the current result stack.
744  *
745  ****************************************************************************/
746
747 acpi_status acpi_ds_evaluate_name_path(struct acpi_walk_state *walk_state)
748 {
749         acpi_status status = AE_OK;
750         union acpi_parse_object *op = walk_state->op;
751         union acpi_operand_object **operand = &walk_state->operands[0];
752         union acpi_operand_object *new_obj_desc;
753         u8 type;
754
755         ACPI_FUNCTION_TRACE_PTR(ds_evaluate_name_path, walk_state);
756
757         if (!op->common.parent) {
758
759                 /* This happens after certain exception processing */
760
761                 goto exit;
762         }
763
764         if ((op->common.parent->common.aml_opcode == AML_PACKAGE_OP) ||
765             (op->common.parent->common.aml_opcode == AML_VARIABLE_PACKAGE_OP) ||
766             (op->common.parent->common.aml_opcode == AML_REF_OF_OP)) {
767
768                 /* TBD: Should we specify this feature as a bit of op_info->Flags of these opcodes? */
769
770                 goto exit;
771         }
772
773         status = acpi_ds_create_operand(walk_state, op, 0);
774         if (ACPI_FAILURE(status)) {
775                 goto exit;
776         }
777
778         if (op->common.flags & ACPI_PARSEOP_TARGET) {
779                 new_obj_desc = *operand;
780                 goto push_result;
781         }
782
783         type = (*operand)->common.type;
784
785         status = acpi_ex_resolve_to_value(operand, walk_state);
786         if (ACPI_FAILURE(status)) {
787                 goto exit;
788         }
789
790         if (type == ACPI_TYPE_INTEGER) {
791
792                 /* It was incremented by acpi_ex_resolve_to_value */
793
794                 acpi_ut_remove_reference(*operand);
795
796                 status =
797                     acpi_ut_copy_iobject_to_iobject(*operand, &new_obj_desc,
798                                                     walk_state);
799                 if (ACPI_FAILURE(status)) {
800                         goto exit;
801                 }
802         } else {
803                 /*
804                  * The object either was anew created or is
805                  * a Namespace node - don't decrement it.
806                  */
807                 new_obj_desc = *operand;
808         }
809
810         /* Cleanup for name-path operand */
811
812         status = acpi_ds_obj_stack_pop(1, walk_state);
813         if (ACPI_FAILURE(status)) {
814                 walk_state->result_obj = new_obj_desc;
815                 goto exit;
816         }
817
818 push_result:
819
820         walk_state->result_obj = new_obj_desc;
821
822         status = acpi_ds_result_push(walk_state->result_obj, walk_state);
823         if (ACPI_SUCCESS(status)) {
824
825                 /* Force to take it from stack */
826
827                 op->common.flags |= ACPI_PARSEOP_IN_STACK;
828         }
829
830 exit:
831
832         return_ACPI_STATUS(status);
833 }