Subversion Repositories Kolibri OS

Rev

Rev 1498 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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 - 2011, 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
  399.      * contained 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/update the PCI ID for this device */
  433.  
  434.     Status = AcpiHwDerivePciId (PciId, PciRootNode, RegionObj->Region.Node);
  435.     if (ACPI_FAILURE (Status))
  436.     {
  437.         ACPI_FREE (PciId);
  438.         return_ACPI_STATUS (Status);
  439.     }
  440.  
  441.     *RegionContext = PciId;
  442.     return_ACPI_STATUS (AE_OK);
  443. }
  444.  
  445.  
  446. /*******************************************************************************
  447.  *
  448.  * FUNCTION:    AcpiEvIsPciRootBridge
  449.  *
  450.  * PARAMETERS:  Node            - Device node being examined
  451.  *
  452.  * RETURN:      TRUE if device is a PCI/PCI-Express Root Bridge
  453.  *
  454.  * DESCRIPTION: Determine if the input device represents a PCI Root Bridge by
  455.  *              examining the _HID and _CID for the device.
  456.  *
  457.  ******************************************************************************/
  458.  
  459. static BOOLEAN
  460. AcpiEvIsPciRootBridge (
  461.     ACPI_NAMESPACE_NODE     *Node)
  462. {
  463.     ACPI_STATUS             Status;
  464.     ACPI_DEVICE_ID          *Hid;
  465.     ACPI_DEVICE_ID_LIST     *Cid;
  466.     UINT32                  i;
  467.     BOOLEAN                 Match;
  468.  
  469.  
  470.     /* Get the _HID and check for a PCI Root Bridge */
  471.  
  472.     Status = AcpiUtExecute_HID (Node, &Hid);
  473.     if (ACPI_FAILURE (Status))
  474.     {
  475.         return (FALSE);
  476.     }
  477.  
  478.     Match = AcpiUtIsPciRootBridge (Hid->String);
  479.     ACPI_FREE (Hid);
  480.  
  481.     if (Match)
  482.     {
  483.         return (TRUE);
  484.     }
  485.  
  486.     /* The _HID did not match. Get the _CID and check for a PCI Root Bridge */
  487.  
  488.     Status = AcpiUtExecute_CID (Node, &Cid);
  489.     if (ACPI_FAILURE (Status))
  490.     {
  491.         return (FALSE);
  492.     }
  493.  
  494.     /* Check all _CIDs in the returned list */
  495.  
  496.     for (i = 0; i < Cid->Count; i++)
  497.     {
  498.         if (AcpiUtIsPciRootBridge (Cid->Ids[i].String))
  499.         {
  500.             ACPI_FREE (Cid);
  501.             return (TRUE);
  502.         }
  503.     }
  504.  
  505.     ACPI_FREE (Cid);
  506.     return (FALSE);
  507. }
  508.  
  509.  
  510. /*******************************************************************************
  511.  *
  512.  * FUNCTION:    AcpiEvPciBarRegionSetup
  513.  *
  514.  * PARAMETERS:  Handle              - Region we are interested in
  515.  *              Function            - Start or stop
  516.  *              HandlerContext      - Address space handler context
  517.  *              RegionContext       - Region specific context
  518.  *
  519.  * RETURN:      Status
  520.  *
  521.  * DESCRIPTION: Setup a PciBAR operation region
  522.  *
  523.  * MUTEX:       Assumes namespace is not locked
  524.  *
  525.  ******************************************************************************/
  526.  
  527. ACPI_STATUS
  528. AcpiEvPciBarRegionSetup (
  529.     ACPI_HANDLE             Handle,
  530.     UINT32                  Function,
  531.     void                    *HandlerContext,
  532.     void                    **RegionContext)
  533. {
  534.     ACPI_FUNCTION_TRACE (EvPciBarRegionSetup);
  535.  
  536.  
  537.     return_ACPI_STATUS (AE_OK);
  538. }
  539.  
  540.  
  541. /*******************************************************************************
  542.  *
  543.  * FUNCTION:    AcpiEvCmosRegionSetup
  544.  *
  545.  * PARAMETERS:  Handle              - Region we are interested in
  546.  *              Function            - Start or stop
  547.  *              HandlerContext      - Address space handler context
  548.  *              RegionContext       - Region specific context
  549.  *
  550.  * RETURN:      Status
  551.  *
  552.  * DESCRIPTION: Setup a CMOS operation region
  553.  *
  554.  * MUTEX:       Assumes namespace is not locked
  555.  *
  556.  ******************************************************************************/
  557.  
  558. ACPI_STATUS
  559. AcpiEvCmosRegionSetup (
  560.     ACPI_HANDLE             Handle,
  561.     UINT32                  Function,
  562.     void                    *HandlerContext,
  563.     void                    **RegionContext)
  564. {
  565.     ACPI_FUNCTION_TRACE (EvCmosRegionSetup);
  566.  
  567.  
  568.     return_ACPI_STATUS (AE_OK);
  569. }
  570.  
  571.  
  572. /*******************************************************************************
  573.  *
  574.  * FUNCTION:    AcpiEvDefaultRegionSetup
  575.  *
  576.  * PARAMETERS:  Handle              - Region we are interested in
  577.  *              Function            - Start or stop
  578.  *              HandlerContext      - Address space handler context
  579.  *              RegionContext       - Region specific context
  580.  *
  581.  * RETURN:      Status
  582.  *
  583.  * DESCRIPTION: Default region initialization
  584.  *
  585.  ******************************************************************************/
  586.  
  587. ACPI_STATUS
  588. AcpiEvDefaultRegionSetup (
  589.     ACPI_HANDLE             Handle,
  590.     UINT32                  Function,
  591.     void                    *HandlerContext,
  592.     void                    **RegionContext)
  593. {
  594.     ACPI_FUNCTION_TRACE (EvDefaultRegionSetup);
  595.  
  596.  
  597.     if (Function == ACPI_REGION_DEACTIVATE)
  598.     {
  599.         *RegionContext = NULL;
  600.     }
  601.     else
  602.     {
  603.         *RegionContext = HandlerContext;
  604.     }
  605.  
  606.     return_ACPI_STATUS (AE_OK);
  607. }
  608.  
  609.  
  610. /*******************************************************************************
  611.  *
  612.  * FUNCTION:    AcpiEvInitializeRegion
  613.  *
  614.  * PARAMETERS:  RegionObj       - Region we are initializing
  615.  *              AcpiNsLocked    - Is namespace locked?
  616.  *
  617.  * RETURN:      Status
  618.  *
  619.  * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
  620.  *              for execution at a later time
  621.  *
  622.  *              Get the appropriate address space handler for a newly
  623.  *              created region.
  624.  *
  625.  *              This also performs address space specific initialization. For
  626.  *              example, PCI regions must have an _ADR object that contains
  627.  *              a PCI address in the scope of the definition. This address is
  628.  *              required to perform an access to PCI config space.
  629.  *
  630.  * MUTEX:       Interpreter should be unlocked, because we may run the _REG
  631.  *              method for this region.
  632.  *
  633.  ******************************************************************************/
  634.  
  635. ACPI_STATUS
  636. AcpiEvInitializeRegion (
  637.     ACPI_OPERAND_OBJECT     *RegionObj,
  638.     BOOLEAN                 AcpiNsLocked)
  639. {
  640.     ACPI_OPERAND_OBJECT     *HandlerObj;
  641.     ACPI_OPERAND_OBJECT     *ObjDesc;
  642.     ACPI_ADR_SPACE_TYPE     SpaceId;
  643.     ACPI_NAMESPACE_NODE     *Node;
  644.     ACPI_STATUS             Status;
  645.     ACPI_NAMESPACE_NODE     *MethodNode;
  646.     ACPI_NAME               *RegNamePtr = (ACPI_NAME *) METHOD_NAME__REG;
  647.     ACPI_OPERAND_OBJECT     *RegionObj2;
  648.  
  649.  
  650.     ACPI_FUNCTION_TRACE_U32 (EvInitializeRegion, AcpiNsLocked);
  651.  
  652.  
  653.     if (!RegionObj)
  654.     {
  655.         return_ACPI_STATUS (AE_BAD_PARAMETER);
  656.     }
  657.  
  658.     if (RegionObj->Common.Flags & AOPOBJ_OBJECT_INITIALIZED)
  659.     {
  660.         return_ACPI_STATUS (AE_OK);
  661.     }
  662.  
  663.     RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
  664.     if (!RegionObj2)
  665.     {
  666.         return_ACPI_STATUS (AE_NOT_EXIST);
  667.     }
  668.  
  669.     Node = RegionObj->Region.Node->Parent;
  670.     SpaceId = RegionObj->Region.SpaceId;
  671.  
  672.     /* Setup defaults */
  673.  
  674.     RegionObj->Region.Handler = NULL;
  675.     RegionObj2->Extra.Method_REG = NULL;
  676.     RegionObj->Common.Flags &= ~(AOPOBJ_SETUP_COMPLETE);
  677.     RegionObj->Common.Flags |= AOPOBJ_OBJECT_INITIALIZED;
  678.  
  679.     /* Find any "_REG" method associated with this region definition */
  680.  
  681.     Status = AcpiNsSearchOneScope (
  682.                 *RegNamePtr, Node, ACPI_TYPE_METHOD, &MethodNode);
  683.     if (ACPI_SUCCESS (Status))
  684.     {
  685.         /*
  686.          * The _REG method is optional and there can be only one per region
  687.          * definition. This will be executed when the handler is attached
  688.          * or removed
  689.          */
  690.         RegionObj2->Extra.Method_REG = MethodNode;
  691.     }
  692.  
  693.     /*
  694.      * The following loop depends upon the root Node having no parent
  695.      * ie: AcpiGbl_RootNode->ParentEntry being set to NULL
  696.      */
  697.     while (Node)
  698.     {
  699.         /* Check to see if a handler exists */
  700.  
  701.         HandlerObj = NULL;
  702.         ObjDesc = AcpiNsGetAttachedObject (Node);
  703.         if (ObjDesc)
  704.         {
  705.             /* Can only be a handler if the object exists */
  706.  
  707.             switch (Node->Type)
  708.             {
  709.             case ACPI_TYPE_DEVICE:
  710.  
  711.                 HandlerObj = ObjDesc->Device.Handler;
  712.                 break;
  713.  
  714.             case ACPI_TYPE_PROCESSOR:
  715.  
  716.                 HandlerObj = ObjDesc->Processor.Handler;
  717.                 break;
  718.  
  719.             case ACPI_TYPE_THERMAL:
  720.  
  721.                 HandlerObj = ObjDesc->ThermalZone.Handler;
  722.                 break;
  723.  
  724.             case ACPI_TYPE_METHOD:
  725.                 /*
  726.                  * If we are executing module level code, the original
  727.                  * Node's object was replaced by this Method object and we
  728.                  * saved the handler in the method object.
  729.                  *
  730.                  * See AcpiNsExecModuleCode
  731.                  */
  732.                 if (ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL)
  733.                 {
  734.                     HandlerObj = ObjDesc->Method.Dispatch.Handler;
  735.                 }
  736.                 break;
  737.  
  738.             default:
  739.                 /* Ignore other objects */
  740.                 break;
  741.             }
  742.  
  743.             while (HandlerObj)
  744.             {
  745.                 /* Is this handler of the correct type? */
  746.  
  747.                 if (HandlerObj->AddressSpace.SpaceId == SpaceId)
  748.                 {
  749.                     /* Found correct handler */
  750.  
  751.                     ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
  752.                         "Found handler %p for region %p in obj %p\n",
  753.                         HandlerObj, RegionObj, ObjDesc));
  754.  
  755.                     Status = AcpiEvAttachRegion (HandlerObj, RegionObj,
  756.                                 AcpiNsLocked);
  757.  
  758.                     /*
  759.                      * Tell all users that this region is usable by
  760.                      * running the _REG method
  761.                      */
  762.                     if (AcpiNsLocked)
  763.                     {
  764.                         Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  765.                         if (ACPI_FAILURE (Status))
  766.                         {
  767.                             return_ACPI_STATUS (Status);
  768.                         }
  769.                     }
  770.  
  771.                     Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_CONNECT);
  772.  
  773.                     if (AcpiNsLocked)
  774.                     {
  775.                         Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  776.                         if (ACPI_FAILURE (Status))
  777.                         {
  778.                             return_ACPI_STATUS (Status);
  779.                         }
  780.                     }
  781.  
  782.                     return_ACPI_STATUS (AE_OK);
  783.                 }
  784.  
  785.                 /* Try next handler in the list */
  786.  
  787.                 HandlerObj = HandlerObj->AddressSpace.Next;
  788.             }
  789.         }
  790.  
  791.         /* This node does not have the handler we need; Pop up one level */
  792.  
  793.         Node = Node->Parent;
  794.     }
  795.  
  796.     /* If we get here, there is no handler for this region */
  797.  
  798.     ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
  799.         "No handler for RegionType %s(%X) (RegionObj %p)\n",
  800.         AcpiUtGetRegionName (SpaceId), SpaceId, RegionObj));
  801.  
  802.     return_ACPI_STATUS (AE_NOT_EXIST);
  803. }
  804.  
  805.