aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/parser
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2005-08-04 18:09:09 -0400
committerLen Brown <len.brown@intel.com>2005-08-04 18:09:09 -0400
commit5d2a22079c825669d91a3a200332f1053b4b61b0 (patch)
tree2e6e88bbcc3e17535fdf3103540b246b3658e20b /drivers/acpi/parser
parent1c5ad84516ae7ea4ec868436a910a6bd8d20215a (diff)
parentbd6dbdf3c7b9784fbf5d8500e427a954e27a976a (diff)
/home/lenb/src/to-akpm branch 'acpi-2.6.12'
Diffstat (limited to 'drivers/acpi/parser')
-rw-r--r--drivers/acpi/parser/Makefile2
-rw-r--r--drivers/acpi/parser/psloop.c781
-rw-r--r--drivers/acpi/parser/psopcode.c30
-rw-r--r--drivers/acpi/parser/psparse.c723
-rw-r--r--drivers/acpi/parser/psutils.c37
-rw-r--r--drivers/acpi/parser/psxface.c241
6 files changed, 966 insertions, 848 deletions
diff --git a/drivers/acpi/parser/Makefile b/drivers/acpi/parser/Makefile
index bbdd286c660d..db24ee09cf11 100644
--- a/drivers/acpi/parser/Makefile
+++ b/drivers/acpi/parser/Makefile
@@ -2,7 +2,7 @@
2# Makefile for all Linux ACPI interpreter subdirectories 2# Makefile for all Linux ACPI interpreter subdirectories
3# 3#
4 4
5obj-y := psargs.o psparse.o pstree.o pswalk.o \ 5obj-y := psargs.o psparse.o psloop.o pstree.o pswalk.o \
6 psopcode.o psscope.o psutils.o psxface.o 6 psopcode.o psscope.o psutils.o psxface.o
7 7
8EXTRA_CFLAGS += $(ACPI_CFLAGS) 8EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c
new file mode 100644
index 000000000000..551d54bdbec3
--- /dev/null
+++ b/drivers/acpi/parser/psloop.c
@@ -0,0 +1,781 @@
1/******************************************************************************
2 *
3 * Module Name: psloop - Main AML parse loop
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/*
46 * 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
48 * generated parser to tightly constrain stack and dynamic memory
49 * usage. At the same time, parsing is kept flexible and the code
50 * fairly compact by parsing based on a list of AML opcode
51 * templates in aml_op_info[]
52 */
53
54#include <acpi/acpi.h>
55#include <acpi/acparser.h>
56#include <acpi/acdispat.h>
57#include <acpi/amlcode.h>
58
59#define _COMPONENT ACPI_PARSER
60 ACPI_MODULE_NAME ("psloop")
61
62static u32 acpi_gbl_depth = 0;
63
64
65/*******************************************************************************
66 *
67 * FUNCTION: acpi_ps_parse_loop
68 *
69 * PARAMETERS: walk_state - Current state
70 *
71 * RETURN: Status
72 *
73 * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
74 * a tree of ops.
75 *
76 ******************************************************************************/
77
78acpi_status
79acpi_ps_parse_loop (
80 struct acpi_walk_state *walk_state)
81{
82 acpi_status status = AE_OK;
83 acpi_status status2;
84 union acpi_parse_object *op = NULL; /* current op */
85 union acpi_parse_object *arg = NULL;
86 union acpi_parse_object *pre_op = NULL;
87 struct acpi_parse_state *parser_state;
88 u8 *aml_op_start = NULL;
89
90
91 ACPI_FUNCTION_TRACE_PTR ("ps_parse_loop", walk_state);
92
93 if (walk_state->descending_callback == NULL) {
94 return_ACPI_STATUS (AE_BAD_PARAMETER);
95 }
96
97 parser_state = &walk_state->parser_state;
98 walk_state->arg_types = 0;
99
100#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
101
102 if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) {
103 /* We are restarting a preempted control method */
104
105 if (acpi_ps_has_completed_scope (parser_state)) {
106 /*
107 * We must check if a predicate to an IF or WHILE statement
108 * was just completed
109 */
110 if ((parser_state->scope->parse_scope.op) &&
111 ((parser_state->scope->parse_scope.op->common.aml_opcode == AML_IF_OP) ||
112 (parser_state->scope->parse_scope.op->common.aml_opcode == AML_WHILE_OP)) &&
113 (walk_state->control_state) &&
114 (walk_state->control_state->common.state ==
115 ACPI_CONTROL_PREDICATE_EXECUTING)) {
116 /*
117 * A predicate was just completed, get the value of the
118 * predicate and branch based on that value
119 */
120 walk_state->op = NULL;
121 status = acpi_ds_get_predicate_value (walk_state, ACPI_TO_POINTER (TRUE));
122 if (ACPI_FAILURE (status) &&
123 ((status & AE_CODE_MASK) != AE_CODE_CONTROL)) {
124 if (status == AE_AML_NO_RETURN_VALUE) {
125 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
126 "Invoked method did not return a value, %s\n",
127 acpi_format_exception (status)));
128
129 }
130 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
131 "get_predicate Failed, %s\n",
132 acpi_format_exception (status)));
133 return_ACPI_STATUS (status);
134 }
135
136 status = acpi_ps_next_parse_state (walk_state, op, status);
137 }
138
139 acpi_ps_pop_scope (parser_state, &op,
140 &walk_state->arg_types, &walk_state->arg_count);
141 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op));
142 }
143 else if (walk_state->prev_op) {
144 /* We were in the middle of an op */
145
146 op = walk_state->prev_op;
147 walk_state->arg_types = walk_state->prev_arg_types;
148 }
149 }
150#endif
151
152 /* Iterative parsing loop, while there is more AML to process: */
153
154 while ((parser_state->aml < parser_state->aml_end) || (op)) {
155 aml_op_start = parser_state->aml;
156 if (!op) {
157 /* Get the next opcode from the AML stream */
158
159 walk_state->aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml,
160 parser_state->aml_start);
161 walk_state->opcode = acpi_ps_peek_opcode (parser_state);
162
163 /*
164 * First cut to determine what we have found:
165 * 1) A valid AML opcode
166 * 2) A name string
167 * 3) An unknown/invalid opcode
168 */
169 walk_state->op_info = acpi_ps_get_opcode_info (walk_state->opcode);
170 switch (walk_state->op_info->class) {
171 case AML_CLASS_ASCII:
172 case AML_CLASS_PREFIX:
173 /*
174 * Starts with a valid prefix or ASCII char, this is a name
175 * string. Convert the bare name string to a namepath.
176 */
177 walk_state->opcode = AML_INT_NAMEPATH_OP;
178 walk_state->arg_types = ARGP_NAMESTRING;
179 break;
180
181 case AML_CLASS_UNKNOWN:
182
183 /* The opcode is unrecognized. Just skip unknown opcodes */
184
185 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
186 "Found unknown opcode %X at AML address %p offset %X, ignoring\n",
187 walk_state->opcode, parser_state->aml, walk_state->aml_offset));
188
189 ACPI_DUMP_BUFFER (parser_state->aml, 128);
190
191 /* Assume one-byte bad opcode */
192
193 parser_state->aml++;
194 continue;
195
196 default:
197
198 /* Found opcode info, this is a normal opcode */
199
200 parser_state->aml += acpi_ps_get_opcode_size (walk_state->opcode);
201 walk_state->arg_types = walk_state->op_info->parse_args;
202 break;
203 }
204
205 /* Create Op structure and append to parent's argument list */
206
207 if (walk_state->op_info->flags & AML_NAMED) {
208 /* Allocate a new pre_op if necessary */
209
210 if (!pre_op) {
211 pre_op = acpi_ps_alloc_op (walk_state->opcode);
212 if (!pre_op) {
213 status = AE_NO_MEMORY;
214 goto close_this_op;
215 }
216 }
217
218 pre_op->common.value.arg = NULL;
219 pre_op->common.aml_opcode = walk_state->opcode;
220
221 /*
222 * Get and append arguments until we find the node that contains
223 * the name (the type ARGP_NAME).
224 */
225 while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) &&
226 (GET_CURRENT_ARG_TYPE (walk_state->arg_types) != ARGP_NAME)) {
227 status = acpi_ps_get_next_arg (walk_state, parser_state,
228 GET_CURRENT_ARG_TYPE (walk_state->arg_types), &arg);
229 if (ACPI_FAILURE (status)) {
230 goto close_this_op;
231 }
232
233 acpi_ps_append_arg (pre_op, arg);
234 INCREMENT_ARG_LIST (walk_state->arg_types);
235 }
236
237 /*
238 * Make sure that we found a NAME and didn't run out of
239 * arguments
240 */
241 if (!GET_CURRENT_ARG_TYPE (walk_state->arg_types)) {
242 status = AE_AML_NO_OPERAND;
243 goto close_this_op;
244 }
245
246 /* We know that this arg is a name, move to next arg */
247
248 INCREMENT_ARG_LIST (walk_state->arg_types);
249
250 /*
251 * Find the object. This will either insert the object into
252 * the namespace or simply look it up
253 */
254 walk_state->op = NULL;
255
256 status = walk_state->descending_callback (walk_state, &op);
257 if (ACPI_FAILURE (status)) {
258 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
259 "During name lookup/catalog, %s\n",
260 acpi_format_exception (status)));
261 goto close_this_op;
262 }
263
264 if (!op) {
265 continue;
266 }
267
268 status = acpi_ps_next_parse_state (walk_state, op, status);
269 if (status == AE_CTRL_PENDING) {
270 status = AE_OK;
271 goto close_this_op;
272 }
273
274 if (ACPI_FAILURE (status)) {
275 goto close_this_op;
276 }
277
278 acpi_ps_append_arg (op, pre_op->common.value.arg);
279 acpi_gbl_depth++;
280
281 if (op->common.aml_opcode == AML_REGION_OP) {
282 /*
283 * Defer final parsing of an operation_region body,
284 * because we don't have enough info in the first pass
285 * to parse it correctly (i.e., there may be method
286 * calls within the term_arg elements of the body.)
287 *
288 * However, we must continue parsing because
289 * the opregion is not a standalone package --
290 * we don't know where the end is at this point.
291 *
292 * (Length is unknown until parse of the body complete)
293 */
294 op->named.data = aml_op_start;
295 op->named.length = 0;
296 }
297 }
298 else {
299 /* Not a named opcode, just allocate Op and append to parent */
300
301 walk_state->op_info = acpi_ps_get_opcode_info (walk_state->opcode);
302 op = acpi_ps_alloc_op (walk_state->opcode);
303 if (!op) {
304 status = AE_NO_MEMORY;
305 goto close_this_op;
306 }
307
308 if (walk_state->op_info->flags & AML_CREATE) {
309 /*
310 * Backup to beginning of create_xXXfield declaration
311 * body_length is unknown until we parse the body
312 */
313 op->named.data = aml_op_start;
314 op->named.length = 0;
315 }
316
317 acpi_ps_append_arg (acpi_ps_get_parent_scope (parser_state), op);
318
319 if ((walk_state->descending_callback != NULL)) {
320 /*
321 * Find the object. This will either insert the object into
322 * the namespace or simply look it up
323 */
324 walk_state->op = op;
325
326 status = walk_state->descending_callback (walk_state, &op);
327 status = acpi_ps_next_parse_state (walk_state, op, status);
328 if (status == AE_CTRL_PENDING) {
329 status = AE_OK;
330 goto close_this_op;
331 }
332
333 if (ACPI_FAILURE (status)) {
334 goto close_this_op;
335 }
336 }
337 }
338
339 op->common.aml_offset = walk_state->aml_offset;
340
341 if (walk_state->op_info) {
342 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
343 "Opcode %4.4X [%s] Op %p Aml %p aml_offset %5.5X\n",
344 (u32) op->common.aml_opcode, walk_state->op_info->name,
345 op, parser_state->aml, op->common.aml_offset));
346 }
347 }
348
349
350 /*
351 * Start arg_count at zero because we don't know if there are
352 * any args yet
353 */
354 walk_state->arg_count = 0;
355
356 /* Are there any arguments that must be processed? */
357
358 if (walk_state->arg_types) {
359 /* Get arguments */
360
361 switch (op->common.aml_opcode) {
362 case AML_BYTE_OP: /* AML_BYTEDATA_ARG */
363 case AML_WORD_OP: /* AML_WORDDATA_ARG */
364 case AML_DWORD_OP: /* AML_DWORDATA_ARG */
365 case AML_QWORD_OP: /* AML_QWORDATA_ARG */
366 case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */
367
368 /* Fill in constant or string argument directly */
369
370 acpi_ps_get_next_simple_arg (parser_state,
371 GET_CURRENT_ARG_TYPE (walk_state->arg_types), op);
372 break;
373
374 case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */
375
376 status = acpi_ps_get_next_namepath (walk_state, parser_state, op, 1);
377 if (ACPI_FAILURE (status)) {
378 goto close_this_op;
379 }
380
381 walk_state->arg_types = 0;
382 break;
383
384 default:
385 /*
386 * Op is not a constant or string, append each argument
387 * to the Op
388 */
389 while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) &&
390 !walk_state->arg_count) {
391 walk_state->aml_offset = (u32)
392 ACPI_PTR_DIFF (parser_state->aml, parser_state->aml_start);
393
394 status = acpi_ps_get_next_arg (walk_state, parser_state,
395 GET_CURRENT_ARG_TYPE (walk_state->arg_types),
396 &arg);
397 if (ACPI_FAILURE (status)) {
398 goto close_this_op;
399 }
400
401 if (arg) {
402 arg->common.aml_offset = walk_state->aml_offset;
403 acpi_ps_append_arg (op, arg);
404 }
405 INCREMENT_ARG_LIST (walk_state->arg_types);
406 }
407
408
409 /* Special processing for certain opcodes */
410
411 /* TBD (remove): Temporary mechanism to disable this code if needed */
412
413#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE
414
415 if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS1) &&
416 ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) {
417 /*
418 * We want to skip If/Else/While constructs during Pass1
419 * because we want to actually conditionally execute the
420 * code during Pass2.
421 *
422 * Except for disassembly, where we always want to
423 * walk the If/Else/While packages
424 */
425 switch (op->common.aml_opcode) {
426 case AML_IF_OP:
427 case AML_ELSE_OP:
428 case AML_WHILE_OP:
429
430 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
431 "Pass1: Skipping an If/Else/While body\n"));
432
433 /* Skip body of if/else/while in pass 1 */
434
435 parser_state->aml = parser_state->pkg_end;
436 walk_state->arg_count = 0;
437 break;
438
439 default:
440 break;
441 }
442 }
443#endif
444 switch (op->common.aml_opcode) {
445 case AML_METHOD_OP:
446
447 /*
448 * Skip parsing of control method
449 * because we don't have enough info in the first pass
450 * to parse it correctly.
451 *
452 * Save the length and address of the body
453 */
454 op->named.data = parser_state->aml;
455 op->named.length = (u32) (parser_state->pkg_end -
456 parser_state->aml);
457
458 /* Skip body of method */
459
460 parser_state->aml = parser_state->pkg_end;
461 walk_state->arg_count = 0;
462 break;
463
464 case AML_BUFFER_OP:
465 case AML_PACKAGE_OP:
466 case AML_VAR_PACKAGE_OP:
467
468 if ((op->common.parent) &&
469 (op->common.parent->common.aml_opcode == AML_NAME_OP) &&
470 (walk_state->pass_number <= ACPI_IMODE_LOAD_PASS2)) {
471 /*
472 * Skip parsing of Buffers and Packages
473 * because we don't have enough info in the first pass
474 * to parse them correctly.
475 */
476 op->named.data = aml_op_start;
477 op->named.length = (u32) (parser_state->pkg_end -
478 aml_op_start);
479
480 /* Skip body */
481
482 parser_state->aml = parser_state->pkg_end;
483 walk_state->arg_count = 0;
484 }
485 break;
486
487 case AML_WHILE_OP:
488
489 if (walk_state->control_state) {
490 walk_state->control_state->control.package_end =
491 parser_state->pkg_end;
492 }
493 break;
494
495 default:
496
497 /* No action for all other opcodes */
498 break;
499 }
500 break;
501 }
502 }
503
504 /* Check for arguments that need to be processed */
505
506 if (walk_state->arg_count) {
507 /*
508 * There are arguments (complex ones), push Op and
509 * prepare for argument
510 */
511 status = acpi_ps_push_scope (parser_state, op,
512 walk_state->arg_types, walk_state->arg_count);
513 if (ACPI_FAILURE (status)) {
514 goto close_this_op;
515 }
516 op = NULL;
517 continue;
518 }
519
520 /*
521 * All arguments have been processed -- Op is complete,
522 * prepare for next
523 */
524 walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
525 if (walk_state->op_info->flags & AML_NAMED) {
526 if (acpi_gbl_depth) {
527 acpi_gbl_depth--;
528 }
529
530 if (op->common.aml_opcode == AML_REGION_OP) {
531 /*
532 * Skip parsing of control method or opregion body,
533 * because we don't have enough info in the first pass
534 * to parse them correctly.
535 *
536 * Completed parsing an op_region declaration, we now
537 * know the length.
538 */
539 op->named.length = (u32) (parser_state->aml - op->named.data);
540 }
541 }
542
543 if (walk_state->op_info->flags & AML_CREATE) {
544 /*
545 * Backup to beginning of create_xXXfield declaration (1 for
546 * Opcode)
547 *
548 * body_length is unknown until we parse the body
549 */
550 op->named.length = (u32) (parser_state->aml - op->named.data);
551 }
552
553 /* This op complete, notify the dispatcher */
554
555 if (walk_state->ascending_callback != NULL) {
556 walk_state->op = op;
557 walk_state->opcode = op->common.aml_opcode;
558
559 status = walk_state->ascending_callback (walk_state);
560 status = acpi_ps_next_parse_state (walk_state, op, status);
561 if (status == AE_CTRL_PENDING) {
562 status = AE_OK;
563 goto close_this_op;
564 }
565 }
566
567
568close_this_op:
569 /*
570 * Finished one argument of the containing scope
571 */
572 parser_state->scope->parse_scope.arg_count--;
573
574 /* Finished with pre_op */
575
576 if (pre_op) {
577 acpi_ps_free_op (pre_op);
578 pre_op = NULL;
579 }
580
581 /* Close this Op (will result in parse subtree deletion) */
582
583 status2 = acpi_ps_complete_this_op (walk_state, op);
584 if (ACPI_FAILURE (status2)) {
585 return_ACPI_STATUS (status2);
586 }
587 op = NULL;
588
589 switch (status) {
590 case AE_OK:
591 break;
592
593
594 case AE_CTRL_TRANSFER:
595
596 /* We are about to transfer to a called method. */
597
598 walk_state->prev_op = op;
599 walk_state->prev_arg_types = walk_state->arg_types;
600 return_ACPI_STATUS (status);
601
602
603 case AE_CTRL_END:
604
605 acpi_ps_pop_scope (parser_state, &op,
606 &walk_state->arg_types, &walk_state->arg_count);
607
608 if (op) {
609 walk_state->op = op;
610 walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
611 walk_state->opcode = op->common.aml_opcode;
612
613 status = walk_state->ascending_callback (walk_state);
614 status = acpi_ps_next_parse_state (walk_state, op, status);
615
616 status2 = acpi_ps_complete_this_op (walk_state, op);
617 if (ACPI_FAILURE (status2)) {
618 return_ACPI_STATUS (status2);
619 }
620 op = NULL;
621 }
622 status = AE_OK;
623 break;
624
625
626 case AE_CTRL_BREAK:
627 case AE_CTRL_CONTINUE:
628
629 /* Pop off scopes until we find the While */
630
631 while (!op || (op->common.aml_opcode != AML_WHILE_OP)) {
632 acpi_ps_pop_scope (parser_state, &op,
633 &walk_state->arg_types, &walk_state->arg_count);
634 }
635
636 /* Close this iteration of the While loop */
637
638 walk_state->op = op;
639 walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
640 walk_state->opcode = op->common.aml_opcode;
641
642 status = walk_state->ascending_callback (walk_state);
643 status = acpi_ps_next_parse_state (walk_state, op, status);
644
645 status2 = acpi_ps_complete_this_op (walk_state, op);
646 if (ACPI_FAILURE (status2)) {
647 return_ACPI_STATUS (status2);
648 }
649 op = NULL;
650
651 status = AE_OK;
652 break;
653
654
655 case AE_CTRL_TERMINATE:
656
657 status = AE_OK;
658
659 /* Clean up */
660 do {
661 if (op) {
662 status2 = acpi_ps_complete_this_op (walk_state, op);
663 if (ACPI_FAILURE (status2)) {
664 return_ACPI_STATUS (status2);
665 }
666 }
667 acpi_ps_pop_scope (parser_state, &op,
668 &walk_state->arg_types, &walk_state->arg_count);
669
670 } while (op);
671
672 return_ACPI_STATUS (status);
673
674
675 default: /* All other non-AE_OK status */
676
677 do {
678 if (op) {
679 status2 = acpi_ps_complete_this_op (walk_state, op);
680 if (ACPI_FAILURE (status2)) {
681 return_ACPI_STATUS (status2);
682 }
683 }
684 acpi_ps_pop_scope (parser_state, &op,
685 &walk_state->arg_types, &walk_state->arg_count);
686
687 } while (op);
688
689
690 /*
691 * TBD: Cleanup parse ops on error
692 */
693#if 0
694 if (op == NULL) {
695 acpi_ps_pop_scope (parser_state, &op,
696 &walk_state->arg_types, &walk_state->arg_count);
697 }
698#endif
699 walk_state->prev_op = op;
700 walk_state->prev_arg_types = walk_state->arg_types;
701 return_ACPI_STATUS (status);
702 }
703
704 /* This scope complete? */
705
706 if (acpi_ps_has_completed_scope (parser_state)) {
707 acpi_ps_pop_scope (parser_state, &op,
708 &walk_state->arg_types, &walk_state->arg_count);
709 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op));
710 }
711 else {
712 op = NULL;
713 }
714
715 } /* while parser_state->Aml */
716
717
718 /*
719 * Complete the last Op (if not completed), and clear the scope stack.
720 * It is easily possible to end an AML "package" with an unbounded number
721 * of open scopes (such as when several ASL blocks are closed with
722 * sequential closing braces). We want to terminate each one cleanly.
723 */
724 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", op));
725 do {
726 if (op) {
727 if (walk_state->ascending_callback != NULL) {
728 walk_state->op = op;
729 walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
730 walk_state->opcode = op->common.aml_opcode;
731
732 status = walk_state->ascending_callback (walk_state);
733 status = acpi_ps_next_parse_state (walk_state, op, status);
734 if (status == AE_CTRL_PENDING) {
735 status = AE_OK;
736 goto close_this_op;
737 }
738
739 if (status == AE_CTRL_TERMINATE) {
740 status = AE_OK;
741
742 /* Clean up */
743 do {
744 if (op) {
745 status2 = acpi_ps_complete_this_op (walk_state, op);
746 if (ACPI_FAILURE (status2)) {
747 return_ACPI_STATUS (status2);
748 }
749 }
750
751 acpi_ps_pop_scope (parser_state, &op,
752 &walk_state->arg_types, &walk_state->arg_count);
753
754 } while (op);
755
756 return_ACPI_STATUS (status);
757 }
758
759 else if (ACPI_FAILURE (status)) {
760 /* First error is most important */
761
762 (void) acpi_ps_complete_this_op (walk_state, op);
763 return_ACPI_STATUS (status);
764 }
765 }
766
767 status2 = acpi_ps_complete_this_op (walk_state, op);
768 if (ACPI_FAILURE (status2)) {
769 return_ACPI_STATUS (status2);
770 }
771 }
772
773 acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types,
774 &walk_state->arg_count);
775
776 } while (op);
777
778 return_ACPI_STATUS (status);
779}
780
781
diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c
index 5744673568c0..6f7594a516d2 100644
--- a/drivers/acpi/parser/psopcode.c
+++ b/drivers/acpi/parser/psopcode.c
@@ -311,7 +311,7 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] =
311/* ACPI 2.0 opcodes */ 311/* ACPI 2.0 opcodes */
312 312
313/* 6E */ ACPI_OP ("QwordConst", ARGP_QWORD_OP, ARGI_QWORD_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_CONSTANT), 313/* 6E */ ACPI_OP ("QwordConst", ARGP_QWORD_OP, ARGI_QWORD_OP, ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT, AML_TYPE_LITERAL, AML_CONSTANT),
314/* 6F */ ACPI_OP ("Package /*Var*/", ARGP_VAR_PACKAGE_OP, ARGI_VAR_PACKAGE_OP, ACPI_TYPE_PACKAGE, AML_CLASS_CREATE, AML_TYPE_CREATE_OBJECT, AML_HAS_ARGS | AML_DEFER), 314/* 6F */ ACPI_OP ("Package", /* Var */ ARGP_VAR_PACKAGE_OP, ARGI_VAR_PACKAGE_OP, ACPI_TYPE_PACKAGE, AML_CLASS_CREATE, AML_TYPE_CREATE_OBJECT, AML_HAS_ARGS | AML_DEFER),
315/* 70 */ ACPI_OP ("ConcatenateResTemplate", ARGP_CONCAT_RES_OP, ARGI_CONCAT_RES_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT), 315/* 70 */ ACPI_OP ("ConcatenateResTemplate", ARGP_CONCAT_RES_OP, ARGI_CONCAT_RES_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
316/* 71 */ ACPI_OP ("Mod", ARGP_MOD_OP, ARGI_MOD_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT), 316/* 71 */ ACPI_OP ("Mod", ARGP_MOD_OP, ARGI_MOD_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
317/* 72 */ ACPI_OP ("CreateQWordField", ARGP_CREATE_QWORD_FIELD_OP,ARGI_CREATE_QWORD_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE), 317/* 72 */ ACPI_OP ("CreateQWordField", ARGP_CREATE_QWORD_FIELD_OP,ARGI_CREATE_QWORD_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
@@ -428,33 +428,23 @@ acpi_ps_get_opcode_info (
428 /* 428 /*
429 * Detect normal 8-bit opcode or extended 16-bit opcode 429 * Detect normal 8-bit opcode or extended 16-bit opcode
430 */ 430 */
431 switch ((u8) (opcode >> 8)) { 431 if (!(opcode & 0xFF00)) {
432 case 0:
433
434 /* Simple (8-bit) opcode: 0-255, can't index beyond table */ 432 /* Simple (8-bit) opcode: 0-255, can't index beyond table */
435 433
436 return (&acpi_gbl_aml_op_info [acpi_gbl_short_op_index [(u8) opcode]]); 434 return (&acpi_gbl_aml_op_info [acpi_gbl_short_op_index [(u8) opcode]]);
435 }
437 436
438 case AML_EXTOP: 437 if (((opcode & 0xFF00) == AML_EXTENDED_OPCODE) &&
439 438 (((u8) opcode) <= MAX_EXTENDED_OPCODE)) {
440 /* Extended (16-bit, prefix+opcode) opcode */ 439 /* Valid extended (16-bit) opcode */
441
442 if (((u8) opcode) <= MAX_EXTENDED_OPCODE) {
443 return (&acpi_gbl_aml_op_info [acpi_gbl_long_op_index [(u8) opcode]]);
444 }
445
446 /* Else fall through to error case below */
447 /*lint -fallthrough */
448
449 default:
450 440
451 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 441 return (&acpi_gbl_aml_op_info [acpi_gbl_long_op_index [(u8) opcode]]);
452 "Unknown AML opcode [%4.4X]\n", opcode));
453 break;
454 } 442 }
455 443
444 /* Unknown AML opcode */
456 445
457 /* Default is "unknown opcode" */ 446 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
447 "Unknown AML opcode [%4.4X]\n", opcode));
458 448
459 return (&acpi_gbl_aml_op_info [_UNK]); 449 return (&acpi_gbl_aml_op_info [_UNK]);
460} 450}
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
index bbfdc1a58c27..16b84a3d0436 100644
--- a/drivers/acpi/parser/psparse.c
+++ b/drivers/acpi/parser/psparse.c
@@ -62,26 +62,6 @@
62 ACPI_MODULE_NAME ("psparse") 62 ACPI_MODULE_NAME ("psparse")
63 63
64 64
65static u32 acpi_gbl_depth = 0;
66
67/* Local prototypes */
68
69static void
70acpi_ps_complete_this_op (
71 struct acpi_walk_state *walk_state,
72 union acpi_parse_object *op);
73
74static acpi_status
75acpi_ps_next_parse_state (
76 struct acpi_walk_state *walk_state,
77 union acpi_parse_object *op,
78 acpi_status callback_status);
79
80static acpi_status
81acpi_ps_parse_loop (
82 struct acpi_walk_state *walk_state);
83
84
85/******************************************************************************* 65/*******************************************************************************
86 * 66 *
87 * FUNCTION: acpi_ps_get_opcode_size 67 * FUNCTION: acpi_ps_get_opcode_size
@@ -134,8 +114,8 @@ acpi_ps_peek_opcode (
134 aml = parser_state->aml; 114 aml = parser_state->aml;
135 opcode = (u16) ACPI_GET8 (aml); 115 opcode = (u16) ACPI_GET8 (aml);
136 116
137 if (opcode == AML_EXTOP) { 117 if (opcode == AML_EXTENDED_OP_PREFIX) {
138 /* Extended opcode */ 118 /* Extended opcode, get the second opcode byte */
139 119
140 aml++; 120 aml++;
141 opcode = (u16) ((opcode << 8) | ACPI_GET8 (aml)); 121 opcode = (u16) ((opcode << 8) | ACPI_GET8 (aml));
@@ -152,13 +132,13 @@ acpi_ps_peek_opcode (
152 * PARAMETERS: walk_state - Current State 132 * PARAMETERS: walk_state - Current State
153 * Op - Op to complete 133 * Op - Op to complete
154 * 134 *
155 * RETURN: None. 135 * RETURN: Status
156 * 136 *
157 * DESCRIPTION: Perform any cleanup at the completion of an Op. 137 * DESCRIPTION: Perform any cleanup at the completion of an Op.
158 * 138 *
159 ******************************************************************************/ 139 ******************************************************************************/
160 140
161static void 141acpi_status
162acpi_ps_complete_this_op ( 142acpi_ps_complete_this_op (
163 struct acpi_walk_state *walk_state, 143 struct acpi_walk_state *walk_state,
164 union acpi_parse_object *op) 144 union acpi_parse_object *op)
@@ -175,19 +155,26 @@ acpi_ps_complete_this_op (
175 /* Check for null Op, can happen if AML code is corrupt */ 155 /* Check for null Op, can happen if AML code is corrupt */
176 156
177 if (!op) { 157 if (!op) {
178 return_VOID; 158 return_ACPI_STATUS (AE_OK); /* OK for now */
179 } 159 }
180 160
181 /* Delete this op and the subtree below it if asked to */ 161 /* Delete this op and the subtree below it if asked to */
182 162
183 if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) != ACPI_PARSE_DELETE_TREE) || 163 if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) != ACPI_PARSE_DELETE_TREE) ||
184 (walk_state->op_info->class == AML_CLASS_ARGUMENT)) { 164 (walk_state->op_info->class == AML_CLASS_ARGUMENT)) {
185 return_VOID; 165 return_ACPI_STATUS (AE_OK);
186 } 166 }
187 167
188 /* Make sure that we only delete this subtree */ 168 /* Make sure that we only delete this subtree */
189 169
190 if (op->common.parent) { 170 if (op->common.parent) {
171 prev = op->common.parent->common.value.arg;
172 if (!prev) {
173 /* Nothing more to do */
174
175 goto cleanup;
176 }
177
191 /* 178 /*
192 * Check if we need to replace the operator and its subtree 179 * Check if we need to replace the operator and its subtree
193 * with a return value op (placeholder op) 180 * with a return value op (placeholder op)
@@ -206,7 +193,7 @@ acpi_ps_complete_this_op (
206 */ 193 */
207 replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP); 194 replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
208 if (!replacement_op) { 195 if (!replacement_op) {
209 goto cleanup; 196 goto allocate_error;
210 } 197 }
211 break; 198 break;
212 199
@@ -223,18 +210,17 @@ acpi_ps_complete_this_op (
223 (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) { 210 (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) {
224 replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP); 211 replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
225 if (!replacement_op) { 212 if (!replacement_op) {
226 goto cleanup; 213 goto allocate_error;
227 } 214 }
228 } 215 }
229 216 else if ((op->common.parent->common.aml_opcode == AML_NAME_OP) &&
230 if ((op->common.parent->common.aml_opcode == AML_NAME_OP) && 217 (walk_state->pass_number <= ACPI_IMODE_LOAD_PASS2)) {
231 (walk_state->descending_callback != acpi_ds_exec_begin_op)) {
232 if ((op->common.aml_opcode == AML_BUFFER_OP) || 218 if ((op->common.aml_opcode == AML_BUFFER_OP) ||
233 (op->common.aml_opcode == AML_PACKAGE_OP) || 219 (op->common.aml_opcode == AML_PACKAGE_OP) ||
234 (op->common.aml_opcode == AML_VAR_PACKAGE_OP)) { 220 (op->common.aml_opcode == AML_VAR_PACKAGE_OP)) {
235 replacement_op = acpi_ps_alloc_op (op->common.aml_opcode); 221 replacement_op = acpi_ps_alloc_op (op->common.aml_opcode);
236 if (!replacement_op) { 222 if (!replacement_op) {
237 goto cleanup; 223 goto allocate_error;
238 } 224 }
239 225
240 replacement_op->named.data = op->named.data; 226 replacement_op->named.data = op->named.data;
@@ -244,15 +230,15 @@ acpi_ps_complete_this_op (
244 break; 230 break;
245 231
246 default: 232 default:
233
247 replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP); 234 replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
248 if (!replacement_op) { 235 if (!replacement_op) {
249 goto cleanup; 236 goto allocate_error;
250 } 237 }
251 } 238 }
252 239
253 /* We must unlink this op from the parent tree */ 240 /* We must unlink this op from the parent tree */
254 241
255 prev = op->common.parent->common.value.arg;
256 if (prev == op) { 242 if (prev == op) {
257 /* This op is the first in the list */ 243 /* This op is the first in the list */
258 244
@@ -298,7 +284,15 @@ cleanup:
298 /* Now we can actually delete the subtree rooted at Op */ 284 /* Now we can actually delete the subtree rooted at Op */
299 285
300 acpi_ps_delete_parse_tree (op); 286 acpi_ps_delete_parse_tree (op);
301 return_VOID; 287 return_ACPI_STATUS (AE_OK);
288
289
290allocate_error:
291
292 /* Always delete the subtree, even on error */
293
294 acpi_ps_delete_parse_tree (op);
295 return_ACPI_STATUS (AE_NO_MEMORY);
302} 296}
303 297
304 298
@@ -317,7 +311,7 @@ cleanup:
317 * 311 *
318 ******************************************************************************/ 312 ******************************************************************************/
319 313
320static acpi_status 314acpi_status
321acpi_ps_next_parse_state ( 315acpi_ps_next_parse_state (
322 struct acpi_walk_state *walk_state, 316 struct acpi_walk_state *walk_state,
323 union acpi_parse_object *op, 317 union acpi_parse_object *op,
@@ -427,663 +421,6 @@ acpi_ps_next_parse_state (
427 421
428/******************************************************************************* 422/*******************************************************************************
429 * 423 *
430 * FUNCTION: acpi_ps_parse_loop
431 *
432 * PARAMETERS: walk_state - Current state
433 *
434 * RETURN: Status
435 *
436 * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
437 * a tree of ops.
438 *
439 ******************************************************************************/
440
441static acpi_status
442acpi_ps_parse_loop (
443 struct acpi_walk_state *walk_state)
444{
445 acpi_status status = AE_OK;
446 union acpi_parse_object *op = NULL; /* current op */
447 union acpi_parse_object *arg = NULL;
448 union acpi_parse_object *pre_op = NULL;
449 struct acpi_parse_state *parser_state;
450 u8 *aml_op_start = NULL;
451
452
453 ACPI_FUNCTION_TRACE_PTR ("ps_parse_loop", walk_state);
454
455 if (walk_state->descending_callback == NULL) {
456 return_ACPI_STATUS (AE_BAD_PARAMETER);
457 }
458
459 parser_state = &walk_state->parser_state;
460 walk_state->arg_types = 0;
461
462#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
463
464 if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) {
465 /* We are restarting a preempted control method */
466
467 if (acpi_ps_has_completed_scope (parser_state)) {
468 /*
469 * We must check if a predicate to an IF or WHILE statement
470 * was just completed
471 */
472 if ((parser_state->scope->parse_scope.op) &&
473 ((parser_state->scope->parse_scope.op->common.aml_opcode == AML_IF_OP) ||
474 (parser_state->scope->parse_scope.op->common.aml_opcode == AML_WHILE_OP)) &&
475 (walk_state->control_state) &&
476 (walk_state->control_state->common.state ==
477 ACPI_CONTROL_PREDICATE_EXECUTING)) {
478 /*
479 * A predicate was just completed, get the value of the
480 * predicate and branch based on that value
481 */
482 walk_state->op = NULL;
483 status = acpi_ds_get_predicate_value (walk_state, ACPI_TO_POINTER (TRUE));
484 if (ACPI_FAILURE (status) &&
485 ((status & AE_CODE_MASK) != AE_CODE_CONTROL)) {
486 if (status == AE_AML_NO_RETURN_VALUE) {
487 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
488 "Invoked method did not return a value, %s\n",
489 acpi_format_exception (status)));
490
491 }
492 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
493 "get_predicate Failed, %s\n",
494 acpi_format_exception (status)));
495 return_ACPI_STATUS (status);
496 }
497
498 status = acpi_ps_next_parse_state (walk_state, op, status);
499 }
500
501 acpi_ps_pop_scope (parser_state, &op,
502 &walk_state->arg_types, &walk_state->arg_count);
503 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op));
504 }
505 else if (walk_state->prev_op) {
506 /* We were in the middle of an op */
507
508 op = walk_state->prev_op;
509 walk_state->arg_types = walk_state->prev_arg_types;
510 }
511 }
512#endif
513
514 /* Iterative parsing loop, while there is more AML to process: */
515
516 while ((parser_state->aml < parser_state->aml_end) || (op)) {
517 aml_op_start = parser_state->aml;
518 if (!op) {
519 /* Get the next opcode from the AML stream */
520
521 walk_state->aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml,
522 parser_state->aml_start);
523 walk_state->opcode = acpi_ps_peek_opcode (parser_state);
524
525 /*
526 * First cut to determine what we have found:
527 * 1) A valid AML opcode
528 * 2) A name string
529 * 3) An unknown/invalid opcode
530 */
531 walk_state->op_info = acpi_ps_get_opcode_info (walk_state->opcode);
532 switch (walk_state->op_info->class) {
533 case AML_CLASS_ASCII:
534 case AML_CLASS_PREFIX:
535 /*
536 * Starts with a valid prefix or ASCII char, this is a name
537 * string. Convert the bare name string to a namepath.
538 */
539 walk_state->opcode = AML_INT_NAMEPATH_OP;
540 walk_state->arg_types = ARGP_NAMESTRING;
541 break;
542
543 case AML_CLASS_UNKNOWN:
544
545 /* The opcode is unrecognized. Just skip unknown opcodes */
546
547 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
548 "Found unknown opcode %X at AML address %p offset %X, ignoring\n",
549 walk_state->opcode, parser_state->aml, walk_state->aml_offset));
550
551 ACPI_DUMP_BUFFER (parser_state->aml, 128);
552
553 /* Assume one-byte bad opcode */
554
555 parser_state->aml++;
556 continue;
557
558 default:
559
560 /* Found opcode info, this is a normal opcode */
561
562 parser_state->aml += acpi_ps_get_opcode_size (walk_state->opcode);
563 walk_state->arg_types = walk_state->op_info->parse_args;
564 break;
565 }
566
567 /* Create Op structure and append to parent's argument list */
568
569 if (walk_state->op_info->flags & AML_NAMED) {
570 /* Allocate a new pre_op if necessary */
571
572 if (!pre_op) {
573 pre_op = acpi_ps_alloc_op (walk_state->opcode);
574 if (!pre_op) {
575 status = AE_NO_MEMORY;
576 goto close_this_op;
577 }
578 }
579
580 pre_op->common.value.arg = NULL;
581 pre_op->common.aml_opcode = walk_state->opcode;
582
583 /*
584 * Get and append arguments until we find the node that contains
585 * the name (the type ARGP_NAME).
586 */
587 while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) &&
588 (GET_CURRENT_ARG_TYPE (walk_state->arg_types) != ARGP_NAME)) {
589 status = acpi_ps_get_next_arg (walk_state, parser_state,
590 GET_CURRENT_ARG_TYPE (walk_state->arg_types), &arg);
591 if (ACPI_FAILURE (status)) {
592 goto close_this_op;
593 }
594
595 acpi_ps_append_arg (pre_op, arg);
596 INCREMENT_ARG_LIST (walk_state->arg_types);
597 }
598
599 /*
600 * Make sure that we found a NAME and didn't run out of
601 * arguments
602 */
603 if (!GET_CURRENT_ARG_TYPE (walk_state->arg_types)) {
604 status = AE_AML_NO_OPERAND;
605 goto close_this_op;
606 }
607
608 /* We know that this arg is a name, move to next arg */
609
610 INCREMENT_ARG_LIST (walk_state->arg_types);
611
612 /*
613 * Find the object. This will either insert the object into
614 * the namespace or simply look it up
615 */
616 walk_state->op = NULL;
617
618 status = walk_state->descending_callback (walk_state, &op);
619 if (ACPI_FAILURE (status)) {
620 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
621 "During name lookup/catalog, %s\n",
622 acpi_format_exception (status)));
623 goto close_this_op;
624 }
625
626 if (!op) {
627 continue;
628 }
629
630 status = acpi_ps_next_parse_state (walk_state, op, status);
631 if (status == AE_CTRL_PENDING) {
632 status = AE_OK;
633 goto close_this_op;
634 }
635
636 if (ACPI_FAILURE (status)) {
637 goto close_this_op;
638 }
639
640 acpi_ps_append_arg (op, pre_op->common.value.arg);
641 acpi_gbl_depth++;
642
643 if (op->common.aml_opcode == AML_REGION_OP) {
644 /*
645 * Defer final parsing of an operation_region body,
646 * because we don't have enough info in the first pass
647 * to parse it correctly (i.e., there may be method
648 * calls within the term_arg elements of the body.)
649 *
650 * However, we must continue parsing because
651 * the opregion is not a standalone package --
652 * we don't know where the end is at this point.
653 *
654 * (Length is unknown until parse of the body complete)
655 */
656 op->named.data = aml_op_start;
657 op->named.length = 0;
658 }
659 }
660 else {
661 /* Not a named opcode, just allocate Op and append to parent */
662
663 walk_state->op_info = acpi_ps_get_opcode_info (walk_state->opcode);
664 op = acpi_ps_alloc_op (walk_state->opcode);
665 if (!op) {
666 status = AE_NO_MEMORY;
667 goto close_this_op;
668 }
669
670 if (walk_state->op_info->flags & AML_CREATE) {
671 /*
672 * Backup to beginning of create_xXXfield declaration
673 * body_length is unknown until we parse the body
674 */
675 op->named.data = aml_op_start;
676 op->named.length = 0;
677 }
678
679 acpi_ps_append_arg (acpi_ps_get_parent_scope (parser_state), op);
680
681 if ((walk_state->descending_callback != NULL)) {
682 /*
683 * Find the object. This will either insert the object into
684 * the namespace or simply look it up
685 */
686 walk_state->op = op;
687
688 status = walk_state->descending_callback (walk_state, &op);
689 status = acpi_ps_next_parse_state (walk_state, op, status);
690 if (status == AE_CTRL_PENDING) {
691 status = AE_OK;
692 goto close_this_op;
693 }
694
695 if (ACPI_FAILURE (status)) {
696 goto close_this_op;
697 }
698 }
699 }
700
701 op->common.aml_offset = walk_state->aml_offset;
702
703 if (walk_state->op_info) {
704 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
705 "Opcode %4.4X [%s] Op %p Aml %p aml_offset %5.5X\n",
706 (u32) op->common.aml_opcode, walk_state->op_info->name,
707 op, parser_state->aml, op->common.aml_offset));
708 }
709 }
710
711
712 /*
713 * Start arg_count at zero because we don't know if there are
714 * any args yet
715 */
716 walk_state->arg_count = 0;
717
718 /* Are there any arguments that must be processed? */
719
720 if (walk_state->arg_types) {
721 /* Get arguments */
722
723 switch (op->common.aml_opcode) {
724 case AML_BYTE_OP: /* AML_BYTEDATA_ARG */
725 case AML_WORD_OP: /* AML_WORDDATA_ARG */
726 case AML_DWORD_OP: /* AML_DWORDATA_ARG */
727 case AML_QWORD_OP: /* AML_QWORDATA_ARG */
728 case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */
729
730 /* Fill in constant or string argument directly */
731
732 acpi_ps_get_next_simple_arg (parser_state,
733 GET_CURRENT_ARG_TYPE (walk_state->arg_types), op);
734 break;
735
736 case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */
737
738 status = acpi_ps_get_next_namepath (walk_state, parser_state, op, 1);
739 if (ACPI_FAILURE (status)) {
740 goto close_this_op;
741 }
742
743 walk_state->arg_types = 0;
744 break;
745
746 default:
747
748 /*
749 * Op is not a constant or string, append each argument
750 * to the Op
751 */
752 while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) &&
753 !walk_state->arg_count) {
754 walk_state->aml_offset = (u32)
755 ACPI_PTR_DIFF (parser_state->aml, parser_state->aml_start);
756
757 status = acpi_ps_get_next_arg (walk_state, parser_state,
758 GET_CURRENT_ARG_TYPE (walk_state->arg_types),
759 &arg);
760 if (ACPI_FAILURE (status)) {
761 goto close_this_op;
762 }
763
764 if (arg) {
765 arg->common.aml_offset = walk_state->aml_offset;
766 acpi_ps_append_arg (op, arg);
767 }
768 INCREMENT_ARG_LIST (walk_state->arg_types);
769 }
770
771 /* Special processing for certain opcodes */
772
773 switch (op->common.aml_opcode) {
774 case AML_METHOD_OP:
775
776 /*
777 * Skip parsing of control method
778 * because we don't have enough info in the first pass
779 * to parse it correctly.
780 *
781 * Save the length and address of the body
782 */
783 op->named.data = parser_state->aml;
784 op->named.length = (u32) (parser_state->pkg_end -
785 parser_state->aml);
786
787 /* Skip body of method */
788
789 parser_state->aml = parser_state->pkg_end;
790 walk_state->arg_count = 0;
791 break;
792
793 case AML_BUFFER_OP:
794 case AML_PACKAGE_OP:
795 case AML_VAR_PACKAGE_OP:
796
797 if ((op->common.parent) &&
798 (op->common.parent->common.aml_opcode == AML_NAME_OP) &&
799 (walk_state->descending_callback != acpi_ds_exec_begin_op)) {
800 /*
801 * Skip parsing of Buffers and Packages
802 * because we don't have enough info in the first pass
803 * to parse them correctly.
804 */
805 op->named.data = aml_op_start;
806 op->named.length = (u32) (parser_state->pkg_end -
807 aml_op_start);
808
809 /* Skip body */
810
811 parser_state->aml = parser_state->pkg_end;
812 walk_state->arg_count = 0;
813 }
814 break;
815
816 case AML_WHILE_OP:
817
818 if (walk_state->control_state) {
819 walk_state->control_state->control.package_end =
820 parser_state->pkg_end;
821 }
822 break;
823
824 default:
825
826 /* No action for all other opcodes */
827 break;
828 }
829 break;
830 }
831 }
832
833 /* Check for arguments that need to be processed */
834
835 if (walk_state->arg_count) {
836 /*
837 * There are arguments (complex ones), push Op and
838 * prepare for argument
839 */
840 status = acpi_ps_push_scope (parser_state, op,
841 walk_state->arg_types, walk_state->arg_count);
842 if (ACPI_FAILURE (status)) {
843 goto close_this_op;
844 }
845 op = NULL;
846 continue;
847 }
848
849 /*
850 * All arguments have been processed -- Op is complete,
851 * prepare for next
852 */
853 walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
854 if (walk_state->op_info->flags & AML_NAMED) {
855 if (acpi_gbl_depth) {
856 acpi_gbl_depth--;
857 }
858
859 if (op->common.aml_opcode == AML_REGION_OP) {
860 /*
861 * Skip parsing of control method or opregion body,
862 * because we don't have enough info in the first pass
863 * to parse them correctly.
864 *
865 * Completed parsing an op_region declaration, we now
866 * know the length.
867 */
868 op->named.length = (u32) (parser_state->aml - op->named.data);
869 }
870 }
871
872 if (walk_state->op_info->flags & AML_CREATE) {
873 /*
874 * Backup to beginning of create_xXXfield declaration (1 for
875 * Opcode)
876 *
877 * body_length is unknown until we parse the body
878 */
879 op->named.length = (u32) (parser_state->aml - op->named.data);
880 }
881
882 /* This op complete, notify the dispatcher */
883
884 if (walk_state->ascending_callback != NULL) {
885 walk_state->op = op;
886 walk_state->opcode = op->common.aml_opcode;
887
888 status = walk_state->ascending_callback (walk_state);
889 status = acpi_ps_next_parse_state (walk_state, op, status);
890 if (status == AE_CTRL_PENDING) {
891 status = AE_OK;
892 goto close_this_op;
893 }
894 }
895
896
897close_this_op:
898 /*
899 * Finished one argument of the containing scope
900 */
901 parser_state->scope->parse_scope.arg_count--;
902
903 /* Close this Op (will result in parse subtree deletion) */
904
905 acpi_ps_complete_this_op (walk_state, op);
906 op = NULL;
907 if (pre_op) {
908 acpi_ps_free_op (pre_op);
909 pre_op = NULL;
910 }
911
912 switch (status) {
913 case AE_OK:
914 break;
915
916
917 case AE_CTRL_TRANSFER:
918
919 /* We are about to transfer to a called method. */
920
921 walk_state->prev_op = op;
922 walk_state->prev_arg_types = walk_state->arg_types;
923 return_ACPI_STATUS (status);
924
925
926 case AE_CTRL_END:
927
928 acpi_ps_pop_scope (parser_state, &op,
929 &walk_state->arg_types, &walk_state->arg_count);
930
931 if (op) {
932 walk_state->op = op;
933 walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
934 walk_state->opcode = op->common.aml_opcode;
935
936 status = walk_state->ascending_callback (walk_state);
937 status = acpi_ps_next_parse_state (walk_state, op, status);
938
939 acpi_ps_complete_this_op (walk_state, op);
940 op = NULL;
941 }
942 status = AE_OK;
943 break;
944
945
946 case AE_CTRL_BREAK:
947 case AE_CTRL_CONTINUE:
948
949 /* Pop off scopes until we find the While */
950
951 while (!op || (op->common.aml_opcode != AML_WHILE_OP)) {
952 acpi_ps_pop_scope (parser_state, &op,
953 &walk_state->arg_types, &walk_state->arg_count);
954 }
955
956 /* Close this iteration of the While loop */
957
958 walk_state->op = op;
959 walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
960 walk_state->opcode = op->common.aml_opcode;
961
962 status = walk_state->ascending_callback (walk_state);
963 status = acpi_ps_next_parse_state (walk_state, op, status);
964
965 acpi_ps_complete_this_op (walk_state, op);
966 op = NULL;
967
968 status = AE_OK;
969 break;
970
971
972 case AE_CTRL_TERMINATE:
973
974 status = AE_OK;
975
976 /* Clean up */
977 do {
978 if (op) {
979 acpi_ps_complete_this_op (walk_state, op);
980 }
981 acpi_ps_pop_scope (parser_state, &op,
982 &walk_state->arg_types, &walk_state->arg_count);
983
984 } while (op);
985
986 return_ACPI_STATUS (status);
987
988
989 default: /* All other non-AE_OK status */
990
991 do {
992 if (op) {
993 acpi_ps_complete_this_op (walk_state, op);
994 }
995 acpi_ps_pop_scope (parser_state, &op,
996 &walk_state->arg_types, &walk_state->arg_count);
997
998 } while (op);
999
1000
1001 /*
1002 * TBD: Cleanup parse ops on error
1003 */
1004#if 0
1005 if (op == NULL) {
1006 acpi_ps_pop_scope (parser_state, &op,
1007 &walk_state->arg_types, &walk_state->arg_count);
1008 }
1009#endif
1010 walk_state->prev_op = op;
1011 walk_state->prev_arg_types = walk_state->arg_types;
1012 return_ACPI_STATUS (status);
1013 }
1014
1015 /* This scope complete? */
1016
1017 if (acpi_ps_has_completed_scope (parser_state)) {
1018 acpi_ps_pop_scope (parser_state, &op,
1019 &walk_state->arg_types, &walk_state->arg_count);
1020 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op));
1021 }
1022 else {
1023 op = NULL;
1024 }
1025
1026 } /* while parser_state->Aml */
1027
1028
1029 /*
1030 * Complete the last Op (if not completed), and clear the scope stack.
1031 * It is easily possible to end an AML "package" with an unbounded number
1032 * of open scopes (such as when several ASL blocks are closed with
1033 * sequential closing braces). We want to terminate each one cleanly.
1034 */
1035 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", op));
1036 do {
1037 if (op) {
1038 if (walk_state->ascending_callback != NULL) {
1039 walk_state->op = op;
1040 walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
1041 walk_state->opcode = op->common.aml_opcode;
1042
1043 status = walk_state->ascending_callback (walk_state);
1044 status = acpi_ps_next_parse_state (walk_state, op, status);
1045 if (status == AE_CTRL_PENDING) {
1046 status = AE_OK;
1047 goto close_this_op;
1048 }
1049
1050 if (status == AE_CTRL_TERMINATE) {
1051 status = AE_OK;
1052
1053 /* Clean up */
1054 do {
1055 if (op) {
1056 acpi_ps_complete_this_op (walk_state, op);
1057 }
1058
1059 acpi_ps_pop_scope (parser_state, &op,
1060 &walk_state->arg_types, &walk_state->arg_count);
1061
1062 } while (op);
1063
1064 return_ACPI_STATUS (status);
1065 }
1066
1067 else if (ACPI_FAILURE (status)) {
1068 acpi_ps_complete_this_op (walk_state, op);
1069 return_ACPI_STATUS (status);
1070 }
1071 }
1072
1073 acpi_ps_complete_this_op (walk_state, op);
1074 }
1075
1076 acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types,
1077 &walk_state->arg_count);
1078
1079 } while (op);
1080
1081 return_ACPI_STATUS (status);
1082}
1083
1084
1085/*******************************************************************************
1086 *
1087 * FUNCTION: acpi_ps_parse_aml 424 * FUNCTION: acpi_ps_parse_aml
1088 * 425 *
1089 * PARAMETERS: walk_state - Current state 426 * PARAMETERS: walk_state - Current state
diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c
index a10f88715d43..4221b41ae1a6 100644
--- a/drivers/acpi/parser/psutils.c
+++ b/drivers/acpi/parser/psutils.c
@@ -154,12 +154,14 @@ acpi_ps_alloc_op (
154 if (flags == ACPI_PARSEOP_GENERIC) { 154 if (flags == ACPI_PARSEOP_GENERIC) {
155 /* The generic op (default) is by far the most common (16 to 1) */ 155 /* The generic op (default) is by far the most common (16 to 1) */
156 156
157 op = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_PSNODE); 157 op = acpi_os_acquire_object (acpi_gbl_ps_node_cache);
158 memset(op, 0, sizeof(struct acpi_parse_obj_common));
158 } 159 }
159 else { 160 else {
160 /* Extended parseop */ 161 /* Extended parseop */
161 162
162 op = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_PSNODE_EXT); 163 op = acpi_os_acquire_object (acpi_gbl_ps_node_ext_cache);
164 memset(op, 0, sizeof(struct acpi_parse_obj_named));
163 } 165 }
164 166
165 /* Initialize the Op */ 167 /* Initialize the Op */
@@ -198,41 +200,14 @@ acpi_ps_free_op (
198 } 200 }
199 201
200 if (op->common.flags & ACPI_PARSEOP_GENERIC) { 202 if (op->common.flags & ACPI_PARSEOP_GENERIC) {
201 acpi_ut_release_to_cache (ACPI_MEM_LIST_PSNODE, op); 203 (void) acpi_os_release_object (acpi_gbl_ps_node_cache, op);
202 } 204 }
203 else { 205 else {
204 acpi_ut_release_to_cache (ACPI_MEM_LIST_PSNODE_EXT, op); 206 (void) acpi_os_release_object (acpi_gbl_ps_node_ext_cache, op);
205 } 207 }
206} 208}
207 209
208 210
209#ifdef ACPI_ENABLE_OBJECT_CACHE
210/*******************************************************************************
211 *
212 * FUNCTION: acpi_ps_delete_parse_cache
213 *
214 * PARAMETERS: None
215 *
216 * RETURN: None
217 *
218 * DESCRIPTION: Free all objects that are on the parse cache list.
219 *
220 ******************************************************************************/
221
222void
223acpi_ps_delete_parse_cache (
224 void)
225{
226 ACPI_FUNCTION_TRACE ("ps_delete_parse_cache");
227
228
229 acpi_ut_delete_generic_cache (ACPI_MEM_LIST_PSNODE);
230 acpi_ut_delete_generic_cache (ACPI_MEM_LIST_PSNODE_EXT);
231 return_VOID;
232}
233#endif
234
235
236/******************************************************************************* 211/*******************************************************************************
237 * 212 *
238 * FUNCTION: Utility functions 213 * FUNCTION: Utility functions
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
index dba893648e84..d1541fabaf0a 100644
--- a/drivers/acpi/parser/psxface.c
+++ b/drivers/acpi/parser/psxface.c
@@ -46,19 +46,30 @@
46#include <acpi/acparser.h> 46#include <acpi/acparser.h>
47#include <acpi/acdispat.h> 47#include <acpi/acdispat.h>
48#include <acpi/acinterp.h> 48#include <acpi/acinterp.h>
49#include <acpi/acnamesp.h>
50 49
51 50
52#define _COMPONENT ACPI_PARSER 51#define _COMPONENT ACPI_PARSER
53 ACPI_MODULE_NAME ("psxface") 52 ACPI_MODULE_NAME ("psxface")
54 53
54/* Local Prototypes */
55
56static acpi_status
57acpi_ps_execute_pass (
58 struct acpi_parameter_info *info);
59
60static void
61acpi_ps_update_parameter_list (
62 struct acpi_parameter_info *info,
63 u16 action);
64
55 65
56/******************************************************************************* 66/*******************************************************************************
57 * 67 *
58 * FUNCTION: acpi_psx_execute 68 * FUNCTION: acpi_ps_execute_method
59 * 69 *
60 * PARAMETERS: Info - Method info block, contains: 70 * PARAMETERS: Info - Method info block, contains:
61 * Node - Method Node to execute 71 * Node - Method Node to execute
72 * obj_desc - Method object
62 * Parameters - List of parameters to pass to the method, 73 * Parameters - List of parameters to pass to the method,
63 * terminated by NULL. Params itself may be 74 * terminated by NULL. Params itself may be
64 * NULL if no parameters are being passed. 75 * NULL if no parameters are being passed.
@@ -67,6 +78,7 @@
67 * parameter_type - Type of Parameter list 78 * parameter_type - Type of Parameter list
68 * return_object - Where to put method's return value (if 79 * return_object - Where to put method's return value (if
69 * any). If NULL, no value is returned. 80 * any). If NULL, no value is returned.
81 * pass_number - Parse or execute pass
70 * 82 *
71 * RETURN: Status 83 * RETURN: Status
72 * 84 *
@@ -75,171 +87,194 @@
75 ******************************************************************************/ 87 ******************************************************************************/
76 88
77acpi_status 89acpi_status
78acpi_psx_execute ( 90acpi_ps_execute_method (
79 struct acpi_parameter_info *info) 91 struct acpi_parameter_info *info)
80{ 92{
81 acpi_status status; 93 acpi_status status;
82 union acpi_operand_object *obj_desc;
83 u32 i;
84 union acpi_parse_object *op;
85 struct acpi_walk_state *walk_state;
86 94
87 95
88 ACPI_FUNCTION_TRACE ("psx_execute"); 96 ACPI_FUNCTION_TRACE ("ps_execute_method");
89 97
90 98
91 /* Validate the Node and get the attached object */ 99 /* Validate the Info and method Node */
92 100
93 if (!info || !info->node) { 101 if (!info || !info->node) {
94 return_ACPI_STATUS (AE_NULL_ENTRY); 102 return_ACPI_STATUS (AE_NULL_ENTRY);
95 } 103 }
96 104
97 obj_desc = acpi_ns_get_attached_object (info->node);
98 if (!obj_desc) {
99 return_ACPI_STATUS (AE_NULL_OBJECT);
100 }
101
102 /* Init for new method, wait on concurrency semaphore */ 105 /* Init for new method, wait on concurrency semaphore */
103 106
104 status = acpi_ds_begin_method_execution (info->node, obj_desc, NULL); 107 status = acpi_ds_begin_method_execution (info->node, info->obj_desc, NULL);
105 if (ACPI_FAILURE (status)) { 108 if (ACPI_FAILURE (status)) {
106 return_ACPI_STATUS (status); 109 return_ACPI_STATUS (status);
107 } 110 }
108 111
109 if ((info->parameter_type == ACPI_PARAM_ARGS) &&
110 (info->parameters)) {
111 /*
112 * The caller "owns" the parameters, so give each one an extra
113 * reference
114 */
115 for (i = 0; info->parameters[i]; i++) {
116 acpi_ut_add_reference (info->parameters[i]);
117 }
118 }
119
120 /*
121 * 1) Perform the first pass parse of the method to enter any
122 * named objects that it creates into the namespace
123 */
124 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
125 "**** Begin Method Parse **** Entry=%p obj=%p\n",
126 info->node, obj_desc));
127
128 /* Create and init a Root Node */
129
130 op = acpi_ps_create_scope_op ();
131 if (!op) {
132 status = AE_NO_MEMORY;
133 goto cleanup1;
134 }
135
136 /* 112 /*
137 * Get a new owner_id for objects created by this method. Namespace 113 * Get a new owner_id for objects created by this method. Namespace
138 * objects (such as Operation Regions) can be created during the 114 * objects (such as Operation Regions) can be created during the
139 * first pass parse. 115 * first pass parse.
140 */ 116 */
141 obj_desc->method.owning_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD); 117 status = acpi_ut_allocate_owner_id (&info->obj_desc->method.owner_id);
142
143 /* Create and initialize a new walk state */
144
145 walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id,
146 NULL, NULL, NULL);
147 if (!walk_state) {
148 status = AE_NO_MEMORY;
149 goto cleanup2;
150 }
151
152 status = acpi_ds_init_aml_walk (walk_state, op, info->node,
153 obj_desc->method.aml_start,
154 obj_desc->method.aml_length, NULL, 1);
155 if (ACPI_FAILURE (status)) { 118 if (ACPI_FAILURE (status)) {
156 goto cleanup3; 119 return_ACPI_STATUS (status);
157 } 120 }
158 121
159 /* Parse the AML */ 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);
160 127
161 status = acpi_ps_parse_aml (walk_state); 128 /*
162 acpi_ps_delete_parse_tree (op); 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));
135
136 info->pass_number = 1;
137 status = acpi_ps_execute_pass (info);
163 if (ACPI_FAILURE (status)) { 138 if (ACPI_FAILURE (status)) {
164 goto cleanup1; /* Walk state is already deleted */ 139 goto cleanup;
165 } 140 }
166 141
167 /* 142 /*
168 * 2) Execute the method. Performs second pass parse simultaneously 143 * 2) Execute the method. Performs second pass parse simultaneously
169 */ 144 */
170 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 145 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
171 "**** Begin Method Execution **** Entry=%p obj=%p\n", 146 "**** Begin Method Execution **** Entry=%p obj=%p\n",
172 info->node, obj_desc)); 147 info->node, info->obj_desc));
173 148
174 /* Create and init a Root Node */ 149 info->pass_number = 3;
150 status = acpi_ps_execute_pass (info);
175 151
176 op = acpi_ps_create_scope_op (); 152
177 if (!op) { 153cleanup:
178 status = AE_NO_MEMORY; 154 if (info->obj_desc->method.owner_id) {
179 goto cleanup1; 155 acpi_ut_release_owner_id (&info->obj_desc->method.owner_id);
180 } 156 }
181 157
182 /* Init new op with the method name and pointer back to the NS node */ 158 /* Take away the extra reference that we gave the parameters above */
183 159
184 acpi_ps_set_name (op, info->node->name.integer); 160 acpi_ps_update_parameter_list (info, REF_DECREMENT);
185 op->common.node = info->node;
186 161
187 /* Create and initialize a new walk state */ 162 /* Exit now if error above */
188 163
189 walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); 164 if (ACPI_FAILURE (status)) {
190 if (!walk_state) { 165 return_ACPI_STATUS (status);
191 status = AE_NO_MEMORY;
192 goto cleanup2;
193 } 166 }
194 167
195 status = acpi_ds_init_aml_walk (walk_state, op, info->node, 168 /*
196 obj_desc->method.aml_start, 169 * If the method has returned an object, signal this to the caller with
197 obj_desc->method.aml_length, info, 3); 170 * a control exception code
198 if (ACPI_FAILURE (status)) { 171 */
199 goto cleanup3; 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;
200 } 178 }
201 179
202 /* The walk of the parse tree is where we actually execute the method */ 180 return_ACPI_STATUS (status);
181}
203 182
204 status = acpi_ps_parse_aml (walk_state);
205 goto cleanup2; /* Walk state already deleted */
206 183
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 ******************************************************************************/
207 197
208cleanup3: 198static void
209 acpi_ds_delete_walk_state (walk_state); 199acpi_ps_update_parameter_list (
200 struct acpi_parameter_info *info,
201 u16 action)
202{
203 acpi_native_uint i;
210 204
211cleanup2:
212 acpi_ps_delete_parse_tree (op);
213 205
214cleanup1:
215 if ((info->parameter_type == ACPI_PARAM_ARGS) && 206 if ((info->parameter_type == ACPI_PARAM_ARGS) &&
216 (info->parameters)) { 207 (info->parameters)) {
217 /* Take away the extra reference that we gave the parameters above */ 208 /* Update reference count for each parameter */
218 209
219 for (i = 0; info->parameters[i]; i++) { 210 for (i = 0; info->parameters[i]; i++) {
220 /* Ignore errors, just do them all */ 211 /* Ignore errors, just do them all */
221 212
222 (void) acpi_ut_update_object_reference ( 213 (void) acpi_ut_update_object_reference (info->parameters[i], action);
223 info->parameters[i], REF_DECREMENT);
224 } 214 }
225 } 215 }
216}
226 217
227 if (ACPI_FAILURE (status)) { 218
228 return_ACPI_STATUS (status); 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
232static acpi_status
233acpi_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);
229 } 249 }
230 250
231 /* 251 /* Create and initialize a new walk state */
232 * If the method has returned an object, signal this to the caller with
233 * a control exception code
234 */
235 if (info->return_object) {
236 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned obj_desc=%p\n",
237 info->return_object));
238 ACPI_DUMP_STACK_ENTRY (info->return_object);
239 252
240 status = AE_CTRL_RETURN_VALUE; 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;
241 } 268 }
242 269
270 /* Parse the AML */
271
272 status = acpi_ps_parse_aml (walk_state);
273
274 /* Walk state was deleted by parse_aml */
275
276cleanup:
277 acpi_ps_delete_parse_tree (op);
243 return_ACPI_STATUS (status); 278 return_ACPI_STATUS (status);
244} 279}
245 280