import of ftp.dlink.com/GPL/DSMG-600_reB/ppclinux.tar.gz
[linux-2.4.21-pre4.git] / drivers / acpi / parser / psxface.c
1 /******************************************************************************
2  *
3  * Module Name: psxface - Parser external interfaces
4  *              $Revision: 1.1.1.1 $
5  *
6  *****************************************************************************/
7
8 /*
9  *  Copyright (C) 2000, 2001 R. Byron Moore
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  */
25
26
27 #include "acpi.h"
28 #include "acparser.h"
29 #include "acdispat.h"
30 #include "acinterp.h"
31 #include "amlcode.h"
32 #include "acnamesp.h"
33
34
35 #define _COMPONENT          ACPI_PARSER
36          MODULE_NAME         ("psxface")
37
38
39 /*******************************************************************************
40  *
41  * FUNCTION:    Acpi_psx_execute
42  *
43  * PARAMETERS:  Method_node         - A method object containing both the AML
44  *                                    address and length.
45  *              **Params            - List of parameters to pass to method,
46  *                                    terminated by NULL. Params itself may be
47  *                                    NULL if no parameters are being passed.
48  *              **Return_obj_desc   - Return object from execution of the
49  *                                    method.
50  *
51  * RETURN:      Status
52  *
53  * DESCRIPTION: Execute a control method
54  *
55  ******************************************************************************/
56
57 acpi_status
58 acpi_psx_execute (
59         acpi_namespace_node     *method_node,
60         acpi_operand_object     **params,
61         acpi_operand_object     **return_obj_desc)
62 {
63         acpi_status             status;
64         acpi_operand_object     *obj_desc;
65         u32                     i;
66         acpi_parse_object       *op;
67         acpi_walk_state         *walk_state;
68
69
70         FUNCTION_TRACE ("Psx_execute");
71
72
73         /* Validate the Node and get the attached object */
74
75         if (!method_node) {
76                 return_ACPI_STATUS (AE_NULL_ENTRY);
77         }
78
79         obj_desc = acpi_ns_get_attached_object (method_node);
80         if (!obj_desc) {
81                 return_ACPI_STATUS (AE_NULL_OBJECT);
82         }
83
84         /* Init for new method, wait on concurrency semaphore */
85
86         status = acpi_ds_begin_method_execution (method_node, obj_desc, NULL);
87         if (ACPI_FAILURE (status)) {
88                 return_ACPI_STATUS (status);
89         }
90
91         if (params) {
92                 /*
93                  * The caller "owns" the parameters, so give each one an extra
94                  * reference
95                  */
96                 for (i = 0; params[i]; i++) {
97                         acpi_ut_add_reference (params[i]);
98                 }
99         }
100
101         /*
102          * 1) Perform the first pass parse of the method to enter any
103          * named objects that it creates into the namespace
104          */
105         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
106                 "**** Begin Method Parse **** Entry=%p obj=%p\n",
107                 method_node, obj_desc));
108
109         /* Create and init a Root Node */
110
111         op = acpi_ps_alloc_op (AML_SCOPE_OP);
112         if (!op) {
113                 return_ACPI_STATUS (AE_NO_MEMORY);
114         }
115
116         /* Create and initialize a new walk state */
117
118         walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT,
119                            NULL, NULL, NULL);
120         if (!walk_state) {
121                 return_ACPI_STATUS (AE_NO_MEMORY);
122         }
123
124         status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start,
125                           obj_desc->method.aml_length, NULL, NULL, 1);
126         if (ACPI_FAILURE (status)) {
127                 /* TBD: delete walk state */
128                 return_ACPI_STATUS (status);
129         }
130
131         /* Parse the AML */
132
133         status = acpi_ps_parse_aml (walk_state);
134         acpi_ps_delete_parse_tree (op);
135
136
137         /*
138          * 2) Execute the method.  Performs second pass parse simultaneously
139          */
140         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
141                 "**** Begin Method Execution **** Entry=%p obj=%p\n",
142                 method_node, obj_desc));
143
144         /* Create and init a Root Node */
145
146         op = acpi_ps_alloc_op (AML_SCOPE_OP);
147         if (!op) {
148                 return_ACPI_STATUS (AE_NO_MEMORY);
149         }
150
151         /* Init new op with the method name and pointer back to the NS node */
152
153         acpi_ps_set_name (op, method_node->name);
154         op->node = method_node;
155
156         /* Create and initialize a new walk state */
157
158         walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT,
159                            NULL, NULL, NULL);
160         if (!walk_state) {
161                 return_ACPI_STATUS (AE_NO_MEMORY);
162         }
163
164         status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start,
165                           obj_desc->method.aml_length, params, return_obj_desc, 3);
166         if (ACPI_FAILURE (status)) {
167                 /* TBD: delete walk state */
168                 return_ACPI_STATUS (status);
169         }
170
171         /*
172          * The walk of the parse tree is where we actually execute the method
173          */
174         status = acpi_ps_parse_aml (walk_state);
175         acpi_ps_delete_parse_tree (op);
176
177         if (params) {
178                 /* Take away the extra reference that we gave the parameters above */
179
180                 for (i = 0; params[i]; i++) {
181                         acpi_ut_update_object_reference (params[i], REF_DECREMENT);
182                 }
183         }
184
185
186         if (ACPI_FAILURE (status)) {
187                 DUMP_PATHNAME (method_node, "Ps_execute: method failed -",
188                         ACPI_LV_ERROR, _COMPONENT);
189         }
190
191
192         /*
193          * If the method has returned an object, signal this to the caller with
194          * a control exception code
195          */
196         if (*return_obj_desc) {
197                 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Method returned Obj_desc=%p\n",
198                         *return_obj_desc));
199                 DUMP_STACK_ENTRY (*return_obj_desc);
200
201                 status = AE_CTRL_RETURN_VALUE;
202         }
203
204
205         return_ACPI_STATUS (status);
206 }
207
208