Rev 1498 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1498 | Rev 2216 | ||
---|---|---|---|
Line 6... | Line 6... | ||
6 | 6 | ||
7 | /****************************************************************************** |
7 | /****************************************************************************** |
8 | * |
8 | * |
9 | * 1. Copyright Notice |
9 | * 1. Copyright Notice |
10 | * |
10 | * |
11 | * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. |
11 | * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp. |
12 | * All rights reserved. |
12 | * All rights reserved. |
13 | * |
13 | * |
14 | * 2. License |
14 | * 2. License |
15 | * |
15 | * |
Line 115... | Line 115... | ||
115 | 115 | ||
Line 116... | Line 116... | ||
116 | #define __DSMETHOD_C__ |
116 | #define __DSMETHOD_C__ |
117 | 117 | ||
118 | #include "acpi.h" |
- | |
119 | #include "accommon.h" |
118 | #include "acpi.h" |
120 | #include "amlcode.h" |
119 | #include "accommon.h" |
121 | #include "acdispat.h" |
120 | #include "acdispat.h" |
122 | #include "acinterp.h" |
121 | #include "acinterp.h" |
Line 289... | Line 288... | ||
289 | } |
288 | } |
Line 290... | Line 289... | ||
290 | 289 | ||
291 | /* |
290 | /* |
292 | * If this method is serialized, we need to acquire the method mutex. |
291 | * If this method is serialized, we need to acquire the method mutex. |
293 | */ |
292 | */ |
294 | if (ObjDesc->Method.MethodFlags & AML_METHOD_SERIALIZED) |
293 | if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED) |
295 | { |
294 | { |
296 | /* |
295 | /* |
297 | * Create a mutex for the method if it is defined to be Serialized |
296 | * Create a mutex for the method if it is defined to be Serialized |
298 | * and a mutex has not already been created. We defer the mutex creation |
297 | * and a mutex has not already been created. We defer the mutex creation |
Line 515... | Line 514... | ||
515 | "**** Begin nested execution of [%4.4s] **** WalkState=%p\n", |
514 | "**** Begin nested execution of [%4.4s] **** WalkState=%p\n", |
516 | MethodNode->Name.Ascii, NextWalkState)); |
515 | MethodNode->Name.Ascii, NextWalkState)); |
Line 517... | Line 516... | ||
517 | 516 | ||
Line 518... | Line 517... | ||
518 | /* Invoke an internal method if necessary */ |
517 | /* Invoke an internal method if necessary */ |
519 | 518 | ||
520 | if (ObjDesc->Method.MethodFlags & AML_METHOD_INTERNAL_ONLY) |
519 | if (ObjDesc->Method.InfoFlags & ACPI_METHOD_INTERNAL_ONLY) |
521 | { |
520 | { |
522 | Status = ObjDesc->Method.Extra.Implementation (NextWalkState); |
521 | Status = ObjDesc->Method.Dispatch.Implementation (NextWalkState); |
523 | if (Status == AE_OK) |
522 | if (Status == AE_OK) |
524 | { |
523 | { |
525 | Status = AE_CTRL_TERMINATE; |
524 | Status = AE_CTRL_TERMINATE; |
Line 692... | Line 691... | ||
692 | } |
691 | } |
693 | } |
692 | } |
Line 694... | Line 693... | ||
694 | 693 | ||
695 | /* |
694 | /* |
696 | * Delete any namespace objects created anywhere within the |
695 | * Delete any namespace objects created anywhere within the |
697 | * namespace by the execution of this method. Unless this method |
696 | * namespace by the execution of this method. Unless: |
698 | * is a module-level executable code method, in which case we |
697 | * 1) This method is a module-level executable code method, in which |
- | 698 | * case we want make the objects permanent. |
|
- | 699 | * 2) There are other threads executing the method, in which case we |
|
699 | * want make the objects permanent. |
700 | * will wait until the last thread has completed. |
700 | */ |
701 | */ |
- | 702 | if (!(MethodDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL) && |
|
701 | if (!(MethodDesc->Method.Flags & AOPOBJ_MODULE_LEVEL)) |
703 | (MethodDesc->Method.ThreadCount == 1)) |
702 | { |
704 | { |
Line 703... | Line 705... | ||
703 | /* Delete any direct children of (created by) this method */ |
705 | /* Delete any direct children of (created by) this method */ |
Line 704... | Line 706... | ||
704 | 706 | ||
705 | AcpiNsDeleteNamespaceSubtree (WalkState->MethodNode); |
707 | AcpiNsDeleteNamespaceSubtree (WalkState->MethodNode); |
706 | 708 | ||
- | 709 | /* |
|
- | 710 | * Delete any objects that were created by this method |
|
- | 711 | * elsewhere in the namespace (if any were created). |
|
707 | /* |
712 | * Use of the ACPI_METHOD_MODIFIED_NAMESPACE optimizes the |
708 | * Delete any objects that were created by this method |
713 | * deletion such that we don't have to perform an entire |
709 | * elsewhere in the namespace (if any were created). |
714 | * namespace walk for every control method execution. |
710 | */ |
715 | */ |
- | 716 | if (MethodDesc->Method.InfoFlags & ACPI_METHOD_MODIFIED_NAMESPACE) |
|
711 | if (MethodDesc->Method.Flags & AOPOBJ_MODIFIED_NAMESPACE) |
717 | { |
712 | { |
718 | AcpiNsDeleteNamespaceByOwner (MethodDesc->Method.OwnerId); |
713 | AcpiNsDeleteNamespaceByOwner (MethodDesc->Method.OwnerId); |
719 | MethodDesc->Method.InfoFlags &= ~ACPI_METHOD_MODIFIED_NAMESPACE; |
Line 714... | Line 720... | ||
714 | } |
720 | } |
Line 746... | Line 752... | ||
746 | /* |
752 | /* |
747 | * Support to dynamically change a method from NotSerialized to |
753 | * Support to dynamically change a method from NotSerialized to |
748 | * Serialized if it appears that the method is incorrectly written and |
754 | * Serialized if it appears that the method is incorrectly written and |
749 | * does not support multiple thread execution. The best example of this |
755 | * does not support multiple thread execution. The best example of this |
750 | * is if such a method creates namespace objects and blocks. A second |
756 | * is if such a method creates namespace objects and blocks. A second |
751 | * thread will fail with an AE_ALREADY_EXISTS exception |
757 | * thread will fail with an AE_ALREADY_EXISTS exception. |
752 | * |
758 | * |
753 | * This code is here because we must wait until the last thread exits |
759 | * This code is here because we must wait until the last thread exits |
754 | * before creating the synchronization semaphore. |
760 | * before marking the method as serialized. |
755 | */ |
761 | */ |
756 | if ((MethodDesc->Method.MethodFlags & AML_METHOD_SERIALIZED) && |
762 | if (MethodDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED_PENDING) |
757 | (!MethodDesc->Method.Mutex)) |
- | |
758 | { |
763 | { |
- | 764 | if (WalkState) |
|
- | 765 | { |
|
- | 766 | ACPI_INFO ((AE_INFO, |
|
- | 767 | "Marking method %4.4s as Serialized because of AE_ALREADY_EXISTS error", |
|
759 | (void) AcpiDsCreateMethodMutex (MethodDesc); |
768 | WalkState->MethodNode->Name.Ascii)); |
- | 769 | } |
|
- | 770 | ||
- | 771 | /* |
|
- | 772 | * Method tried to create an object twice and was marked as |
|
- | 773 | * "pending serialized". The probable cause is that the method |
|
- | 774 | * cannot handle reentrancy. |
|
- | 775 | * |
|
- | 776 | * The method was created as NotSerialized, but it tried to create |
|
- | 777 | * a named object and then blocked, causing the second thread |
|
- | 778 | * entrance to begin and then fail. Workaround this problem by |
|
- | 779 | * marking the method permanently as Serialized when the last |
|
- | 780 | * thread exits here. |
|
- | 781 | */ |
|
- | 782 | MethodDesc->Method.InfoFlags &= ~ACPI_METHOD_SERIALIZED_PENDING; |
|
- | 783 | MethodDesc->Method.InfoFlags |= ACPI_METHOD_SERIALIZED; |
|
- | 784 | MethodDesc->Method.SyncLevel = 0; |
|
760 | } |
785 | } |
Line 761... | Line 786... | ||
761 | 786 | ||
Line 762... | Line 787... | ||
762 | /* No more threads, we can free the OwnerId */ |
787 | /* No more threads, we can free the OwnerId */ |
763 | 788 | ||
764 | if (!(MethodDesc->Method.Flags & AOPOBJ_MODULE_LEVEL)) |
789 | if (!(MethodDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL)) |
765 | { |
790 | { |
766 | AcpiUtReleaseOwnerId (&MethodDesc->Method.OwnerId); |
791 | AcpiUtReleaseOwnerId (&MethodDesc->Method.OwnerId); |