diff options
Diffstat (limited to 'drivers/acpi/parser/psparse.c')
-rw-r--r-- | drivers/acpi/parser/psparse.c | 362 |
1 files changed, 185 insertions, 177 deletions
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index 16b84a3d0436..3248051d77ee 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c | |||
@@ -41,7 +41,6 @@ | |||
41 | * POSSIBILITY OF SUCH DAMAGES. | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | |||
45 | /* | 44 | /* |
46 | * Parse the AML and build an operation tree as most interpreters, | 45 | * Parse the AML and build an operation tree as most interpreters, |
47 | * like Perl, do. Parsing is done by hand rather than with a YACC | 46 | * like Perl, do. Parsing is done by hand rather than with a YACC |
@@ -59,8 +58,7 @@ | |||
59 | #include <acpi/acinterp.h> | 58 | #include <acpi/acinterp.h> |
60 | 59 | ||
61 | #define _COMPONENT ACPI_PARSER | 60 | #define _COMPONENT ACPI_PARSER |
62 | ACPI_MODULE_NAME ("psparse") | 61 | ACPI_MODULE_NAME("psparse") |
63 | |||
64 | 62 | ||
65 | /******************************************************************************* | 63 | /******************************************************************************* |
66 | * | 64 | * |
@@ -73,10 +71,7 @@ | |||
73 | * DESCRIPTION: Get the size of the current opcode. | 71 | * DESCRIPTION: Get the size of the current opcode. |
74 | * | 72 | * |
75 | ******************************************************************************/ | 73 | ******************************************************************************/ |
76 | 74 | u32 acpi_ps_get_opcode_size(u32 opcode) | |
77 | u32 | ||
78 | acpi_ps_get_opcode_size ( | ||
79 | u32 opcode) | ||
80 | { | 75 | { |
81 | 76 | ||
82 | /* Extended (2-byte) opcode if > 255 */ | 77 | /* Extended (2-byte) opcode if > 255 */ |
@@ -90,7 +85,6 @@ acpi_ps_get_opcode_size ( | |||
90 | return (1); | 85 | return (1); |
91 | } | 86 | } |
92 | 87 | ||
93 | |||
94 | /******************************************************************************* | 88 | /******************************************************************************* |
95 | * | 89 | * |
96 | * FUNCTION: acpi_ps_peek_opcode | 90 | * FUNCTION: acpi_ps_peek_opcode |
@@ -103,28 +97,24 @@ acpi_ps_get_opcode_size ( | |||
103 | * | 97 | * |
104 | ******************************************************************************/ | 98 | ******************************************************************************/ |
105 | 99 | ||
106 | u16 | 100 | u16 acpi_ps_peek_opcode(struct acpi_parse_state * parser_state) |
107 | acpi_ps_peek_opcode ( | ||
108 | struct acpi_parse_state *parser_state) | ||
109 | { | 101 | { |
110 | u8 *aml; | 102 | u8 *aml; |
111 | u16 opcode; | 103 | u16 opcode; |
112 | |||
113 | 104 | ||
114 | aml = parser_state->aml; | 105 | aml = parser_state->aml; |
115 | opcode = (u16) ACPI_GET8 (aml); | 106 | opcode = (u16) ACPI_GET8(aml); |
116 | 107 | ||
117 | if (opcode == AML_EXTENDED_OP_PREFIX) { | 108 | if (opcode == AML_EXTENDED_OP_PREFIX) { |
118 | /* Extended opcode, get the second opcode byte */ | 109 | /* Extended opcode, get the second opcode byte */ |
119 | 110 | ||
120 | aml++; | 111 | aml++; |
121 | opcode = (u16) ((opcode << 8) | ACPI_GET8 (aml)); | 112 | opcode = (u16) ((opcode << 8) | ACPI_GET8(aml)); |
122 | } | 113 | } |
123 | 114 | ||
124 | return (opcode); | 115 | return (opcode); |
125 | } | 116 | } |
126 | 117 | ||
127 | |||
128 | /******************************************************************************* | 118 | /******************************************************************************* |
129 | * | 119 | * |
130 | * FUNCTION: acpi_ps_complete_this_op | 120 | * FUNCTION: acpi_ps_complete_this_op |
@@ -139,30 +129,28 @@ acpi_ps_peek_opcode ( | |||
139 | ******************************************************************************/ | 129 | ******************************************************************************/ |
140 | 130 | ||
141 | acpi_status | 131 | acpi_status |
142 | acpi_ps_complete_this_op ( | 132 | acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, |
143 | struct acpi_walk_state *walk_state, | 133 | union acpi_parse_object * op) |
144 | union acpi_parse_object *op) | ||
145 | { | 134 | { |
146 | union acpi_parse_object *prev; | 135 | union acpi_parse_object *prev; |
147 | union acpi_parse_object *next; | 136 | union acpi_parse_object *next; |
148 | const struct acpi_opcode_info *parent_info; | 137 | const struct acpi_opcode_info *parent_info; |
149 | union acpi_parse_object *replacement_op = NULL; | 138 | union acpi_parse_object *replacement_op = NULL; |
150 | |||
151 | |||
152 | ACPI_FUNCTION_TRACE_PTR ("ps_complete_this_op", op); | ||
153 | 139 | ||
140 | ACPI_FUNCTION_TRACE_PTR("ps_complete_this_op", op); | ||
154 | 141 | ||
155 | /* Check for null Op, can happen if AML code is corrupt */ | 142 | /* Check for null Op, can happen if AML code is corrupt */ |
156 | 143 | ||
157 | if (!op) { | 144 | if (!op) { |
158 | return_ACPI_STATUS (AE_OK); /* OK for now */ | 145 | return_ACPI_STATUS(AE_OK); /* OK for now */ |
159 | } | 146 | } |
160 | 147 | ||
161 | /* Delete this op and the subtree below it if asked to */ | 148 | /* Delete this op and the subtree below it if asked to */ |
162 | 149 | ||
163 | if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) != ACPI_PARSE_DELETE_TREE) || | 150 | if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) != |
164 | (walk_state->op_info->class == AML_CLASS_ARGUMENT)) { | 151 | ACPI_PARSE_DELETE_TREE) |
165 | return_ACPI_STATUS (AE_OK); | 152 | || (walk_state->op_info->class == AML_CLASS_ARGUMENT)) { |
153 | return_ACPI_STATUS(AE_OK); | ||
166 | } | 154 | } |
167 | 155 | ||
168 | /* Make sure that we only delete this subtree */ | 156 | /* Make sure that we only delete this subtree */ |
@@ -179,7 +167,9 @@ acpi_ps_complete_this_op ( | |||
179 | * Check if we need to replace the operator and its subtree | 167 | * Check if we need to replace the operator and its subtree |
180 | * with a return value op (placeholder op) | 168 | * with a return value op (placeholder op) |
181 | */ | 169 | */ |
182 | parent_info = acpi_ps_get_opcode_info (op->common.parent->common.aml_opcode); | 170 | parent_info = |
171 | acpi_ps_get_opcode_info(op->common.parent->common. | ||
172 | aml_opcode); | ||
183 | 173 | ||
184 | switch (parent_info->class) { | 174 | switch (parent_info->class) { |
185 | case AML_CLASS_CONTROL: | 175 | case AML_CLASS_CONTROL: |
@@ -191,7 +181,8 @@ acpi_ps_complete_this_op ( | |||
191 | * These opcodes contain term_arg operands. The current | 181 | * These opcodes contain term_arg operands. The current |
192 | * op must be replaced by a placeholder return op | 182 | * op must be replaced by a placeholder return op |
193 | */ | 183 | */ |
194 | replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP); | 184 | replacement_op = |
185 | acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); | ||
195 | if (!replacement_op) { | 186 | if (!replacement_op) { |
196 | goto allocate_error; | 187 | goto allocate_error; |
197 | } | 188 | } |
@@ -203,35 +194,49 @@ acpi_ps_complete_this_op ( | |||
203 | * These opcodes contain term_arg operands. The current | 194 | * These opcodes contain term_arg operands. The current |
204 | * op must be replaced by a placeholder return op | 195 | * op must be replaced by a placeholder return op |
205 | */ | 196 | */ |
206 | if ((op->common.parent->common.aml_opcode == AML_REGION_OP) || | 197 | if ((op->common.parent->common.aml_opcode == |
207 | (op->common.parent->common.aml_opcode == AML_DATA_REGION_OP) || | 198 | AML_REGION_OP) |
208 | (op->common.parent->common.aml_opcode == AML_BUFFER_OP) || | 199 | || (op->common.parent->common.aml_opcode == |
209 | (op->common.parent->common.aml_opcode == AML_PACKAGE_OP) || | 200 | AML_DATA_REGION_OP) |
210 | (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) { | 201 | || (op->common.parent->common.aml_opcode == |
211 | replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP); | 202 | AML_BUFFER_OP) |
203 | || (op->common.parent->common.aml_opcode == | ||
204 | AML_PACKAGE_OP) | ||
205 | || (op->common.parent->common.aml_opcode == | ||
206 | AML_VAR_PACKAGE_OP)) { | ||
207 | replacement_op = | ||
208 | acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); | ||
212 | if (!replacement_op) { | 209 | if (!replacement_op) { |
213 | goto allocate_error; | 210 | goto allocate_error; |
214 | } | 211 | } |
215 | } | 212 | } else |
216 | else if ((op->common.parent->common.aml_opcode == AML_NAME_OP) && | 213 | if ((op->common.parent->common.aml_opcode == |
217 | (walk_state->pass_number <= ACPI_IMODE_LOAD_PASS2)) { | 214 | AML_NAME_OP) |
218 | if ((op->common.aml_opcode == AML_BUFFER_OP) || | 215 | && (walk_state->pass_number <= |
219 | (op->common.aml_opcode == AML_PACKAGE_OP) || | 216 | ACPI_IMODE_LOAD_PASS2)) { |
220 | (op->common.aml_opcode == AML_VAR_PACKAGE_OP)) { | 217 | if ((op->common.aml_opcode == AML_BUFFER_OP) |
221 | replacement_op = acpi_ps_alloc_op (op->common.aml_opcode); | 218 | || (op->common.aml_opcode == AML_PACKAGE_OP) |
219 | || (op->common.aml_opcode == | ||
220 | AML_VAR_PACKAGE_OP)) { | ||
221 | replacement_op = | ||
222 | acpi_ps_alloc_op(op->common. | ||
223 | aml_opcode); | ||
222 | if (!replacement_op) { | 224 | if (!replacement_op) { |
223 | goto allocate_error; | 225 | goto allocate_error; |
224 | } | 226 | } |
225 | 227 | ||
226 | replacement_op->named.data = op->named.data; | 228 | replacement_op->named.data = |
227 | replacement_op->named.length = op->named.length; | 229 | op->named.data; |
230 | replacement_op->named.length = | ||
231 | op->named.length; | ||
228 | } | 232 | } |
229 | } | 233 | } |
230 | break; | 234 | break; |
231 | 235 | ||
232 | default: | 236 | default: |
233 | 237 | ||
234 | replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP); | 238 | replacement_op = |
239 | acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); | ||
235 | if (!replacement_op) { | 240 | if (!replacement_op) { |
236 | goto allocate_error; | 241 | goto allocate_error; |
237 | } | 242 | } |
@@ -243,59 +248,64 @@ acpi_ps_complete_this_op ( | |||
243 | /* This op is the first in the list */ | 248 | /* This op is the first in the list */ |
244 | 249 | ||
245 | if (replacement_op) { | 250 | if (replacement_op) { |
246 | replacement_op->common.parent = op->common.parent; | 251 | replacement_op->common.parent = |
247 | replacement_op->common.value.arg = NULL; | 252 | op->common.parent; |
248 | replacement_op->common.node = op->common.node; | 253 | replacement_op->common.value.arg = NULL; |
249 | op->common.parent->common.value.arg = replacement_op; | 254 | replacement_op->common.node = op->common.node; |
250 | replacement_op->common.next = op->common.next; | 255 | op->common.parent->common.value.arg = |
251 | } | 256 | replacement_op; |
252 | else { | 257 | replacement_op->common.next = op->common.next; |
253 | op->common.parent->common.value.arg = op->common.next; | 258 | } else { |
259 | op->common.parent->common.value.arg = | ||
260 | op->common.next; | ||
254 | } | 261 | } |
255 | } | 262 | } |
256 | 263 | ||
257 | /* Search the parent list */ | 264 | /* Search the parent list */ |
258 | 265 | ||
259 | else while (prev) { | 266 | else |
260 | /* Traverse all siblings in the parent's argument list */ | 267 | while (prev) { |
261 | 268 | /* Traverse all siblings in the parent's argument list */ | |
262 | next = prev->common.next; | 269 | |
263 | if (next == op) { | 270 | next = prev->common.next; |
264 | if (replacement_op) { | 271 | if (next == op) { |
265 | replacement_op->common.parent = op->common.parent; | 272 | if (replacement_op) { |
266 | replacement_op->common.value.arg = NULL; | 273 | replacement_op->common.parent = |
267 | replacement_op->common.node = op->common.node; | 274 | op->common.parent; |
268 | prev->common.next = replacement_op; | 275 | replacement_op->common.value. |
269 | replacement_op->common.next = op->common.next; | 276 | arg = NULL; |
270 | next = NULL; | 277 | replacement_op->common.node = |
271 | } | 278 | op->common.node; |
272 | else { | 279 | prev->common.next = |
273 | prev->common.next = op->common.next; | 280 | replacement_op; |
274 | next = NULL; | 281 | replacement_op->common.next = |
282 | op->common.next; | ||
283 | next = NULL; | ||
284 | } else { | ||
285 | prev->common.next = | ||
286 | op->common.next; | ||
287 | next = NULL; | ||
288 | } | ||
275 | } | 289 | } |
290 | prev = next; | ||
276 | } | 291 | } |
277 | prev = next; | ||
278 | } | ||
279 | } | 292 | } |
280 | 293 | ||
281 | 294 | cleanup: | |
282 | cleanup: | ||
283 | 295 | ||
284 | /* Now we can actually delete the subtree rooted at Op */ | 296 | /* Now we can actually delete the subtree rooted at Op */ |
285 | 297 | ||
286 | acpi_ps_delete_parse_tree (op); | 298 | acpi_ps_delete_parse_tree(op); |
287 | return_ACPI_STATUS (AE_OK); | 299 | return_ACPI_STATUS(AE_OK); |
288 | 300 | ||
289 | 301 | allocate_error: | |
290 | allocate_error: | ||
291 | 302 | ||
292 | /* Always delete the subtree, even on error */ | 303 | /* Always delete the subtree, even on error */ |
293 | 304 | ||
294 | acpi_ps_delete_parse_tree (op); | 305 | acpi_ps_delete_parse_tree(op); |
295 | return_ACPI_STATUS (AE_NO_MEMORY); | 306 | return_ACPI_STATUS(AE_NO_MEMORY); |
296 | } | 307 | } |
297 | 308 | ||
298 | |||
299 | /******************************************************************************* | 309 | /******************************************************************************* |
300 | * | 310 | * |
301 | * FUNCTION: acpi_ps_next_parse_state | 311 | * FUNCTION: acpi_ps_next_parse_state |
@@ -312,17 +322,14 @@ allocate_error: | |||
312 | ******************************************************************************/ | 322 | ******************************************************************************/ |
313 | 323 | ||
314 | acpi_status | 324 | acpi_status |
315 | acpi_ps_next_parse_state ( | 325 | acpi_ps_next_parse_state(struct acpi_walk_state *walk_state, |
316 | struct acpi_walk_state *walk_state, | 326 | union acpi_parse_object *op, |
317 | union acpi_parse_object *op, | 327 | acpi_status callback_status) |
318 | acpi_status callback_status) | ||
319 | { | 328 | { |
320 | struct acpi_parse_state *parser_state = &walk_state->parser_state; | 329 | struct acpi_parse_state *parser_state = &walk_state->parser_state; |
321 | acpi_status status = AE_CTRL_PENDING; | 330 | acpi_status status = AE_CTRL_PENDING; |
322 | |||
323 | |||
324 | ACPI_FUNCTION_TRACE_PTR ("ps_next_parse_state", op); | ||
325 | 331 | ||
332 | ACPI_FUNCTION_TRACE_PTR("ps_next_parse_state", op); | ||
326 | 333 | ||
327 | switch (callback_status) { | 334 | switch (callback_status) { |
328 | case AE_CTRL_TERMINATE: | 335 | case AE_CTRL_TERMINATE: |
@@ -335,7 +342,6 @@ acpi_ps_next_parse_state ( | |||
335 | status = AE_CTRL_TERMINATE; | 342 | status = AE_CTRL_TERMINATE; |
336 | break; | 343 | break; |
337 | 344 | ||
338 | |||
339 | case AE_CTRL_BREAK: | 345 | case AE_CTRL_BREAK: |
340 | 346 | ||
341 | parser_state->aml = walk_state->aml_last_while; | 347 | parser_state->aml = walk_state->aml_last_while; |
@@ -345,7 +351,6 @@ acpi_ps_next_parse_state ( | |||
345 | 351 | ||
346 | case AE_CTRL_CONTINUE: | 352 | case AE_CTRL_CONTINUE: |
347 | 353 | ||
348 | |||
349 | parser_state->aml = walk_state->aml_last_while; | 354 | parser_state->aml = walk_state->aml_last_while; |
350 | status = AE_CTRL_CONTINUE; | 355 | status = AE_CTRL_CONTINUE; |
351 | break; | 356 | break; |
@@ -369,10 +374,9 @@ acpi_ps_next_parse_state ( | |||
369 | * Predicate of an IF was true, and we are at the matching ELSE. | 374 | * Predicate of an IF was true, and we are at the matching ELSE. |
370 | * Just close out this package | 375 | * Just close out this package |
371 | */ | 376 | */ |
372 | parser_state->aml = acpi_ps_get_next_package_end (parser_state); | 377 | parser_state->aml = acpi_ps_get_next_package_end(parser_state); |
373 | break; | 378 | break; |
374 | 379 | ||
375 | |||
376 | case AE_CTRL_FALSE: | 380 | case AE_CTRL_FALSE: |
377 | 381 | ||
378 | /* | 382 | /* |
@@ -390,7 +394,6 @@ acpi_ps_next_parse_state ( | |||
390 | status = AE_CTRL_END; | 394 | status = AE_CTRL_END; |
391 | break; | 395 | break; |
392 | 396 | ||
393 | |||
394 | case AE_CTRL_TRANSFER: | 397 | case AE_CTRL_TRANSFER: |
395 | 398 | ||
396 | /* A method call (invocation) -- transfer control */ | 399 | /* A method call (invocation) -- transfer control */ |
@@ -398,14 +401,15 @@ acpi_ps_next_parse_state ( | |||
398 | status = AE_CTRL_TRANSFER; | 401 | status = AE_CTRL_TRANSFER; |
399 | walk_state->prev_op = op; | 402 | walk_state->prev_op = op; |
400 | walk_state->method_call_op = op; | 403 | walk_state->method_call_op = op; |
401 | walk_state->method_call_node = (op->common.value.arg)->common.node; | 404 | walk_state->method_call_node = |
405 | (op->common.value.arg)->common.node; | ||
402 | 406 | ||
403 | /* Will return value (if any) be used by the caller? */ | 407 | /* Will return value (if any) be used by the caller? */ |
404 | 408 | ||
405 | walk_state->return_used = acpi_ds_is_result_used (op, walk_state); | 409 | walk_state->return_used = |
410 | acpi_ds_is_result_used(op, walk_state); | ||
406 | break; | 411 | break; |
407 | 412 | ||
408 | |||
409 | default: | 413 | default: |
410 | 414 | ||
411 | status = callback_status; | 415 | status = callback_status; |
@@ -415,10 +419,9 @@ acpi_ps_next_parse_state ( | |||
415 | break; | 419 | break; |
416 | } | 420 | } |
417 | 421 | ||
418 | return_ACPI_STATUS (status); | 422 | return_ACPI_STATUS(status); |
419 | } | 423 | } |
420 | 424 | ||
421 | |||
422 | /******************************************************************************* | 425 | /******************************************************************************* |
423 | * | 426 | * |
424 | * FUNCTION: acpi_ps_parse_aml | 427 | * FUNCTION: acpi_ps_parse_aml |
@@ -432,34 +435,30 @@ acpi_ps_next_parse_state ( | |||
432 | * | 435 | * |
433 | ******************************************************************************/ | 436 | ******************************************************************************/ |
434 | 437 | ||
435 | acpi_status | 438 | acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) |
436 | acpi_ps_parse_aml ( | ||
437 | struct acpi_walk_state *walk_state) | ||
438 | { | 439 | { |
439 | acpi_status status; | 440 | acpi_status status; |
440 | acpi_status terminate_status; | 441 | acpi_status terminate_status; |
441 | struct acpi_thread_state *thread; | 442 | struct acpi_thread_state *thread; |
442 | struct acpi_thread_state *prev_walk_list = acpi_gbl_current_walk_list; | 443 | struct acpi_thread_state *prev_walk_list = acpi_gbl_current_walk_list; |
443 | struct acpi_walk_state *previous_walk_state; | 444 | struct acpi_walk_state *previous_walk_state; |
444 | |||
445 | |||
446 | ACPI_FUNCTION_TRACE ("ps_parse_aml"); | ||
447 | 445 | ||
448 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, | 446 | ACPI_FUNCTION_TRACE("ps_parse_aml"); |
449 | "Entered with walk_state=%p Aml=%p size=%X\n", | ||
450 | walk_state, walk_state->parser_state.aml, | ||
451 | walk_state->parser_state.aml_size)); | ||
452 | 447 | ||
448 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, | ||
449 | "Entered with walk_state=%p Aml=%p size=%X\n", | ||
450 | walk_state, walk_state->parser_state.aml, | ||
451 | walk_state->parser_state.aml_size)); | ||
453 | 452 | ||
454 | /* Create and initialize a new thread state */ | 453 | /* Create and initialize a new thread state */ |
455 | 454 | ||
456 | thread = acpi_ut_create_thread_state (); | 455 | thread = acpi_ut_create_thread_state(); |
457 | if (!thread) { | 456 | if (!thread) { |
458 | return_ACPI_STATUS (AE_NO_MEMORY); | 457 | return_ACPI_STATUS(AE_NO_MEMORY); |
459 | } | 458 | } |
460 | 459 | ||
461 | walk_state->thread = thread; | 460 | walk_state->thread = thread; |
462 | acpi_ds_push_walk_state (walk_state, thread); | 461 | acpi_ds_push_walk_state(walk_state, thread); |
463 | 462 | ||
464 | /* | 463 | /* |
465 | * This global allows the AML debugger to get a handle to the currently | 464 | * This global allows the AML debugger to get a handle to the currently |
@@ -471,54 +470,56 @@ acpi_ps_parse_aml ( | |||
471 | * Execute the walk loop as long as there is a valid Walk State. This | 470 | * Execute the walk loop as long as there is a valid Walk State. This |
472 | * handles nested control method invocations without recursion. | 471 | * handles nested control method invocations without recursion. |
473 | */ | 472 | */ |
474 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "State=%p\n", walk_state)); | 473 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "State=%p\n", walk_state)); |
475 | 474 | ||
476 | status = AE_OK; | 475 | status = AE_OK; |
477 | while (walk_state) { | 476 | while (walk_state) { |
478 | if (ACPI_SUCCESS (status)) { | 477 | if (ACPI_SUCCESS(status)) { |
479 | /* | 478 | /* |
480 | * The parse_loop executes AML until the method terminates | 479 | * The parse_loop executes AML until the method terminates |
481 | * or calls another method. | 480 | * or calls another method. |
482 | */ | 481 | */ |
483 | status = acpi_ps_parse_loop (walk_state); | 482 | status = acpi_ps_parse_loop(walk_state); |
484 | } | 483 | } |
485 | 484 | ||
486 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, | 485 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, |
487 | "Completed one call to walk loop, %s State=%p\n", | 486 | "Completed one call to walk loop, %s State=%p\n", |
488 | acpi_format_exception (status), walk_state)); | 487 | acpi_format_exception(status), walk_state)); |
489 | 488 | ||
490 | if (status == AE_CTRL_TRANSFER) { | 489 | if (status == AE_CTRL_TRANSFER) { |
491 | /* | 490 | /* |
492 | * A method call was detected. | 491 | * A method call was detected. |
493 | * Transfer control to the called control method | 492 | * Transfer control to the called control method |
494 | */ | 493 | */ |
495 | status = acpi_ds_call_control_method (thread, walk_state, NULL); | 494 | status = |
495 | acpi_ds_call_control_method(thread, walk_state, | ||
496 | NULL); | ||
496 | 497 | ||
497 | /* | 498 | /* |
498 | * If the transfer to the new method method call worked, a new walk | 499 | * If the transfer to the new method method call worked, a new walk |
499 | * state was created -- get it | 500 | * state was created -- get it |
500 | */ | 501 | */ |
501 | walk_state = acpi_ds_get_current_walk_state (thread); | 502 | walk_state = acpi_ds_get_current_walk_state(thread); |
502 | continue; | 503 | continue; |
503 | } | 504 | } else if (status == AE_CTRL_TERMINATE) { |
504 | else if (status == AE_CTRL_TERMINATE) { | ||
505 | status = AE_OK; | 505 | status = AE_OK; |
506 | } | 506 | } else if ((status != AE_OK) && (walk_state->method_desc)) { |
507 | else if ((status != AE_OK) && (walk_state->method_desc)) { | 507 | ACPI_REPORT_METHOD_ERROR("Method execution failed", |
508 | ACPI_REPORT_METHOD_ERROR ("Method execution failed", | 508 | walk_state->method_node, NULL, |
509 | walk_state->method_node, NULL, status); | 509 | status); |
510 | 510 | ||
511 | /* Check for possible multi-thread reentrancy problem */ | 511 | /* Check for possible multi-thread reentrancy problem */ |
512 | 512 | ||
513 | if ((status == AE_ALREADY_EXISTS) && | 513 | if ((status == AE_ALREADY_EXISTS) && |
514 | (!walk_state->method_desc->method.semaphore)) { | 514 | (!walk_state->method_desc->method.semaphore)) { |
515 | /* | 515 | /* |
516 | * This method is marked not_serialized, but it tried to create | 516 | * This method is marked not_serialized, but it tried to create |
517 | * a named object, causing the second thread entrance to fail. | 517 | * a named object, causing the second thread entrance to fail. |
518 | * We will workaround this by marking the method permanently | 518 | * We will workaround this by marking the method permanently |
519 | * as Serialized. | 519 | * as Serialized. |
520 | */ | 520 | */ |
521 | walk_state->method_desc->method.method_flags |= AML_METHOD_SERIALIZED; | 521 | walk_state->method_desc->method.method_flags |= |
522 | AML_METHOD_SERIALIZED; | ||
522 | walk_state->method_desc->method.concurrency = 1; | 523 | walk_state->method_desc->method.concurrency = 1; |
523 | } | 524 | } |
524 | } | 525 | } |
@@ -533,21 +534,22 @@ acpi_ps_parse_aml ( | |||
533 | 534 | ||
534 | /* We are done with this walk, move on to the parent if any */ | 535 | /* We are done with this walk, move on to the parent if any */ |
535 | 536 | ||
536 | walk_state = acpi_ds_pop_walk_state (thread); | 537 | walk_state = acpi_ds_pop_walk_state(thread); |
537 | 538 | ||
538 | /* Reset the current scope to the beginning of scope stack */ | 539 | /* Reset the current scope to the beginning of scope stack */ |
539 | 540 | ||
540 | acpi_ds_scope_stack_clear (walk_state); | 541 | acpi_ds_scope_stack_clear(walk_state); |
541 | 542 | ||
542 | /* | 543 | /* |
543 | * If we just returned from the execution of a control method, | 544 | * If we just returned from the execution of a control method, |
544 | * there's lots of cleanup to do | 545 | * there's lots of cleanup to do |
545 | */ | 546 | */ |
546 | if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) { | 547 | if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == |
547 | terminate_status = acpi_ds_terminate_control_method (walk_state); | 548 | ACPI_PARSE_EXECUTE) { |
548 | if (ACPI_FAILURE (terminate_status)) { | 549 | terminate_status = |
549 | ACPI_REPORT_ERROR (( | 550 | acpi_ds_terminate_control_method(walk_state); |
550 | "Could not terminate control method properly\n")); | 551 | if (ACPI_FAILURE(terminate_status)) { |
552 | ACPI_REPORT_ERROR(("Could not terminate control method properly\n")); | ||
551 | 553 | ||
552 | /* Ignore error and continue */ | 554 | /* Ignore error and continue */ |
553 | } | 555 | } |
@@ -555,46 +557,53 @@ acpi_ps_parse_aml ( | |||
555 | 557 | ||
556 | /* Delete this walk state and all linked control states */ | 558 | /* Delete this walk state and all linked control states */ |
557 | 559 | ||
558 | acpi_ps_cleanup_scope (&walk_state->parser_state); | 560 | acpi_ps_cleanup_scope(&walk_state->parser_state); |
559 | 561 | ||
560 | previous_walk_state = walk_state; | 562 | previous_walk_state = walk_state; |
561 | 563 | ||
562 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, | 564 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, |
563 | "return_value=%p, implicit_value=%p State=%p\n", | 565 | "return_value=%p, implicit_value=%p State=%p\n", |
564 | walk_state->return_desc, walk_state->implicit_return_obj, walk_state)); | 566 | walk_state->return_desc, |
567 | walk_state->implicit_return_obj, walk_state)); | ||
565 | 568 | ||
566 | /* Check if we have restarted a preempted walk */ | 569 | /* Check if we have restarted a preempted walk */ |
567 | 570 | ||
568 | walk_state = acpi_ds_get_current_walk_state (thread); | 571 | walk_state = acpi_ds_get_current_walk_state(thread); |
569 | if (walk_state) { | 572 | if (walk_state) { |
570 | if (ACPI_SUCCESS (status)) { | 573 | if (ACPI_SUCCESS(status)) { |
571 | /* | 574 | /* |
572 | * There is another walk state, restart it. | 575 | * There is another walk state, restart it. |
573 | * If the method return value is not used by the parent, | 576 | * If the method return value is not used by the parent, |
574 | * The object is deleted | 577 | * The object is deleted |
575 | */ | 578 | */ |
576 | if (!previous_walk_state->return_desc) { | 579 | if (!previous_walk_state->return_desc) { |
577 | status = acpi_ds_restart_control_method (walk_state, | 580 | status = |
578 | previous_walk_state->implicit_return_obj); | 581 | acpi_ds_restart_control_method |
579 | } | 582 | (walk_state, |
580 | else { | 583 | previous_walk_state-> |
584 | implicit_return_obj); | ||
585 | } else { | ||
581 | /* | 586 | /* |
582 | * We have a valid return value, delete any implicit | 587 | * We have a valid return value, delete any implicit |
583 | * return value. | 588 | * return value. |
584 | */ | 589 | */ |
585 | acpi_ds_clear_implicit_return (previous_walk_state); | 590 | acpi_ds_clear_implicit_return |
591 | (previous_walk_state); | ||
586 | 592 | ||
587 | status = acpi_ds_restart_control_method (walk_state, | 593 | status = |
588 | previous_walk_state->return_desc); | 594 | acpi_ds_restart_control_method |
595 | (walk_state, | ||
596 | previous_walk_state->return_desc); | ||
589 | } | 597 | } |
590 | if (ACPI_SUCCESS (status)) { | 598 | if (ACPI_SUCCESS(status)) { |
591 | walk_state->walk_type |= ACPI_WALK_METHOD_RESTART; | 599 | walk_state->walk_type |= |
600 | ACPI_WALK_METHOD_RESTART; | ||
592 | } | 601 | } |
593 | } | 602 | } else { |
594 | else { | ||
595 | /* On error, delete any return object */ | 603 | /* On error, delete any return object */ |
596 | 604 | ||
597 | acpi_ut_remove_reference (previous_walk_state->return_desc); | 605 | acpi_ut_remove_reference(previous_walk_state-> |
606 | return_desc); | ||
598 | } | 607 | } |
599 | } | 608 | } |
600 | 609 | ||
@@ -605,37 +614,36 @@ acpi_ps_parse_aml ( | |||
605 | else if (previous_walk_state->caller_return_desc) { | 614 | else if (previous_walk_state->caller_return_desc) { |
606 | if (previous_walk_state->implicit_return_obj) { | 615 | if (previous_walk_state->implicit_return_obj) { |
607 | *(previous_walk_state->caller_return_desc) = | 616 | *(previous_walk_state->caller_return_desc) = |
608 | previous_walk_state->implicit_return_obj; | 617 | previous_walk_state->implicit_return_obj; |
609 | } | 618 | } else { |
610 | else { | 619 | /* NULL if no return value */ |
611 | /* NULL if no return value */ | ||
612 | 620 | ||
613 | *(previous_walk_state->caller_return_desc) = | 621 | *(previous_walk_state->caller_return_desc) = |
614 | previous_walk_state->return_desc; | 622 | previous_walk_state->return_desc; |
615 | } | 623 | } |
616 | } | 624 | } else { |
617 | else { | ||
618 | if (previous_walk_state->return_desc) { | 625 | if (previous_walk_state->return_desc) { |
619 | /* Caller doesn't want it, must delete it */ | 626 | /* Caller doesn't want it, must delete it */ |
620 | 627 | ||
621 | acpi_ut_remove_reference (previous_walk_state->return_desc); | 628 | acpi_ut_remove_reference(previous_walk_state-> |
629 | return_desc); | ||
622 | } | 630 | } |
623 | if (previous_walk_state->implicit_return_obj) { | 631 | if (previous_walk_state->implicit_return_obj) { |
624 | /* Caller doesn't want it, must delete it */ | 632 | /* Caller doesn't want it, must delete it */ |
625 | 633 | ||
626 | acpi_ut_remove_reference (previous_walk_state->implicit_return_obj); | 634 | acpi_ut_remove_reference(previous_walk_state-> |
635 | implicit_return_obj); | ||
627 | } | 636 | } |
628 | } | 637 | } |
629 | 638 | ||
630 | acpi_ds_delete_walk_state (previous_walk_state); | 639 | acpi_ds_delete_walk_state(previous_walk_state); |
631 | } | 640 | } |
632 | 641 | ||
633 | /* Normal exit */ | 642 | /* Normal exit */ |
634 | 643 | ||
635 | acpi_ex_release_all_mutexes (thread); | 644 | acpi_ex_release_all_mutexes(thread); |
636 | acpi_ut_delete_generic_state (ACPI_CAST_PTR (union acpi_generic_state, thread)); | 645 | acpi_ut_delete_generic_state(ACPI_CAST_PTR |
646 | (union acpi_generic_state, thread)); | ||
637 | acpi_gbl_current_walk_list = prev_walk_list; | 647 | acpi_gbl_current_walk_list = prev_walk_list; |
638 | return_ACPI_STATUS (status); | 648 | return_ACPI_STATUS(status); |
639 | } | 649 | } |
640 | |||
641 | |||