aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/dispatcher/dsmethod.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/dispatcher/dsmethod.c')
-rw-r--r--drivers/acpi/dispatcher/dsmethod.c404
1 files changed, 208 insertions, 196 deletions
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index 9fc3f4c033eb..36c1ca0b9adb 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -41,7 +41,6 @@
41 * POSSIBILITY OF SUCH DAMAGES. 41 * POSSIBILITY OF SUCH DAMAGES.
42 */ 42 */
43 43
44
45#include <acpi/acpi.h> 44#include <acpi/acpi.h>
46#include <acpi/acparser.h> 45#include <acpi/acparser.h>
47#include <acpi/amlcode.h> 46#include <acpi/amlcode.h>
@@ -49,67 +48,57 @@
49#include <acpi/acinterp.h> 48#include <acpi/acinterp.h>
50#include <acpi/acnamesp.h> 49#include <acpi/acnamesp.h>
51 50
52
53#define _COMPONENT ACPI_DISPATCHER 51#define _COMPONENT ACPI_DISPATCHER
54 ACPI_MODULE_NAME ("dsmethod") 52ACPI_MODULE_NAME("dsmethod")
55
56 53
57/******************************************************************************* 54/*******************************************************************************
58 * 55 *
59 * FUNCTION: acpi_ds_parse_method 56 * FUNCTION: acpi_ds_parse_method
60 * 57 *
61 * PARAMETERS: obj_handle - Method node 58 * PARAMETERS: Node - Method node
62 * 59 *
63 * RETURN: Status 60 * RETURN: Status
64 * 61 *
65 * DESCRIPTION: Call the parser and parse the AML that is associated with the 62 * DESCRIPTION: Parse the AML that is associated with the method.
66 * method.
67 * 63 *
68 * MUTEX: Assumes parser is locked 64 * MUTEX: Assumes parser is locked
69 * 65 *
70 ******************************************************************************/ 66 ******************************************************************************/
71 67acpi_status acpi_ds_parse_method(struct acpi_namespace_node *node)
72acpi_status
73acpi_ds_parse_method (
74 acpi_handle obj_handle)
75{ 68{
76 acpi_status status; 69 acpi_status status;
77 union acpi_operand_object *obj_desc; 70 union acpi_operand_object *obj_desc;
78 union acpi_parse_object *op; 71 union acpi_parse_object *op;
79 struct acpi_namespace_node *node; 72 struct acpi_walk_state *walk_state;
80 acpi_owner_id owner_id;
81 struct acpi_walk_state *walk_state;
82
83
84 ACPI_FUNCTION_TRACE_PTR ("ds_parse_method", obj_handle);
85 73
74 ACPI_FUNCTION_TRACE_PTR("ds_parse_method", node);
86 75
87 /* Parameter Validation */ 76 /* Parameter Validation */
88 77
89 if (!obj_handle) { 78 if (!node) {
90 return_ACPI_STATUS (AE_NULL_ENTRY); 79 return_ACPI_STATUS(AE_NULL_ENTRY);
91 } 80 }
92 81
93 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Parsing [%4.4s] **** named_obj=%p\n", 82 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
94 acpi_ut_get_node_name (obj_handle), obj_handle)); 83 "**** Parsing [%4.4s] **** named_obj=%p\n",
84 acpi_ut_get_node_name(node), node));
95 85
96 /* Extract the method object from the method Node */ 86 /* Extract the method object from the method Node */
97 87
98 node = (struct acpi_namespace_node *) obj_handle; 88 obj_desc = acpi_ns_get_attached_object(node);
99 obj_desc = acpi_ns_get_attached_object (node);
100 if (!obj_desc) { 89 if (!obj_desc) {
101 return_ACPI_STATUS (AE_NULL_OBJECT); 90 return_ACPI_STATUS(AE_NULL_OBJECT);
102 } 91 }
103 92
104 /* Create a mutex for the method if there is a concurrency limit */ 93 /* Create a mutex for the method if there is a concurrency limit */
105 94
106 if ((obj_desc->method.concurrency != ACPI_INFINITE_CONCURRENCY) && 95 if ((obj_desc->method.concurrency != ACPI_INFINITE_CONCURRENCY) &&
107 (!obj_desc->method.semaphore)) { 96 (!obj_desc->method.semaphore)) {
108 status = acpi_os_create_semaphore (obj_desc->method.concurrency, 97 status = acpi_os_create_semaphore(obj_desc->method.concurrency,
109 obj_desc->method.concurrency, 98 obj_desc->method.concurrency,
110 &obj_desc->method.semaphore); 99 &obj_desc->method.semaphore);
111 if (ACPI_FAILURE (status)) { 100 if (ACPI_FAILURE(status)) {
112 return_ACPI_STATUS (status); 101 return_ACPI_STATUS(status);
113 } 102 }
114 } 103 }
115 104
@@ -117,14 +106,14 @@ acpi_ds_parse_method (
117 * Allocate a new parser op to be the root of the parsed 106 * Allocate a new parser op to be the root of the parsed
118 * method tree 107 * method tree
119 */ 108 */
120 op = acpi_ps_alloc_op (AML_METHOD_OP); 109 op = acpi_ps_alloc_op(AML_METHOD_OP);
121 if (!op) { 110 if (!op) {
122 return_ACPI_STATUS (AE_NO_MEMORY); 111 return_ACPI_STATUS(AE_NO_MEMORY);
123 } 112 }
124 113
125 /* Init new op with the method name and pointer back to the Node */ 114 /* Init new op with the method name and pointer back to the Node */
126 115
127 acpi_ps_set_name (op, node->name.integer); 116 acpi_ps_set_name(op, node->name.integer);
128 op->common.node = node; 117 op->common.node = node;
129 118
130 /* 119 /*
@@ -132,22 +121,27 @@ acpi_ds_parse_method (
132 * objects (such as Operation Regions) can be created during the 121 * objects (such as Operation Regions) can be created during the
133 * first pass parse. 122 * first pass parse.
134 */ 123 */
135 owner_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD); 124 status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id);
136 obj_desc->method.owning_id = owner_id; 125 if (ACPI_FAILURE(status)) {
126 goto cleanup;
127 }
137 128
138 /* Create and initialize a new walk state */ 129 /* Create and initialize a new walk state */
139 130
140 walk_state = acpi_ds_create_walk_state (owner_id, NULL, NULL, NULL); 131 walk_state =
132 acpi_ds_create_walk_state(obj_desc->method.owner_id, NULL, NULL,
133 NULL);
141 if (!walk_state) { 134 if (!walk_state) {
142 return_ACPI_STATUS (AE_NO_MEMORY); 135 status = AE_NO_MEMORY;
136 goto cleanup2;
143 } 137 }
144 138
145 status = acpi_ds_init_aml_walk (walk_state, op, node, 139 status = acpi_ds_init_aml_walk(walk_state, op, node,
146 obj_desc->method.aml_start, 140 obj_desc->method.aml_start,
147 obj_desc->method.aml_length, NULL, 1); 141 obj_desc->method.aml_length, NULL, 1);
148 if (ACPI_FAILURE (status)) { 142 if (ACPI_FAILURE(status)) {
149 acpi_ds_delete_walk_state (walk_state); 143 acpi_ds_delete_walk_state(walk_state);
150 return_ACPI_STATUS (status); 144 goto cleanup2;
151 } 145 }
152 146
153 /* 147 /*
@@ -159,19 +153,30 @@ acpi_ds_parse_method (
159 * method so that operands to the named objects can take on dynamic 153 * method so that operands to the named objects can take on dynamic
160 * run-time values. 154 * run-time values.
161 */ 155 */
162 status = acpi_ps_parse_aml (walk_state); 156 status = acpi_ps_parse_aml(walk_state);
163 if (ACPI_FAILURE (status)) { 157 if (ACPI_FAILURE(status)) {
164 return_ACPI_STATUS (status); 158 goto cleanup2;
165 } 159 }
166 160
167 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 161 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
168 "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n", 162 "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n",
169 acpi_ut_get_node_name (obj_handle), obj_handle, op)); 163 acpi_ut_get_node_name(node), node, op));
170 164
171 acpi_ps_delete_parse_tree (op); 165 /*
172 return_ACPI_STATUS (status); 166 * Delete the parse tree. We simply re-parse the method for every
173} 167 * execution since there isn't much overhead (compared to keeping lots
168 * of parse trees around)
169 */
170 acpi_ns_delete_namespace_subtree(node);
171 acpi_ns_delete_namespace_by_owner(obj_desc->method.owner_id);
172
173 cleanup2:
174 acpi_ut_release_owner_id(&obj_desc->method.owner_id);
174 175
176 cleanup:
177 acpi_ps_delete_parse_tree(op);
178 return_ACPI_STATUS(status);
179}
175 180
176/******************************************************************************* 181/*******************************************************************************
177 * 182 *
@@ -190,19 +195,23 @@ acpi_ds_parse_method (
190 ******************************************************************************/ 195 ******************************************************************************/
191 196
192acpi_status 197acpi_status
193acpi_ds_begin_method_execution ( 198acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
194 struct acpi_namespace_node *method_node, 199 union acpi_operand_object *obj_desc,
195 union acpi_operand_object *obj_desc, 200 struct acpi_namespace_node *calling_method_node)
196 struct acpi_namespace_node *calling_method_node)
197{ 201{
198 acpi_status status = AE_OK; 202 acpi_status status = AE_OK;
199 203
204 ACPI_FUNCTION_TRACE_PTR("ds_begin_method_execution", method_node);
200 205
201 ACPI_FUNCTION_TRACE_PTR ("ds_begin_method_execution", method_node); 206 if (!method_node) {
207 return_ACPI_STATUS(AE_NULL_ENTRY);
208 }
202 209
210 /* Prevent wraparound of thread count */
203 211
204 if (!method_node) { 212 if (obj_desc->method.thread_count == ACPI_UINT8_MAX) {
205 return_ACPI_STATUS (AE_NULL_ENTRY); 213 ACPI_REPORT_ERROR(("Method reached maximum reentrancy limit (255)\n"));
214 return_ACPI_STATUS(AE_AML_METHOD_LIMIT);
206 } 215 }
207 216
208 /* 217 /*
@@ -219,8 +228,9 @@ acpi_ds_begin_method_execution (
219 * thread that is making recursive method calls. 228 * thread that is making recursive method calls.
220 */ 229 */
221 if (method_node == calling_method_node) { 230 if (method_node == calling_method_node) {
222 if (obj_desc->method.thread_count >= obj_desc->method.concurrency) { 231 if (obj_desc->method.thread_count >=
223 return_ACPI_STATUS (AE_AML_METHOD_LIMIT); 232 obj_desc->method.concurrency) {
233 return_ACPI_STATUS(AE_AML_METHOD_LIMIT);
224 } 234 }
225 } 235 }
226 236
@@ -228,8 +238,21 @@ acpi_ds_begin_method_execution (
228 * Get a unit from the method semaphore. This releases the 238 * Get a unit from the method semaphore. This releases the
229 * interpreter if we block 239 * interpreter if we block
230 */ 240 */
231 status = acpi_ex_system_wait_semaphore (obj_desc->method.semaphore, 241 status =
232 ACPI_WAIT_FOREVER); 242 acpi_ex_system_wait_semaphore(obj_desc->method.semaphore,
243 ACPI_WAIT_FOREVER);
244 }
245
246 /*
247 * Allocate an Owner ID for this method, only if this is the first thread
248 * to begin concurrent execution. We only need one owner_id, even if the
249 * method is invoked recursively.
250 */
251 if (!obj_desc->method.owner_id) {
252 status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id);
253 if (ACPI_FAILURE(status)) {
254 return_ACPI_STATUS(status);
255 }
233 } 256 }
234 257
235 /* 258 /*
@@ -237,10 +260,9 @@ acpi_ds_begin_method_execution (
237 * reentered one more time (even if it is the same thread) 260 * reentered one more time (even if it is the same thread)
238 */ 261 */
239 obj_desc->method.thread_count++; 262 obj_desc->method.thread_count++;
240 return_ACPI_STATUS (status); 263 return_ACPI_STATUS(status);
241} 264}
242 265
243
244/******************************************************************************* 266/*******************************************************************************
245 * 267 *
246 * FUNCTION: acpi_ds_call_control_method 268 * FUNCTION: acpi_ds_call_control_method
@@ -256,101 +278,99 @@ acpi_ds_begin_method_execution (
256 ******************************************************************************/ 278 ******************************************************************************/
257 279
258acpi_status 280acpi_status
259acpi_ds_call_control_method ( 281acpi_ds_call_control_method(struct acpi_thread_state *thread,
260 struct acpi_thread_state *thread, 282 struct acpi_walk_state *this_walk_state,
261 struct acpi_walk_state *this_walk_state, 283 union acpi_parse_object *op)
262 union acpi_parse_object *op)
263{ 284{
264 acpi_status status; 285 acpi_status status;
265 struct acpi_namespace_node *method_node; 286 struct acpi_namespace_node *method_node;
266 struct acpi_walk_state *next_walk_state; 287 struct acpi_walk_state *next_walk_state = NULL;
267 union acpi_operand_object *obj_desc; 288 union acpi_operand_object *obj_desc;
268 struct acpi_parameter_info info; 289 struct acpi_parameter_info info;
269 u32 i; 290 u32 i;
270
271 291
272 ACPI_FUNCTION_TRACE_PTR ("ds_call_control_method", this_walk_state); 292 ACPI_FUNCTION_TRACE_PTR("ds_call_control_method", this_walk_state);
273 293
274 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Execute method %p, currentstate=%p\n", 294 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
275 this_walk_state->prev_op, this_walk_state)); 295 "Execute method %p, currentstate=%p\n",
296 this_walk_state->prev_op, this_walk_state));
276 297
277 /* 298 /*
278 * Get the namespace entry for the control method we are about to call 299 * Get the namespace entry for the control method we are about to call
279 */ 300 */
280 method_node = this_walk_state->method_call_node; 301 method_node = this_walk_state->method_call_node;
281 if (!method_node) { 302 if (!method_node) {
282 return_ACPI_STATUS (AE_NULL_ENTRY); 303 return_ACPI_STATUS(AE_NULL_ENTRY);
283 } 304 }
284 305
285 obj_desc = acpi_ns_get_attached_object (method_node); 306 obj_desc = acpi_ns_get_attached_object(method_node);
286 if (!obj_desc) { 307 if (!obj_desc) {
287 return_ACPI_STATUS (AE_NULL_OBJECT); 308 return_ACPI_STATUS(AE_NULL_OBJECT);
288 } 309 }
289 310
290 obj_desc->method.owning_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD);
291
292 /* Init for new method, wait on concurrency semaphore */ 311 /* Init for new method, wait on concurrency semaphore */
293 312
294 status = acpi_ds_begin_method_execution (method_node, obj_desc, 313 status = acpi_ds_begin_method_execution(method_node, obj_desc,
295 this_walk_state->method_node); 314 this_walk_state->method_node);
296 if (ACPI_FAILURE (status)) { 315 if (ACPI_FAILURE(status)) {
297 return_ACPI_STATUS (status); 316 goto cleanup;
298 } 317 }
299 318
300 if (!(obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY)) { 319 if (!(obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY)) {
301 /* 1) Parse: Create a new walk state for the preempting walk */ 320 /* 1) Parse: Create a new walk state for the preempting walk */
302 321
303 next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id, 322 next_walk_state =
304 op, obj_desc, NULL); 323 acpi_ds_create_walk_state(obj_desc->method.owner_id, op,
324 obj_desc, NULL);
305 if (!next_walk_state) { 325 if (!next_walk_state) {
306 return_ACPI_STATUS (AE_NO_MEMORY); 326 return_ACPI_STATUS(AE_NO_MEMORY);
307 } 327 }
308 328
309 /* Create and init a Root Node */ 329 /* Create and init a Root Node */
310 330
311 op = acpi_ps_create_scope_op (); 331 op = acpi_ps_create_scope_op();
312 if (!op) { 332 if (!op) {
313 status = AE_NO_MEMORY; 333 status = AE_NO_MEMORY;
314 goto cleanup; 334 goto cleanup;
315 } 335 }
316 336
317 status = acpi_ds_init_aml_walk (next_walk_state, op, method_node, 337 status = acpi_ds_init_aml_walk(next_walk_state, op, method_node,
318 obj_desc->method.aml_start, obj_desc->method.aml_length, 338 obj_desc->method.aml_start,
319 NULL, 1); 339 obj_desc->method.aml_length,
320 if (ACPI_FAILURE (status)) { 340 NULL, 1);
321 acpi_ds_delete_walk_state (next_walk_state); 341 if (ACPI_FAILURE(status)) {
342 acpi_ds_delete_walk_state(next_walk_state);
322 goto cleanup; 343 goto cleanup;
323 } 344 }
324 345
325 /* Begin AML parse */ 346 /* Begin AML parse */
326 347
327 status = acpi_ps_parse_aml (next_walk_state); 348 status = acpi_ps_parse_aml(next_walk_state);
328 acpi_ps_delete_parse_tree (op); 349 acpi_ps_delete_parse_tree(op);
329 } 350 }
330 351
331 /* 2) Execute: Create a new state for the preempting walk */ 352 /* 2) Execute: Create a new state for the preempting walk */
332 353
333 next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id, 354 next_walk_state = acpi_ds_create_walk_state(obj_desc->method.owner_id,
334 NULL, obj_desc, thread); 355 NULL, obj_desc, thread);
335 if (!next_walk_state) { 356 if (!next_walk_state) {
336 status = AE_NO_MEMORY; 357 status = AE_NO_MEMORY;
337 goto cleanup; 358 goto cleanup;
338 } 359 }
339 /* 360 /*
340 * The resolved arguments were put on the previous walk state's operand 361 * The resolved arguments were put on the previous walk state's operand
341 * stack. Operands on the previous walk state stack always 362 * stack. Operands on the previous walk state stack always
342 * start at index 0. 363 * start at index 0. Also, null terminate the list of arguments
343 * Null terminate the list of arguments
344 */ 364 */
345 this_walk_state->operands [this_walk_state->num_operands] = NULL; 365 this_walk_state->operands[this_walk_state->num_operands] = NULL;
346 366
347 info.parameters = &this_walk_state->operands[0]; 367 info.parameters = &this_walk_state->operands[0];
348 info.parameter_type = ACPI_PARAM_ARGS; 368 info.parameter_type = ACPI_PARAM_ARGS;
349 369
350 status = acpi_ds_init_aml_walk (next_walk_state, NULL, method_node, 370 status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node,
351 obj_desc->method.aml_start, obj_desc->method.aml_length, 371 obj_desc->method.aml_start,
352 &info, 3); 372 obj_desc->method.aml_length, &info, 3);
353 if (ACPI_FAILURE (status)) { 373 if (ACPI_FAILURE(status)) {
354 goto cleanup; 374 goto cleanup;
355 } 375 }
356 376
@@ -359,38 +379,37 @@ acpi_ds_call_control_method (
359 * (they were copied to new objects) 379 * (they were copied to new objects)
360 */ 380 */
361 for (i = 0; i < obj_desc->method.param_count; i++) { 381 for (i = 0; i < obj_desc->method.param_count; i++) {
362 acpi_ut_remove_reference (this_walk_state->operands [i]); 382 acpi_ut_remove_reference(this_walk_state->operands[i]);
363 this_walk_state->operands [i] = NULL; 383 this_walk_state->operands[i] = NULL;
364 } 384 }
365 385
366 /* Clear the operand stack */ 386 /* Clear the operand stack */
367 387
368 this_walk_state->num_operands = 0; 388 this_walk_state->num_operands = 0;
369 389
370 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 390 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
371 "Starting nested execution, newstate=%p\n", next_walk_state)); 391 "Starting nested execution, newstate=%p\n",
392 next_walk_state));
372 393
373 if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) { 394 if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) {
374 status = obj_desc->method.implementation (next_walk_state); 395 status = obj_desc->method.implementation(next_walk_state);
375 return_ACPI_STATUS (status);
376 } 396 }
377 397
378 return_ACPI_STATUS (AE_OK); 398 return_ACPI_STATUS(status);
379
380 399
381 /* On error, we must delete the new walk state */ 400 cleanup:
401 /* Decrement the thread count on the method parse tree */
382 402
383cleanup:
384 if (next_walk_state && (next_walk_state->method_desc)) { 403 if (next_walk_state && (next_walk_state->method_desc)) {
385 /* Decrement the thread count on the method parse tree */ 404 next_walk_state->method_desc->method.thread_count--;
386
387 next_walk_state->method_desc->method.thread_count--;
388 } 405 }
389 (void) acpi_ds_terminate_control_method (next_walk_state);
390 acpi_ds_delete_walk_state (next_walk_state);
391 return_ACPI_STATUS (status);
392}
393 406
407 /* On error, we must delete the new walk state */
408
409 acpi_ds_terminate_control_method(next_walk_state);
410 acpi_ds_delete_walk_state(next_walk_state);
411 return_ACPI_STATUS(status);
412}
394 413
395/******************************************************************************* 414/*******************************************************************************
396 * 415 *
@@ -407,25 +426,22 @@ cleanup:
407 ******************************************************************************/ 426 ******************************************************************************/
408 427
409acpi_status 428acpi_status
410acpi_ds_restart_control_method ( 429acpi_ds_restart_control_method(struct acpi_walk_state *walk_state,
411 struct acpi_walk_state *walk_state, 430 union acpi_operand_object *return_desc)
412 union acpi_operand_object *return_desc)
413{ 431{
414 acpi_status status; 432 acpi_status status;
415 433
434 ACPI_FUNCTION_TRACE_PTR("ds_restart_control_method", walk_state);
416 435
417 ACPI_FUNCTION_TRACE_PTR ("ds_restart_control_method", walk_state); 436 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
437 "****Restart [%4.4s] Op %p return_value_from_callee %p\n",
438 (char *)&walk_state->method_node->name,
439 walk_state->method_call_op, return_desc));
418 440
419 441 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
420 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 442 " return_from_this_method_used?=%X res_stack %p Walk %p\n",
421 "****Restart [%4.4s] Op %p return_value_from_callee %p\n", 443 walk_state->return_used,
422 (char *) &walk_state->method_node->name, walk_state->method_call_op, 444 walk_state->results, walk_state));
423 return_desc));
424
425 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
426 " return_from_this_method_used?=%X res_stack %p Walk %p\n",
427 walk_state->return_used,
428 walk_state->results, walk_state));
429 445
430 /* Did the called method return a value? */ 446 /* Did the called method return a value? */
431 447
@@ -435,10 +451,10 @@ acpi_ds_restart_control_method (
435 if (walk_state->return_used) { 451 if (walk_state->return_used) {
436 /* Save the return value from the previous method */ 452 /* Save the return value from the previous method */
437 453
438 status = acpi_ds_result_push (return_desc, walk_state); 454 status = acpi_ds_result_push(return_desc, walk_state);
439 if (ACPI_FAILURE (status)) { 455 if (ACPI_FAILURE(status)) {
440 acpi_ut_remove_reference (return_desc); 456 acpi_ut_remove_reference(return_desc);
441 return_ACPI_STATUS (status); 457 return_ACPI_STATUS(status);
442 } 458 }
443 459
444 /* 460 /*
@@ -456,26 +472,26 @@ acpi_ds_restart_control_method (
456 * NOTE: this is optional because the ASL language does not actually 472 * NOTE: this is optional because the ASL language does not actually
457 * support this behavior. 473 * support this behavior.
458 */ 474 */
459 else if (!acpi_ds_do_implicit_return (return_desc, walk_state, FALSE)) { 475 else if (!acpi_ds_do_implicit_return
476 (return_desc, walk_state, FALSE)) {
460 /* 477 /*
461 * Delete the return value if it will not be used by the 478 * Delete the return value if it will not be used by the
462 * calling method 479 * calling method
463 */ 480 */
464 acpi_ut_remove_reference (return_desc); 481 acpi_ut_remove_reference(return_desc);
465 } 482 }
466 } 483 }
467 484
468 return_ACPI_STATUS (AE_OK); 485 return_ACPI_STATUS(AE_OK);
469} 486}
470 487
471
472/******************************************************************************* 488/*******************************************************************************
473 * 489 *
474 * FUNCTION: acpi_ds_terminate_control_method 490 * FUNCTION: acpi_ds_terminate_control_method
475 * 491 *
476 * PARAMETERS: walk_state - State of the method 492 * PARAMETERS: walk_state - State of the method
477 * 493 *
478 * RETURN: Status 494 * RETURN: None
479 * 495 *
480 * DESCRIPTION: Terminate a control method. Delete everything that the method 496 * DESCRIPTION: Terminate a control method. Delete everything that the method
481 * created, delete all locals and arguments, and delete the parse 497 * created, delete all locals and arguments, and delete the parse
@@ -483,63 +499,59 @@ acpi_ds_restart_control_method (
483 * 499 *
484 ******************************************************************************/ 500 ******************************************************************************/
485 501
486acpi_status 502void acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state)
487acpi_ds_terminate_control_method (
488 struct acpi_walk_state *walk_state)
489{ 503{
490 union acpi_operand_object *obj_desc; 504 union acpi_operand_object *obj_desc;
491 struct acpi_namespace_node *method_node; 505 struct acpi_namespace_node *method_node;
492 acpi_status status; 506 acpi_status status;
493
494
495 ACPI_FUNCTION_TRACE_PTR ("ds_terminate_control_method", walk_state);
496 507
508 ACPI_FUNCTION_TRACE_PTR("ds_terminate_control_method", walk_state);
497 509
498 if (!walk_state) { 510 if (!walk_state) {
499 return (AE_BAD_PARAMETER); 511 return_VOID;
500 } 512 }
501 513
502 /* The current method object was saved in the walk state */ 514 /* The current method object was saved in the walk state */
503 515
504 obj_desc = walk_state->method_desc; 516 obj_desc = walk_state->method_desc;
505 if (!obj_desc) { 517 if (!obj_desc) {
506 return_ACPI_STATUS (AE_OK); 518 return_VOID;
507 } 519 }
508 520
509 /* Delete all arguments and locals */ 521 /* Delete all arguments and locals */
510 522
511 acpi_ds_method_data_delete_all (walk_state); 523 acpi_ds_method_data_delete_all(walk_state);
512 524
513 /* 525 /*
514 * Lock the parser while we terminate this method. 526 * Lock the parser while we terminate this method.
515 * If this is the last thread executing the method, 527 * If this is the last thread executing the method,
516 * we have additional cleanup to perform 528 * we have additional cleanup to perform
517 */ 529 */
518 status = acpi_ut_acquire_mutex (ACPI_MTX_PARSER); 530 status = acpi_ut_acquire_mutex(ACPI_MTX_PARSER);
519 if (ACPI_FAILURE (status)) { 531 if (ACPI_FAILURE(status)) {
520 return_ACPI_STATUS (status); 532 return_VOID;
521 } 533 }
522 534
523 /* Signal completion of the execution of this method if necessary */ 535 /* Signal completion of the execution of this method if necessary */
524 536
525 if (walk_state->method_desc->method.semaphore) { 537 if (walk_state->method_desc->method.semaphore) {
526 status = acpi_os_signal_semaphore ( 538 status =
527 walk_state->method_desc->method.semaphore, 1); 539 acpi_os_signal_semaphore(walk_state->method_desc->method.
528 if (ACPI_FAILURE (status)) { 540 semaphore, 1);
529 ACPI_REPORT_ERROR (("Could not signal method semaphore\n")); 541 if (ACPI_FAILURE(status)) {
530 status = AE_OK; 542 ACPI_REPORT_ERROR(("Could not signal method semaphore\n"));
531 543
532 /* Ignore error and continue cleanup */ 544 /* Ignore error and continue cleanup */
533 } 545 }
534 } 546 }
535 547
536 if (walk_state->method_desc->method.thread_count) { 548 if (walk_state->method_desc->method.thread_count) {
537 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 549 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
538 "*** Not deleting method namespace, there are still %d threads\n", 550 "*** Not deleting method namespace, there are still %d threads\n",
539 walk_state->method_desc->method.thread_count)); 551 walk_state->method_desc->method.
540 } 552 thread_count));
553 } else { /* This is the last executing thread */
541 554
542 if (!walk_state->method_desc->method.thread_count) {
543 /* 555 /*
544 * Support to dynamically change a method from not_serialized to 556 * Support to dynamically change a method from not_serialized to
545 * Serialized if it appears that the method is written foolishly and 557 * Serialized if it appears that the method is written foolishly and
@@ -551,10 +563,11 @@ acpi_ds_terminate_control_method (
551 * before creating the synchronization semaphore. 563 * before creating the synchronization semaphore.
552 */ 564 */
553 if ((walk_state->method_desc->method.concurrency == 1) && 565 if ((walk_state->method_desc->method.concurrency == 1) &&
554 (!walk_state->method_desc->method.semaphore)) { 566 (!walk_state->method_desc->method.semaphore)) {
555 status = acpi_os_create_semaphore (1, 567 status = acpi_os_create_semaphore(1, 1,
556 1, 568 &walk_state->
557 &walk_state->method_desc->method.semaphore); 569 method_desc->method.
570 semaphore);
558 } 571 }
559 572
560 /* 573 /*
@@ -569,28 +582,27 @@ acpi_ds_terminate_control_method (
569 * Delete any namespace entries created immediately underneath 582 * Delete any namespace entries created immediately underneath
570 * the method 583 * the method
571 */ 584 */
572 status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); 585 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
573 if (ACPI_FAILURE (status)) { 586 if (ACPI_FAILURE(status)) {
574 return_ACPI_STATUS (status); 587 goto exit;
575 } 588 }
576 589
577 if (method_node->child) { 590 if (method_node->child) {
578 acpi_ns_delete_namespace_subtree (method_node); 591 acpi_ns_delete_namespace_subtree(method_node);
579 } 592 }
580 593
581 /* 594 /*
582 * Delete any namespace entries created anywhere else within 595 * Delete any namespace entries created anywhere else within
583 * the namespace 596 * the namespace
584 */ 597 */
585 acpi_ns_delete_namespace_by_owner (walk_state->method_desc->method.owning_id); 598 acpi_ns_delete_namespace_by_owner(walk_state->method_desc->
586 status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); 599 method.owner_id);
587 if (ACPI_FAILURE (status)) { 600 status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
588 return_ACPI_STATUS (status); 601 acpi_ut_release_owner_id(&walk_state->method_desc->method.
589 } 602 owner_id);
590 } 603 }
591 604
592 status = acpi_ut_release_mutex (ACPI_MTX_PARSER); 605 exit:
593 return_ACPI_STATUS (status); 606 (void)acpi_ut_release_mutex(ACPI_MTX_PARSER);
607 return_VOID;
594} 608}
595
596