blob: 80c67f2d3dd214e53b04d3667482be048e102d4f [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/******************************************************************************
2 *
3 * Module Name: psxface - Parser external interfaces
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
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#include <acpi/acpi.h>
45#include <acpi/acparser.h>
46#include <acpi/acdispat.h>
47#include <acpi/acinterp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
Linus Torvalds1da177e2005-04-16 15:20:36 -070049#define _COMPONENT ACPI_PARSER
Len Brown4be44fc2005-08-05 00:44:28 -040050ACPI_MODULE_NAME("psxface")
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
Robert Moore0c9938c2005-07-29 15:15:00 -070052/* Local Prototypes */
Len Brown4be44fc2005-08-05 00:44:28 -040053static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info);
Robert Moore0c9938c2005-07-29 15:15:00 -070054
55static void
Len Brown4be44fc2005-08-05 00:44:28 -040056acpi_ps_update_parameter_list(struct acpi_parameter_info *info, u16 action);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
58/*******************************************************************************
59 *
Robert Moore0c9938c2005-07-29 15:15:00 -070060 * FUNCTION: acpi_ps_execute_method
Linus Torvalds1da177e2005-04-16 15:20:36 -070061 *
Robert Moore44f6c012005-04-18 22:49:35 -040062 * PARAMETERS: Info - Method info block, contains:
63 * Node - Method Node to execute
Robert Moore0c9938c2005-07-29 15:15:00 -070064 * obj_desc - Method object
Robert Moore44f6c012005-04-18 22:49:35 -040065 * Parameters - List of parameters to pass to the method,
Linus Torvalds1da177e2005-04-16 15:20:36 -070066 * terminated by NULL. Params itself may be
67 * NULL if no parameters are being passed.
Robert Moore44f6c012005-04-18 22:49:35 -040068 * return_object - Where to put method's return value (if
69 * any). If NULL, no value is returned.
70 * parameter_type - Type of Parameter list
71 * return_object - Where to put method's return value (if
72 * any). If NULL, no value is returned.
Robert Moore0c9938c2005-07-29 15:15:00 -070073 * pass_number - Parse or execute pass
Linus Torvalds1da177e2005-04-16 15:20:36 -070074 *
75 * RETURN: Status
76 *
77 * DESCRIPTION: Execute a control method
78 *
79 ******************************************************************************/
80
Len Brown4be44fc2005-08-05 00:44:28 -040081acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -070082{
Len Brown4be44fc2005-08-05 00:44:28 -040083 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -070084
Len Brown4be44fc2005-08-05 00:44:28 -040085 ACPI_FUNCTION_TRACE("ps_execute_method");
Linus Torvalds1da177e2005-04-16 15:20:36 -070086
Robert Moore0c9938c2005-07-29 15:15:00 -070087 /* Validate the Info and method Node */
Linus Torvalds1da177e2005-04-16 15:20:36 -070088
89 if (!info || !info->node) {
Len Brown4be44fc2005-08-05 00:44:28 -040090 return_ACPI_STATUS(AE_NULL_ENTRY);
Linus Torvalds1da177e2005-04-16 15:20:36 -070091 }
92
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 /* Init for new method, wait on concurrency semaphore */
94
Len Brown4be44fc2005-08-05 00:44:28 -040095 status =
96 acpi_ds_begin_method_execution(info->node, info->obj_desc, NULL);
97 if (ACPI_FAILURE(status)) {
98 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 }
100
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101 /*
102 * Get a new owner_id for objects created by this method. Namespace
103 * objects (such as Operation Regions) can be created during the
104 * first pass parse.
105 */
Len Brown4be44fc2005-08-05 00:44:28 -0400106 status = acpi_ut_allocate_owner_id(&info->obj_desc->method.owner_id);
107 if (ACPI_FAILURE(status)) {
108 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109 }
110
111 /*
Robert Moore0c9938c2005-07-29 15:15:00 -0700112 * The caller "owns" the parameters, so give each one an extra
113 * reference
114 */
Len Brown4be44fc2005-08-05 00:44:28 -0400115 acpi_ps_update_parameter_list(info, REF_INCREMENT);
Robert Moore0c9938c2005-07-29 15:15:00 -0700116
117 /*
118 * 1) Perform the first pass parse of the method to enter any
119 * named objects that it creates into the namespace
120 */
Len Brown4be44fc2005-08-05 00:44:28 -0400121 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
122 "**** Begin Method Parse **** Entry=%p obj=%p\n",
123 info->node, info->obj_desc));
Robert Moore0c9938c2005-07-29 15:15:00 -0700124
125 info->pass_number = 1;
Len Brown4be44fc2005-08-05 00:44:28 -0400126 status = acpi_ps_execute_pass(info);
127 if (ACPI_FAILURE(status)) {
Robert Moore0c9938c2005-07-29 15:15:00 -0700128 goto cleanup;
129 }
130
131 /*
132 * 2) Execute the method. Performs second pass parse simultaneously
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133 */
Len Brown4be44fc2005-08-05 00:44:28 -0400134 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
135 "**** Begin Method Execution **** Entry=%p obj=%p\n",
136 info->node, info->obj_desc));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137
Robert Moore0c9938c2005-07-29 15:15:00 -0700138 info->pass_number = 3;
Len Brown4be44fc2005-08-05 00:44:28 -0400139 status = acpi_ps_execute_pass(info);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140
Len Brown4be44fc2005-08-05 00:44:28 -0400141 cleanup:
Robert Moore0c9938c2005-07-29 15:15:00 -0700142 if (info->obj_desc->method.owner_id) {
Len Brown4be44fc2005-08-05 00:44:28 -0400143 acpi_ut_release_owner_id(&info->obj_desc->method.owner_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 }
145
Robert Moore0c9938c2005-07-29 15:15:00 -0700146 /* Take away the extra reference that we gave the parameters above */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147
Len Brown4be44fc2005-08-05 00:44:28 -0400148 acpi_ps_update_parameter_list(info, REF_DECREMENT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149
Robert Moore0c9938c2005-07-29 15:15:00 -0700150 /* Exit now if error above */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151
Len Brown4be44fc2005-08-05 00:44:28 -0400152 if (ACPI_FAILURE(status)) {
153 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154 }
155
156 /*
157 * If the method has returned an object, signal this to the caller with
158 * a control exception code
159 */
160 if (info->return_object) {
Len Brown4be44fc2005-08-05 00:44:28 -0400161 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
162 "Method returned obj_desc=%p\n",
163 info->return_object));
164 ACPI_DUMP_STACK_ENTRY(info->return_object);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165
166 status = AE_CTRL_RETURN_VALUE;
167 }
168
Len Brown4be44fc2005-08-05 00:44:28 -0400169 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170}
171
Robert Moore0c9938c2005-07-29 15:15:00 -0700172/*******************************************************************************
173 *
174 * FUNCTION: acpi_ps_update_parameter_list
175 *
176 * PARAMETERS: Info - See struct acpi_parameter_info
177 * (Used: parameter_type and Parameters)
178 * Action - Add or Remove reference
179 *
180 * RETURN: Status
181 *
182 * DESCRIPTION: Update reference count on all method parameter objects
183 *
184 ******************************************************************************/
185
186static void
Len Brown4be44fc2005-08-05 00:44:28 -0400187acpi_ps_update_parameter_list(struct acpi_parameter_info *info, u16 action)
Robert Moore0c9938c2005-07-29 15:15:00 -0700188{
Len Brown4be44fc2005-08-05 00:44:28 -0400189 acpi_native_uint i;
Robert Moore0c9938c2005-07-29 15:15:00 -0700190
Len Brown4be44fc2005-08-05 00:44:28 -0400191 if ((info->parameter_type == ACPI_PARAM_ARGS) && (info->parameters)) {
Robert Moore0c9938c2005-07-29 15:15:00 -0700192 /* Update reference count for each parameter */
193
194 for (i = 0; info->parameters[i]; i++) {
195 /* Ignore errors, just do them all */
196
Len Brown4be44fc2005-08-05 00:44:28 -0400197 (void)acpi_ut_update_object_reference(info->
198 parameters[i],
199 action);
Robert Moore0c9938c2005-07-29 15:15:00 -0700200 }
201 }
202}
203
Robert Moore0c9938c2005-07-29 15:15:00 -0700204/*******************************************************************************
205 *
206 * FUNCTION: acpi_ps_execute_pass
207 *
208 * PARAMETERS: Info - See struct acpi_parameter_info
209 * (Used: pass_number, Node, and obj_desc)
210 *
211 * RETURN: Status
212 *
213 * DESCRIPTION: Single AML pass: Parse or Execute a control method
214 *
215 ******************************************************************************/
216
Len Brown4be44fc2005-08-05 00:44:28 -0400217static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info)
Robert Moore0c9938c2005-07-29 15:15:00 -0700218{
Len Brown4be44fc2005-08-05 00:44:28 -0400219 acpi_status status;
220 union acpi_parse_object *op;
221 struct acpi_walk_state *walk_state;
Robert Moore0c9938c2005-07-29 15:15:00 -0700222
Len Brown4be44fc2005-08-05 00:44:28 -0400223 ACPI_FUNCTION_TRACE("ps_execute_pass");
Robert Moore0c9938c2005-07-29 15:15:00 -0700224
225 /* Create and init a Root Node */
226
Len Brown4be44fc2005-08-05 00:44:28 -0400227 op = acpi_ps_create_scope_op();
Robert Moore0c9938c2005-07-29 15:15:00 -0700228 if (!op) {
Len Brown4be44fc2005-08-05 00:44:28 -0400229 return_ACPI_STATUS(AE_NO_MEMORY);
Robert Moore0c9938c2005-07-29 15:15:00 -0700230 }
231
232 /* Create and initialize a new walk state */
233
Len Brown4be44fc2005-08-05 00:44:28 -0400234 walk_state =
235 acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,
236 NULL, NULL);
Robert Moore0c9938c2005-07-29 15:15:00 -0700237 if (!walk_state) {
238 status = AE_NO_MEMORY;
239 goto cleanup;
240 }
241
Len Brown4be44fc2005-08-05 00:44:28 -0400242 status = acpi_ds_init_aml_walk(walk_state, op, info->node,
243 info->obj_desc->method.aml_start,
244 info->obj_desc->method.aml_length,
245 info->pass_number == 1 ? NULL : info,
246 info->pass_number);
247 if (ACPI_FAILURE(status)) {
248 acpi_ds_delete_walk_state(walk_state);
Robert Moore0c9938c2005-07-29 15:15:00 -0700249 goto cleanup;
250 }
251
252 /* Parse the AML */
253
Len Brown4be44fc2005-08-05 00:44:28 -0400254 status = acpi_ps_parse_aml(walk_state);
Robert Moore0c9938c2005-07-29 15:15:00 -0700255
256 /* Walk state was deleted by parse_aml */
257
Len Brown4be44fc2005-08-05 00:44:28 -0400258 cleanup:
259 acpi_ps_delete_parse_tree(op);
260 return_ACPI_STATUS(status);
Robert Moore0c9938c2005-07-29 15:15:00 -0700261}