:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / drivers / bus / acpi / parser / psxface.c
1 /******************************************************************************
2  *
3  * Module Name: psxface - Parser external interfaces
4  *              $Revision$
5  *
6  *****************************************************************************/
7
8 /*
9  *  Copyright (C) 2000, 2001 R. Byron Moore
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  */
25
26
27 #include "acpi.h"
28 #include "acparser.h"
29 #include "acdispat.h"
30 #include "acinterp.h"
31 #include "amlcode.h"
32 #include "acnamesp.h"
33
34
35 #define _COMPONENT          ACPI_PARSER
36          MODULE_NAME         ("psxface")
37
38
39 /*****************************************************************************
40  *
41  * FUNCTION:    Acpi_psx_execute
42  *
43  * PARAMETERS:  Method_node         - A method object containing both the AML
44  *                                    address and length.
45  *              **Params            - List of parameters to pass to method,
46  *                                    terminated by NULL. Params itself may be
47  *                                    NULL if no parameters are being passed.
48  *              **Return_obj_desc   - Return object from execution of the
49  *                                    method.
50  *
51  * RETURN:      Status
52  *
53  * DESCRIPTION: Execute a control method
54  *
55  ****************************************************************************/
56
57 ACPI_STATUS
58 acpi_psx_execute (
59         ACPI_NAMESPACE_NODE     *method_node,
60         ACPI_OPERAND_OBJECT     **params,
61         ACPI_OPERAND_OBJECT     **return_obj_desc)
62 {
63         ACPI_STATUS             status;
64         ACPI_OPERAND_OBJECT     *obj_desc;
65         u32                     i;
66         ACPI_PARSE_OBJECT       *op;
67
68
69         /* Validate the Node and get the attached object */
70
71         if (!method_node) {
72                 return (AE_NULL_ENTRY);
73         }
74
75         obj_desc = acpi_ns_get_attached_object (method_node);
76         if (!obj_desc) {
77                 return (AE_NULL_OBJECT);
78         }
79
80         /* Init for new method, wait on concurrency semaphore */
81
82         status = acpi_ds_begin_method_execution (method_node, obj_desc, NULL);
83         if (ACPI_FAILURE (status)) {
84                 return (status);
85         }
86
87         if (params) {
88                 /*
89                  * The caller "owns" the parameters, so give each one an extra
90                  * reference
91                  */
92
93                 for (i = 0; params[i]; i++) {
94                         acpi_cm_add_reference (params[i]);
95                 }
96         }
97
98         /*
99          * Perform the first pass parse of the method to enter any
100          * named objects that it creates into the namespace
101          */
102
103         /* Create and init a Root Node */
104
105         op = acpi_ps_alloc_op (AML_SCOPE_OP);
106         if (!op) {
107                 return (AE_NO_MEMORY);
108         }
109
110         status = acpi_ps_parse_aml (op, obj_desc->method.pcode,
111                           obj_desc->method.pcode_length,
112                           ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE,
113                           method_node, params, return_obj_desc,
114                           acpi_ds_load1_begin_op, acpi_ds_load1_end_op);
115         acpi_ps_delete_parse_tree (op);
116
117         /* Create and init a Root Node */
118
119         op = acpi_ps_alloc_op (AML_SCOPE_OP);
120         if (!op) {
121                 return (AE_NO_MEMORY);
122         }
123
124
125         /* Init new op with the method name and pointer back to the NS node */
126
127         acpi_ps_set_name (op, method_node->name);
128         op->node = method_node;
129
130         /*
131          * The walk of the parse tree is where we actually execute the method
132          */
133         status = acpi_ps_parse_aml (op, obj_desc->method.pcode,
134                           obj_desc->method.pcode_length,
135                           ACPI_PARSE_EXECUTE | ACPI_PARSE_DELETE_TREE,
136                           method_node, params, return_obj_desc,
137                           acpi_ds_exec_begin_op, acpi_ds_exec_end_op);
138         acpi_ps_delete_parse_tree (op);
139
140         if (params) {
141                 /* Take away the extra reference that we gave the parameters above */
142
143                 for (i = 0; params[i]; i++) {
144                         acpi_cm_update_object_reference (params[i], REF_DECREMENT);
145                 }
146         }
147
148
149         /*
150          * Normal exit is with Status == AE_RETURN_VALUE when a Return_op has been
151          * executed, or with Status == AE_PENDING at end of AML block (end of
152          * Method code)
153          */
154
155         if (*return_obj_desc) {
156                 status = AE_CTRL_RETURN_VALUE;
157         }
158
159
160         return (status);
161 }
162
163