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