1 /******************************************************************************
   2  *
   3  * Module Name: dsinit - Object initialization namespace walk
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2011, 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 
 132     case ACPI_TYPE_METHOD:
 133 
 134         Info->MethodCount++;
 135         break;
 136 
 137 
 138     case ACPI_TYPE_DEVICE:
 139 
 140         Info->DeviceCount++;
 141         break;
 142 
 143 
 144     default:
 145         break;
 146     }
 147 
 148     /*
 149      * We ignore errors from above, and always return OK, since
 150      * we don't want to abort the walk on a single error.
 151      */
 152     return (AE_OK);
 153 }
 154 
 155 
 156 /*******************************************************************************
 157  *
 158  * FUNCTION:    AcpiDsInitializeObjects
 159  *
 160  * PARAMETERS:  TableDesc       - Descriptor for parent ACPI table
 161  *              StartNode       - Root of subtree to be initialized.
 162  *
 163  * RETURN:      Status
 164  *
 165  * DESCRIPTION: Walk the namespace starting at "StartNode" and perform any
 166  *              necessary initialization on the objects found therein
 167  *
 168  ******************************************************************************/
 169 
 170 ACPI_STATUS
 171 AcpiDsInitializeObjects (
 172     UINT32                  TableIndex,
 173     ACPI_NAMESPACE_NODE     *StartNode)
 174 {
 175     ACPI_STATUS             Status;
 176     ACPI_INIT_WALK_INFO     Info;
 177     ACPI_TABLE_HEADER       *Table;
 178     ACPI_OWNER_ID           OwnerId;
 179 
 180 
 181     ACPI_FUNCTION_TRACE (DsInitializeObjects);
 182 
 183 
 184     Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
 185     if (ACPI_FAILURE (Status))
 186     {
 187         return_ACPI_STATUS (Status);
 188     }
 189 
 190     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
 191         "**** Starting initialization of namespace objects ****\n"));
 192     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "Parsing all Control Methods:"));
 193 
 194     /* Set all init info to zero */
 195 
 196     ACPI_MEMSET (&Info, 0, sizeof (ACPI_INIT_WALK_INFO));
 197 
 198     Info.OwnerId = OwnerId;
 199     Info.TableIndex = TableIndex;
 200 
 201     /* Walk entire namespace from the supplied root */
 202 
 203     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
 204     if (ACPI_FAILURE (Status))
 205     {
 206         return_ACPI_STATUS (Status);
 207     }
 208 
 209     /*
 210      * We don't use AcpiWalkNamespace since we do not want to acquire
 211      * the namespace reader lock.
 212      */
 213     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, StartNode, ACPI_UINT32_MAX,
 214                 ACPI_NS_WALK_UNLOCK, AcpiDsInitOneObject, NULL, &Info, NULL);
 215     if (ACPI_FAILURE (Status))
 216     {
 217         ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace"));
 218     }
 219     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
 220 
 221     Status = AcpiGetTableByIndex (TableIndex, &Table);
 222     if (ACPI_FAILURE (Status))
 223     {
 224         return_ACPI_STATUS (Status);
 225     }
 226 
 227     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
 228         "\nTable [%4.4s](id %4.4X) - %u Objects with %u Devices %u Methods %u Regions\n",
 229         Table->Signature, OwnerId, Info.ObjectCount,
 230         Info.DeviceCount, Info.MethodCount, Info.OpRegionCount));
 231 
 232     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
 233         "%u Methods, %u Regions\n", Info.MethodCount, Info.OpRegionCount));
 234 
 235     return_ACPI_STATUS (AE_OK);
 236 }
 237 
 238