Subversion Repositories Kolibri OS

Rev

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

  1. /******************************************************************************
  2.  *
  3.  * Module Name: nsinit - namespace initialization
  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 __NSXFINIT_C__
  118.  
  119. #include "acpi.h"
  120. #include "accommon.h"
  121. #include "acnamesp.h"
  122. #include "acdispat.h"
  123. #include "acinterp.h"
  124.  
  125. #define _COMPONENT          ACPI_NAMESPACE
  126.         ACPI_MODULE_NAME    ("nsinit")
  127.  
  128. /* Local prototypes */
  129.  
  130. static ACPI_STATUS
  131. AcpiNsInitOneObject (
  132.     ACPI_HANDLE             ObjHandle,
  133.     UINT32                  Level,
  134.     void                    *Context,
  135.     void                    **ReturnValue);
  136.  
  137. static ACPI_STATUS
  138. AcpiNsInitOneDevice (
  139.     ACPI_HANDLE             ObjHandle,
  140.     UINT32                  NestingLevel,
  141.     void                    *Context,
  142.     void                    **ReturnValue);
  143.  
  144. static ACPI_STATUS
  145. AcpiNsFindIniMethods (
  146.     ACPI_HANDLE             ObjHandle,
  147.     UINT32                  NestingLevel,
  148.     void                    *Context,
  149.     void                    **ReturnValue);
  150.  
  151.  
  152. /*******************************************************************************
  153.  *
  154.  * FUNCTION:    AcpiNsInitializeObjects
  155.  *
  156.  * PARAMETERS:  None
  157.  *
  158.  * RETURN:      Status
  159.  *
  160.  * DESCRIPTION: Walk the entire namespace and perform any necessary
  161.  *              initialization on the objects found therein
  162.  *
  163.  ******************************************************************************/
  164.  
  165. ACPI_STATUS
  166. AcpiNsInitializeObjects (
  167.     void)
  168. {
  169.     ACPI_STATUS             Status;
  170.     ACPI_INIT_WALK_INFO     Info;
  171.  
  172.  
  173.     ACPI_FUNCTION_TRACE (NsInitializeObjects);
  174.  
  175.  
  176.     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
  177.         "**** Starting initialization of namespace objects ****\n"));
  178.     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
  179.         "Completing Region/Field/Buffer/Package initialization:"));
  180.  
  181.     /* Set all init info to zero */
  182.  
  183.     ACPI_MEMSET (&Info, 0, sizeof (ACPI_INIT_WALK_INFO));
  184.  
  185.     /* Walk entire namespace from the supplied root */
  186.  
  187.     Status = AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
  188.                 ACPI_UINT32_MAX, AcpiNsInitOneObject, NULL,
  189.                 &Info, NULL);
  190.     if (ACPI_FAILURE (Status))
  191.     {
  192.         ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace"));
  193.     }
  194.  
  195.     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
  196.         "\nInitialized %u/%u Regions %u/%u Fields %u/%u "
  197.         "Buffers %u/%u Packages (%u nodes)\n",
  198.         Info.OpRegionInit,  Info.OpRegionCount,
  199.         Info.FieldInit,     Info.FieldCount,
  200.         Info.BufferInit,    Info.BufferCount,
  201.         Info.PackageInit,   Info.PackageCount, Info.ObjectCount));
  202.  
  203.     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
  204.         "%u Control Methods found\n", Info.MethodCount));
  205.     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
  206.         "%u Op Regions found\n", Info.OpRegionCount));
  207.  
  208.     return_ACPI_STATUS (AE_OK);
  209. }
  210.  
  211.  
  212. /*******************************************************************************
  213.  *
  214.  * FUNCTION:    AcpiNsInitializeDevices
  215.  *
  216.  * PARAMETERS:  None
  217.  *
  218.  * RETURN:      ACPI_STATUS
  219.  *
  220.  * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices.
  221.  *              This means running _INI on all present devices.
  222.  *
  223.  *              Note: We install PCI config space handler on region access,
  224.  *              not here.
  225.  *
  226.  ******************************************************************************/
  227.  
  228. ACPI_STATUS
  229. AcpiNsInitializeDevices (
  230.     void)
  231. {
  232.     ACPI_STATUS             Status;
  233.     ACPI_DEVICE_WALK_INFO   Info;
  234.  
  235.  
  236.     ACPI_FUNCTION_TRACE (NsInitializeDevices);
  237.  
  238.  
  239.     /* Init counters */
  240.  
  241.     Info.DeviceCount = 0;
  242.     Info.Num_STA = 0;
  243.     Info.Num_INI = 0;
  244.  
  245.     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
  246.         "Initializing Device/Processor/Thermal objects "
  247.         "by executing _INI methods:"));
  248.  
  249.     /* Tree analysis: find all subtrees that contain _INI methods */
  250.  
  251.     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
  252.                 ACPI_UINT32_MAX, FALSE, AcpiNsFindIniMethods, NULL, &Info, NULL);
  253.     if (ACPI_FAILURE (Status))
  254.     {
  255.         goto ErrorExit;
  256.     }
  257.  
  258.     /* Allocate the evaluation information block */
  259.  
  260.     Info.EvaluateInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
  261.     if (!Info.EvaluateInfo)
  262.     {
  263.         Status = AE_NO_MEMORY;
  264.         goto ErrorExit;
  265.     }
  266.  
  267.     /*
  268.      * Execute the "global" _INI method that may appear at the root. This
  269.      * support is provided for Windows compatibility (Vista+) and is not
  270.      * part of the ACPI specification.
  271.      */
  272.     Info.EvaluateInfo->PrefixNode = AcpiGbl_RootNode;
  273.     Info.EvaluateInfo->Pathname = METHOD_NAME__INI;
  274.     Info.EvaluateInfo->Parameters = NULL;
  275.     Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE;
  276.  
  277.     Status = AcpiNsEvaluate (Info.EvaluateInfo);
  278.     if (ACPI_SUCCESS (Status))
  279.     {
  280.         Info.Num_INI++;
  281.     }
  282.  
  283.     /* Walk namespace to execute all _INIs on present devices */
  284.  
  285.     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
  286.                 ACPI_UINT32_MAX, FALSE, AcpiNsInitOneDevice, NULL, &Info, NULL);
  287.  
  288.     /*
  289.      * Any _OSI requests should be completed by now. If the BIOS has
  290.      * requested any Windows OSI strings, we will always truncate
  291.      * I/O addresses to 16 bits -- for Windows compatibility.
  292.      */
  293.     if (AcpiGbl_OsiData >= ACPI_OSI_WIN_2000)
  294.     {
  295.         AcpiGbl_TruncateIoAddresses = TRUE;
  296.     }
  297.  
  298.     ACPI_FREE (Info.EvaluateInfo);
  299.     if (ACPI_FAILURE (Status))
  300.     {
  301.         goto ErrorExit;
  302.     }
  303.  
  304.     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
  305.         "\nExecuted %u _INI methods requiring %u _STA executions "
  306.         "(examined %u objects)\n",
  307.         Info.Num_INI, Info.Num_STA, Info.DeviceCount));
  308.  
  309.     return_ACPI_STATUS (Status);
  310.  
  311.  
  312. ErrorExit:
  313.     ACPI_EXCEPTION ((AE_INFO, Status, "During device initialization"));
  314.     return_ACPI_STATUS (Status);
  315. }
  316.  
  317.  
  318. /*******************************************************************************
  319.  *
  320.  * FUNCTION:    AcpiNsInitOneObject
  321.  *
  322.  * PARAMETERS:  ObjHandle       - Node
  323.  *              Level           - Current nesting level
  324.  *              Context         - Points to a init info struct
  325.  *              ReturnValue     - Not used
  326.  *
  327.  * RETURN:      Status
  328.  *
  329.  * DESCRIPTION: Callback from AcpiWalkNamespace.  Invoked for every object
  330.  *              within the  namespace.
  331.  *
  332.  *              Currently, the only objects that require initialization are:
  333.  *              1) Methods
  334.  *              2) Op Regions
  335.  *
  336.  ******************************************************************************/
  337.  
  338. static ACPI_STATUS
  339. AcpiNsInitOneObject (
  340.     ACPI_HANDLE             ObjHandle,
  341.     UINT32                  Level,
  342.     void                    *Context,
  343.     void                    **ReturnValue)
  344. {
  345.     ACPI_OBJECT_TYPE        Type;
  346.     ACPI_STATUS             Status = AE_OK;
  347.     ACPI_INIT_WALK_INFO     *Info = (ACPI_INIT_WALK_INFO *) Context;
  348.     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
  349.     ACPI_OPERAND_OBJECT     *ObjDesc;
  350.  
  351.  
  352.     ACPI_FUNCTION_NAME (NsInitOneObject);
  353.  
  354.  
  355.     Info->ObjectCount++;
  356.  
  357.     /* And even then, we are only interested in a few object types */
  358.  
  359.     Type = AcpiNsGetType (ObjHandle);
  360.     ObjDesc = AcpiNsGetAttachedObject (Node);
  361.     if (!ObjDesc)
  362.     {
  363.         return (AE_OK);
  364.     }
  365.  
  366.     /* Increment counters for object types we are looking for */
  367.  
  368.     switch (Type)
  369.     {
  370.     case ACPI_TYPE_REGION:
  371.         Info->OpRegionCount++;
  372.         break;
  373.  
  374.     case ACPI_TYPE_BUFFER_FIELD:
  375.         Info->FieldCount++;
  376.         break;
  377.  
  378.     case ACPI_TYPE_LOCAL_BANK_FIELD:
  379.         Info->FieldCount++;
  380.         break;
  381.  
  382.     case ACPI_TYPE_BUFFER:
  383.         Info->BufferCount++;
  384.         break;
  385.  
  386.     case ACPI_TYPE_PACKAGE:
  387.         Info->PackageCount++;
  388.         break;
  389.  
  390.     default:
  391.  
  392.         /* No init required, just exit now */
  393.         return (AE_OK);
  394.     }
  395.  
  396.     /* If the object is already initialized, nothing else to do */
  397.  
  398.     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
  399.     {
  400.         return (AE_OK);
  401.     }
  402.  
  403.     /* Must lock the interpreter before executing AML code */
  404.  
  405.     AcpiExEnterInterpreter ();
  406.  
  407.     /*
  408.      * Each of these types can contain executable AML code within the
  409.      * declaration.
  410.      */
  411.     switch (Type)
  412.     {
  413.     case ACPI_TYPE_REGION:
  414.  
  415.         Info->OpRegionInit++;
  416.         Status = AcpiDsGetRegionArguments (ObjDesc);
  417.         break;
  418.  
  419.     case ACPI_TYPE_BUFFER_FIELD:
  420.  
  421.         Info->FieldInit++;
  422.         Status = AcpiDsGetBufferFieldArguments (ObjDesc);
  423.         break;
  424.  
  425.     case ACPI_TYPE_LOCAL_BANK_FIELD:
  426.  
  427.         Info->FieldInit++;
  428.         Status = AcpiDsGetBankFieldArguments (ObjDesc);
  429.         break;
  430.  
  431.     case ACPI_TYPE_BUFFER:
  432.  
  433.         Info->BufferInit++;
  434.         Status = AcpiDsGetBufferArguments (ObjDesc);
  435.         break;
  436.  
  437.     case ACPI_TYPE_PACKAGE:
  438.  
  439.         Info->PackageInit++;
  440.         Status = AcpiDsGetPackageArguments (ObjDesc);
  441.         break;
  442.  
  443.     default:
  444.         /* No other types can get here */
  445.         break;
  446.     }
  447.  
  448.     if (ACPI_FAILURE (Status))
  449.     {
  450.         ACPI_EXCEPTION ((AE_INFO, Status,
  451.             "Could not execute arguments for [%4.4s] (%s)",
  452.             AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Type)));
  453.     }
  454.  
  455.     /*
  456.      * Print a dot for each object unless we are going to print the entire
  457.      * pathname
  458.      */
  459.     if (!(AcpiDbgLevel & ACPI_LV_INIT_NAMES))
  460.     {
  461.         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "."));
  462.     }
  463.  
  464.     /*
  465.      * We ignore errors from above, and always return OK, since we don't want
  466.      * to abort the walk on any single error.
  467.      */
  468.     AcpiExExitInterpreter ();
  469.     return (AE_OK);
  470. }
  471.  
  472.  
  473. /*******************************************************************************
  474.  *
  475.  * FUNCTION:    AcpiNsFindIniMethods
  476.  *
  477.  * PARAMETERS:  ACPI_WALK_CALLBACK
  478.  *
  479.  * RETURN:      ACPI_STATUS
  480.  *
  481.  * DESCRIPTION: Called during namespace walk. Finds objects named _INI under
  482.  *              device/processor/thermal objects, and marks the entire subtree
  483.  *              with a SUBTREE_HAS_INI flag. This flag is used during the
  484.  *              subsequent device initialization walk to avoid entire subtrees
  485.  *              that do not contain an _INI.
  486.  *
  487.  ******************************************************************************/
  488.  
  489. static ACPI_STATUS
  490. AcpiNsFindIniMethods (
  491.     ACPI_HANDLE             ObjHandle,
  492.     UINT32                  NestingLevel,
  493.     void                    *Context,
  494.     void                    **ReturnValue)
  495. {
  496.     ACPI_DEVICE_WALK_INFO   *Info = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context);
  497.     ACPI_NAMESPACE_NODE     *Node;
  498.     ACPI_NAMESPACE_NODE     *ParentNode;
  499.  
  500.  
  501.     /* Keep count of device/processor/thermal objects */
  502.  
  503.     Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
  504.     if ((Node->Type == ACPI_TYPE_DEVICE)    ||
  505.         (Node->Type == ACPI_TYPE_PROCESSOR) ||
  506.         (Node->Type == ACPI_TYPE_THERMAL))
  507.     {
  508.         Info->DeviceCount++;
  509.         return (AE_OK);
  510.     }
  511.  
  512.     /* We are only looking for methods named _INI */
  513.  
  514.     if (!ACPI_COMPARE_NAME (Node->Name.Ascii, METHOD_NAME__INI))
  515.     {
  516.         return (AE_OK);
  517.     }
  518.  
  519.     /*
  520.      * The only _INI methods that we care about are those that are
  521.      * present under Device, Processor, and Thermal objects.
  522.      */
  523.     ParentNode = Node->Parent;
  524.     switch (ParentNode->Type)
  525.     {
  526.     case ACPI_TYPE_DEVICE:
  527.     case ACPI_TYPE_PROCESSOR:
  528.     case ACPI_TYPE_THERMAL:
  529.  
  530.         /* Mark parent and bubble up the INI present flag to the root */
  531.  
  532.         while (ParentNode)
  533.         {
  534.             ParentNode->Flags |= ANOBJ_SUBTREE_HAS_INI;
  535.             ParentNode = ParentNode->Parent;
  536.         }
  537.         break;
  538.  
  539.     default:
  540.         break;
  541.     }
  542.  
  543.     return (AE_OK);
  544. }
  545.  
  546.  
  547. /*******************************************************************************
  548.  *
  549.  * FUNCTION:    AcpiNsInitOneDevice
  550.  *
  551.  * PARAMETERS:  ACPI_WALK_CALLBACK
  552.  *
  553.  * RETURN:      ACPI_STATUS
  554.  *
  555.  * DESCRIPTION: This is called once per device soon after ACPI is enabled
  556.  *              to initialize each device. It determines if the device is
  557.  *              present, and if so, calls _INI.
  558.  *
  559.  ******************************************************************************/
  560.  
  561. static ACPI_STATUS
  562. AcpiNsInitOneDevice (
  563.     ACPI_HANDLE             ObjHandle,
  564.     UINT32                  NestingLevel,
  565.     void                    *Context,
  566.     void                    **ReturnValue)
  567. {
  568.     ACPI_DEVICE_WALK_INFO   *WalkInfo = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context);
  569.     ACPI_EVALUATE_INFO      *Info = WalkInfo->EvaluateInfo;
  570.     UINT32                  Flags;
  571.     ACPI_STATUS             Status;
  572.     ACPI_NAMESPACE_NODE     *DeviceNode;
  573.  
  574.  
  575.     ACPI_FUNCTION_TRACE (NsInitOneDevice);
  576.  
  577.  
  578.     /* We are interested in Devices, Processors and ThermalZones only */
  579.  
  580.     DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
  581.     if ((DeviceNode->Type != ACPI_TYPE_DEVICE)    &&
  582.         (DeviceNode->Type != ACPI_TYPE_PROCESSOR) &&
  583.         (DeviceNode->Type != ACPI_TYPE_THERMAL))
  584.     {
  585.         return_ACPI_STATUS (AE_OK);
  586.     }
  587.  
  588.     /*
  589.      * Because of an earlier namespace analysis, all subtrees that contain an
  590.      * _INI method are tagged.
  591.      *
  592.      * If this device subtree does not contain any _INI methods, we
  593.      * can exit now and stop traversing this entire subtree.
  594.      */
  595.     if (!(DeviceNode->Flags & ANOBJ_SUBTREE_HAS_INI))
  596.     {
  597.         return_ACPI_STATUS (AE_CTRL_DEPTH);
  598.     }
  599.  
  600.     /*
  601.      * Run _STA to determine if this device is present and functioning. We
  602.      * must know this information for two important reasons (from ACPI spec):
  603.      *
  604.      * 1) We can only run _INI if the device is present.
  605.      * 2) We must abort the device tree walk on this subtree if the device is
  606.      *    not present and is not functional (we will not examine the children)
  607.      *
  608.      * The _STA method is not required to be present under the device, we
  609.      * assume the device is present if _STA does not exist.
  610.      */
  611.     ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
  612.         ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__STA));
  613.  
  614.     Status = AcpiUtExecute_STA (DeviceNode, &Flags);
  615.     if (ACPI_FAILURE (Status))
  616.     {
  617.         /* Ignore error and move on to next device */
  618.  
  619.         return_ACPI_STATUS (AE_OK);
  620.     }
  621.  
  622.     /*
  623.      * Flags == -1 means that _STA was not found. In this case, we assume that
  624.      * the device is both present and functional.
  625.      *
  626.      * From the ACPI spec, description of _STA:
  627.      *
  628.      * "If a device object (including the processor object) does not have an
  629.      * _STA object, then OSPM assumes that all of the above bits are set (in
  630.      * other words, the device is present, ..., and functioning)"
  631.      */
  632.     if (Flags != ACPI_UINT32_MAX)
  633.     {
  634.         WalkInfo->Num_STA++;
  635.     }
  636.  
  637.     /*
  638.      * Examine the PRESENT and FUNCTIONING status bits
  639.      *
  640.      * Note: ACPI spec does not seem to specify behavior for the present but
  641.      * not functioning case, so we assume functioning if present.
  642.      */
  643.     if (!(Flags & ACPI_STA_DEVICE_PRESENT))
  644.     {
  645.         /* Device is not present, we must examine the Functioning bit */
  646.  
  647.         if (Flags & ACPI_STA_DEVICE_FUNCTIONING)
  648.         {
  649.             /*
  650.              * Device is not present but is "functioning". In this case,
  651.              * we will not run _INI, but we continue to examine the children
  652.              * of this device.
  653.              *
  654.              * From the ACPI spec, description of _STA: (Note - no mention
  655.              * of whether to run _INI or not on the device in question)
  656.              *
  657.              * "_STA may return bit 0 clear (not present) with bit 3 set
  658.              * (device is functional). This case is used to indicate a valid
  659.              * device for which no device driver should be loaded (for example,
  660.              * a bridge device.) Children of this device may be present and
  661.              * valid. OSPM should continue enumeration below a device whose
  662.              * _STA returns this bit combination"
  663.              */
  664.             return_ACPI_STATUS (AE_OK);
  665.         }
  666.         else
  667.         {
  668.             /*
  669.              * Device is not present and is not functioning. We must abort the
  670.              * walk of this subtree immediately -- don't look at the children
  671.              * of such a device.
  672.              *
  673.              * From the ACPI spec, description of _INI:
  674.              *
  675.              * "If the _STA method indicates that the device is not present,
  676.              * OSPM will not run the _INI and will not examine the children
  677.              * of the device for _INI methods"
  678.              */
  679.             return_ACPI_STATUS (AE_CTRL_DEPTH);
  680.         }
  681.     }
  682.  
  683.     /*
  684.      * The device is present or is assumed present if no _STA exists.
  685.      * Run the _INI if it exists (not required to exist)
  686.      *
  687.      * Note: We know there is an _INI within this subtree, but it may not be
  688.      * under this particular device, it may be lower in the branch.
  689.      */
  690.     ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
  691.         ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__INI));
  692.  
  693.     Info->PrefixNode = DeviceNode;
  694.     Info->Pathname = METHOD_NAME__INI;
  695.     Info->Parameters = NULL;
  696.     Info->Flags = ACPI_IGNORE_RETURN_VALUE;
  697.  
  698.     Status = AcpiNsEvaluate (Info);
  699.     if (ACPI_SUCCESS (Status))
  700.     {
  701.         WalkInfo->Num_INI++;
  702.  
  703.         if ((AcpiDbgLevel <= ACPI_LV_ALL_EXCEPTIONS) &&
  704.             (!(AcpiDbgLevel & ACPI_LV_INFO)))
  705.         {
  706.             ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "."));
  707.         }
  708.     }
  709.  
  710. #ifdef ACPI_DEBUG_OUTPUT
  711.     else if (Status != AE_NOT_FOUND)
  712.     {
  713.         /* Ignore error and move on to next device */
  714.  
  715.         char *ScopeName = AcpiNsGetExternalPathname (Info->ResolvedNode);
  716.  
  717.         ACPI_EXCEPTION ((AE_INFO, Status, "during %s._INI execution",
  718.             ScopeName));
  719.         ACPI_FREE (ScopeName);
  720.     }
  721. #endif
  722.  
  723.     /* Ignore errors from above */
  724.  
  725.     Status = AE_OK;
  726.  
  727.     /*
  728.      * The _INI method has been run if present; call the Global Initialization
  729.      * Handler for this device.
  730.      */
  731.     if (AcpiGbl_InitHandler)
  732.     {
  733.         Status = AcpiGbl_InitHandler (DeviceNode, ACPI_INIT_DEVICE_INI);
  734.     }
  735.  
  736.     return_ACPI_STATUS (Status);
  737. }
  738.