Home | History | Annotate | Line # | Download | only in namespace
nsinit.c revision 1.14
      1 /******************************************************************************
      2  *
      3  * Module Name: nsinit - namespace initialization
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2018, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "acpi.h"
     45 #include "accommon.h"
     46 #include "acnamesp.h"
     47 #include "acdispat.h"
     48 #include "acinterp.h"
     49 #include "acevents.h"
     50 
     51 #define _COMPONENT          ACPI_NAMESPACE
     52         ACPI_MODULE_NAME    ("nsinit")
     53 
     54 /* Local prototypes */
     55 
     56 static ACPI_STATUS
     57 AcpiNsInitOneObject (
     58     ACPI_HANDLE             ObjHandle,
     59     UINT32                  Level,
     60     void                    *Context,
     61     void                    **ReturnValue);
     62 
     63 static ACPI_STATUS
     64 AcpiNsInitOneDevice (
     65     ACPI_HANDLE             ObjHandle,
     66     UINT32                  NestingLevel,
     67     void                    *Context,
     68     void                    **ReturnValue);
     69 
     70 static ACPI_STATUS
     71 AcpiNsFindIniMethods (
     72     ACPI_HANDLE             ObjHandle,
     73     UINT32                  NestingLevel,
     74     void                    *Context,
     75     void                    **ReturnValue);
     76 
     77 
     78 /*******************************************************************************
     79  *
     80  * FUNCTION:    AcpiNsInitializeObjects
     81  *
     82  * PARAMETERS:  None
     83  *
     84  * RETURN:      Status
     85  *
     86  * DESCRIPTION: Walk the entire namespace and perform any necessary
     87  *              initialization on the objects found therein
     88  *
     89  ******************************************************************************/
     90 
     91 ACPI_STATUS
     92 AcpiNsInitializeObjects (
     93     void)
     94 {
     95     ACPI_STATUS             Status;
     96     ACPI_INIT_WALK_INFO     Info;
     97 
     98 
     99     ACPI_FUNCTION_TRACE (NsInitializeObjects);
    100 
    101 
    102     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
    103         "[Init] Completing Initialization of ACPI Objects\n"));
    104     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
    105         "**** Starting initialization of namespace objects ****\n"));
    106     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
    107         "Completing Region/Field/Buffer/Package initialization:\n"));
    108 
    109     /* Set all init info to zero */
    110 
    111     memset (&Info, 0, sizeof (ACPI_INIT_WALK_INFO));
    112 
    113     /* Walk entire namespace from the supplied root */
    114 
    115     Status = AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    116         ACPI_UINT32_MAX, AcpiNsInitOneObject, NULL,
    117         &Info, NULL);
    118     if (ACPI_FAILURE (Status))
    119     {
    120         ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace"));
    121     }
    122 
    123     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
    124         "    Initialized %u/%u Regions %u/%u Fields %u/%u "
    125         "Buffers %u/%u Packages (%u nodes)\n",
    126         Info.OpRegionInit,  Info.OpRegionCount,
    127         Info.FieldInit,     Info.FieldCount,
    128         Info.BufferInit,    Info.BufferCount,
    129         Info.PackageInit,   Info.PackageCount, Info.ObjectCount));
    130 
    131     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
    132         "%u Control Methods found\n%u Op Regions found\n",
    133         Info.MethodCount, Info.OpRegionCount));
    134 
    135     return_ACPI_STATUS (AE_OK);
    136 }
    137 
    138 
    139 /*******************************************************************************
    140  *
    141  * FUNCTION:    AcpiNsInitializeDevices
    142  *
    143  * PARAMETERS:  None
    144  *
    145  * RETURN:      ACPI_STATUS
    146  *
    147  * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices.
    148  *              This means running _INI on all present devices.
    149  *
    150  *              Note: We install PCI config space handler on region access,
    151  *              not here.
    152  *
    153  ******************************************************************************/
    154 
    155 ACPI_STATUS
    156 AcpiNsInitializeDevices (
    157     UINT32                  Flags)
    158 {
    159     ACPI_STATUS             Status = AE_OK;
    160     ACPI_DEVICE_WALK_INFO   Info;
    161     ACPI_HANDLE             Handle;
    162 
    163 
    164     ACPI_FUNCTION_TRACE (NsInitializeDevices);
    165 
    166 
    167     if (!(Flags & ACPI_NO_DEVICE_INIT))
    168     {
    169         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
    170             "[Init] Initializing ACPI Devices\n"));
    171 
    172         /* Init counters */
    173 
    174         Info.DeviceCount = 0;
    175         Info.Num_STA = 0;
    176         Info.Num_INI = 0;
    177 
    178         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
    179             "Initializing Device/Processor/Thermal objects "
    180             "and executing _INI/_STA methods:\n"));
    181 
    182         /* Tree analysis: find all subtrees that contain _INI methods */
    183 
    184         Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    185             ACPI_UINT32_MAX, FALSE, AcpiNsFindIniMethods, NULL, &Info, NULL);
    186         if (ACPI_FAILURE (Status))
    187         {
    188             goto ErrorExit;
    189         }
    190 
    191         /* Allocate the evaluation information block */
    192 
    193         Info.EvaluateInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
    194         if (!Info.EvaluateInfo)
    195         {
    196             Status = AE_NO_MEMORY;
    197             goto ErrorExit;
    198         }
    199 
    200         /*
    201          * Execute the "global" _INI method that may appear at the root.
    202          * This support is provided for Windows compatibility (Vista+) and
    203          * is not part of the ACPI specification.
    204          */
    205         Info.EvaluateInfo->PrefixNode = AcpiGbl_RootNode;
    206         Info.EvaluateInfo->RelativePathname = METHOD_NAME__INI;
    207         Info.EvaluateInfo->Parameters = NULL;
    208         Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE;
    209 
    210         Status = AcpiNsEvaluate (Info.EvaluateInfo);
    211         if (ACPI_SUCCESS (Status))
    212         {
    213             Info.Num_INI++;
    214         }
    215 
    216         /*
    217          * Execute \_SB._INI.
    218          * There appears to be a strict order requirement for \_SB._INI,
    219          * which should be evaluated before any _REG evaluations.
    220          */
    221         Status = AcpiGetHandle (NULL, "\\_SB", &Handle);
    222         if (ACPI_SUCCESS (Status))
    223         {
    224             memset (Info.EvaluateInfo, 0, sizeof (ACPI_EVALUATE_INFO));
    225             Info.EvaluateInfo->PrefixNode = Handle;
    226             Info.EvaluateInfo->RelativePathname = METHOD_NAME__INI;
    227             Info.EvaluateInfo->Parameters = NULL;
    228             Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE;
    229 
    230             Status = AcpiNsEvaluate (Info.EvaluateInfo);
    231             if (ACPI_SUCCESS (Status))
    232             {
    233                 Info.Num_INI++;
    234             }
    235         }
    236     }
    237 
    238     /*
    239      * Run all _REG methods
    240      *
    241      * Note: Any objects accessed by the _REG methods will be automatically
    242      * initialized, even if they contain executable AML (see the call to
    243      * AcpiNsInitializeObjects below).
    244      *
    245      * Note: According to the ACPI specification, we actually needn't execute
    246      * _REG for SystemMemory/SystemIo operation regions, but for PCI_Config
    247      * operation regions, it is required to evaluate _REG for those on a PCI
    248      * root bus that doesn't contain _BBN object. So this code is kept here
    249      * in order not to break things.
    250      */
    251     if (!(Flags & ACPI_NO_ADDRESS_SPACE_INIT))
    252     {
    253         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
    254             "[Init] Executing _REG OpRegion methods\n"));
    255 
    256         Status = AcpiEvInitializeOpRegions ();
    257         if (ACPI_FAILURE (Status))
    258         {
    259             goto ErrorExit;
    260         }
    261     }
    262 
    263     if (!(Flags & ACPI_NO_DEVICE_INIT))
    264     {
    265         /* Walk namespace to execute all _INIs on present devices */
    266 
    267         Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    268             ACPI_UINT32_MAX, FALSE, AcpiNsInitOneDevice, NULL, &Info, NULL);
    269 
    270         /*
    271          * Any _OSI requests should be completed by now. If the BIOS has
    272          * requested any Windows OSI strings, we will always truncate
    273          * I/O addresses to 16 bits -- for Windows compatibility.
    274          */
    275         if (AcpiGbl_OsiData >= ACPI_OSI_WIN_2000)
    276         {
    277             AcpiGbl_TruncateIoAddresses = TRUE;
    278         }
    279 
    280         ACPI_FREE (Info.EvaluateInfo);
    281         if (ACPI_FAILURE (Status))
    282         {
    283             goto ErrorExit;
    284         }
    285 
    286         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
    287             "    Executed %u _INI methods requiring %u _STA executions "
    288             "(examined %u objects)\n",
    289             Info.Num_INI, Info.Num_STA, Info.DeviceCount));
    290     }
    291 
    292     return_ACPI_STATUS (Status);
    293 
    294 
    295 ErrorExit:
    296     ACPI_EXCEPTION ((AE_INFO, Status, "During device initialization"));
    297     return_ACPI_STATUS (Status);
    298 }
    299 
    300 
    301 /*******************************************************************************
    302  *
    303  * FUNCTION:    AcpiNsInitOneObject
    304  *
    305  * PARAMETERS:  ObjHandle       - Node
    306  *              Level           - Current nesting level
    307  *              Context         - Points to a init info struct
    308  *              ReturnValue     - Not used
    309  *
    310  * RETURN:      Status
    311  *
    312  * DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every object
    313  *              within the namespace.
    314  *
    315  *              Currently, the only objects that require initialization are:
    316  *              1) Methods
    317  *              2) Op Regions
    318  *
    319  ******************************************************************************/
    320 
    321 static ACPI_STATUS
    322 AcpiNsInitOneObject (
    323     ACPI_HANDLE             ObjHandle,
    324     UINT32                  Level,
    325     void                    *Context,
    326     void                    **ReturnValue)
    327 {
    328     ACPI_OBJECT_TYPE        Type;
    329     ACPI_STATUS             Status = AE_OK;
    330     ACPI_INIT_WALK_INFO     *Info = (ACPI_INIT_WALK_INFO *) Context;
    331     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
    332     ACPI_OPERAND_OBJECT     *ObjDesc;
    333 
    334 
    335     ACPI_FUNCTION_NAME (NsInitOneObject);
    336 
    337 
    338     Info->ObjectCount++;
    339 
    340     /* And even then, we are only interested in a few object types */
    341 
    342     Type = AcpiNsGetType (ObjHandle);
    343     ObjDesc = AcpiNsGetAttachedObject (Node);
    344     if (!ObjDesc)
    345     {
    346         return (AE_OK);
    347     }
    348 
    349     /* Increment counters for object types we are looking for */
    350 
    351     switch (Type)
    352     {
    353     case ACPI_TYPE_REGION:
    354 
    355         Info->OpRegionCount++;
    356         break;
    357 
    358     case ACPI_TYPE_BUFFER_FIELD:
    359 
    360         Info->FieldCount++;
    361         break;
    362 
    363     case ACPI_TYPE_LOCAL_BANK_FIELD:
    364 
    365         Info->FieldCount++;
    366         break;
    367 
    368     case ACPI_TYPE_BUFFER:
    369 
    370         Info->BufferCount++;
    371         break;
    372 
    373     case ACPI_TYPE_PACKAGE:
    374 
    375         Info->PackageCount++;
    376         break;
    377 
    378     default:
    379 
    380         /* No init required, just exit now */
    381 
    382         return (AE_OK);
    383     }
    384 
    385     /* If the object is already initialized, nothing else to do */
    386 
    387     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
    388     {
    389         return (AE_OK);
    390     }
    391 
    392     /* Must lock the interpreter before executing AML code */
    393 
    394     AcpiExEnterInterpreter ();
    395 
    396     /*
    397      * Each of these types can contain executable AML code within the
    398      * declaration.
    399      */
    400     switch (Type)
    401     {
    402     case ACPI_TYPE_REGION:
    403 
    404         Info->OpRegionInit++;
    405         Status = AcpiDsGetRegionArguments (ObjDesc);
    406         break;
    407 
    408     case ACPI_TYPE_BUFFER_FIELD:
    409 
    410         Info->FieldInit++;
    411         Status = AcpiDsGetBufferFieldArguments (ObjDesc);
    412         break;
    413 
    414     case ACPI_TYPE_LOCAL_BANK_FIELD:
    415 
    416         Info->FieldInit++;
    417         Status = AcpiDsGetBankFieldArguments (ObjDesc);
    418         break;
    419 
    420     case ACPI_TYPE_BUFFER:
    421 
    422         Info->BufferInit++;
    423         Status = AcpiDsGetBufferArguments (ObjDesc);
    424         break;
    425 
    426     case ACPI_TYPE_PACKAGE:
    427 
    428         Info->PackageInit++;
    429         Status = AcpiDsGetPackageArguments (ObjDesc);
    430         if (ACPI_FAILURE (Status))
    431         {
    432             break;
    433         }
    434 
    435         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_PARSE,
    436             "%s: Completing resolution of Package elements\n",
    437             ACPI_GET_FUNCTION_NAME));
    438 
    439         /*
    440          * Resolve all named references in package objects (and all
    441          * sub-packages). This action has been deferred until the entire
    442          * namespace has been loaded, in order to support external and
    443          * forward references from individual package elements (05/2017).
    444          */
    445         Status = AcpiUtWalkPackageTree (ObjDesc, NULL,
    446             AcpiDsInitPackageElement, NULL);
    447 
    448         ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID;
    449         break;
    450 
    451     default:
    452 
    453         /* No other types can get here */
    454 
    455         break;
    456     }
    457 
    458     if (ACPI_FAILURE (Status))
    459     {
    460         ACPI_EXCEPTION ((AE_INFO, Status,
    461             "Could not execute arguments for [%4.4s] (%s)",
    462             AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Type)));
    463     }
    464 
    465     /*
    466      * We ignore errors from above, and always return OK, since we don't want
    467      * to abort the walk on any single error.
    468      */
    469     AcpiExExitInterpreter ();
    470     return (AE_OK);
    471 }
    472 
    473 
    474 /*******************************************************************************
    475  *
    476  * FUNCTION:    AcpiNsFindIniMethods
    477  *
    478  * PARAMETERS:  ACPI_WALK_CALLBACK
    479  *
    480  * RETURN:      ACPI_STATUS
    481  *
    482  * DESCRIPTION: Called during namespace walk. Finds objects named _INI under
    483  *              device/processor/thermal objects, and marks the entire subtree
    484  *              with a SUBTREE_HAS_INI flag. This flag is used during the
    485  *              subsequent device initialization walk to avoid entire subtrees
    486  *              that do not contain an _INI.
    487  *
    488  ******************************************************************************/
    489 
    490 static ACPI_STATUS
    491 AcpiNsFindIniMethods (
    492     ACPI_HANDLE             ObjHandle,
    493     UINT32                  NestingLevel,
    494     void                    *Context,
    495     void                    **ReturnValue)
    496 {
    497     ACPI_DEVICE_WALK_INFO   *Info = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context);
    498     ACPI_NAMESPACE_NODE     *Node;
    499     ACPI_NAMESPACE_NODE     *ParentNode;
    500 
    501 
    502     /* Keep count of device/processor/thermal objects */
    503 
    504     Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
    505     if ((Node->Type == ACPI_TYPE_DEVICE)    ||
    506         (Node->Type == ACPI_TYPE_PROCESSOR) ||
    507         (Node->Type == ACPI_TYPE_THERMAL))
    508     {
    509         Info->DeviceCount++;
    510         return (AE_OK);
    511     }
    512 
    513     /* We are only looking for methods named _INI */
    514 
    515     if (!ACPI_COMPARE_NAME (Node->Name.Ascii, METHOD_NAME__INI))
    516     {
    517         return (AE_OK);
    518     }
    519 
    520     /*
    521      * The only _INI methods that we care about are those that are
    522      * present under Device, Processor, and Thermal objects.
    523      */
    524     ParentNode = Node->Parent;
    525     switch (ParentNode->Type)
    526     {
    527     case ACPI_TYPE_DEVICE:
    528     case ACPI_TYPE_PROCESSOR:
    529     case ACPI_TYPE_THERMAL:
    530 
    531         /* Mark parent and bubble up the INI present flag to the root */
    532 
    533         while (ParentNode)
    534         {
    535             ParentNode->Flags |= ANOBJ_SUBTREE_HAS_INI;
    536             ParentNode = ParentNode->Parent;
    537         }
    538         break;
    539 
    540     default:
    541 
    542         break;
    543     }
    544 
    545     return (AE_OK);
    546 }
    547 
    548 
    549 /*******************************************************************************
    550  *
    551  * FUNCTION:    AcpiNsInitOneDevice
    552  *
    553  * PARAMETERS:  ACPI_WALK_CALLBACK
    554  *
    555  * RETURN:      ACPI_STATUS
    556  *
    557  * DESCRIPTION: This is called once per device soon after ACPI is enabled
    558  *              to initialize each device. It determines if the device is
    559  *              present, and if so, calls _INI.
    560  *
    561  ******************************************************************************/
    562 
    563 static ACPI_STATUS
    564 AcpiNsInitOneDevice (
    565     ACPI_HANDLE             ObjHandle,
    566     UINT32                  NestingLevel,
    567     void                    *Context,
    568     void                    **ReturnValue)
    569 {
    570     ACPI_DEVICE_WALK_INFO   *WalkInfo = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context);
    571     ACPI_EVALUATE_INFO      *Info = WalkInfo->EvaluateInfo;
    572     UINT32                  Flags;
    573     ACPI_STATUS             Status;
    574     ACPI_NAMESPACE_NODE     *DeviceNode;
    575 
    576 
    577     ACPI_FUNCTION_TRACE (NsInitOneDevice);
    578 
    579 
    580     /* We are interested in Devices, Processors and ThermalZones only */
    581 
    582     DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
    583     if ((DeviceNode->Type != ACPI_TYPE_DEVICE)    &&
    584         (DeviceNode->Type != ACPI_TYPE_PROCESSOR) &&
    585         (DeviceNode->Type != ACPI_TYPE_THERMAL))
    586     {
    587         return_ACPI_STATUS (AE_OK);
    588     }
    589 
    590     /*
    591      * Because of an earlier namespace analysis, all subtrees that contain an
    592      * _INI method are tagged.
    593      *
    594      * If this device subtree does not contain any _INI methods, we
    595      * can exit now and stop traversing this entire subtree.
    596      */
    597     if (!(DeviceNode->Flags & ANOBJ_SUBTREE_HAS_INI))
    598     {
    599         return_ACPI_STATUS (AE_CTRL_DEPTH);
    600     }
    601 
    602     /*
    603      * Run _STA to determine if this device is present and functioning. We
    604      * must know this information for two important reasons (from ACPI spec):
    605      *
    606      * 1) We can only run _INI if the device is present.
    607      * 2) We must abort the device tree walk on this subtree if the device is
    608      *    not present and is not functional (we will not examine the children)
    609      *
    610      * The _STA method is not required to be present under the device, we
    611      * assume the device is present if _STA does not exist.
    612      */
    613     ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
    614         ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__STA));
    615 
    616     Status = AcpiUtExecute_STA (DeviceNode, &Flags);
    617     if (ACPI_FAILURE (Status))
    618     {
    619         /* Ignore error and move on to next device */
    620 
    621         return_ACPI_STATUS (AE_OK);
    622     }
    623 
    624     /*
    625      * Flags == -1 means that _STA was not found. In this case, we assume that
    626      * the device is both present and functional.
    627      *
    628      * From the ACPI spec, description of _STA:
    629      *
    630      * "If a device object (including the processor object) does not have an
    631      * _STA object, then OSPM assumes that all of the above bits are set (in
    632      * other words, the device is present, ..., and functioning)"
    633      */
    634     if (Flags != ACPI_UINT32_MAX)
    635     {
    636         WalkInfo->Num_STA++;
    637     }
    638 
    639     /*
    640      * Examine the PRESENT and FUNCTIONING status bits
    641      *
    642      * Note: ACPI spec does not seem to specify behavior for the present but
    643      * not functioning case, so we assume functioning if present.
    644      */
    645     if (!(Flags & ACPI_STA_DEVICE_PRESENT))
    646     {
    647         /* Device is not present, we must examine the Functioning bit */
    648 
    649         if (Flags & ACPI_STA_DEVICE_FUNCTIONING)
    650         {
    651             /*
    652              * Device is not present but is "functioning". In this case,
    653              * we will not run _INI, but we continue to examine the children
    654              * of this device.
    655              *
    656              * From the ACPI spec, description of _STA: (Note - no mention
    657              * of whether to run _INI or not on the device in question)
    658              *
    659              * "_STA may return bit 0 clear (not present) with bit 3 set
    660              * (device is functional). This case is used to indicate a valid
    661              * device for which no device driver should be loaded (for example,
    662              * a bridge device.) Children of this device may be present and
    663              * valid. OSPM should continue enumeration below a device whose
    664              * _STA returns this bit combination"
    665              */
    666             return_ACPI_STATUS (AE_OK);
    667         }
    668         else
    669         {
    670             /*
    671              * Device is not present and is not functioning. We must abort the
    672              * walk of this subtree immediately -- don't look at the children
    673              * of such a device.
    674              *
    675              * From the ACPI spec, description of _INI:
    676              *
    677              * "If the _STA method indicates that the device is not present,
    678              * OSPM will not run the _INI and will not examine the children
    679              * of the device for _INI methods"
    680              */
    681             return_ACPI_STATUS (AE_CTRL_DEPTH);
    682         }
    683     }
    684 
    685     /*
    686      * The device is present or is assumed present if no _STA exists.
    687      * Run the _INI if it exists (not required to exist)
    688      *
    689      * Note: We know there is an _INI within this subtree, but it may not be
    690      * under this particular device, it may be lower in the branch.
    691      */
    692     if (!ACPI_COMPARE_NAME (DeviceNode->Name.Ascii, "_SB_") ||
    693         DeviceNode->Parent != AcpiGbl_RootNode)
    694     {
    695         ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
    696             ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__INI));
    697 
    698         memset (Info, 0, sizeof (ACPI_EVALUATE_INFO));
    699         Info->PrefixNode = DeviceNode;
    700         Info->RelativePathname = METHOD_NAME__INI;
    701         Info->Parameters = NULL;
    702         Info->Flags = ACPI_IGNORE_RETURN_VALUE;
    703 
    704         Status = AcpiNsEvaluate (Info);
    705         if (ACPI_SUCCESS (Status))
    706         {
    707             WalkInfo->Num_INI++;
    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 = AcpiNsGetNormalizedPathname (DeviceNode, TRUE);
    716 
    717             ACPI_EXCEPTION ((AE_INFO, Status, "during %s._INI execution",
    718                 ScopeName));
    719             ACPI_FREE (ScopeName);
    720         }
    721 #endif
    722     }
    723 
    724     /* Ignore errors from above */
    725 
    726     Status = AE_OK;
    727 
    728     /*
    729      * The _INI method has been run if present; call the Global Initialization
    730      * Handler for this device.
    731      */
    732     if (AcpiGbl_InitHandler)
    733     {
    734         Status = AcpiGbl_InitHandler (DeviceNode, ACPI_INIT_DEVICE_INI);
    735     }
    736 
    737     return_ACPI_STATUS (Status);
    738 }
    739