1
2
3
4
5
6
7
8
9
10#include <acpi/acpi.h>
11#include "accommon.h"
12#include "acparser.h"
13#include "acdispat.h"
14#include "acinterp.h"
15#include "actables.h"
16#include "acnamesp.h"
17
18#define _COMPONENT ACPI_PARSER
19ACPI_MODULE_NAME("psxface")
20
21
22static void
23acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action);
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41acpi_status
42acpi_debug_trace(const char *name, u32 debug_level, u32 debug_layer, u32 flags)
43{
44 acpi_status status;
45
46 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
47 if (ACPI_FAILURE(status)) {
48 return (status);
49 }
50
51 acpi_gbl_trace_method_name = name;
52 acpi_gbl_trace_flags = flags;
53 acpi_gbl_trace_dbg_level = debug_level;
54 acpi_gbl_trace_dbg_layer = debug_layer;
55 status = AE_OK;
56
57 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
58 return (status);
59}
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
85{
86 acpi_status status;
87 union acpi_parse_object *op;
88 struct acpi_walk_state *walk_state;
89
90 ACPI_FUNCTION_TRACE(ps_execute_method);
91
92
93
94 acpi_tb_check_dsdt_header();
95
96
97
98 if (!info || !info->node) {
99 return_ACPI_STATUS(AE_NULL_ENTRY);
100 }
101
102
103
104 status =
105 acpi_ds_begin_method_execution(info->node, info->obj_desc, NULL);
106 if (ACPI_FAILURE(status)) {
107 return_ACPI_STATUS(status);
108 }
109
110
111
112
113 acpi_ps_update_parameter_list(info, REF_INCREMENT);
114
115
116
117
118 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
119 "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n",
120 info->node->name.ascii, info->node, info->obj_desc));
121
122
123
124 op = acpi_ps_create_scope_op(info->obj_desc->method.aml_start);
125 if (!op) {
126 status = AE_NO_MEMORY;
127 goto cleanup;
128 }
129
130
131
132 info->pass_number = ACPI_IMODE_EXECUTE;
133 walk_state =
134 acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,
135 NULL, NULL);
136 if (!walk_state) {
137 status = AE_NO_MEMORY;
138 goto cleanup;
139 }
140
141 status = acpi_ds_init_aml_walk(walk_state, op, info->node,
142 info->obj_desc->method.aml_start,
143 info->obj_desc->method.aml_length, info,
144 info->pass_number);
145 if (ACPI_FAILURE(status)) {
146 acpi_ds_delete_walk_state(walk_state);
147 goto cleanup;
148 }
149
150 if (info->obj_desc->method.info_flags & ACPI_METHOD_MODULE_LEVEL) {
151 walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL;
152 }
153
154
155
156 if (info->obj_desc->method.info_flags & ACPI_METHOD_INTERNAL_ONLY) {
157 status =
158 info->obj_desc->method.dispatch.implementation(walk_state);
159 info->return_object = walk_state->return_desc;
160
161
162
163 acpi_ds_scope_stack_clear(walk_state);
164 acpi_ps_cleanup_scope(&walk_state->parser_state);
165 acpi_ds_terminate_control_method(walk_state->method_desc,
166 walk_state);
167 acpi_ds_delete_walk_state(walk_state);
168 goto cleanup;
169 }
170
171
172
173
174
175 if (acpi_gbl_enable_interpreter_slack) {
176 walk_state->implicit_return_obj =
177 acpi_ut_create_integer_object((u64) 0);
178 if (!walk_state->implicit_return_obj) {
179 status = AE_NO_MEMORY;
180 acpi_ds_delete_walk_state(walk_state);
181 goto cleanup;
182 }
183 }
184
185
186
187 status = acpi_ps_parse_aml(walk_state);
188
189
190
191cleanup:
192 acpi_ps_delete_parse_tree(op);
193
194
195
196 acpi_ps_update_parameter_list(info, REF_DECREMENT);
197
198
199
200 if (ACPI_FAILURE(status)) {
201 return_ACPI_STATUS(status);
202 }
203
204
205
206
207
208 if (info->return_object) {
209 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Method returned ObjDesc=%p\n",
210 info->return_object));
211 ACPI_DUMP_STACK_ENTRY(info->return_object);
212
213 status = AE_CTRL_RETURN_VALUE;
214 }
215
216 return_ACPI_STATUS(status);
217}
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236acpi_status acpi_ps_execute_table(struct acpi_evaluate_info *info)
237{
238 acpi_status status;
239 union acpi_parse_object *op = NULL;
240 struct acpi_walk_state *walk_state = NULL;
241
242 ACPI_FUNCTION_TRACE(ps_execute_table);
243
244
245
246 op = acpi_ps_create_scope_op(info->obj_desc->method.aml_start);
247 if (!op) {
248 status = AE_NO_MEMORY;
249 goto cleanup;
250 }
251
252
253
254 walk_state =
255 acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,
256 NULL, NULL);
257 if (!walk_state) {
258 status = AE_NO_MEMORY;
259 goto cleanup;
260 }
261
262 status = acpi_ds_init_aml_walk(walk_state, op, info->node,
263 info->obj_desc->method.aml_start,
264 info->obj_desc->method.aml_length, info,
265 info->pass_number);
266 if (ACPI_FAILURE(status)) {
267 goto cleanup;
268 }
269
270 if (info->obj_desc->method.info_flags & ACPI_METHOD_MODULE_LEVEL) {
271 walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL;
272 }
273
274
275
276 if (info->node && info->node != acpi_gbl_root_node) {
277 status =
278 acpi_ds_scope_stack_push(info->node, ACPI_TYPE_METHOD,
279 walk_state);
280 if (ACPI_FAILURE(status)) {
281 goto cleanup;
282 }
283 }
284
285
286
287
288 acpi_ex_enter_interpreter();
289 status = acpi_ps_parse_aml(walk_state);
290 acpi_ex_exit_interpreter();
291 walk_state = NULL;
292
293cleanup:
294 if (walk_state) {
295 acpi_ds_delete_walk_state(walk_state);
296 }
297 if (op) {
298 acpi_ps_delete_parse_tree(op);
299 }
300 return_ACPI_STATUS(status);
301}
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317static void
318acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action)
319{
320 u32 i;
321
322 if (info->parameters) {
323
324
325
326 for (i = 0; info->parameters[i]; i++) {
327
328
329
330 (void)acpi_ut_update_object_reference(info->
331 parameters[i],
332 action);
333 }
334 }
335}
336