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