diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/acpi/dispatcher/dsopcode.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/acpi/dispatcher/dsopcode.c')
-rw-r--r-- | drivers/acpi/dispatcher/dsopcode.c | 1151 |
1 files changed, 1151 insertions, 0 deletions
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c new file mode 100644 index 000000000000..5c987a0e7b75 --- /dev/null +++ b/drivers/acpi/dispatcher/dsopcode.c | |||
@@ -0,0 +1,1151 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: dsopcode - Dispatcher Op Region support and handling of | ||
4 | * "control" opcodes | ||
5 | * | ||
6 | *****************************************************************************/ | ||
7 | |||
8 | /* | ||
9 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
10 | * All rights reserved. | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or without | ||
13 | * modification, are permitted provided that the following conditions | ||
14 | * are met: | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions, and the following disclaimer, | ||
17 | * without modification. | ||
18 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
19 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
20 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
21 | * including a substantially similar Disclaimer requirement for further | ||
22 | * binary redistribution. | ||
23 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
24 | * of any contributors may be used to endorse or promote products derived | ||
25 | * from this software without specific prior written permission. | ||
26 | * | ||
27 | * Alternatively, this software may be distributed under the terms of the | ||
28 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
29 | * Software Foundation. | ||
30 | * | ||
31 | * NO WARRANTY | ||
32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
33 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
35 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
36 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
37 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
38 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
39 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
40 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
41 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
42 | * POSSIBILITY OF SUCH DAMAGES. | ||
43 | */ | ||
44 | |||
45 | |||
46 | #include <acpi/acpi.h> | ||
47 | #include <acpi/acparser.h> | ||
48 | #include <acpi/amlcode.h> | ||
49 | #include <acpi/acdispat.h> | ||
50 | #include <acpi/acinterp.h> | ||
51 | #include <acpi/acnamesp.h> | ||
52 | #include <acpi/acevents.h> | ||
53 | |||
54 | #define _COMPONENT ACPI_DISPATCHER | ||
55 | ACPI_MODULE_NAME ("dsopcode") | ||
56 | |||
57 | |||
58 | /***************************************************************************** | ||
59 | * | ||
60 | * FUNCTION: acpi_ds_execute_arguments | ||
61 | * | ||
62 | * PARAMETERS: Node - Parent NS node | ||
63 | * aml_length - Length of executable AML | ||
64 | * aml_start - Pointer to the AML | ||
65 | * | ||
66 | * RETURN: Status. | ||
67 | * | ||
68 | * DESCRIPTION: Late (deferred) execution of region or field arguments | ||
69 | * | ||
70 | ****************************************************************************/ | ||
71 | |||
72 | acpi_status | ||
73 | acpi_ds_execute_arguments ( | ||
74 | struct acpi_namespace_node *node, | ||
75 | struct acpi_namespace_node *scope_node, | ||
76 | u32 aml_length, | ||
77 | u8 *aml_start) | ||
78 | { | ||
79 | acpi_status status; | ||
80 | union acpi_parse_object *op; | ||
81 | struct acpi_walk_state *walk_state; | ||
82 | |||
83 | |||
84 | ACPI_FUNCTION_TRACE ("ds_execute_arguments"); | ||
85 | |||
86 | |||
87 | /* | ||
88 | * Allocate a new parser op to be the root of the parsed tree | ||
89 | */ | ||
90 | op = acpi_ps_alloc_op (AML_INT_EVAL_SUBTREE_OP); | ||
91 | if (!op) { | ||
92 | return_ACPI_STATUS (AE_NO_MEMORY); | ||
93 | } | ||
94 | |||
95 | /* Save the Node for use in acpi_ps_parse_aml */ | ||
96 | |||
97 | op->common.node = scope_node; | ||
98 | |||
99 | /* Create and initialize a new parser state */ | ||
100 | |||
101 | walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); | ||
102 | if (!walk_state) { | ||
103 | return_ACPI_STATUS (AE_NO_MEMORY); | ||
104 | } | ||
105 | |||
106 | status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start, | ||
107 | aml_length, NULL, 1); | ||
108 | if (ACPI_FAILURE (status)) { | ||
109 | acpi_ds_delete_walk_state (walk_state); | ||
110 | return_ACPI_STATUS (status); | ||
111 | } | ||
112 | |||
113 | /* Mark this parse as a deferred opcode */ | ||
114 | |||
115 | walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP; | ||
116 | walk_state->deferred_node = node; | ||
117 | |||
118 | /* Pass1: Parse the entire declaration */ | ||
119 | |||
120 | status = acpi_ps_parse_aml (walk_state); | ||
121 | if (ACPI_FAILURE (status)) { | ||
122 | acpi_ps_delete_parse_tree (op); | ||
123 | return_ACPI_STATUS (status); | ||
124 | } | ||
125 | |||
126 | /* Get and init the Op created above */ | ||
127 | |||
128 | op->common.node = node; | ||
129 | acpi_ps_delete_parse_tree (op); | ||
130 | |||
131 | /* Evaluate the deferred arguments */ | ||
132 | |||
133 | op = acpi_ps_alloc_op (AML_INT_EVAL_SUBTREE_OP); | ||
134 | if (!op) { | ||
135 | return_ACPI_STATUS (AE_NO_MEMORY); | ||
136 | } | ||
137 | |||
138 | op->common.node = scope_node; | ||
139 | |||
140 | /* Create and initialize a new parser state */ | ||
141 | |||
142 | walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); | ||
143 | if (!walk_state) { | ||
144 | return_ACPI_STATUS (AE_NO_MEMORY); | ||
145 | } | ||
146 | |||
147 | /* Execute the opcode and arguments */ | ||
148 | |||
149 | status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start, | ||
150 | aml_length, NULL, 3); | ||
151 | if (ACPI_FAILURE (status)) { | ||
152 | acpi_ds_delete_walk_state (walk_state); | ||
153 | return_ACPI_STATUS (status); | ||
154 | } | ||
155 | |||
156 | /* Mark this execution as a deferred opcode */ | ||
157 | |||
158 | walk_state->deferred_node = node; | ||
159 | status = acpi_ps_parse_aml (walk_state); | ||
160 | acpi_ps_delete_parse_tree (op); | ||
161 | return_ACPI_STATUS (status); | ||
162 | } | ||
163 | |||
164 | |||
165 | /***************************************************************************** | ||
166 | * | ||
167 | * FUNCTION: acpi_ds_get_buffer_field_arguments | ||
168 | * | ||
169 | * PARAMETERS: obj_desc - A valid buffer_field object | ||
170 | * | ||
171 | * RETURN: Status. | ||
172 | * | ||
173 | * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late | ||
174 | * evaluation of these field attributes. | ||
175 | * | ||
176 | ****************************************************************************/ | ||
177 | |||
178 | acpi_status | ||
179 | acpi_ds_get_buffer_field_arguments ( | ||
180 | union acpi_operand_object *obj_desc) | ||
181 | { | ||
182 | union acpi_operand_object *extra_desc; | ||
183 | struct acpi_namespace_node *node; | ||
184 | acpi_status status; | ||
185 | |||
186 | |||
187 | ACPI_FUNCTION_TRACE_PTR ("ds_get_buffer_field_arguments", obj_desc); | ||
188 | |||
189 | |||
190 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { | ||
191 | return_ACPI_STATUS (AE_OK); | ||
192 | } | ||
193 | |||
194 | /* Get the AML pointer (method object) and buffer_field node */ | ||
195 | |||
196 | extra_desc = acpi_ns_get_secondary_object (obj_desc); | ||
197 | node = obj_desc->buffer_field.node; | ||
198 | |||
199 | ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_BUFFER_FIELD, node, NULL)); | ||
200 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] buffer_field Arg Init\n", | ||
201 | acpi_ut_get_node_name (node))); | ||
202 | |||
203 | /* Execute the AML code for the term_arg arguments */ | ||
204 | |||
205 | status = acpi_ds_execute_arguments (node, acpi_ns_get_parent_node (node), | ||
206 | extra_desc->extra.aml_length, extra_desc->extra.aml_start); | ||
207 | return_ACPI_STATUS (status); | ||
208 | } | ||
209 | |||
210 | |||
211 | /***************************************************************************** | ||
212 | * | ||
213 | * FUNCTION: acpi_ds_get_buffer_arguments | ||
214 | * | ||
215 | * PARAMETERS: obj_desc - A valid Buffer object | ||
216 | * | ||
217 | * RETURN: Status. | ||
218 | * | ||
219 | * DESCRIPTION: Get Buffer length and initializer byte list. This implements | ||
220 | * the late evaluation of these attributes. | ||
221 | * | ||
222 | ****************************************************************************/ | ||
223 | |||
224 | acpi_status | ||
225 | acpi_ds_get_buffer_arguments ( | ||
226 | union acpi_operand_object *obj_desc) | ||
227 | { | ||
228 | struct acpi_namespace_node *node; | ||
229 | acpi_status status; | ||
230 | |||
231 | |||
232 | ACPI_FUNCTION_TRACE_PTR ("ds_get_buffer_arguments", obj_desc); | ||
233 | |||
234 | |||
235 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { | ||
236 | return_ACPI_STATUS (AE_OK); | ||
237 | } | ||
238 | |||
239 | /* Get the Buffer node */ | ||
240 | |||
241 | node = obj_desc->buffer.node; | ||
242 | if (!node) { | ||
243 | ACPI_REPORT_ERROR (( | ||
244 | "No pointer back to NS node in buffer obj %p\n", obj_desc)); | ||
245 | return_ACPI_STATUS (AE_AML_INTERNAL); | ||
246 | } | ||
247 | |||
248 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n")); | ||
249 | |||
250 | /* Execute the AML code for the term_arg arguments */ | ||
251 | |||
252 | status = acpi_ds_execute_arguments (node, node, | ||
253 | obj_desc->buffer.aml_length, obj_desc->buffer.aml_start); | ||
254 | return_ACPI_STATUS (status); | ||
255 | } | ||
256 | |||
257 | |||
258 | /***************************************************************************** | ||
259 | * | ||
260 | * FUNCTION: acpi_ds_get_package_arguments | ||
261 | * | ||
262 | * PARAMETERS: obj_desc - A valid Package object | ||
263 | * | ||
264 | * RETURN: Status. | ||
265 | * | ||
266 | * DESCRIPTION: Get Package length and initializer byte list. This implements | ||
267 | * the late evaluation of these attributes. | ||
268 | * | ||
269 | ****************************************************************************/ | ||
270 | |||
271 | acpi_status | ||
272 | acpi_ds_get_package_arguments ( | ||
273 | union acpi_operand_object *obj_desc) | ||
274 | { | ||
275 | struct acpi_namespace_node *node; | ||
276 | acpi_status status; | ||
277 | |||
278 | |||
279 | ACPI_FUNCTION_TRACE_PTR ("ds_get_package_arguments", obj_desc); | ||
280 | |||
281 | |||
282 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { | ||
283 | return_ACPI_STATUS (AE_OK); | ||
284 | } | ||
285 | |||
286 | /* Get the Package node */ | ||
287 | |||
288 | node = obj_desc->package.node; | ||
289 | if (!node) { | ||
290 | ACPI_REPORT_ERROR (( | ||
291 | "No pointer back to NS node in package %p\n", obj_desc)); | ||
292 | return_ACPI_STATUS (AE_AML_INTERNAL); | ||
293 | } | ||
294 | |||
295 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Arg Init\n")); | ||
296 | |||
297 | /* Execute the AML code for the term_arg arguments */ | ||
298 | |||
299 | status = acpi_ds_execute_arguments (node, node, | ||
300 | obj_desc->package.aml_length, obj_desc->package.aml_start); | ||
301 | return_ACPI_STATUS (status); | ||
302 | } | ||
303 | |||
304 | |||
305 | /***************************************************************************** | ||
306 | * | ||
307 | * FUNCTION: acpi_ds_get_region_arguments | ||
308 | * | ||
309 | * PARAMETERS: obj_desc - A valid region object | ||
310 | * | ||
311 | * RETURN: Status. | ||
312 | * | ||
313 | * DESCRIPTION: Get region address and length. This implements the late | ||
314 | * evaluation of these region attributes. | ||
315 | * | ||
316 | ****************************************************************************/ | ||
317 | |||
318 | acpi_status | ||
319 | acpi_ds_get_region_arguments ( | ||
320 | union acpi_operand_object *obj_desc) | ||
321 | { | ||
322 | struct acpi_namespace_node *node; | ||
323 | acpi_status status; | ||
324 | union acpi_operand_object *extra_desc; | ||
325 | |||
326 | |||
327 | ACPI_FUNCTION_TRACE_PTR ("ds_get_region_arguments", obj_desc); | ||
328 | |||
329 | |||
330 | if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { | ||
331 | return_ACPI_STATUS (AE_OK); | ||
332 | } | ||
333 | |||
334 | extra_desc = acpi_ns_get_secondary_object (obj_desc); | ||
335 | if (!extra_desc) { | ||
336 | return_ACPI_STATUS (AE_NOT_EXIST); | ||
337 | } | ||
338 | |||
339 | /* Get the Region node */ | ||
340 | |||
341 | node = obj_desc->region.node; | ||
342 | |||
343 | ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_REGION, node, NULL)); | ||
344 | |||
345 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] op_region Arg Init at AML %p\n", | ||
346 | acpi_ut_get_node_name (node), extra_desc->extra.aml_start)); | ||
347 | |||
348 | /* Execute the argument AML */ | ||
349 | |||
350 | status = acpi_ds_execute_arguments (node, acpi_ns_get_parent_node (node), | ||
351 | extra_desc->extra.aml_length, extra_desc->extra.aml_start); | ||
352 | return_ACPI_STATUS (status); | ||
353 | } | ||
354 | |||
355 | |||
356 | /***************************************************************************** | ||
357 | * | ||
358 | * FUNCTION: acpi_ds_initialize_region | ||
359 | * | ||
360 | * PARAMETERS: Op - A valid region Op object | ||
361 | * | ||
362 | * RETURN: Status | ||
363 | * | ||
364 | * DESCRIPTION: Front end to ev_initialize_region | ||
365 | * | ||
366 | ****************************************************************************/ | ||
367 | |||
368 | acpi_status | ||
369 | acpi_ds_initialize_region ( | ||
370 | acpi_handle obj_handle) | ||
371 | { | ||
372 | union acpi_operand_object *obj_desc; | ||
373 | acpi_status status; | ||
374 | |||
375 | |||
376 | obj_desc = acpi_ns_get_attached_object (obj_handle); | ||
377 | |||
378 | /* Namespace is NOT locked */ | ||
379 | |||
380 | status = acpi_ev_initialize_region (obj_desc, FALSE); | ||
381 | return (status); | ||
382 | } | ||
383 | |||
384 | |||
385 | /***************************************************************************** | ||
386 | * | ||
387 | * FUNCTION: acpi_ds_init_buffer_field | ||
388 | * | ||
389 | * PARAMETERS: aml_opcode - create_xxx_field | ||
390 | * obj_desc - buffer_field object | ||
391 | * buffer_desc - Host Buffer | ||
392 | * offset_desc - Offset into buffer | ||
393 | * Length - Length of field (CREATE_FIELD_OP only) | ||
394 | * Result - Where to store the result | ||
395 | * | ||
396 | * RETURN: Status | ||
397 | * | ||
398 | * DESCRIPTION: Perform actual initialization of a buffer field | ||
399 | * | ||
400 | ****************************************************************************/ | ||
401 | |||
402 | acpi_status | ||
403 | acpi_ds_init_buffer_field ( | ||
404 | u16 aml_opcode, | ||
405 | union acpi_operand_object *obj_desc, | ||
406 | union acpi_operand_object *buffer_desc, | ||
407 | union acpi_operand_object *offset_desc, | ||
408 | union acpi_operand_object *length_desc, | ||
409 | union acpi_operand_object *result_desc) | ||
410 | { | ||
411 | u32 offset; | ||
412 | u32 bit_offset; | ||
413 | u32 bit_count; | ||
414 | u8 field_flags; | ||
415 | acpi_status status; | ||
416 | |||
417 | |||
418 | ACPI_FUNCTION_TRACE_PTR ("ds_init_buffer_field", obj_desc); | ||
419 | |||
420 | |||
421 | /* Host object must be a Buffer */ | ||
422 | |||
423 | if (ACPI_GET_OBJECT_TYPE (buffer_desc) != ACPI_TYPE_BUFFER) { | ||
424 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
425 | "Target of Create Field is not a Buffer object - %s\n", | ||
426 | acpi_ut_get_object_type_name (buffer_desc))); | ||
427 | |||
428 | status = AE_AML_OPERAND_TYPE; | ||
429 | goto cleanup; | ||
430 | } | ||
431 | |||
432 | /* | ||
433 | * The last parameter to all of these opcodes (result_desc) started | ||
434 | * out as a name_string, and should therefore now be a NS node | ||
435 | * after resolution in acpi_ex_resolve_operands(). | ||
436 | */ | ||
437 | if (ACPI_GET_DESCRIPTOR_TYPE (result_desc) != ACPI_DESC_TYPE_NAMED) { | ||
438 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) destination not a NS Node [%s]\n", | ||
439 | acpi_ps_get_opcode_name (aml_opcode), acpi_ut_get_descriptor_name (result_desc))); | ||
440 | |||
441 | status = AE_AML_OPERAND_TYPE; | ||
442 | goto cleanup; | ||
443 | } | ||
444 | |||
445 | offset = (u32) offset_desc->integer.value; | ||
446 | |||
447 | /* | ||
448 | * Setup the Bit offsets and counts, according to the opcode | ||
449 | */ | ||
450 | switch (aml_opcode) { | ||
451 | case AML_CREATE_FIELD_OP: | ||
452 | |||
453 | /* Offset is in bits, count is in bits */ | ||
454 | |||
455 | bit_offset = offset; | ||
456 | bit_count = (u32) length_desc->integer.value; | ||
457 | field_flags = AML_FIELD_ACCESS_BYTE; | ||
458 | break; | ||
459 | |||
460 | case AML_CREATE_BIT_FIELD_OP: | ||
461 | |||
462 | /* Offset is in bits, Field is one bit */ | ||
463 | |||
464 | bit_offset = offset; | ||
465 | bit_count = 1; | ||
466 | field_flags = AML_FIELD_ACCESS_BYTE; | ||
467 | break; | ||
468 | |||
469 | case AML_CREATE_BYTE_FIELD_OP: | ||
470 | |||
471 | /* Offset is in bytes, field is one byte */ | ||
472 | |||
473 | bit_offset = 8 * offset; | ||
474 | bit_count = 8; | ||
475 | field_flags = AML_FIELD_ACCESS_BYTE; | ||
476 | break; | ||
477 | |||
478 | case AML_CREATE_WORD_FIELD_OP: | ||
479 | |||
480 | /* Offset is in bytes, field is one word */ | ||
481 | |||
482 | bit_offset = 8 * offset; | ||
483 | bit_count = 16; | ||
484 | field_flags = AML_FIELD_ACCESS_WORD; | ||
485 | break; | ||
486 | |||
487 | case AML_CREATE_DWORD_FIELD_OP: | ||
488 | |||
489 | /* Offset is in bytes, field is one dword */ | ||
490 | |||
491 | bit_offset = 8 * offset; | ||
492 | bit_count = 32; | ||
493 | field_flags = AML_FIELD_ACCESS_DWORD; | ||
494 | break; | ||
495 | |||
496 | case AML_CREATE_QWORD_FIELD_OP: | ||
497 | |||
498 | /* Offset is in bytes, field is one qword */ | ||
499 | |||
500 | bit_offset = 8 * offset; | ||
501 | bit_count = 64; | ||
502 | field_flags = AML_FIELD_ACCESS_QWORD; | ||
503 | break; | ||
504 | |||
505 | default: | ||
506 | |||
507 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
508 | "Unknown field creation opcode %02x\n", | ||
509 | aml_opcode)); | ||
510 | status = AE_AML_BAD_OPCODE; | ||
511 | goto cleanup; | ||
512 | } | ||
513 | |||
514 | /* Entire field must fit within the current length of the buffer */ | ||
515 | |||
516 | if ((bit_offset + bit_count) > | ||
517 | (8 * (u32) buffer_desc->buffer.length)) { | ||
518 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
519 | "Field [%4.4s] size %d exceeds Buffer [%4.4s] size %d (bits)\n", | ||
520 | acpi_ut_get_node_name (result_desc), | ||
521 | bit_offset + bit_count, | ||
522 | acpi_ut_get_node_name (buffer_desc->buffer.node), | ||
523 | 8 * (u32) buffer_desc->buffer.length)); | ||
524 | status = AE_AML_BUFFER_LIMIT; | ||
525 | goto cleanup; | ||
526 | } | ||
527 | |||
528 | /* | ||
529 | * Initialize areas of the field object that are common to all fields | ||
530 | * For field_flags, use LOCK_RULE = 0 (NO_LOCK), UPDATE_RULE = 0 (UPDATE_PRESERVE) | ||
531 | */ | ||
532 | status = acpi_ex_prep_common_field_object (obj_desc, field_flags, 0, | ||
533 | bit_offset, bit_count); | ||
534 | if (ACPI_FAILURE (status)) { | ||
535 | goto cleanup; | ||
536 | } | ||
537 | |||
538 | obj_desc->buffer_field.buffer_obj = buffer_desc; | ||
539 | |||
540 | /* Reference count for buffer_desc inherits obj_desc count */ | ||
541 | |||
542 | buffer_desc->common.reference_count = (u16) (buffer_desc->common.reference_count + | ||
543 | obj_desc->common.reference_count); | ||
544 | |||
545 | |||
546 | cleanup: | ||
547 | |||
548 | /* Always delete the operands */ | ||
549 | |||
550 | acpi_ut_remove_reference (offset_desc); | ||
551 | acpi_ut_remove_reference (buffer_desc); | ||
552 | |||
553 | if (aml_opcode == AML_CREATE_FIELD_OP) { | ||
554 | acpi_ut_remove_reference (length_desc); | ||
555 | } | ||
556 | |||
557 | /* On failure, delete the result descriptor */ | ||
558 | |||
559 | if (ACPI_FAILURE (status)) { | ||
560 | acpi_ut_remove_reference (result_desc); /* Result descriptor */ | ||
561 | } | ||
562 | else { | ||
563 | /* Now the address and length are valid for this buffer_field */ | ||
564 | |||
565 | obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID; | ||
566 | } | ||
567 | |||
568 | return_ACPI_STATUS (status); | ||
569 | } | ||
570 | |||
571 | |||
572 | /***************************************************************************** | ||
573 | * | ||
574 | * FUNCTION: acpi_ds_eval_buffer_field_operands | ||
575 | * | ||
576 | * PARAMETERS: walk_state - Current walk | ||
577 | * Op - A valid buffer_field Op object | ||
578 | * | ||
579 | * RETURN: Status | ||
580 | * | ||
581 | * DESCRIPTION: Get buffer_field Buffer and Index | ||
582 | * Called from acpi_ds_exec_end_op during buffer_field parse tree walk | ||
583 | * | ||
584 | ****************************************************************************/ | ||
585 | |||
586 | acpi_status | ||
587 | acpi_ds_eval_buffer_field_operands ( | ||
588 | struct acpi_walk_state *walk_state, | ||
589 | union acpi_parse_object *op) | ||
590 | { | ||
591 | acpi_status status; | ||
592 | union acpi_operand_object *obj_desc; | ||
593 | struct acpi_namespace_node *node; | ||
594 | union acpi_parse_object *next_op; | ||
595 | |||
596 | |||
597 | ACPI_FUNCTION_TRACE_PTR ("ds_eval_buffer_field_operands", op); | ||
598 | |||
599 | |||
600 | /* | ||
601 | * This is where we evaluate the address and length fields of the | ||
602 | * create_xxx_field declaration | ||
603 | */ | ||
604 | node = op->common.node; | ||
605 | |||
606 | /* next_op points to the op that holds the Buffer */ | ||
607 | |||
608 | next_op = op->common.value.arg; | ||
609 | |||
610 | /* Evaluate/create the address and length operands */ | ||
611 | |||
612 | status = acpi_ds_create_operands (walk_state, next_op); | ||
613 | if (ACPI_FAILURE (status)) { | ||
614 | return_ACPI_STATUS (status); | ||
615 | } | ||
616 | |||
617 | obj_desc = acpi_ns_get_attached_object (node); | ||
618 | if (!obj_desc) { | ||
619 | return_ACPI_STATUS (AE_NOT_EXIST); | ||
620 | } | ||
621 | |||
622 | /* Resolve the operands */ | ||
623 | |||
624 | status = acpi_ex_resolve_operands (op->common.aml_opcode, | ||
625 | ACPI_WALK_OPERANDS, walk_state); | ||
626 | |||
627 | ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE, | ||
628 | acpi_ps_get_opcode_name (op->common.aml_opcode), | ||
629 | walk_state->num_operands, "after acpi_ex_resolve_operands"); | ||
630 | |||
631 | if (ACPI_FAILURE (status)) { | ||
632 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) bad operand(s) (%X)\n", | ||
633 | acpi_ps_get_opcode_name (op->common.aml_opcode), status)); | ||
634 | |||
635 | return_ACPI_STATUS (status); | ||
636 | } | ||
637 | |||
638 | /* Initialize the Buffer Field */ | ||
639 | |||
640 | if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { | ||
641 | /* NOTE: Slightly different operands for this opcode */ | ||
642 | |||
643 | status = acpi_ds_init_buffer_field (op->common.aml_opcode, obj_desc, | ||
644 | walk_state->operands[0], walk_state->operands[1], | ||
645 | walk_state->operands[2], walk_state->operands[3]); | ||
646 | } | ||
647 | else { | ||
648 | /* All other, create_xxx_field opcodes */ | ||
649 | |||
650 | status = acpi_ds_init_buffer_field (op->common.aml_opcode, obj_desc, | ||
651 | walk_state->operands[0], walk_state->operands[1], | ||
652 | NULL, walk_state->operands[2]); | ||
653 | } | ||
654 | |||
655 | return_ACPI_STATUS (status); | ||
656 | } | ||
657 | |||
658 | |||
659 | /***************************************************************************** | ||
660 | * | ||
661 | * FUNCTION: acpi_ds_eval_region_operands | ||
662 | * | ||
663 | * PARAMETERS: walk_state - Current walk | ||
664 | * Op - A valid region Op object | ||
665 | * | ||
666 | * RETURN: Status | ||
667 | * | ||
668 | * DESCRIPTION: Get region address and length | ||
669 | * Called from acpi_ds_exec_end_op during op_region parse tree walk | ||
670 | * | ||
671 | ****************************************************************************/ | ||
672 | |||
673 | acpi_status | ||
674 | acpi_ds_eval_region_operands ( | ||
675 | struct acpi_walk_state *walk_state, | ||
676 | union acpi_parse_object *op) | ||
677 | { | ||
678 | acpi_status status; | ||
679 | union acpi_operand_object *obj_desc; | ||
680 | union acpi_operand_object *operand_desc; | ||
681 | struct acpi_namespace_node *node; | ||
682 | union acpi_parse_object *next_op; | ||
683 | |||
684 | |||
685 | ACPI_FUNCTION_TRACE_PTR ("ds_eval_region_operands", op); | ||
686 | |||
687 | |||
688 | /* | ||
689 | * This is where we evaluate the address and length fields of the op_region declaration | ||
690 | */ | ||
691 | node = op->common.node; | ||
692 | |||
693 | /* next_op points to the op that holds the space_iD */ | ||
694 | |||
695 | next_op = op->common.value.arg; | ||
696 | |||
697 | /* next_op points to address op */ | ||
698 | |||
699 | next_op = next_op->common.next; | ||
700 | |||
701 | /* Evaluate/create the address and length operands */ | ||
702 | |||
703 | status = acpi_ds_create_operands (walk_state, next_op); | ||
704 | if (ACPI_FAILURE (status)) { | ||
705 | return_ACPI_STATUS (status); | ||
706 | } | ||
707 | |||
708 | /* Resolve the length and address operands to numbers */ | ||
709 | |||
710 | status = acpi_ex_resolve_operands (op->common.aml_opcode, ACPI_WALK_OPERANDS, walk_state); | ||
711 | if (ACPI_FAILURE (status)) { | ||
712 | return_ACPI_STATUS (status); | ||
713 | } | ||
714 | |||
715 | ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE, | ||
716 | acpi_ps_get_opcode_name (op->common.aml_opcode), | ||
717 | 1, "after acpi_ex_resolve_operands"); | ||
718 | |||
719 | obj_desc = acpi_ns_get_attached_object (node); | ||
720 | if (!obj_desc) { | ||
721 | return_ACPI_STATUS (AE_NOT_EXIST); | ||
722 | } | ||
723 | |||
724 | /* | ||
725 | * Get the length operand and save it | ||
726 | * (at Top of stack) | ||
727 | */ | ||
728 | operand_desc = walk_state->operands[walk_state->num_operands - 1]; | ||
729 | |||
730 | obj_desc->region.length = (u32) operand_desc->integer.value; | ||
731 | acpi_ut_remove_reference (operand_desc); | ||
732 | |||
733 | /* | ||
734 | * Get the address and save it | ||
735 | * (at top of stack - 1) | ||
736 | */ | ||
737 | operand_desc = walk_state->operands[walk_state->num_operands - 2]; | ||
738 | |||
739 | obj_desc->region.address = (acpi_physical_address) operand_desc->integer.value; | ||
740 | acpi_ut_remove_reference (operand_desc); | ||
741 | |||
742 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "rgn_obj %p Addr %8.8X%8.8X Len %X\n", | ||
743 | obj_desc, | ||
744 | ACPI_FORMAT_UINT64 (obj_desc->region.address), | ||
745 | obj_desc->region.length)); | ||
746 | |||
747 | /* Now the address and length are valid for this opregion */ | ||
748 | |||
749 | obj_desc->region.flags |= AOPOBJ_DATA_VALID; | ||
750 | |||
751 | return_ACPI_STATUS (status); | ||
752 | } | ||
753 | |||
754 | |||
755 | /***************************************************************************** | ||
756 | * | ||
757 | * FUNCTION: acpi_ds_eval_data_object_operands | ||
758 | * | ||
759 | * PARAMETERS: walk_state - Current walk | ||
760 | * Op - A valid data_object Op object | ||
761 | * obj_desc - data_object | ||
762 | * | ||
763 | * RETURN: Status | ||
764 | * | ||
765 | * DESCRIPTION: Get the operands and complete the following data object types: | ||
766 | * Buffer, Package. | ||
767 | * | ||
768 | ****************************************************************************/ | ||
769 | |||
770 | acpi_status | ||
771 | acpi_ds_eval_data_object_operands ( | ||
772 | struct acpi_walk_state *walk_state, | ||
773 | union acpi_parse_object *op, | ||
774 | union acpi_operand_object *obj_desc) | ||
775 | { | ||
776 | acpi_status status; | ||
777 | union acpi_operand_object *arg_desc; | ||
778 | u32 length; | ||
779 | |||
780 | |||
781 | ACPI_FUNCTION_TRACE ("ds_eval_data_object_operands"); | ||
782 | |||
783 | |||
784 | /* The first operand (for all of these data objects) is the length */ | ||
785 | |||
786 | status = acpi_ds_create_operand (walk_state, op->common.value.arg, 1); | ||
787 | if (ACPI_FAILURE (status)) { | ||
788 | return_ACPI_STATUS (status); | ||
789 | } | ||
790 | |||
791 | status = acpi_ex_resolve_operands (walk_state->opcode, | ||
792 | &(walk_state->operands [walk_state->num_operands -1]), | ||
793 | walk_state); | ||
794 | if (ACPI_FAILURE (status)) { | ||
795 | return_ACPI_STATUS (status); | ||
796 | } | ||
797 | |||
798 | /* Extract length operand */ | ||
799 | |||
800 | arg_desc = walk_state->operands [walk_state->num_operands - 1]; | ||
801 | length = (u32) arg_desc->integer.value; | ||
802 | |||
803 | /* Cleanup for length operand */ | ||
804 | |||
805 | status = acpi_ds_obj_stack_pop (1, walk_state); | ||
806 | if (ACPI_FAILURE (status)) { | ||
807 | return_ACPI_STATUS (status); | ||
808 | } | ||
809 | |||
810 | acpi_ut_remove_reference (arg_desc); | ||
811 | |||
812 | /* | ||
813 | * Create the actual data object | ||
814 | */ | ||
815 | switch (op->common.aml_opcode) { | ||
816 | case AML_BUFFER_OP: | ||
817 | |||
818 | status = acpi_ds_build_internal_buffer_obj (walk_state, op, length, &obj_desc); | ||
819 | break; | ||
820 | |||
821 | case AML_PACKAGE_OP: | ||
822 | case AML_VAR_PACKAGE_OP: | ||
823 | |||
824 | status = acpi_ds_build_internal_package_obj (walk_state, op, length, &obj_desc); | ||
825 | break; | ||
826 | |||
827 | default: | ||
828 | return_ACPI_STATUS (AE_AML_BAD_OPCODE); | ||
829 | } | ||
830 | |||
831 | if (ACPI_SUCCESS (status)) { | ||
832 | /* | ||
833 | * Return the object in the walk_state, unless the parent is a package -- | ||
834 | * in this case, the return object will be stored in the parse tree | ||
835 | * for the package. | ||
836 | */ | ||
837 | if ((!op->common.parent) || | ||
838 | ((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) && | ||
839 | (op->common.parent->common.aml_opcode != AML_VAR_PACKAGE_OP) && | ||
840 | (op->common.parent->common.aml_opcode != AML_NAME_OP))) { | ||
841 | walk_state->result_obj = obj_desc; | ||
842 | } | ||
843 | } | ||
844 | |||
845 | return_ACPI_STATUS (status); | ||
846 | } | ||
847 | |||
848 | |||
849 | /******************************************************************************* | ||
850 | * | ||
851 | * FUNCTION: acpi_ds_exec_begin_control_op | ||
852 | * | ||
853 | * PARAMETERS: walk_list - The list that owns the walk stack | ||
854 | * Op - The control Op | ||
855 | * | ||
856 | * RETURN: Status | ||
857 | * | ||
858 | * DESCRIPTION: Handles all control ops encountered during control method | ||
859 | * execution. | ||
860 | * | ||
861 | ******************************************************************************/ | ||
862 | |||
863 | acpi_status | ||
864 | acpi_ds_exec_begin_control_op ( | ||
865 | struct acpi_walk_state *walk_state, | ||
866 | union acpi_parse_object *op) | ||
867 | { | ||
868 | acpi_status status = AE_OK; | ||
869 | union acpi_generic_state *control_state; | ||
870 | |||
871 | |||
872 | ACPI_FUNCTION_NAME ("ds_exec_begin_control_op"); | ||
873 | |||
874 | |||
875 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", op, | ||
876 | op->common.aml_opcode, walk_state)); | ||
877 | |||
878 | switch (op->common.aml_opcode) { | ||
879 | case AML_IF_OP: | ||
880 | case AML_WHILE_OP: | ||
881 | |||
882 | /* | ||
883 | * IF/WHILE: Create a new control state to manage these | ||
884 | * constructs. We need to manage these as a stack, in order | ||
885 | * to handle nesting. | ||
886 | */ | ||
887 | control_state = acpi_ut_create_control_state (); | ||
888 | if (!control_state) { | ||
889 | status = AE_NO_MEMORY; | ||
890 | break; | ||
891 | } | ||
892 | /* | ||
893 | * Save a pointer to the predicate for multiple executions | ||
894 | * of a loop | ||
895 | */ | ||
896 | control_state->control.aml_predicate_start = walk_state->parser_state.aml - 1; | ||
897 | control_state->control.package_end = walk_state->parser_state.pkg_end; | ||
898 | control_state->control.opcode = op->common.aml_opcode; | ||
899 | |||
900 | |||
901 | /* Push the control state on this walk's control stack */ | ||
902 | |||
903 | acpi_ut_push_generic_state (&walk_state->control_state, control_state); | ||
904 | break; | ||
905 | |||
906 | case AML_ELSE_OP: | ||
907 | |||
908 | /* Predicate is in the state object */ | ||
909 | /* If predicate is true, the IF was executed, ignore ELSE part */ | ||
910 | |||
911 | if (walk_state->last_predicate) { | ||
912 | status = AE_CTRL_TRUE; | ||
913 | } | ||
914 | |||
915 | break; | ||
916 | |||
917 | case AML_RETURN_OP: | ||
918 | |||
919 | break; | ||
920 | |||
921 | default: | ||
922 | break; | ||
923 | } | ||
924 | |||
925 | return (status); | ||
926 | } | ||
927 | |||
928 | |||
929 | /******************************************************************************* | ||
930 | * | ||
931 | * FUNCTION: acpi_ds_exec_end_control_op | ||
932 | * | ||
933 | * PARAMETERS: walk_list - The list that owns the walk stack | ||
934 | * Op - The control Op | ||
935 | * | ||
936 | * RETURN: Status | ||
937 | * | ||
938 | * DESCRIPTION: Handles all control ops encountered during control method | ||
939 | * execution. | ||
940 | * | ||
941 | ******************************************************************************/ | ||
942 | |||
943 | acpi_status | ||
944 | acpi_ds_exec_end_control_op ( | ||
945 | struct acpi_walk_state *walk_state, | ||
946 | union acpi_parse_object *op) | ||
947 | { | ||
948 | acpi_status status = AE_OK; | ||
949 | union acpi_generic_state *control_state; | ||
950 | |||
951 | |||
952 | ACPI_FUNCTION_NAME ("ds_exec_end_control_op"); | ||
953 | |||
954 | |||
955 | switch (op->common.aml_opcode) { | ||
956 | case AML_IF_OP: | ||
957 | |||
958 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", op)); | ||
959 | |||
960 | /* | ||
961 | * Save the result of the predicate in case there is an | ||
962 | * ELSE to come | ||
963 | */ | ||
964 | walk_state->last_predicate = | ||
965 | (u8) walk_state->control_state->common.value; | ||
966 | |||
967 | /* | ||
968 | * Pop the control state that was created at the start | ||
969 | * of the IF and free it | ||
970 | */ | ||
971 | control_state = acpi_ut_pop_generic_state (&walk_state->control_state); | ||
972 | acpi_ut_delete_generic_state (control_state); | ||
973 | break; | ||
974 | |||
975 | |||
976 | case AML_ELSE_OP: | ||
977 | |||
978 | break; | ||
979 | |||
980 | |||
981 | case AML_WHILE_OP: | ||
982 | |||
983 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op)); | ||
984 | |||
985 | if (walk_state->control_state->common.value) { | ||
986 | /* Predicate was true, go back and evaluate it again! */ | ||
987 | |||
988 | status = AE_CTRL_PENDING; | ||
989 | } | ||
990 | |||
991 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] termination! Op=%p\n", op)); | ||
992 | |||
993 | /* Pop this control state and free it */ | ||
994 | |||
995 | control_state = acpi_ut_pop_generic_state (&walk_state->control_state); | ||
996 | |||
997 | walk_state->aml_last_while = control_state->control.aml_predicate_start; | ||
998 | acpi_ut_delete_generic_state (control_state); | ||
999 | break; | ||
1000 | |||
1001 | |||
1002 | case AML_RETURN_OP: | ||
1003 | |||
1004 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, | ||
1005 | "[RETURN_OP] Op=%p Arg=%p\n",op, op->common.value.arg)); | ||
1006 | |||
1007 | /* | ||
1008 | * One optional operand -- the return value | ||
1009 | * It can be either an immediate operand or a result that | ||
1010 | * has been bubbled up the tree | ||
1011 | */ | ||
1012 | if (op->common.value.arg) { | ||
1013 | /* Since we have a real Return(), delete any implicit return */ | ||
1014 | |||
1015 | acpi_ds_clear_implicit_return (walk_state); | ||
1016 | |||
1017 | /* Return statement has an immediate operand */ | ||
1018 | |||
1019 | status = acpi_ds_create_operands (walk_state, op->common.value.arg); | ||
1020 | if (ACPI_FAILURE (status)) { | ||
1021 | return (status); | ||
1022 | } | ||
1023 | |||
1024 | /* | ||
1025 | * If value being returned is a Reference (such as | ||
1026 | * an arg or local), resolve it now because it may | ||
1027 | * cease to exist at the end of the method. | ||
1028 | */ | ||
1029 | status = acpi_ex_resolve_to_value (&walk_state->operands [0], walk_state); | ||
1030 | if (ACPI_FAILURE (status)) { | ||
1031 | return (status); | ||
1032 | } | ||
1033 | |||
1034 | /* | ||
1035 | * Get the return value and save as the last result | ||
1036 | * value. This is the only place where walk_state->return_desc | ||
1037 | * is set to anything other than zero! | ||
1038 | */ | ||
1039 | walk_state->return_desc = walk_state->operands[0]; | ||
1040 | } | ||
1041 | else if ((walk_state->results) && | ||
1042 | (walk_state->results->results.num_results > 0)) { | ||
1043 | /* Since we have a real Return(), delete any implicit return */ | ||
1044 | |||
1045 | acpi_ds_clear_implicit_return (walk_state); | ||
1046 | |||
1047 | /* | ||
1048 | * The return value has come from a previous calculation. | ||
1049 | * | ||
1050 | * If value being returned is a Reference (such as | ||
1051 | * an arg or local), resolve it now because it may | ||
1052 | * cease to exist at the end of the method. | ||
1053 | * | ||
1054 | * Allow references created by the Index operator to return unchanged. | ||
1055 | */ | ||
1056 | if ((ACPI_GET_DESCRIPTOR_TYPE (walk_state->results->results.obj_desc[0]) == ACPI_DESC_TYPE_OPERAND) && | ||
1057 | (ACPI_GET_OBJECT_TYPE (walk_state->results->results.obj_desc [0]) == ACPI_TYPE_LOCAL_REFERENCE) && | ||
1058 | ((walk_state->results->results.obj_desc [0])->reference.opcode != AML_INDEX_OP)) { | ||
1059 | status = acpi_ex_resolve_to_value (&walk_state->results->results.obj_desc [0], walk_state); | ||
1060 | if (ACPI_FAILURE (status)) { | ||
1061 | return (status); | ||
1062 | } | ||
1063 | } | ||
1064 | |||
1065 | walk_state->return_desc = walk_state->results->results.obj_desc [0]; | ||
1066 | } | ||
1067 | else { | ||
1068 | /* No return operand */ | ||
1069 | |||
1070 | if (walk_state->num_operands) { | ||
1071 | acpi_ut_remove_reference (walk_state->operands [0]); | ||
1072 | } | ||
1073 | |||
1074 | walk_state->operands [0] = NULL; | ||
1075 | walk_state->num_operands = 0; | ||
1076 | walk_state->return_desc = NULL; | ||
1077 | } | ||
1078 | |||
1079 | |||
1080 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, | ||
1081 | "Completed RETURN_OP State=%p, ret_val=%p\n", | ||
1082 | walk_state, walk_state->return_desc)); | ||
1083 | |||
1084 | /* End the control method execution right now */ | ||
1085 | |||
1086 | status = AE_CTRL_TERMINATE; | ||
1087 | break; | ||
1088 | |||
1089 | |||
1090 | case AML_NOOP_OP: | ||
1091 | |||
1092 | /* Just do nothing! */ | ||
1093 | break; | ||
1094 | |||
1095 | |||
1096 | case AML_BREAK_POINT_OP: | ||
1097 | |||
1098 | /* Call up to the OS service layer to handle this */ | ||
1099 | |||
1100 | status = acpi_os_signal (ACPI_SIGNAL_BREAKPOINT, "Executed AML Breakpoint opcode"); | ||
1101 | |||
1102 | /* If and when it returns, all done. */ | ||
1103 | |||
1104 | break; | ||
1105 | |||
1106 | |||
1107 | case AML_BREAK_OP: | ||
1108 | case AML_CONTINUE_OP: /* ACPI 2.0 */ | ||
1109 | |||
1110 | |||
1111 | /* Pop and delete control states until we find a while */ | ||
1112 | |||
1113 | while (walk_state->control_state && | ||
1114 | (walk_state->control_state->control.opcode != AML_WHILE_OP)) { | ||
1115 | control_state = acpi_ut_pop_generic_state (&walk_state->control_state); | ||
1116 | acpi_ut_delete_generic_state (control_state); | ||
1117 | } | ||
1118 | |||
1119 | /* No while found? */ | ||
1120 | |||
1121 | if (!walk_state->control_state) { | ||
1122 | return (AE_AML_NO_WHILE); | ||
1123 | } | ||
1124 | |||
1125 | /* Was: walk_state->aml_last_while = walk_state->control_state->Control.aml_predicate_start; */ | ||
1126 | |||
1127 | walk_state->aml_last_while = walk_state->control_state->control.package_end; | ||
1128 | |||
1129 | /* Return status depending on opcode */ | ||
1130 | |||
1131 | if (op->common.aml_opcode == AML_BREAK_OP) { | ||
1132 | status = AE_CTRL_BREAK; | ||
1133 | } | ||
1134 | else { | ||
1135 | status = AE_CTRL_CONTINUE; | ||
1136 | } | ||
1137 | break; | ||
1138 | |||
1139 | |||
1140 | default: | ||
1141 | |||
1142 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown control opcode=%X Op=%p\n", | ||
1143 | op->common.aml_opcode, op)); | ||
1144 | |||
1145 | status = AE_AML_BAD_OPCODE; | ||
1146 | break; | ||
1147 | } | ||
1148 | |||
1149 | return (status); | ||
1150 | } | ||
1151 | |||