1 /******************************************************************************
   2  *
   3  * Module Name: dsinit - Object initialization namespace walk
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2014, 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 #define __DSINIT_C__
  45 
  46 #include "acpi.h"
  47 #include "accommon.h"
  48 #include "acdispat.h"
  49 #include "acnamesp.h"
  50 #include "actables.h"
  51 
  52 #define _COMPONENT          ACPI_DISPATCHER
  53         ACPI_MODULE_NAME    ("dsinit")
  54 
  55 /* Local prototypes */
  56 
  57 static ACPI_STATUS
  58 AcpiDsInitOneObject (
  59     ACPI_HANDLE             ObjHandle,
  60     UINT32                  Level,
  61     void                    *Context,
  62     void                    **ReturnValue);
  63 
  64 
  65 /*******************************************************************************
  66  *
  67  * FUNCTION:    AcpiDsInitOneObject
  68  *
  69  * PARAMETERS:  ObjHandle       - Node for the object
  70  *              Level           - Current nesting level
  71  *              Context         - Points to a init info struct
  72  *              ReturnValue     - Not used
  73  *
  74  * RETURN:      Status
  75  *
  76  * DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every object
  77  *              within the namespace.
  78  *
  79  *              Currently, the only objects that require initialization are:
  80  *              1) Methods
  81  *              2) Operation Regions
  82  *
  83  ******************************************************************************/
  84 
  85 static ACPI_STATUS
  86 AcpiDsInitOneObject (
  87     ACPI_HANDLE             ObjHandle,
  88     UINT32                  Level,
  89     void                    *Context,
  90     void                    **ReturnValue)
  91 {
  92     ACPI_INIT_WALK_INFO     *Info = (ACPI_INIT_WALK_INFO *) Context;
  93     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
  94     ACPI_OBJECT_TYPE        Type;
  95     ACPI_STATUS             Status;
  96 
  97 
  98     ACPI_FUNCTION_ENTRY ();
  99 
 100 
 101     /*
 102      * We are only interested in NS nodes owned by the table that
 103      * was just loaded
 104      */
 105     if (Node->OwnerId != Info->OwnerId)
 106     {
 107         return (AE_OK);
 108     }
 109 
 110     Info->ObjectCount++;
 111 
 112     /* And even then, we are only interested in a few object types */
 113 
 114     Type = AcpiNsGetType (ObjHandle);
 115 
 116     switch (Type)
 117     {
 118     case ACPI_TYPE_REGION:
 119 
 120         Status = AcpiDsInitializeRegion (ObjHandle);
 121         if (ACPI_FAILURE (Status))
 122         {
 123             ACPI_EXCEPTION ((AE_INFO, Status,
 124                 "During Region initialization %p [%4.4s]",
 125                 ObjHandle, AcpiUtGetNodeName (ObjHandle)));
 126         }
 127 
 128         Info->OpRegionCount++;
 129         break;
 130 
 131     case ACPI_TYPE_METHOD:
 132 
 133         Info->MethodCount++;
 134         break;
 135 
 136     case ACPI_TYPE_DEVICE:
 137 
 138         Info->DeviceCount++;
 139         break;
 140 
 141     default:
 142 
 143         break;
 144     }
 145 
 146     /*
 147      * We ignore errors from above, and always return OK, since
 148      * we don't want to abort the walk on a single error.
 149      */
 150     return (AE_OK);
 151 }
 152 
 153 
 154 /*******************************************************************************
 155  *
 156  * FUNCTION:    AcpiDsInitializeObjects
 157  *
 158  * PARAMETERS:  TableDesc       - Descriptor for parent ACPI table
 159  *              StartNode       - Root of subtree to be initialized.
 160  *
 161  * RETURN:      Status
 162  *
 163  * DESCRIPTION: Walk the namespace starting at "StartNode" and perform any
 164  *              necessary initialization on the objects found therein
 165  *
 166  ******************************************************************************/
 167 
 168 ACPI_STATUS
 169 AcpiDsInitializeObjects (
 170     UINT32                  TableIndex,
 171     ACPI_NAMESPACE_NODE     *StartNode)
 172 {
 173     ACPI_STATUS             Status;
 174     ACPI_INIT_WALK_INFO     Info;
 175     ACPI_TABLE_HEADER       *Table;
 176     ACPI_OWNER_ID           OwnerId;
 177 
 178 
 179     ACPI_FUNCTION_TRACE (DsInitializeObjects);
 180 
 181 
 182     Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
 183     if (ACPI_FAILURE (Status))
 184     {
 185         return_ACPI_STATUS (Status);
 186     }
 187 
 188     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
 189         "**** Starting initialization of namespace objects ****\n"));
 190     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "Parsing all Control Methods:"));
 191 
 192     /* Set all init info to zero */
 193 
 194     ACPI_MEMSET (&Info, 0, sizeof (ACPI_INIT_WALK_INFO));
 195 
 196     Info.OwnerId = OwnerId;
 197     Info.TableIndex = TableIndex;
 198 
 199     /* Walk entire namespace from the supplied root */
 200 
 201     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
 202     if (ACPI_FAILURE (Status))
 203     {
 204         return_ACPI_STATUS (Status);
 205     }
 206 
 207     /*
 208      * We don't use AcpiWalkNamespace since we do not want to acquire
 209      * the namespace reader lock.
 210      */
 211     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, StartNode, ACPI_UINT32_MAX,
 212                 ACPI_NS_WALK_UNLOCK, AcpiDsInitOneObject, NULL, &Info, NULL);
 213     if (ACPI_FAILURE (Status))
 214     {
 215         ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace"));
 216     }
 217     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
 218 
 219     Status = AcpiGetTableByIndex (TableIndex, &Table);
 220     if (ACPI_FAILURE (Status))
 221     {
 222         return_ACPI_STATUS (Status);
 223     }
 224 
 225     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
 226         "\nTable [%4.4s](id %4.4X) - %u Objects with %u Devices %u Methods %u Regions\n",
 227         Table->Signature, OwnerId, Info.ObjectCount,
 228         Info.DeviceCount, Info.MethodCount, Info.OpRegionCount));
 229 
 230     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
 231         "%u Methods, %u Regions\n", Info.MethodCount, Info.OpRegionCount));
 232 
 233     return_ACPI_STATUS (AE_OK);
 234 }