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