Home | History | Annotate | Line # | Download | only in events
evrgnini.c revision 1.1
      1 /******************************************************************************
      2  *
      3  * Module Name: evrgnini- ACPI AddressSpace (OpRegion) init
      4  *
      5  *****************************************************************************/
      6 
      7 /******************************************************************************
      8  *
      9  * 1. Copyright Notice
     10  *
     11  * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
     12  * All rights reserved.
     13  *
     14  * 2. License
     15  *
     16  * 2.1. This is your license from Intel Corp. under its intellectual property
     17  * rights.  You may have additional license terms from the party that provided
     18  * you this software, covering your right to use that party's intellectual
     19  * property rights.
     20  *
     21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
     22  * copy of the source code appearing in this file ("Covered Code") an
     23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
     24  * base code distributed originally by Intel ("Original Intel Code") to copy,
     25  * make derivatives, distribute, use and display any portion of the Covered
     26  * Code in any form, with the right to sublicense such rights; and
     27  *
     28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
     29  * license (with the right to sublicense), under only those claims of Intel
     30  * patents that are infringed by the Original Intel Code, to make, use, sell,
     31  * offer to sell, and import the Covered Code and derivative works thereof
     32  * solely to the minimum extent necessary to exercise the above copyright
     33  * license, and in no event shall the patent license extend to any additions
     34  * to or modifications of the Original Intel Code.  No other license or right
     35  * is granted directly or by implication, estoppel or otherwise;
     36  *
     37  * The above copyright and patent license is granted only if the following
     38  * conditions are met:
     39  *
     40  * 3. Conditions
     41  *
     42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
     43  * Redistribution of source code of any substantial portion of the Covered
     44  * Code or modification with rights to further distribute source must include
     45  * the above Copyright Notice, the above License, this list of Conditions,
     46  * and the following Disclaimer and Export Compliance provision.  In addition,
     47  * Licensee must cause all Covered Code to which Licensee contributes to
     48  * contain a file documenting the changes Licensee made to create that Covered
     49  * Code and the date of any change.  Licensee must include in that file the
     50  * documentation of any changes made by any predecessor Licensee.  Licensee
     51  * must include a prominent statement that the modification is derived,
     52  * directly or indirectly, from Original Intel Code.
     53  *
     54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
     55  * Redistribution of source code of any substantial portion of the Covered
     56  * Code or modification without rights to further distribute source must
     57  * include the following Disclaimer and Export Compliance provision in the
     58  * documentation and/or other materials provided with distribution.  In
     59  * addition, Licensee may not authorize further sublicense of source of any
     60  * portion of the Covered Code, and must include terms to the effect that the
     61  * license from Licensee to its licensee is limited to the intellectual
     62  * property embodied in the software Licensee provides to its licensee, and
     63  * not to intellectual property embodied in modifications its licensee may
     64  * make.
     65  *
     66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
     67  * substantial portion of the Covered Code or modification must reproduce the
     68  * above Copyright Notice, and the following Disclaimer and Export Compliance
     69  * provision in the documentation and/or other materials provided with the
     70  * distribution.
     71  *
     72  * 3.4. Intel retains all right, title, and interest in and to the Original
     73  * Intel Code.
     74  *
     75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
     76  * Intel shall be used in advertising or otherwise to promote the sale, use or
     77  * other dealings in products derived from or relating to the Covered Code
     78  * without prior written authorization from Intel.
     79  *
     80  * 4. Disclaimer and Export Compliance
     81  *
     82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
     83  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
     84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
     85  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
     86  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
     87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
     88  * PARTICULAR PURPOSE.
     89  *
     90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
     91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
     92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
     93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
     94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
     95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
     96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
     97  * LIMITED REMEDY.
     98  *
     99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
    100  * software or system incorporating such software without first obtaining any
    101  * required license or other approval from the U. S. Department of Commerce or
    102  * any other agency or department of the United States Government.  In the
    103  * event Licensee exports any such software from the United States or
    104  * re-exports any such software from a foreign destination, Licensee shall
    105  * ensure that the distribution and export/re-export of the software is in
    106  * compliance with all laws, regulations, orders, or other restrictions of the
    107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
    108  * any of its subsidiaries will export/re-export any technical data, process,
    109  * software, or service, directly or indirectly, to any country for which the
    110  * United States government or any agency thereof requires an export license,
    111  * other governmental approval, or letter of assurance, without first obtaining
    112  * such license, approval or letter.
    113  *
    114  *****************************************************************************/
    115 
    116 
    117 #define __EVRGNINI_C__
    118 
    119 #include "acpi.h"
    120 #include "accommon.h"
    121 #include "acevents.h"
    122 #include "acnamesp.h"
    123 
    124 #define _COMPONENT          ACPI_EVENTS
    125         ACPI_MODULE_NAME    ("evrgnini")
    126 
    127 /* Local prototypes */
    128 
    129 static BOOLEAN
    130 AcpiEvIsPciRootBridge (
    131     ACPI_NAMESPACE_NODE     *Node);
    132 
    133 
    134 /*******************************************************************************
    135  *
    136  * FUNCTION:    AcpiEvSystemMemoryRegionSetup
    137  *
    138  * PARAMETERS:  Handle              - Region we are interested in
    139  *              Function            - Start or stop
    140  *              HandlerContext      - Address space handler context
    141  *              RegionContext       - Region specific context
    142  *
    143  * RETURN:      Status
    144  *
    145  * DESCRIPTION: Setup a SystemMemory operation region
    146  *
    147  ******************************************************************************/
    148 
    149 ACPI_STATUS
    150 AcpiEvSystemMemoryRegionSetup (
    151     ACPI_HANDLE             Handle,
    152     UINT32                  Function,
    153     void                    *HandlerContext,
    154     void                    **RegionContext)
    155 {
    156     ACPI_OPERAND_OBJECT     *RegionDesc = (ACPI_OPERAND_OBJECT *) Handle;
    157     ACPI_MEM_SPACE_CONTEXT  *LocalRegionContext;
    158 
    159 
    160     ACPI_FUNCTION_TRACE (EvSystemMemoryRegionSetup);
    161 
    162 
    163     if (Function == ACPI_REGION_DEACTIVATE)
    164     {
    165         if (*RegionContext)
    166         {
    167             LocalRegionContext = (ACPI_MEM_SPACE_CONTEXT *) *RegionContext;
    168 
    169             /* Delete a cached mapping if present */
    170 
    171             if (LocalRegionContext->MappedLength)
    172             {
    173                 AcpiOsUnmapMemory (LocalRegionContext->MappedLogicalAddress,
    174                     LocalRegionContext->MappedLength);
    175             }
    176             ACPI_FREE (LocalRegionContext);
    177             *RegionContext = NULL;
    178         }
    179         return_ACPI_STATUS (AE_OK);
    180     }
    181 
    182     /* Create a new context */
    183 
    184     LocalRegionContext = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_MEM_SPACE_CONTEXT));
    185     if (!(LocalRegionContext))
    186     {
    187         return_ACPI_STATUS (AE_NO_MEMORY);
    188     }
    189 
    190     /* Save the region length and address for use in the handler */
    191 
    192     LocalRegionContext->Length  = RegionDesc->Region.Length;
    193     LocalRegionContext->Address = RegionDesc->Region.Address;
    194 
    195     *RegionContext = LocalRegionContext;
    196     return_ACPI_STATUS (AE_OK);
    197 }
    198 
    199 
    200 /*******************************************************************************
    201  *
    202  * FUNCTION:    AcpiEvIoSpaceRegionSetup
    203  *
    204  * PARAMETERS:  Handle              - Region we are interested in
    205  *              Function            - Start or stop
    206  *              HandlerContext      - Address space handler context
    207  *              RegionContext       - Region specific context
    208  *
    209  * RETURN:      Status
    210  *
    211  * DESCRIPTION: Setup a IO operation region
    212  *
    213  ******************************************************************************/
    214 
    215 ACPI_STATUS
    216 AcpiEvIoSpaceRegionSetup (
    217     ACPI_HANDLE             Handle,
    218     UINT32                  Function,
    219     void                    *HandlerContext,
    220     void                    **RegionContext)
    221 {
    222     ACPI_FUNCTION_TRACE (EvIoSpaceRegionSetup);
    223 
    224 
    225     if (Function == ACPI_REGION_DEACTIVATE)
    226     {
    227         *RegionContext = NULL;
    228     }
    229     else
    230     {
    231         *RegionContext = HandlerContext;
    232     }
    233 
    234     return_ACPI_STATUS (AE_OK);
    235 }
    236 
    237 
    238 /*******************************************************************************
    239  *
    240  * FUNCTION:    AcpiEvPciConfigRegionSetup
    241  *
    242  * PARAMETERS:  Handle              - Region we are interested in
    243  *              Function            - Start or stop
    244  *              HandlerContext      - Address space handler context
    245  *              RegionContext       - Region specific context
    246  *
    247  * RETURN:      Status
    248  *
    249  * DESCRIPTION: Setup a PCI_Config operation region
    250  *
    251  * MUTEX:       Assumes namespace is not locked
    252  *
    253  ******************************************************************************/
    254 
    255 ACPI_STATUS
    256 AcpiEvPciConfigRegionSetup (
    257     ACPI_HANDLE             Handle,
    258     UINT32                  Function,
    259     void                    *HandlerContext,
    260     void                    **RegionContext)
    261 {
    262     ACPI_STATUS             Status = AE_OK;
    263     UINT64                  PciValue;
    264     ACPI_PCI_ID             *PciId = *RegionContext;
    265     ACPI_OPERAND_OBJECT     *HandlerObj;
    266     ACPI_NAMESPACE_NODE     *ParentNode;
    267     ACPI_NAMESPACE_NODE     *PciRootNode;
    268     ACPI_NAMESPACE_NODE     *PciDeviceNode;
    269     ACPI_OPERAND_OBJECT     *RegionObj = (ACPI_OPERAND_OBJECT  *) Handle;
    270 
    271 
    272     ACPI_FUNCTION_TRACE (EvPciConfigRegionSetup);
    273 
    274 
    275     HandlerObj = RegionObj->Region.Handler;
    276     if (!HandlerObj)
    277     {
    278         /*
    279          * No installed handler. This shouldn't happen because the dispatch
    280          * routine checks before we get here, but we check again just in case.
    281          */
    282         ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
    283             "Attempting to init a region %p, with no handler\n", RegionObj));
    284         return_ACPI_STATUS (AE_NOT_EXIST);
    285     }
    286 
    287     *RegionContext = NULL;
    288     if (Function == ACPI_REGION_DEACTIVATE)
    289     {
    290         if (PciId)
    291         {
    292             ACPI_FREE (PciId);
    293         }
    294         return_ACPI_STATUS (Status);
    295     }
    296 
    297     ParentNode = RegionObj->Region.Node->Parent;
    298 
    299     /*
    300      * Get the _SEG and _BBN values from the device upon which the handler
    301      * is installed.
    302      *
    303      * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
    304      * This is the device the handler has been registered to handle.
    305      */
    306 
    307     /*
    308      * If the AddressSpace.Node is still pointing to the root, we need
    309      * to scan upward for a PCI Root bridge and re-associate the OpRegion
    310      * handlers with that device.
    311      */
    312     if (HandlerObj->AddressSpace.Node == AcpiGbl_RootNode)
    313     {
    314         /* Start search from the parent object */
    315 
    316         PciRootNode = ParentNode;
    317         while (PciRootNode != AcpiGbl_RootNode)
    318         {
    319             /* Get the _HID/_CID in order to detect a RootBridge */
    320 
    321             if (AcpiEvIsPciRootBridge (PciRootNode))
    322             {
    323                 /* Install a handler for this PCI root bridge */
    324 
    325                 Status = AcpiInstallAddressSpaceHandler (
    326                             (ACPI_HANDLE) PciRootNode,
    327                             ACPI_ADR_SPACE_PCI_CONFIG,
    328                             ACPI_DEFAULT_HANDLER, NULL, NULL);
    329                 if (ACPI_FAILURE (Status))
    330                 {
    331                     if (Status == AE_SAME_HANDLER)
    332                     {
    333                         /*
    334                          * It is OK if the handler is already installed on the
    335                          * root bridge. Still need to return a context object
    336                          * for the new PCI_Config operation region, however.
    337                          */
    338                         Status = AE_OK;
    339                     }
    340                     else
    341                     {
    342                         ACPI_EXCEPTION ((AE_INFO, Status,
    343                             "Could not install PciConfig handler "
    344                             "for Root Bridge %4.4s",
    345                             AcpiUtGetNodeName (PciRootNode)));
    346                     }
    347                 }
    348                 break;
    349             }
    350 
    351             PciRootNode = PciRootNode->Parent;
    352         }
    353 
    354         /* PCI root bridge not found, use namespace root node */
    355     }
    356     else
    357     {
    358         PciRootNode = HandlerObj->AddressSpace.Node;
    359     }
    360 
    361     /*
    362      * If this region is now initialized, we are done.
    363      * (InstallAddressSpaceHandler could have initialized it)
    364      */
    365     if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)
    366     {
    367         return_ACPI_STATUS (AE_OK);
    368     }
    369 
    370     /* Region is still not initialized. Create a new context */
    371 
    372     PciId = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PCI_ID));
    373     if (!PciId)
    374     {
    375         return_ACPI_STATUS (AE_NO_MEMORY);
    376     }
    377 
    378     /*
    379      * For PCI_Config space access, we need the segment, bus, device and
    380      * function numbers. Acquire them here.
    381      *
    382      * Find the parent device object. (This allows the operation region to be
    383      * within a subscope under the device, such as a control method.)
    384      */
    385     PciDeviceNode = RegionObj->Region.Node;
    386     while (PciDeviceNode && (PciDeviceNode->Type != ACPI_TYPE_DEVICE))
    387     {
    388         PciDeviceNode = PciDeviceNode->Parent;
    389     }
    390 
    391     if (!PciDeviceNode)
    392     {
    393         ACPI_FREE (PciId);
    394         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
    395     }
    396 
    397     /*
    398      * Get the PCI device and function numbers from the _ADR object contained
    399      * in the parent's scope.
    400      */
    401     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR,
    402                 PciDeviceNode, &PciValue);
    403 
    404     /*
    405      * The default is zero, and since the allocation above zeroed the data,
    406      * just do nothing on failure.
    407      */
    408     if (ACPI_SUCCESS (Status))
    409     {
    410         PciId->Device   = ACPI_HIWORD (ACPI_LODWORD (PciValue));
    411         PciId->Function = ACPI_LOWORD (ACPI_LODWORD (PciValue));
    412     }
    413 
    414     /* The PCI segment number comes from the _SEG method */
    415 
    416     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG,
    417                 PciRootNode, &PciValue);
    418     if (ACPI_SUCCESS (Status))
    419     {
    420         PciId->Segment = ACPI_LOWORD (PciValue);
    421     }
    422 
    423     /* The PCI bus number comes from the _BBN method */
    424 
    425     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN,
    426                 PciRootNode, &PciValue);
    427     if (ACPI_SUCCESS (Status))
    428     {
    429         PciId->Bus = ACPI_LOWORD (PciValue);
    430     }
    431 
    432     /* Complete this device's PciId */
    433 
    434     AcpiOsDerivePciId (PciRootNode, RegionObj->Region.Node, &PciId);
    435 
    436     *RegionContext = PciId;
    437     return_ACPI_STATUS (AE_OK);
    438 }
    439 
    440 
    441 /*******************************************************************************
    442  *
    443  * FUNCTION:    AcpiEvIsPciRootBridge
    444  *
    445  * PARAMETERS:  Node            - Device node being examined
    446  *
    447  * RETURN:      TRUE if device is a PCI/PCI-Express Root Bridge
    448  *
    449  * DESCRIPTION: Determine if the input device represents a PCI Root Bridge by
    450  *              examining the _HID and _CID for the device.
    451  *
    452  ******************************************************************************/
    453 
    454 static BOOLEAN
    455 AcpiEvIsPciRootBridge (
    456     ACPI_NAMESPACE_NODE     *Node)
    457 {
    458     ACPI_STATUS             Status;
    459     ACPI_DEVICE_ID          *Hid;
    460     ACPI_DEVICE_ID_LIST     *Cid;
    461     UINT32                  i;
    462     BOOLEAN                 Match;
    463 
    464 
    465     /* Get the _HID and check for a PCI Root Bridge */
    466 
    467     Status = AcpiUtExecute_HID (Node, &Hid);
    468     if (ACPI_FAILURE (Status))
    469     {
    470         return (FALSE);
    471     }
    472 
    473     Match = AcpiUtIsPciRootBridge (Hid->String);
    474     ACPI_FREE (Hid);
    475 
    476     if (Match)
    477     {
    478         return (TRUE);
    479     }
    480 
    481     /* The _HID did not match. Get the _CID and check for a PCI Root Bridge */
    482 
    483     Status = AcpiUtExecute_CID (Node, &Cid);
    484     if (ACPI_FAILURE (Status))
    485     {
    486         return (FALSE);
    487     }
    488 
    489     /* Check all _CIDs in the returned list */
    490 
    491     for (i = 0; i < Cid->Count; i++)
    492     {
    493         if (AcpiUtIsPciRootBridge (Cid->Ids[i].String))
    494         {
    495             ACPI_FREE (Cid);
    496             return (TRUE);
    497         }
    498     }
    499 
    500     ACPI_FREE (Cid);
    501     return (FALSE);
    502 }
    503 
    504 
    505 /*******************************************************************************
    506  *
    507  * FUNCTION:    AcpiEvPciBarRegionSetup
    508  *
    509  * PARAMETERS:  Handle              - Region we are interested in
    510  *              Function            - Start or stop
    511  *              HandlerContext      - Address space handler context
    512  *              RegionContext       - Region specific context
    513  *
    514  * RETURN:      Status
    515  *
    516  * DESCRIPTION: Setup a PciBAR operation region
    517  *
    518  * MUTEX:       Assumes namespace is not locked
    519  *
    520  ******************************************************************************/
    521 
    522 ACPI_STATUS
    523 AcpiEvPciBarRegionSetup (
    524     ACPI_HANDLE             Handle,
    525     UINT32                  Function,
    526     void                    *HandlerContext,
    527     void                    **RegionContext)
    528 {
    529     ACPI_FUNCTION_TRACE (EvPciBarRegionSetup);
    530 
    531 
    532     return_ACPI_STATUS (AE_OK);
    533 }
    534 
    535 
    536 /*******************************************************************************
    537  *
    538  * FUNCTION:    AcpiEvCmosRegionSetup
    539  *
    540  * PARAMETERS:  Handle              - Region we are interested in
    541  *              Function            - Start or stop
    542  *              HandlerContext      - Address space handler context
    543  *              RegionContext       - Region specific context
    544  *
    545  * RETURN:      Status
    546  *
    547  * DESCRIPTION: Setup a CMOS operation region
    548  *
    549  * MUTEX:       Assumes namespace is not locked
    550  *
    551  ******************************************************************************/
    552 
    553 ACPI_STATUS
    554 AcpiEvCmosRegionSetup (
    555     ACPI_HANDLE             Handle,
    556     UINT32                  Function,
    557     void                    *HandlerContext,
    558     void                    **RegionContext)
    559 {
    560     ACPI_FUNCTION_TRACE (EvCmosRegionSetup);
    561 
    562 
    563     return_ACPI_STATUS (AE_OK);
    564 }
    565 
    566 
    567 /*******************************************************************************
    568  *
    569  * FUNCTION:    AcpiEvDefaultRegionSetup
    570  *
    571  * PARAMETERS:  Handle              - Region we are interested in
    572  *              Function            - Start or stop
    573  *              HandlerContext      - Address space handler context
    574  *              RegionContext       - Region specific context
    575  *
    576  * RETURN:      Status
    577  *
    578  * DESCRIPTION: Default region initialization
    579  *
    580  ******************************************************************************/
    581 
    582 ACPI_STATUS
    583 AcpiEvDefaultRegionSetup (
    584     ACPI_HANDLE             Handle,
    585     UINT32                  Function,
    586     void                    *HandlerContext,
    587     void                    **RegionContext)
    588 {
    589     ACPI_FUNCTION_TRACE (EvDefaultRegionSetup);
    590 
    591 
    592     if (Function == ACPI_REGION_DEACTIVATE)
    593     {
    594         *RegionContext = NULL;
    595     }
    596     else
    597     {
    598         *RegionContext = HandlerContext;
    599     }
    600 
    601     return_ACPI_STATUS (AE_OK);
    602 }
    603 
    604 
    605 /*******************************************************************************
    606  *
    607  * FUNCTION:    AcpiEvInitializeRegion
    608  *
    609  * PARAMETERS:  RegionObj       - Region we are initializing
    610  *              AcpiNsLocked    - Is namespace locked?
    611  *
    612  * RETURN:      Status
    613  *
    614  * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
    615  *              for execution at a later time
    616  *
    617  *              Get the appropriate address space handler for a newly
    618  *              created region.
    619  *
    620  *              This also performs address space specific initialization. For
    621  *              example, PCI regions must have an _ADR object that contains
    622  *              a PCI address in the scope of the definition. This address is
    623  *              required to perform an access to PCI config space.
    624  *
    625  * MUTEX:       Interpreter should be unlocked, because we may run the _REG
    626  *              method for this region.
    627  *
    628  ******************************************************************************/
    629 
    630 ACPI_STATUS
    631 AcpiEvInitializeRegion (
    632     ACPI_OPERAND_OBJECT     *RegionObj,
    633     BOOLEAN                 AcpiNsLocked)
    634 {
    635     ACPI_OPERAND_OBJECT     *HandlerObj;
    636     ACPI_OPERAND_OBJECT     *ObjDesc;
    637     ACPI_ADR_SPACE_TYPE     SpaceId;
    638     ACPI_NAMESPACE_NODE     *Node;
    639     ACPI_STATUS             Status;
    640     ACPI_NAMESPACE_NODE     *MethodNode;
    641     ACPI_NAME               *RegNamePtr = (ACPI_NAME *) METHOD_NAME__REG;
    642     ACPI_OPERAND_OBJECT     *RegionObj2;
    643 
    644 
    645     ACPI_FUNCTION_TRACE_U32 (EvInitializeRegion, AcpiNsLocked);
    646 
    647 
    648     if (!RegionObj)
    649     {
    650         return_ACPI_STATUS (AE_BAD_PARAMETER);
    651     }
    652 
    653     if (RegionObj->Common.Flags & AOPOBJ_OBJECT_INITIALIZED)
    654     {
    655         return_ACPI_STATUS (AE_OK);
    656     }
    657 
    658     RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
    659     if (!RegionObj2)
    660     {
    661         return_ACPI_STATUS (AE_NOT_EXIST);
    662     }
    663 
    664     Node = RegionObj->Region.Node->Parent;
    665     SpaceId = RegionObj->Region.SpaceId;
    666 
    667     /* Setup defaults */
    668 
    669     RegionObj->Region.Handler = NULL;
    670     RegionObj2->Extra.Method_REG = NULL;
    671     RegionObj->Common.Flags &= ~(AOPOBJ_SETUP_COMPLETE);
    672     RegionObj->Common.Flags |= AOPOBJ_OBJECT_INITIALIZED;
    673 
    674     /* Find any "_REG" method associated with this region definition */
    675 
    676     Status = AcpiNsSearchOneScope (
    677                 *RegNamePtr, Node, ACPI_TYPE_METHOD, &MethodNode);
    678     if (ACPI_SUCCESS (Status))
    679     {
    680         /*
    681          * The _REG method is optional and there can be only one per region
    682          * definition. This will be executed when the handler is attached
    683          * or removed
    684          */
    685         RegionObj2->Extra.Method_REG = MethodNode;
    686     }
    687 
    688     /*
    689      * The following loop depends upon the root Node having no parent
    690      * ie: AcpiGbl_RootNode->ParentEntry being set to NULL
    691      */
    692     while (Node)
    693     {
    694         /* Check to see if a handler exists */
    695 
    696         HandlerObj = NULL;
    697         ObjDesc = AcpiNsGetAttachedObject (Node);
    698         if (ObjDesc)
    699         {
    700             /* Can only be a handler if the object exists */
    701 
    702             switch (Node->Type)
    703             {
    704             case ACPI_TYPE_DEVICE:
    705 
    706                 HandlerObj = ObjDesc->Device.Handler;
    707                 break;
    708 
    709             case ACPI_TYPE_PROCESSOR:
    710 
    711                 HandlerObj = ObjDesc->Processor.Handler;
    712                 break;
    713 
    714             case ACPI_TYPE_THERMAL:
    715 
    716                 HandlerObj = ObjDesc->ThermalZone.Handler;
    717                 break;
    718 
    719             case ACPI_TYPE_METHOD:
    720                 /*
    721                  * If we are executing module level code, the original
    722                  * Node's object was replaced by this Method object and we
    723                  * saved the handler in the method object.
    724                  *
    725                  * See AcpiNsExecModuleCode
    726                  */
    727                 if (ObjDesc->Method.Flags & AOPOBJ_MODULE_LEVEL)
    728                 {
    729                     HandlerObj = ObjDesc->Method.Extra.Handler;
    730                 }
    731                 break;
    732 
    733             default:
    734                 /* Ignore other objects */
    735                 break;
    736             }
    737 
    738             while (HandlerObj)
    739             {
    740                 /* Is this handler of the correct type? */
    741 
    742                 if (HandlerObj->AddressSpace.SpaceId == SpaceId)
    743                 {
    744                     /* Found correct handler */
    745 
    746                     ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
    747                         "Found handler %p for region %p in obj %p\n",
    748                         HandlerObj, RegionObj, ObjDesc));
    749 
    750                     Status = AcpiEvAttachRegion (HandlerObj, RegionObj,
    751                                 AcpiNsLocked);
    752 
    753                     /*
    754                      * Tell all users that this region is usable by
    755                      * running the _REG method
    756                      */
    757                     if (AcpiNsLocked)
    758                     {
    759                         Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    760                         if (ACPI_FAILURE (Status))
    761                         {
    762                             return_ACPI_STATUS (Status);
    763                         }
    764                     }
    765 
    766                     Status = AcpiEvExecuteRegMethod (RegionObj, 1);
    767 
    768                     if (AcpiNsLocked)
    769                     {
    770                         Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    771                         if (ACPI_FAILURE (Status))
    772                         {
    773                             return_ACPI_STATUS (Status);
    774                         }
    775                     }
    776 
    777                     return_ACPI_STATUS (AE_OK);
    778                 }
    779 
    780                 /* Try next handler in the list */
    781 
    782                 HandlerObj = HandlerObj->AddressSpace.Next;
    783             }
    784         }
    785 
    786         /* This node does not have the handler we need; Pop up one level */
    787 
    788         Node = Node->Parent;
    789     }
    790 
    791     /* If we get here, there is no handler for this region */
    792 
    793     ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
    794         "No handler for RegionType %s(%X) (RegionObj %p)\n",
    795         AcpiUtGetRegionName (SpaceId), SpaceId, RegionObj));
    796 
    797     return_ACPI_STATUS (AE_NOT_EXIST);
    798 }
    799 
    800