1 /****************************************************************************** 2 * 3 * Module Name: dsmethod - Parser/Interpreter interface - control method parsing 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, Intel Corp. 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 44 #include <acpi/acpi.h> 45 #include "accommon.h" 46 #include "acdispat.h" 47 #include "acinterp.h" 48 #include "acnamesp.h" 49 #ifdef ACPI_DISASSEMBLER 50 #include "acdisasm.h" 51 #endif 52 #include "acparser.h" 53 #include "amlcode.h" 54 55 #define _COMPONENT ACPI_DISPATCHER 56 ACPI_MODULE_NAME("dsmethod") 57 58 /* Local prototypes */ 59 static acpi_status 60 acpi_ds_detect_named_opcodes(struct acpi_walk_state *walk_state, 61 union acpi_parse_object **out_op); 62 63 static acpi_status 64 acpi_ds_create_method_mutex(union acpi_operand_object *method_desc); 65 66 /******************************************************************************* 67 * 68 * FUNCTION: acpi_ds_auto_serialize_method 69 * 70 * PARAMETERS: node - Namespace Node of the method 71 * obj_desc - Method object attached to node 72 * 73 * RETURN: Status 74 * 75 * DESCRIPTION: Parse a control method AML to scan for control methods that 76 * need serialization due to the creation of named objects. 77 * 78 * NOTE: It is a bit of overkill to mark all such methods serialized, since 79 * there is only a problem if the method actually blocks during execution. 80 * A blocking operation is, for example, a Sleep() operation, or any access 81 * to an operation region. However, it is probably not possible to easily 82 * detect whether a method will block or not, so we simply mark all suspicious 83 * methods as serialized. 84 * 85 * NOTE2: This code is essentially a generic routine for parsing a single 86 * control method. 87 * 88 ******************************************************************************/ 89 90 acpi_status 91 acpi_ds_auto_serialize_method(struct acpi_namespace_node *node, 92 union acpi_operand_object *obj_desc) 93 { 94 acpi_status status; 95 union acpi_parse_object *op = NULL; 96 struct acpi_walk_state *walk_state; 97 98 ACPI_FUNCTION_TRACE_PTR(ds_auto_serialize_method, node); 99 100 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 101 "Method auto-serialization parse [%4.4s] %p\n", 102 acpi_ut_get_node_name(node), node)); 103 104 /* Create/Init a root op for the method parse tree */ 105 106 op = acpi_ps_alloc_op(AML_METHOD_OP); 107 if (!op) { 108 return_ACPI_STATUS(AE_NO_MEMORY); 109 } 110 111 acpi_ps_set_name(op, node->name.integer); 112 op->common.node = node; 113 114 /* Create and initialize a new walk state */ 115 116 walk_state = 117 acpi_ds_create_walk_state(node->owner_id, NULL, NULL, NULL); 118 if (!walk_state) { 119 acpi_ps_free_op(op); 120 return_ACPI_STATUS(AE_NO_MEMORY); 121 } 122 123 status = 124 acpi_ds_init_aml_walk(walk_state, op, node, 125 obj_desc->method.aml_start, 126 obj_desc->method.aml_length, NULL, 0); 127 if (ACPI_FAILURE(status)) { 128 acpi_ds_delete_walk_state(walk_state); 129 acpi_ps_free_op(op); 130 return_ACPI_STATUS(status); 131 } 132 133 walk_state->descending_callback = acpi_ds_detect_named_opcodes; 134 135 /* Parse the method, scan for creation of named objects */ 136 137 status = acpi_ps_parse_aml(walk_state); 138 139 acpi_ps_delete_parse_tree(op); 140 return_ACPI_STATUS(status); 141 } 142 143 /******************************************************************************* 144 * 145 * FUNCTION: acpi_ds_detect_named_opcodes 146 * 147 * PARAMETERS: walk_state - Current state of the parse tree walk 148 * out_op - Unused, required for parser interface 149 * 150 * RETURN: Status 151 * 152 * DESCRIPTION: Descending callback used during the loading of ACPI tables. 153 * Currently used to detect methods that must be marked serialized 154 * in order to avoid problems with the creation of named objects. 155 * 156 ******************************************************************************/ 157 158 static acpi_status 159 acpi_ds_detect_named_opcodes(struct acpi_walk_state *walk_state, 160 union acpi_parse_object **out_op) 161 { 162 163 ACPI_FUNCTION_NAME(acpi_ds_detect_named_opcodes); 164 165 /* We are only interested in opcodes that create a new name */ 166 167 if (! 168 (walk_state->op_info-> 169 flags & (AML_NAMED | AML_CREATE | AML_FIELD))) { 170 return (AE_OK); 171 } 172 173 /* 174 * At this point, we know we have a Named object opcode. 175 * Mark the method as serialized. Later code will create a mutex for 176 * this method to enforce serialization. 177 * 178 * Note, ACPI_METHOD_IGNORE_SYNC_LEVEL flag means that we will ignore the 179 * Sync Level mechanism for this method, even though it is now serialized. 180 * Otherwise, there can be conflicts with existing ASL code that actually 181 * uses sync levels. 182 */ 183 walk_state->method_desc->method.sync_level = 0; 184 walk_state->method_desc->method.info_flags |= 185 (ACPI_METHOD_SERIALIZED | ACPI_METHOD_IGNORE_SYNC_LEVEL); 186 187 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 188 "Method serialized [%4.4s] %p - [%s] (%4.4X)\n", 189 walk_state->method_node->name.ascii, 190 walk_state->method_node, walk_state->op_info->name, 191 walk_state->opcode)); 192 193 /* Abort the parse, no need to examine this method any further */ 194 195 return (AE_CTRL_TERMINATE); 196 } 197 198 /******************************************************************************* 199 * 200 * FUNCTION: acpi_ds_method_error 201 * 202 * PARAMETERS: status - Execution status 203 * walk_state - Current state 204 * 205 * RETURN: Status 206 * 207 * DESCRIPTION: Called on method error. Invoke the global exception handler if 208 * present, dump the method data if the disassembler is configured 209 * 210 * Note: Allows the exception handler to change the status code 211 * 212 ******************************************************************************/ 213 214 acpi_status 215 acpi_ds_method_error(acpi_status status, struct acpi_walk_state * walk_state) 216 { 217 ACPI_FUNCTION_ENTRY(); 218 219 /* Ignore AE_OK and control exception codes */ 220 221 if (ACPI_SUCCESS(status) || (status & AE_CODE_CONTROL)) { 222 return (status); 223 } 224 225 /* Invoke the global exception handler */ 226 227 if (acpi_gbl_exception_handler) { 228 229 /* Exit the interpreter, allow handler to execute methods */ 230 231 acpi_ex_exit_interpreter(); 232 233 /* 234 * Handler can map the exception code to anything it wants, including 235 * AE_OK, in which case the executing method will not be aborted. 236 */ 237 status = acpi_gbl_exception_handler(status, 238 walk_state->method_node ? 239 walk_state->method_node-> 240 name.integer : 0, 241 walk_state->opcode, 242 walk_state->aml_offset, 243 NULL); 244 acpi_ex_enter_interpreter(); 245 } 246 247 acpi_ds_clear_implicit_return(walk_state); 248 249 #ifdef ACPI_DISASSEMBLER 250 if (ACPI_FAILURE(status)) { 251 252 /* Display method locals/args if disassembler is present */ 253 254 acpi_dm_dump_method_info(status, walk_state, walk_state->op); 255 } 256 #endif 257 258 return (status); 259 } 260 261 /******************************************************************************* 262 * 263 * FUNCTION: acpi_ds_create_method_mutex 264 * 265 * PARAMETERS: obj_desc - The method object 266 * 267 * RETURN: Status 268 * 269 * DESCRIPTION: Create a mutex object for a serialized control method 270 * 271 ******************************************************************************/ 272 273 static acpi_status 274 acpi_ds_create_method_mutex(union acpi_operand_object *method_desc) 275 { 276 union acpi_operand_object *mutex_desc; 277 acpi_status status; 278 279 ACPI_FUNCTION_TRACE(ds_create_method_mutex); 280 281 /* Create the new mutex object */ 282 283 mutex_desc = acpi_ut_create_internal_object(ACPI_TYPE_MUTEX); 284 if (!mutex_desc) { 285 return_ACPI_STATUS(AE_NO_MEMORY); 286 } 287 288 /* Create the actual OS Mutex */ 289 290 status = acpi_os_create_mutex(&mutex_desc->mutex.os_mutex); 291 if (ACPI_FAILURE(status)) { 292 acpi_ut_delete_object_desc(mutex_desc); 293 return_ACPI_STATUS(status); 294 } 295 296 mutex_desc->mutex.sync_level = method_desc->method.sync_level; 297 method_desc->method.mutex = mutex_desc; 298 return_ACPI_STATUS(AE_OK); 299 } 300 301 /******************************************************************************* 302 * 303 * FUNCTION: acpi_ds_begin_method_execution 304 * 305 * PARAMETERS: method_node - Node of the method 306 * obj_desc - The method object 307 * walk_state - current state, NULL if not yet executing 308 * a method. 309 * 310 * RETURN: Status 311 * 312 * DESCRIPTION: Prepare a method for execution. Parses the method if necessary, 313 * increments the thread count, and waits at the method semaphore 314 * for clearance to execute. 315 * 316 ******************************************************************************/ 317 318 acpi_status 319 acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, 320 union acpi_operand_object *obj_desc, 321 struct acpi_walk_state *walk_state) 322 { 323 acpi_status status = AE_OK; 324 325 ACPI_FUNCTION_TRACE_PTR(ds_begin_method_execution, method_node); 326 327 if (!method_node) { 328 return_ACPI_STATUS(AE_NULL_ENTRY); 329 } 330 331 /* Prevent wraparound of thread count */ 332 333 if (obj_desc->method.thread_count == ACPI_UINT8_MAX) { 334 ACPI_ERROR((AE_INFO, 335 "Method reached maximum reentrancy limit (255)")); 336 return_ACPI_STATUS(AE_AML_METHOD_LIMIT); 337 } 338 339 /* 340 * If this method is serialized, we need to acquire the method mutex. 341 */ 342 if (obj_desc->method.info_flags & ACPI_METHOD_SERIALIZED) { 343 /* 344 * Create a mutex for the method if it is defined to be Serialized 345 * and a mutex has not already been created. We defer the mutex creation 346 * until a method is actually executed, to minimize the object count 347 */ 348 if (!obj_desc->method.mutex) { 349 status = acpi_ds_create_method_mutex(obj_desc); 350 if (ACPI_FAILURE(status)) { 351 return_ACPI_STATUS(status); 352 } 353 } 354 355 /* 356 * The current_sync_level (per-thread) must be less than or equal to 357 * the sync level of the method. This mechanism provides some 358 * deadlock prevention. 359 * 360 * If the method was auto-serialized, we just ignore the sync level 361 * mechanism, because auto-serialization of methods can interfere 362 * with ASL code that actually uses sync levels. 363 * 364 * Top-level method invocation has no walk state at this point 365 */ 366 if (walk_state && 367 (!(obj_desc->method. 368 info_flags & ACPI_METHOD_IGNORE_SYNC_LEVEL)) 369 && (walk_state->thread->current_sync_level > 370 obj_desc->method.mutex->mutex.sync_level)) { 371 ACPI_ERROR((AE_INFO, 372 "Cannot acquire Mutex for method [%4.4s], current SyncLevel is too large (%u)", 373 acpi_ut_get_node_name(method_node), 374 walk_state->thread->current_sync_level)); 375 376 return_ACPI_STATUS(AE_AML_MUTEX_ORDER); 377 } 378 379 /* 380 * Obtain the method mutex if necessary. Do not acquire mutex for a 381 * recursive call. 382 */ 383 if (!walk_state || 384 !obj_desc->method.mutex->mutex.thread_id || 385 (walk_state->thread->thread_id != 386 obj_desc->method.mutex->mutex.thread_id)) { 387 /* 388 * Acquire the method mutex. This releases the interpreter if we 389 * block (and reacquires it before it returns) 390 */ 391 status = 392 acpi_ex_system_wait_mutex(obj_desc->method.mutex-> 393 mutex.os_mutex, 394 ACPI_WAIT_FOREVER); 395 if (ACPI_FAILURE(status)) { 396 return_ACPI_STATUS(status); 397 } 398 399 /* Update the mutex and walk info and save the original sync_level */ 400 401 if (walk_state) { 402 obj_desc->method.mutex->mutex. 403 original_sync_level = 404 walk_state->thread->current_sync_level; 405 406 obj_desc->method.mutex->mutex.thread_id = 407 walk_state->thread->thread_id; 408 walk_state->thread->current_sync_level = 409 obj_desc->method.sync_level; 410 } else { 411 obj_desc->method.mutex->mutex. 412 original_sync_level = 413 obj_desc->method.mutex->mutex.sync_level; 414 } 415 } 416 417 /* Always increase acquisition depth */ 418 419 obj_desc->method.mutex->mutex.acquisition_depth++; 420 } 421 422 /* 423 * Allocate an Owner ID for this method, only if this is the first thread 424 * to begin concurrent execution. We only need one owner_id, even if the 425 * method is invoked recursively. 426 */ 427 if (!obj_desc->method.owner_id) { 428 status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id); 429 if (ACPI_FAILURE(status)) { 430 goto cleanup; 431 } 432 } 433 434 /* 435 * Increment the method parse tree thread count since it has been 436 * reentered one more time (even if it is the same thread) 437 */ 438 obj_desc->method.thread_count++; 439 acpi_method_count++; 440 return_ACPI_STATUS(status); 441 442 cleanup: 443 /* On error, must release the method mutex (if present) */ 444 445 if (obj_desc->method.mutex) { 446 acpi_os_release_mutex(obj_desc->method.mutex->mutex.os_mutex); 447 } 448 return_ACPI_STATUS(status); 449 } 450 451 /******************************************************************************* 452 * 453 * FUNCTION: acpi_ds_call_control_method 454 * 455 * PARAMETERS: thread - Info for this thread 456 * this_walk_state - Current walk state 457 * op - Current Op to be walked 458 * 459 * RETURN: Status 460 * 461 * DESCRIPTION: Transfer execution to a called control method 462 * 463 ******************************************************************************/ 464 465 acpi_status 466 acpi_ds_call_control_method(struct acpi_thread_state *thread, 467 struct acpi_walk_state *this_walk_state, 468 union acpi_parse_object *op) 469 { 470 acpi_status status; 471 struct acpi_namespace_node *method_node; 472 struct acpi_walk_state *next_walk_state = NULL; 473 union acpi_operand_object *obj_desc; 474 struct acpi_evaluate_info *info; 475 u32 i; 476 477 ACPI_FUNCTION_TRACE_PTR(ds_call_control_method, this_walk_state); 478 479 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 480 "Calling method %p, currentstate=%p\n", 481 this_walk_state->prev_op, this_walk_state)); 482 483 /* 484 * Get the namespace entry for the control method we are about to call 485 */ 486 method_node = this_walk_state->method_call_node; 487 if (!method_node) { 488 return_ACPI_STATUS(AE_NULL_ENTRY); 489 } 490 491 obj_desc = acpi_ns_get_attached_object(method_node); 492 if (!obj_desc) { 493 return_ACPI_STATUS(AE_NULL_OBJECT); 494 } 495 496 /* Init for new method, possibly wait on method mutex */ 497 498 status = acpi_ds_begin_method_execution(method_node, obj_desc, 499 this_walk_state); 500 if (ACPI_FAILURE(status)) { 501 return_ACPI_STATUS(status); 502 } 503 504 /* Begin method parse/execution. Create a new walk state */ 505 506 next_walk_state = acpi_ds_create_walk_state(obj_desc->method.owner_id, 507 NULL, obj_desc, thread); 508 if (!next_walk_state) { 509 status = AE_NO_MEMORY; 510 goto cleanup; 511 } 512 513 /* 514 * The resolved arguments were put on the previous walk state's operand 515 * stack. Operands on the previous walk state stack always 516 * start at index 0. Also, null terminate the list of arguments 517 */ 518 this_walk_state->operands[this_walk_state->num_operands] = NULL; 519 520 /* 521 * Allocate and initialize the evaluation information block 522 * TBD: this is somewhat inefficient, should change interface to 523 * ds_init_aml_walk. For now, keeps this struct off the CPU stack 524 */ 525 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); 526 if (!info) { 527 status = AE_NO_MEMORY; 528 goto cleanup; 529 } 530 531 info->parameters = &this_walk_state->operands[0]; 532 533 status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node, 534 obj_desc->method.aml_start, 535 obj_desc->method.aml_length, info, 536 ACPI_IMODE_EXECUTE); 537 538 ACPI_FREE(info); 539 if (ACPI_FAILURE(status)) { 540 goto cleanup; 541 } 542 543 /* 544 * Delete the operands on the previous walkstate operand stack 545 * (they were copied to new objects) 546 */ 547 for (i = 0; i < obj_desc->method.param_count; i++) { 548 acpi_ut_remove_reference(this_walk_state->operands[i]); 549 this_walk_state->operands[i] = NULL; 550 } 551 552 /* Clear the operand stack */ 553 554 this_walk_state->num_operands = 0; 555 556 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 557 "**** Begin nested execution of [%4.4s] **** WalkState=%p\n", 558 method_node->name.ascii, next_walk_state)); 559 560 /* Invoke an internal method if necessary */ 561 562 if (obj_desc->method.info_flags & ACPI_METHOD_INTERNAL_ONLY) { 563 status = 564 obj_desc->method.dispatch.implementation(next_walk_state); 565 if (status == AE_OK) { 566 status = AE_CTRL_TERMINATE; 567 } 568 } 569 570 return_ACPI_STATUS(status); 571 572 cleanup: 573 574 /* On error, we must terminate the method properly */ 575 576 acpi_ds_terminate_control_method(obj_desc, next_walk_state); 577 if (next_walk_state) { 578 acpi_ds_delete_walk_state(next_walk_state); 579 } 580 581 return_ACPI_STATUS(status); 582 } 583 584 /******************************************************************************* 585 * 586 * FUNCTION: acpi_ds_restart_control_method 587 * 588 * PARAMETERS: walk_state - State for preempted method (caller) 589 * return_desc - Return value from the called method 590 * 591 * RETURN: Status 592 * 593 * DESCRIPTION: Restart a method that was preempted by another (nested) method 594 * invocation. Handle the return value (if any) from the callee. 595 * 596 ******************************************************************************/ 597 598 acpi_status 599 acpi_ds_restart_control_method(struct acpi_walk_state *walk_state, 600 union acpi_operand_object *return_desc) 601 { 602 acpi_status status; 603 int same_as_implicit_return; 604 605 ACPI_FUNCTION_TRACE_PTR(ds_restart_control_method, walk_state); 606 607 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 608 "****Restart [%4.4s] Op %p ReturnValueFromCallee %p\n", 609 acpi_ut_get_node_name(walk_state->method_node), 610 walk_state->method_call_op, return_desc)); 611 612 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 613 " ReturnFromThisMethodUsed?=%X ResStack %p Walk %p\n", 614 walk_state->return_used, 615 walk_state->results, walk_state)); 616 617 /* Did the called method return a value? */ 618 619 if (return_desc) { 620 621 /* Is the implicit return object the same as the return desc? */ 622 623 same_as_implicit_return = 624 (walk_state->implicit_return_obj == return_desc); 625 626 /* Are we actually going to use the return value? */ 627 628 if (walk_state->return_used) { 629 630 /* Save the return value from the previous method */ 631 632 status = acpi_ds_result_push(return_desc, walk_state); 633 if (ACPI_FAILURE(status)) { 634 acpi_ut_remove_reference(return_desc); 635 return_ACPI_STATUS(status); 636 } 637 638 /* 639 * Save as THIS method's return value in case it is returned 640 * immediately to yet another method 641 */ 642 walk_state->return_desc = return_desc; 643 } 644 645 /* 646 * The following code is the optional support for the so-called 647 * "implicit return". Some AML code assumes that the last value of the 648 * method is "implicitly" returned to the caller, in the absence of an 649 * explicit return value. 650 * 651 * Just save the last result of the method as the return value. 652 * 653 * NOTE: this is optional because the ASL language does not actually 654 * support this behavior. 655 */ 656 else if (!acpi_ds_do_implicit_return 657 (return_desc, walk_state, FALSE) 658 || same_as_implicit_return) { 659 /* 660 * Delete the return value if it will not be used by the 661 * calling method or remove one reference if the explicit return 662 * is the same as the implicit return value. 663 */ 664 acpi_ut_remove_reference(return_desc); 665 } 666 } 667 668 return_ACPI_STATUS(AE_OK); 669 } 670 671 /******************************************************************************* 672 * 673 * FUNCTION: acpi_ds_terminate_control_method 674 * 675 * PARAMETERS: method_desc - Method object 676 * walk_state - State associated with the method 677 * 678 * RETURN: None 679 * 680 * DESCRIPTION: Terminate a control method. Delete everything that the method 681 * created, delete all locals and arguments, and delete the parse 682 * tree if requested. 683 * 684 * MUTEX: Interpreter is locked 685 * 686 ******************************************************************************/ 687 688 void 689 acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, 690 struct acpi_walk_state *walk_state) 691 { 692 693 ACPI_FUNCTION_TRACE_PTR(ds_terminate_control_method, walk_state); 694 695 /* method_desc is required, walk_state is optional */ 696 697 if (!method_desc) { 698 return_VOID; 699 } 700 701 if (walk_state) { 702 703 /* Delete all arguments and locals */ 704 705 acpi_ds_method_data_delete_all(walk_state); 706 707 /* 708 * If method is serialized, release the mutex and restore the 709 * current sync level for this thread 710 */ 711 if (method_desc->method.mutex) { 712 713 /* Acquisition Depth handles recursive calls */ 714 715 method_desc->method.mutex->mutex.acquisition_depth--; 716 if (!method_desc->method.mutex->mutex.acquisition_depth) { 717 walk_state->thread->current_sync_level = 718 method_desc->method.mutex->mutex. 719 original_sync_level; 720 721 acpi_os_release_mutex(method_desc->method. 722 mutex->mutex.os_mutex); 723 method_desc->method.mutex->mutex.thread_id = 0; 724 } 725 } 726 727 /* 728 * Delete any namespace objects created anywhere within the 729 * namespace by the execution of this method. Unless: 730 * 1) This method is a module-level executable code method, in which 731 * case we want make the objects permanent. 732 * 2) There are other threads executing the method, in which case we 733 * will wait until the last thread has completed. 734 */ 735 if (!(method_desc->method.info_flags & ACPI_METHOD_MODULE_LEVEL) 736 && (method_desc->method.thread_count == 1)) { 737 738 /* Delete any direct children of (created by) this method */ 739 740 acpi_ns_delete_namespace_subtree(walk_state-> 741 method_node); 742 743 /* 744 * Delete any objects that were created by this method 745 * elsewhere in the namespace (if any were created). 746 * Use of the ACPI_METHOD_MODIFIED_NAMESPACE optimizes the 747 * deletion such that we don't have to perform an entire 748 * namespace walk for every control method execution. 749 */ 750 if (method_desc->method. 751 info_flags & ACPI_METHOD_MODIFIED_NAMESPACE) { 752 acpi_ns_delete_namespace_by_owner(method_desc-> 753 method. 754 owner_id); 755 method_desc->method.info_flags &= 756 ~ACPI_METHOD_MODIFIED_NAMESPACE; 757 } 758 } 759 } 760 761 /* Decrement the thread count on the method */ 762 763 if (method_desc->method.thread_count) { 764 method_desc->method.thread_count--; 765 } else { 766 ACPI_ERROR((AE_INFO, "Invalid zero thread count in method")); 767 } 768 769 /* Are there any other threads currently executing this method? */ 770 771 if (method_desc->method.thread_count) { 772 /* 773 * Additional threads. Do not release the owner_id in this case, 774 * we immediately reuse it for the next thread executing this method 775 */ 776 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 777 "*** Completed execution of one thread, %u threads remaining\n", 778 method_desc->method.thread_count)); 779 } else { 780 /* This is the only executing thread for this method */ 781 782 /* 783 * Support to dynamically change a method from not_serialized to 784 * Serialized if it appears that the method is incorrectly written and 785 * does not support multiple thread execution. The best example of this 786 * is if such a method creates namespace objects and blocks. A second 787 * thread will fail with an AE_ALREADY_EXISTS exception. 788 * 789 * This code is here because we must wait until the last thread exits 790 * before marking the method as serialized. 791 */ 792 if (method_desc->method. 793 info_flags & ACPI_METHOD_SERIALIZED_PENDING) { 794 if (walk_state) { 795 ACPI_INFO((AE_INFO, 796 "Marking method %4.4s as Serialized because of AE_ALREADY_EXISTS error", 797 walk_state->method_node->name. 798 ascii)); 799 } 800 801 /* 802 * Method tried to create an object twice and was marked as 803 * "pending serialized". The probable cause is that the method 804 * cannot handle reentrancy. 805 * 806 * The method was created as not_serialized, but it tried to create 807 * a named object and then blocked, causing the second thread 808 * entrance to begin and then fail. Workaround this problem by 809 * marking the method permanently as Serialized when the last 810 * thread exits here. 811 */ 812 method_desc->method.info_flags &= 813 ~ACPI_METHOD_SERIALIZED_PENDING; 814 method_desc->method.info_flags |= 815 (ACPI_METHOD_SERIALIZED | 816 ACPI_METHOD_IGNORE_SYNC_LEVEL); 817 method_desc->method.sync_level = 0; 818 } 819 820 /* No more threads, we can free the owner_id */ 821 822 if (! 823 (method_desc->method. 824 info_flags & ACPI_METHOD_MODULE_LEVEL)) { 825 acpi_ut_release_owner_id(&method_desc->method.owner_id); 826 } 827 } 828 829 return_VOID; 830 } 831