aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/parser
diff options
context:
space:
mode:
authorRobert Moore <robert.moore@intel.com>2005-07-29 18:15:00 -0400
committerLen Brown <len.brown@intel.com>2005-07-30 00:51:39 -0400
commit0c9938cc75057c0fca1af55a55dcfc2842436695 (patch)
treed18e809bf9e3811f20c609b6515d4d1b8520cfbc /drivers/acpi/parser
parentdd8f39bbf5154cdbfd698fc70c66faba33eafa44 (diff)
[ACPI] ACPICA 20050729 from Bob Moore
Implemented support to ignore an attempt to install/load a particular ACPI table more than once. Apparently there exists BIOS code that repeatedly attempts to load the same SSDT upon certain events. Thanks to Venkatesh Pallipadi. Restructured the main interface to the AML parser in order to correctly handle all exceptional conditions. This will prevent leakage of the OwnerId resource and should eliminate the AE_OWNER_ID_LIMIT exceptions seen on some machines. Thanks to Alexey Starikovskiy. Support for "module level code" has been disabled in this version due to a number of issues that have appeared on various machines. The support can be enabled by defining ACPI_ENABLE_MODULE_LEVEL_CODE during subsystem compilation. When the issues are fully resolved, the code will be enabled by default again. Modified the internal functions for debug print support to define the FunctionName parameter as a (const char *) for compatibility with compiler built-in macros such as __FUNCTION__, etc. Linted the entire ACPICA source tree for both 32-bit and 64-bit. Signed-off-by: Robert Moore <robert.moore@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/parser')
-rw-r--r--drivers/acpi/parser/psloop.c9
-rw-r--r--drivers/acpi/parser/psutils.c4
-rw-r--r--drivers/acpi/parser/psxface.c242
3 files changed, 143 insertions, 112 deletions
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c
index edf8aa5f86ca..551d54bdbec3 100644
--- a/drivers/acpi/parser/psloop.c
+++ b/drivers/acpi/parser/psloop.c
@@ -55,8 +55,6 @@
55#include <acpi/acparser.h> 55#include <acpi/acparser.h>
56#include <acpi/acdispat.h> 56#include <acpi/acdispat.h>
57#include <acpi/amlcode.h> 57#include <acpi/amlcode.h>
58#include <acpi/acnamesp.h>
59#include <acpi/acinterp.h>
60 58
61#define _COMPONENT ACPI_PARSER 59#define _COMPONENT ACPI_PARSER
62 ACPI_MODULE_NAME ("psloop") 60 ACPI_MODULE_NAME ("psloop")
@@ -410,11 +408,9 @@ acpi_ps_parse_loop (
410 408
411 /* Special processing for certain opcodes */ 409 /* Special processing for certain opcodes */
412 410
413#define ACPI_NO_MODULE_LEVEL_CODE
414
415 /* TBD (remove): Temporary mechanism to disable this code if needed */ 411 /* TBD (remove): Temporary mechanism to disable this code if needed */
416 412
417#ifndef ACPI_NO_MODULE_LEVEL_CODE 413#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE
418 414
419 if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS1) && 415 if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS1) &&
420 ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) { 416 ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) {
@@ -431,6 +427,9 @@ acpi_ps_parse_loop (
431 case AML_ELSE_OP: 427 case AML_ELSE_OP:
432 case AML_WHILE_OP: 428 case AML_WHILE_OP:
433 429
430 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
431 "Pass1: Skipping an If/Else/While body\n"));
432
434 /* Skip body of if/else/while in pass 1 */ 433 /* Skip body of if/else/while in pass 1 */
435 434
436 parser_state->aml = parser_state->pkg_end; 435 parser_state->aml = parser_state->pkg_end;
diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c
index 19a27020eeef..4221b41ae1a6 100644
--- a/drivers/acpi/parser/psutils.c
+++ b/drivers/acpi/parser/psutils.c
@@ -200,10 +200,10 @@ acpi_ps_free_op (
200 } 200 }
201 201
202 if (op->common.flags & ACPI_PARSEOP_GENERIC) { 202 if (op->common.flags & ACPI_PARSEOP_GENERIC) {
203 acpi_os_release_object (acpi_gbl_ps_node_cache, op); 203 (void) acpi_os_release_object (acpi_gbl_ps_node_cache, op);
204 } 204 }
205 else { 205 else {
206 acpi_os_release_object (acpi_gbl_ps_node_ext_cache, op); 206 (void) acpi_os_release_object (acpi_gbl_ps_node_ext_cache, op);
207 } 207 }
208} 208}
209 209
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
index 5279b51e7787..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,174 +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 status = acpi_ut_allocate_owner_id (&obj_desc->method.owner_id); 117 status = acpi_ut_allocate_owner_id (&info->obj_desc->method.owner_id);
142 if (ACPI_FAILURE (status)) { 118 if (ACPI_FAILURE (status)) {
143 goto cleanup2; 119 return_ACPI_STATUS (status);
144 }
145
146 /* Create and initialize a new walk state */
147
148 walk_state = acpi_ds_create_walk_state (obj_desc->method.owner_id,
149 NULL, NULL, NULL);
150 if (!walk_state) {
151 status = AE_NO_MEMORY;
152 goto cleanup2;
153 } 120 }
154 121
155 status = acpi_ds_init_aml_walk (walk_state, op, info->node, 122 /*
156 obj_desc->method.aml_start, 123 * The caller "owns" the parameters, so give each one an extra
157 obj_desc->method.aml_length, NULL, 1); 124 * reference
158 if (ACPI_FAILURE (status)) { 125 */
159 goto cleanup3; 126 acpi_ps_update_parameter_list (info, REF_INCREMENT);
160 }
161 127
162 /* Parse the AML */ 128 /*
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));
163 135
164 status = acpi_ps_parse_aml (walk_state); 136 info->pass_number = 1;
165 acpi_ps_delete_parse_tree (op); 137 status = acpi_ps_execute_pass (info);
166 if (ACPI_FAILURE (status)) { 138 if (ACPI_FAILURE (status)) {
167 goto cleanup1; /* Walk state is already deleted */ 139 goto cleanup;
168 } 140 }
169 141
170 /* 142 /*
171 * 2) Execute the method. Performs second pass parse simultaneously 143 * 2) Execute the method. Performs second pass parse simultaneously
172 */ 144 */
173 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 145 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
174 "**** Begin Method Execution **** Entry=%p obj=%p\n", 146 "**** Begin Method Execution **** Entry=%p obj=%p\n",
175 info->node, obj_desc)); 147 info->node, info->obj_desc));
176 148
177 /* Create and init a Root Node */ 149 info->pass_number = 3;
150 status = acpi_ps_execute_pass (info);
178 151
179 op = acpi_ps_create_scope_op (); 152
180 if (!op) { 153cleanup:
181 status = AE_NO_MEMORY; 154 if (info->obj_desc->method.owner_id) {
182 goto cleanup1; 155 acpi_ut_release_owner_id (&info->obj_desc->method.owner_id);
183 } 156 }
184 157
185 /* 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 */
186 159
187 acpi_ps_set_name (op, info->node->name.integer); 160 acpi_ps_update_parameter_list (info, REF_DECREMENT);
188 op->common.node = info->node;
189 161
190 /* Create and initialize a new walk state */ 162 /* Exit now if error above */
191 163
192 walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); 164 if (ACPI_FAILURE (status)) {
193 if (!walk_state) { 165 return_ACPI_STATUS (status);
194 status = AE_NO_MEMORY;
195 goto cleanup2;
196 } 166 }
197 167
198 status = acpi_ds_init_aml_walk (walk_state, op, info->node, 168 /*
199 obj_desc->method.aml_start, 169 * If the method has returned an object, signal this to the caller with
200 obj_desc->method.aml_length, info, 3); 170 * a control exception code
201 if (ACPI_FAILURE (status)) { 171 */
202 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;
203 } 178 }
204 179
205 /* The walk of the parse tree is where we actually execute the method */ 180 return_ACPI_STATUS (status);
181}
206 182
207 status = acpi_ps_parse_aml (walk_state);
208 goto cleanup2; /* Walk state already deleted */
209 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 ******************************************************************************/
210 197
211cleanup3: 198static void
212 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;
213 204
214cleanup2:
215 acpi_ps_delete_parse_tree (op);
216 205
217cleanup1:
218 if ((info->parameter_type == ACPI_PARAM_ARGS) && 206 if ((info->parameter_type == ACPI_PARAM_ARGS) &&
219 (info->parameters)) { 207 (info->parameters)) {
220 /* Take away the extra reference that we gave the parameters above */ 208 /* Update reference count for each parameter */
221 209
222 for (i = 0; info->parameters[i]; i++) { 210 for (i = 0; info->parameters[i]; i++) {
223 /* Ignore errors, just do them all */ 211 /* Ignore errors, just do them all */
224 212
225 (void) acpi_ut_update_object_reference ( 213 (void) acpi_ut_update_object_reference (info->parameters[i], action);
226 info->parameters[i], REF_DECREMENT);
227 } 214 }
228 } 215 }
216}
229 217
230 if (ACPI_FAILURE (status)) { 218
231 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);
232 } 249 }
233 250
234 /* 251 /* Create and initialize a new walk state */
235 * If the method has returned an object, signal this to the caller with
236 * a control exception code
237 */
238 if (info->return_object) {
239 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned obj_desc=%p\n",
240 info->return_object));
241 ACPI_DUMP_STACK_ENTRY (info->return_object);
242 252
243 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;
244 } 268 }
245 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);
246 return_ACPI_STATUS (status); 278 return_ACPI_STATUS (status);
247} 279}
248 280