Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /****************************************************************************** |
2 | * | |
3 | * Module Name: psxface - Parser external interfaces | |
4 | * | |
5 | *****************************************************************************/ | |
6 | ||
7 | /* | |
8 | * Copyright (C) 2000 - 2005, 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/acdispat.h> | |
48 | #include <acpi/acinterp.h> | |
1da177e4 LT |
49 | |
50 | ||
51 | #define _COMPONENT ACPI_PARSER | |
52 | ACPI_MODULE_NAME ("psxface") | |
53 | ||
0c9938cc RM |
54 | /* Local Prototypes */ |
55 | ||
56 | static acpi_status | |
57 | acpi_ps_execute_pass ( | |
58 | struct acpi_parameter_info *info); | |
59 | ||
60 | static void | |
61 | acpi_ps_update_parameter_list ( | |
62 | struct acpi_parameter_info *info, | |
63 | u16 action); | |
64 | ||
1da177e4 LT |
65 | |
66 | /******************************************************************************* | |
67 | * | |
0c9938cc | 68 | * FUNCTION: acpi_ps_execute_method |
1da177e4 | 69 | * |
44f6c012 RM |
70 | * PARAMETERS: Info - Method info block, contains: |
71 | * Node - Method Node to execute | |
0c9938cc | 72 | * obj_desc - Method object |
44f6c012 | 73 | * Parameters - List of parameters to pass to the method, |
1da177e4 LT |
74 | * terminated by NULL. Params itself may be |
75 | * NULL if no parameters are being passed. | |
44f6c012 RM |
76 | * return_object - Where to put method's return value (if |
77 | * any). If NULL, no value is returned. | |
78 | * parameter_type - Type of Parameter list | |
79 | * return_object - Where to put method's return value (if | |
80 | * any). If NULL, no value is returned. | |
0c9938cc | 81 | * pass_number - Parse or execute pass |
1da177e4 LT |
82 | * |
83 | * RETURN: Status | |
84 | * | |
85 | * DESCRIPTION: Execute a control method | |
86 | * | |
87 | ******************************************************************************/ | |
88 | ||
89 | acpi_status | |
0c9938cc | 90 | acpi_ps_execute_method ( |
1da177e4 LT |
91 | struct acpi_parameter_info *info) |
92 | { | |
93 | acpi_status status; | |
1da177e4 LT |
94 | |
95 | ||
0c9938cc | 96 | ACPI_FUNCTION_TRACE ("ps_execute_method"); |
1da177e4 LT |
97 | |
98 | ||
0c9938cc | 99 | /* Validate the Info and method Node */ |
1da177e4 LT |
100 | |
101 | if (!info || !info->node) { | |
102 | return_ACPI_STATUS (AE_NULL_ENTRY); | |
103 | } | |
104 | ||
1da177e4 LT |
105 | /* Init for new method, wait on concurrency semaphore */ |
106 | ||
0c9938cc | 107 | status = acpi_ds_begin_method_execution (info->node, info->obj_desc, NULL); |
1da177e4 LT |
108 | if (ACPI_FAILURE (status)) { |
109 | return_ACPI_STATUS (status); | |
110 | } | |
111 | ||
1da177e4 LT |
112 | /* |
113 | * Get a new owner_id for objects created by this method. Namespace | |
114 | * objects (such as Operation Regions) can be created during the | |
115 | * first pass parse. | |
116 | */ | |
0c9938cc | 117 | status = acpi_ut_allocate_owner_id (&info->obj_desc->method.owner_id); |
f9f4601f | 118 | if (ACPI_FAILURE (status)) { |
0c9938cc | 119 | return_ACPI_STATUS (status); |
1da177e4 LT |
120 | } |
121 | ||
0c9938cc RM |
122 | /* |
123 | * The caller "owns" the parameters, so give each one an extra | |
124 | * reference | |
125 | */ | |
126 | acpi_ps_update_parameter_list (info, REF_INCREMENT); | |
1da177e4 | 127 | |
0c9938cc RM |
128 | /* |
129 | * 1) Perform the first pass parse of the method to enter any | |
130 | * named objects that it creates into the namespace | |
131 | */ | |
132 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, | |
133 | "**** Begin Method Parse **** Entry=%p obj=%p\n", | |
134 | info->node, info->obj_desc)); | |
1da177e4 | 135 | |
0c9938cc RM |
136 | info->pass_number = 1; |
137 | status = acpi_ps_execute_pass (info); | |
1da177e4 | 138 | if (ACPI_FAILURE (status)) { |
0c9938cc | 139 | goto cleanup; |
1da177e4 LT |
140 | } |
141 | ||
142 | /* | |
0c9938cc | 143 | * 2) Execute the method. Performs second pass parse simultaneously |
1da177e4 LT |
144 | */ |
145 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, | |
146 | "**** Begin Method Execution **** Entry=%p obj=%p\n", | |
0c9938cc | 147 | info->node, info->obj_desc)); |
1da177e4 | 148 | |
0c9938cc RM |
149 | info->pass_number = 3; |
150 | status = acpi_ps_execute_pass (info); | |
1da177e4 | 151 | |
0c9938cc RM |
152 | |
153 | cleanup: | |
154 | if (info->obj_desc->method.owner_id) { | |
155 | acpi_ut_release_owner_id (&info->obj_desc->method.owner_id); | |
1da177e4 LT |
156 | } |
157 | ||
0c9938cc | 158 | /* Take away the extra reference that we gave the parameters above */ |
1da177e4 | 159 | |
0c9938cc | 160 | acpi_ps_update_parameter_list (info, REF_DECREMENT); |
1da177e4 | 161 | |
0c9938cc | 162 | /* Exit now if error above */ |
1da177e4 | 163 | |
0c9938cc RM |
164 | if (ACPI_FAILURE (status)) { |
165 | return_ACPI_STATUS (status); | |
1da177e4 LT |
166 | } |
167 | ||
0c9938cc RM |
168 | /* |
169 | * If the method has returned an object, signal this to the caller with | |
170 | * a control exception code | |
171 | */ | |
172 | if (info->return_object) { | |
173 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned obj_desc=%p\n", | |
174 | info->return_object)); | |
175 | ACPI_DUMP_STACK_ENTRY (info->return_object); | |
176 | ||
177 | status = AE_CTRL_RETURN_VALUE; | |
1da177e4 LT |
178 | } |
179 | ||
0c9938cc RM |
180 | return_ACPI_STATUS (status); |
181 | } | |
44f6c012 | 182 | |
1da177e4 | 183 | |
0c9938cc RM |
184 | /******************************************************************************* |
185 | * | |
186 | * FUNCTION: acpi_ps_update_parameter_list | |
187 | * | |
188 | * PARAMETERS: Info - See struct acpi_parameter_info | |
189 | * (Used: parameter_type and Parameters) | |
190 | * Action - Add or Remove reference | |
191 | * | |
192 | * RETURN: Status | |
193 | * | |
194 | * DESCRIPTION: Update reference count on all method parameter objects | |
195 | * | |
196 | ******************************************************************************/ | |
1da177e4 | 197 | |
0c9938cc RM |
198 | static void |
199 | acpi_ps_update_parameter_list ( | |
200 | struct acpi_parameter_info *info, | |
201 | u16 action) | |
202 | { | |
203 | acpi_native_uint i; | |
1da177e4 | 204 | |
1da177e4 | 205 | |
1da177e4 LT |
206 | if ((info->parameter_type == ACPI_PARAM_ARGS) && |
207 | (info->parameters)) { | |
0c9938cc | 208 | /* Update reference count for each parameter */ |
1da177e4 LT |
209 | |
210 | for (i = 0; info->parameters[i]; i++) { | |
211 | /* Ignore errors, just do them all */ | |
212 | ||
0c9938cc | 213 | (void) acpi_ut_update_object_reference (info->parameters[i], action); |
1da177e4 LT |
214 | } |
215 | } | |
0c9938cc | 216 | } |
1da177e4 | 217 | |
0c9938cc RM |
218 | |
219 | /******************************************************************************* | |
220 | * | |
221 | * FUNCTION: acpi_ps_execute_pass | |
222 | * | |
223 | * PARAMETERS: Info - See struct acpi_parameter_info | |
224 | * (Used: pass_number, Node, and obj_desc) | |
225 | * | |
226 | * RETURN: Status | |
227 | * | |
228 | * DESCRIPTION: Single AML pass: Parse or Execute a control method | |
229 | * | |
230 | ******************************************************************************/ | |
231 | ||
232 | static acpi_status | |
233 | acpi_ps_execute_pass ( | |
234 | struct acpi_parameter_info *info) | |
235 | { | |
236 | acpi_status status; | |
237 | union acpi_parse_object *op; | |
238 | struct acpi_walk_state *walk_state; | |
239 | ||
240 | ||
241 | ACPI_FUNCTION_TRACE ("ps_execute_pass"); | |
242 | ||
243 | ||
244 | /* Create and init a Root Node */ | |
245 | ||
246 | op = acpi_ps_create_scope_op (); | |
247 | if (!op) { | |
248 | return_ACPI_STATUS (AE_NO_MEMORY); | |
1da177e4 LT |
249 | } |
250 | ||
0c9938cc | 251 | /* Create and initialize a new walk state */ |
1da177e4 | 252 | |
0c9938cc RM |
253 | walk_state = acpi_ds_create_walk_state ( |
254 | info->obj_desc->method.owner_id, NULL, NULL, NULL); | |
255 | if (!walk_state) { | |
256 | status = AE_NO_MEMORY; | |
257 | goto cleanup; | |
258 | } | |
259 | ||
260 | status = acpi_ds_init_aml_walk (walk_state, op, info->node, | |
261 | info->obj_desc->method.aml_start, | |
262 | info->obj_desc->method.aml_length, | |
263 | info->pass_number == 1 ? NULL : info, | |
264 | info->pass_number); | |
265 | if (ACPI_FAILURE (status)) { | |
266 | acpi_ds_delete_walk_state (walk_state); | |
267 | goto cleanup; | |
1da177e4 LT |
268 | } |
269 | ||
0c9938cc RM |
270 | /* Parse the AML */ |
271 | ||
272 | status = acpi_ps_parse_aml (walk_state); | |
273 | ||
274 | /* Walk state was deleted by parse_aml */ | |
275 | ||
276 | cleanup: | |
277 | acpi_ps_delete_parse_tree (op); | |
1da177e4 LT |
278 | return_ACPI_STATUS (status); |
279 | } | |
280 | ||
281 |