Subversion Repositories Kolibri OS

Rev

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);