ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / acpi / dispatcher / dsutils.c
1 /*******************************************************************************
2  *
3  * Module Name: dsutils - Dispatcher utilities
4  *
5  ******************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2004, 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
45 #include <acpi/acpi.h>
46 #include <acpi/acparser.h>
47 #include <acpi/amlcode.h>
48 #include <acpi/acdispat.h>
49 #include <acpi/acinterp.h>
50 #include <acpi/acnamesp.h>
51 #include <acpi/acdebug.h>
52
53 #define _COMPONENT          ACPI_DISPATCHER
54          ACPI_MODULE_NAME    ("dsutils")
55
56
57 #ifndef ACPI_NO_METHOD_EXECUTION
58
59 /*******************************************************************************
60  *
61  * FUNCTION:    acpi_ds_is_result_used
62  *
63  * PARAMETERS:  Op
64  *              result_obj
65  *              walk_state
66  *
67  * RETURN:      Status
68  *
69  * DESCRIPTION: Check if a result object will be used by the parent
70  *
71  ******************************************************************************/
72
73 u8
74 acpi_ds_is_result_used (
75         union acpi_parse_object         *op,
76         struct acpi_walk_state          *walk_state)
77 {
78         const struct acpi_opcode_info   *parent_info;
79
80
81         ACPI_FUNCTION_TRACE_PTR ("ds_is_result_used", op);
82
83
84         /* Must have both an Op and a Result Object */
85
86         if (!op) {
87                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Op\n"));
88                 return_VALUE (TRUE);
89         }
90
91         /*
92          * If there is no parent, the result can't possibly be used!
93          * (An executing method typically has no parent, since each
94          * method is parsed separately)  However, a method that is
95          * invoked from another method has a parent.
96          */
97         if (!op->common.parent) {
98                 return_VALUE (FALSE);
99         }
100
101         /*
102          * Get info on the parent.  The root Op is AML_SCOPE
103          */
104         parent_info = acpi_ps_get_opcode_info (op->common.parent->common.aml_opcode);
105         if (parent_info->class == AML_CLASS_UNKNOWN) {
106                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown parent opcode. Op=%p\n", op));
107                 return_VALUE (FALSE);
108         }
109
110         /*
111          * Decide what to do with the result based on the parent.  If
112          * the parent opcode will not use the result, delete the object.
113          * Otherwise leave it as is, it will be deleted when it is used
114          * as an operand later.
115          */
116         switch (parent_info->class) {
117         case AML_CLASS_CONTROL:
118
119                 switch (op->common.parent->common.aml_opcode) {
120                 case AML_RETURN_OP:
121
122                         /* Never delete the return value associated with a return opcode */
123
124                         goto result_used;
125
126                 case AML_IF_OP:
127                 case AML_WHILE_OP:
128
129                         /*
130                          * If we are executing the predicate AND this is the predicate op,
131                          * we will use the return value
132                          */
133                         if ((walk_state->control_state->common.state == ACPI_CONTROL_PREDICATE_EXECUTING) &&
134                                 (walk_state->control_state->control.predicate_op == op)) {
135                                 goto result_used;
136                         }
137                         break;
138
139                 default:
140                         /* Ignore other control opcodes */
141                         break;
142                 }
143
144                 /* The general control opcode returns no result */
145
146                 goto result_not_used;
147
148
149         case AML_CLASS_CREATE:
150
151                 /*
152                  * These opcodes allow term_arg(s) as operands and therefore
153                  * the operands can be method calls.  The result is used.
154                  */
155                 goto result_used;
156
157
158         case AML_CLASS_NAMED_OBJECT:
159
160                 if ((op->common.parent->common.aml_opcode == AML_REGION_OP)      ||
161                         (op->common.parent->common.aml_opcode == AML_DATA_REGION_OP) ||
162                         (op->common.parent->common.aml_opcode == AML_PACKAGE_OP)     ||
163                         (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP) ||
164                         (op->common.parent->common.aml_opcode == AML_BUFFER_OP)      ||
165                         (op->common.parent->common.aml_opcode == AML_INT_EVAL_SUBTREE_OP)) {
166                         /*
167                          * These opcodes allow term_arg(s) as operands and therefore
168                          * the operands can be method calls.  The result is used.
169                          */
170                         goto result_used;
171                 }
172
173                 goto result_not_used;
174
175
176         default:
177
178                 /*
179                  * In all other cases. the parent will actually use the return
180                  * object, so keep it.
181                  */
182                 goto result_used;
183         }
184
185
186 result_used:
187         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Result of [%s] used by Parent [%s] Op=%p\n",
188                         acpi_ps_get_opcode_name (op->common.aml_opcode),
189                         acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op));
190
191         return_VALUE (TRUE);
192
193
194 result_not_used:
195         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Result of [%s] not used by Parent [%s] Op=%p\n",
196                         acpi_ps_get_opcode_name (op->common.aml_opcode),
197                         acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op));
198
199         return_VALUE (FALSE);
200 }
201
202
203 /*******************************************************************************
204  *
205  * FUNCTION:    acpi_ds_delete_result_if_not_used
206  *
207  * PARAMETERS:  Op
208  *              result_obj
209  *              walk_state
210  *
211  * RETURN:      Status
212  *
213  * DESCRIPTION: Used after interpretation of an opcode.  If there is an internal
214  *              result descriptor, check if the parent opcode will actually use
215  *              this result.  If not, delete the result now so that it will
216  *              not become orphaned.
217  *
218  ******************************************************************************/
219
220 void
221 acpi_ds_delete_result_if_not_used (
222         union acpi_parse_object         *op,
223         union acpi_operand_object       *result_obj,
224         struct acpi_walk_state          *walk_state)
225 {
226         union acpi_operand_object       *obj_desc;
227         acpi_status                     status;
228
229
230         ACPI_FUNCTION_TRACE_PTR ("ds_delete_result_if_not_used", result_obj);
231
232
233         if (!op) {
234                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Op\n"));
235                 return_VOID;
236         }
237
238         if (!result_obj) {
239                 return_VOID;
240         }
241
242         if (!acpi_ds_is_result_used (op, walk_state)) {
243                 /*
244                  * Must pop the result stack (obj_desc should be equal to result_obj)
245                  */
246                 status = acpi_ds_result_pop (&obj_desc, walk_state);
247                 if (ACPI_SUCCESS (status)) {
248                         acpi_ut_remove_reference (result_obj);
249                 }
250         }
251
252         return_VOID;
253 }
254
255
256 /*******************************************************************************
257  *
258  * FUNCTION:    acpi_ds_resolve_operands
259  *
260  * PARAMETERS:  walk_state          - Current walk state with operands on stack
261  *
262  * RETURN:      Status
263  *
264  * DESCRIPTION: Resolve all operands to their values.  Used to prepare
265  *              arguments to a control method invocation (a call from one
266  *              method to another.)
267  *
268  ******************************************************************************/
269
270 acpi_status
271 acpi_ds_resolve_operands (
272         struct acpi_walk_state          *walk_state)
273 {
274         u32                             i;
275         acpi_status                     status = AE_OK;
276
277
278         ACPI_FUNCTION_TRACE_PTR ("ds_resolve_operands", walk_state);
279
280
281         /*
282          * Attempt to resolve each of the valid operands
283          * Method arguments are passed by reference, not by value.  This means
284          * that the actual objects are passed, not copies of the objects.
285          */
286         for (i = 0; i < walk_state->num_operands; i++) {
287                 status = acpi_ex_resolve_to_value (&walk_state->operands[i], walk_state);
288                 if (ACPI_FAILURE (status)) {
289                         break;
290                 }
291         }
292
293         return_ACPI_STATUS (status);
294 }
295
296
297 /*******************************************************************************
298  *
299  * FUNCTION:    acpi_ds_clear_operands
300  *
301  * PARAMETERS:  walk_state          - Current walk state with operands on stack
302  *
303  * RETURN:      None
304  *
305  * DESCRIPTION: Clear all operands on the current walk state operand stack.
306  *
307  ******************************************************************************/
308
309 void
310 acpi_ds_clear_operands (
311         struct acpi_walk_state          *walk_state)
312 {
313         u32                             i;
314
315
316         ACPI_FUNCTION_TRACE_PTR ("acpi_ds_clear_operands", walk_state);
317
318
319         /*
320          * Remove a reference on each operand on the stack
321          */
322         for (i = 0; i < walk_state->num_operands; i++) {
323                 /*
324                  * Remove a reference to all operands, including both
325                  * "Arguments" and "Targets".
326                  */
327                 acpi_ut_remove_reference (walk_state->operands[i]);
328                 walk_state->operands[i] = NULL;
329         }
330
331         walk_state->num_operands = 0;
332         return_VOID;
333 }
334 #endif
335
336
337 /*******************************************************************************
338  *
339  * FUNCTION:    acpi_ds_create_operand
340  *
341  * PARAMETERS:  walk_state
342  *              Arg
343  *
344  * RETURN:      Status
345  *
346  * DESCRIPTION: Translate a parse tree object that is an argument to an AML
347  *              opcode to the equivalent interpreter object.  This may include
348  *              looking up a name or entering a new name into the internal
349  *              namespace.
350  *
351  ******************************************************************************/
352
353 acpi_status
354 acpi_ds_create_operand (
355         struct acpi_walk_state          *walk_state,
356         union acpi_parse_object         *arg,
357         u32                             arg_index)
358 {
359         acpi_status                     status = AE_OK;
360         char                            *name_string;
361         u32                             name_length;
362         union acpi_operand_object       *obj_desc;
363         union acpi_parse_object         *parent_op;
364         u16                             opcode;
365         acpi_interpreter_mode           interpreter_mode;
366         const struct acpi_opcode_info   *op_info;
367
368
369         ACPI_FUNCTION_TRACE_PTR ("ds_create_operand", arg);
370
371
372         /* A valid name must be looked up in the namespace */
373
374         if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
375                 (arg->common.value.string)) {
376                 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", arg));
377
378                 /* Get the entire name string from the AML stream */
379
380                 status = acpi_ex_get_name_string (ACPI_TYPE_ANY, arg->common.value.buffer,
381                                   &name_string, &name_length);
382
383                 if (ACPI_FAILURE (status)) {
384                         return_ACPI_STATUS (status);
385                 }
386
387                 /*
388                  * All prefixes have been handled, and the name is
389                  * in name_string
390                  */
391
392
393                 /*
394                  * Special handling for buffer_field declarations. This is a deferred
395                  * opcode that unfortunately defines the field name as the last
396                  * parameter instead of the first.  We get here when we are performing
397                  * the deferred execution, so the actual name of the field is already
398                  * in the namespace.  We don't want to attempt to look it up again
399                  * because we may be executing in a different scope than where the
400                  * actual opcode exists.
401                  */
402                 if ((walk_state->deferred_node) &&
403                         (walk_state->deferred_node->type == ACPI_TYPE_BUFFER_FIELD) &&
404                         (arg_index != 0)) {
405                         obj_desc = ACPI_CAST_PTR (union acpi_operand_object, walk_state->deferred_node);
406                         status = AE_OK;
407                 }
408                 else    /* All other opcodes */ {
409                         /*
410                          * Differentiate between a namespace "create" operation
411                          * versus a "lookup" operation (IMODE_LOAD_PASS2 vs.
412                          * IMODE_EXECUTE) in order to support the creation of
413                          * namespace objects during the execution of control methods.
414                          */
415                         parent_op = arg->common.parent;
416                         op_info = acpi_ps_get_opcode_info (parent_op->common.aml_opcode);
417                         if ((op_info->flags & AML_NSNODE) &&
418                                 (parent_op->common.aml_opcode != AML_INT_METHODCALL_OP) &&
419                                 (parent_op->common.aml_opcode != AML_REGION_OP) &&
420                                 (parent_op->common.aml_opcode != AML_INT_NAMEPATH_OP)) {
421                                 /* Enter name into namespace if not found */
422
423                                 interpreter_mode = ACPI_IMODE_LOAD_PASS2;
424                         }
425                         else {
426                                 /* Return a failure if name not found */
427
428                                 interpreter_mode = ACPI_IMODE_EXECUTE;
429                         }
430
431                         status = acpi_ns_lookup (walk_state->scope_info, name_string,
432                                          ACPI_TYPE_ANY, interpreter_mode,
433                                          ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
434                                          walk_state,
435                                          ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &obj_desc));
436                         /*
437                          * The only case where we pass through (ignore) a NOT_FOUND
438                          * error is for the cond_ref_of opcode.
439                          */
440                         if (status == AE_NOT_FOUND) {
441                                 if (parent_op->common.aml_opcode == AML_COND_REF_OF_OP) {
442                                         /*
443                                          * For the Conditional Reference op, it's OK if
444                                          * the name is not found;  We just need a way to
445                                          * indicate this to the interpreter, set the
446                                          * object to the root
447                                          */
448                                         obj_desc = ACPI_CAST_PTR (union acpi_operand_object, acpi_gbl_root_node);
449                                         status = AE_OK;
450                                 }
451                                 else {
452                                         /*
453                                          * We just plain didn't find it -- which is a
454                                          * very serious error at this point
455                                          */
456                                         status = AE_AML_NAME_NOT_FOUND;
457                                 }
458                         }
459
460                         if (ACPI_FAILURE (status)) {
461                                 ACPI_REPORT_NSERROR (name_string, status);
462                         }
463                 }
464
465                 /* Free the namestring created above */
466
467                 ACPI_MEM_FREE (name_string);
468
469                 /* Check status from the lookup */
470
471                 if (ACPI_FAILURE (status)) {
472                         return_ACPI_STATUS (status);
473                 }
474
475                 /* Put the resulting object onto the current object stack */
476
477                 status = acpi_ds_obj_stack_push (obj_desc, walk_state);
478                 if (ACPI_FAILURE (status)) {
479                         return_ACPI_STATUS (status);
480                 }
481                 ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (obj_desc, walk_state));
482         }
483         else {
484                 /* Check for null name case */
485
486                 if (arg->common.aml_opcode == AML_INT_NAMEPATH_OP) {
487                         /*
488                          * If the name is null, this means that this is an
489                          * optional result parameter that was not specified
490                          * in the original ASL.  Create a Zero Constant for a
491                          * placeholder.  (Store to a constant is a Noop.)
492                          */
493                         opcode = AML_ZERO_OP;       /* Has no arguments! */
494
495                         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Null namepath: Arg=%p\n", arg));
496                 }
497                 else {
498                         opcode = arg->common.aml_opcode;
499                 }
500
501                 /* Get the object type of the argument */
502
503                 op_info = acpi_ps_get_opcode_info (opcode);
504                 if (op_info->object_type == ACPI_TYPE_INVALID) {
505                         return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
506                 }
507
508                 if (op_info->flags & AML_HAS_RETVAL) {
509                         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
510                                 "Argument previously created, already stacked \n"));
511
512                         ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (
513                                 walk_state->operands [walk_state->num_operands - 1], walk_state));
514
515                         /*
516                          * Use value that was already previously returned
517                          * by the evaluation of this argument
518                          */
519                         status = acpi_ds_result_pop_from_bottom (&obj_desc, walk_state);
520                         if (ACPI_FAILURE (status)) {
521                                 /*
522                                  * Only error is underflow, and this indicates
523                                  * a missing or null operand!
524                                  */
525                                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Missing or null operand, %s\n",
526                                         acpi_format_exception (status)));
527                                 return_ACPI_STATUS (status);
528                         }
529                 }
530                 else {
531                         /* Create an ACPI_INTERNAL_OBJECT for the argument */
532
533                         obj_desc = acpi_ut_create_internal_object (op_info->object_type);
534                         if (!obj_desc) {
535                                 return_ACPI_STATUS (AE_NO_MEMORY);
536                         }
537
538                         /* Initialize the new object */
539
540                         status = acpi_ds_init_object_from_op (walk_state, arg,
541                                          opcode, &obj_desc);
542                         if (ACPI_FAILURE (status)) {
543                                 acpi_ut_delete_object_desc (obj_desc);
544                                 return_ACPI_STATUS (status);
545                         }
546                 }
547
548                 /* Put the operand object on the object stack */
549
550                 status = acpi_ds_obj_stack_push (obj_desc, walk_state);
551                 if (ACPI_FAILURE (status)) {
552                         return_ACPI_STATUS (status);
553                 }
554
555                 ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (obj_desc, walk_state));
556         }
557
558         return_ACPI_STATUS (AE_OK);
559 }
560
561
562 /*******************************************************************************
563  *
564  * FUNCTION:    acpi_ds_create_operands
565  *
566  * PARAMETERS:  first_arg           - First argument of a parser argument tree
567  *
568  * RETURN:      Status
569  *
570  * DESCRIPTION: Convert an operator's arguments from a parse tree format to
571  *              namespace objects and place those argument object on the object
572  *              stack in preparation for evaluation by the interpreter.
573  *
574  ******************************************************************************/
575
576 acpi_status
577 acpi_ds_create_operands (
578         struct acpi_walk_state          *walk_state,
579         union acpi_parse_object         *first_arg)
580 {
581         acpi_status                     status = AE_OK;
582         union acpi_parse_object         *arg;
583         u32                             arg_count = 0;
584
585
586         ACPI_FUNCTION_TRACE_PTR ("ds_create_operands", first_arg);
587
588
589         /* For all arguments in the list... */
590
591         arg = first_arg;
592         while (arg) {
593                 status = acpi_ds_create_operand (walk_state, arg, arg_count);
594                 if (ACPI_FAILURE (status)) {
595                         goto cleanup;
596                 }
597
598                 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Arg #%d (%p) done, Arg1=%p\n",
599                         arg_count, arg, first_arg));
600
601                 /* Move on to next argument, if any */
602
603                 arg = arg->common.next;
604                 arg_count++;
605         }
606
607         return_ACPI_STATUS (status);
608
609
610 cleanup:
611         /*
612          * We must undo everything done above; meaning that we must
613          * pop everything off of the operand stack and delete those
614          * objects
615          */
616         (void) acpi_ds_obj_stack_pop_and_delete (arg_count, walk_state);
617
618         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "While creating Arg %d - %s\n",
619                 (arg_count + 1), acpi_format_exception (status)));
620         return_ACPI_STATUS (status);
621 }
622
623