1 /****************************************************************************** 2 * 3 * Module Name: dsinit - Object initialization namespace walk 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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 "acdispat.h" 47 #include "acnamesp.h" 48 #include "actables.h" 49 50 #define _COMPONENT ACPI_DISPATCHER 51 ACPI_MODULE_NAME ("dsinit") 52 53 54 /* Local prototypes */ 55 56 static ACPI_STATUS 57 AcpiDsInitOneObject ( 58 ACPI_HANDLE ObjHandle, 59 UINT32 Level, 60 void *Context, 61 void **ReturnValue); 62 63 64 /******************************************************************************* 65 * 66 * FUNCTION: AcpiDsInitOneObject 67 * 68 * PARAMETERS: ObjHandle - Node for the object 69 * Level - Current nesting level 70 * Context - Points to a init info struct 71 * ReturnValue - Not used 72 * 73 * RETURN: Status 74 * 75 * DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every object 76 * within the namespace. 77 * 78 * Currently, the only objects that require initialization are: 79 * 1) Methods 80 * 2) Operation Regions 81 * 82 ******************************************************************************/ 83 84 static ACPI_STATUS 85 AcpiDsInitOneObject ( 86 ACPI_HANDLE ObjHandle, 87 UINT32 Level, 88 void *Context, 89 void **ReturnValue) 90 { 91 ACPI_INIT_WALK_INFO *Info = (ACPI_INIT_WALK_INFO *) Context; 92 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 93 ACPI_STATUS Status; 94 ACPI_OPERAND_OBJECT *ObjDesc; 95 96 97 ACPI_FUNCTION_ENTRY (); 98 99 100 /* 101 * We are only interested in NS nodes owned by the table that 102 * was just loaded 103 */ 104 if (Node->OwnerId != Info->OwnerId) 105 { 106 return (AE_OK); 107 } 108 109 Info->ObjectCount++; 110 111 /* And even then, we are only interested in a few object types */ 112 113 switch (AcpiNsGetType (ObjHandle)) 114 { 115 case ACPI_TYPE_REGION: 116 117 Status = AcpiDsInitializeRegion (ObjHandle); 118 if (ACPI_FAILURE (Status)) 119 { 120 ACPI_EXCEPTION ((AE_INFO, Status, 121 "During Region initialization %p [%4.4s]", 122 ObjHandle, AcpiUtGetNodeName (ObjHandle))); 123 } 124 125 Info->OpRegionCount++; 126 break; 127 128 case ACPI_TYPE_METHOD: 129 /* 130 * Auto-serialization support. We will examine each method that is 131 * NotSerialized to determine if it creates any Named objects. If 132 * it does, it will be marked serialized to prevent problems if 133 * the method is entered by two or more threads and an attempt is 134 * made to create the same named object twice -- which results in 135 * an AE_ALREADY_EXISTS exception and method abort. 136 */ 137 Info->MethodCount++; 138 ObjDesc = AcpiNsGetAttachedObject (Node); 139 if (!ObjDesc) 140 { 141 break; 142 } 143 144 /* Ignore if already serialized */ 145 146 if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED) 147 { 148 Info->SerialMethodCount++; 149 break; 150 } 151 152 if (AcpiGbl_AutoSerializeMethods) 153 { 154 /* Parse/scan method and serialize it if necessary */ 155 156 AcpiDsAutoSerializeMethod (Node, ObjDesc); 157 if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED) 158 { 159 /* Method was just converted to Serialized */ 160 161 Info->SerialMethodCount++; 162 Info->SerializedMethodCount++; 163 break; 164 } 165 } 166 167 Info->NonSerialMethodCount++; 168 break; 169 170 case ACPI_TYPE_DEVICE: 171 172 Info->DeviceCount++; 173 break; 174 175 default: 176 177 break; 178 } 179 180 /* 181 * We ignore errors from above, and always return OK, since 182 * we don't want to abort the walk on a single error. 183 */ 184 return (AE_OK); 185 } 186 187 188 /******************************************************************************* 189 * 190 * FUNCTION: AcpiDsInitializeObjects 191 * 192 * PARAMETERS: TableDesc - Descriptor for parent ACPI table 193 * StartNode - Root of subtree to be initialized. 194 * 195 * RETURN: Status 196 * 197 * DESCRIPTION: Walk the namespace starting at "StartNode" and perform any 198 * necessary initialization on the objects found therein 199 * 200 ******************************************************************************/ 201 202 ACPI_STATUS 203 AcpiDsInitializeObjects ( 204 UINT32 TableIndex, 205 ACPI_NAMESPACE_NODE *StartNode) 206 { 207 ACPI_STATUS Status; 208 ACPI_INIT_WALK_INFO Info; 209 ACPI_TABLE_HEADER *Table; 210 ACPI_OWNER_ID OwnerId; 211 212 213 ACPI_FUNCTION_TRACE (DsInitializeObjects); 214 215 216 Status = AcpiTbGetOwnerId (TableIndex, &OwnerId); 217 if (ACPI_FAILURE (Status)) 218 { 219 return_ACPI_STATUS (Status); 220 } 221 222 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 223 "**** Starting initialization of namespace objects ****\n")); 224 225 /* Set all init info to zero */ 226 227 memset (&Info, 0, sizeof (ACPI_INIT_WALK_INFO)); 228 229 Info.OwnerId = OwnerId; 230 Info.TableIndex = TableIndex; 231 232 /* Walk entire namespace from the supplied root */ 233 234 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 235 if (ACPI_FAILURE (Status)) 236 { 237 return_ACPI_STATUS (Status); 238 } 239 240 /* 241 * We don't use AcpiWalkNamespace since we do not want to acquire 242 * the namespace reader lock. 243 */ 244 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, StartNode, ACPI_UINT32_MAX, 245 ACPI_NS_WALK_UNLOCK, AcpiDsInitOneObject, NULL, &Info, NULL); 246 if (ACPI_FAILURE (Status)) 247 { 248 ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace")); 249 } 250 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 251 252 Status = AcpiGetTableByIndex (TableIndex, &Table); 253 if (ACPI_FAILURE (Status)) 254 { 255 return_ACPI_STATUS (Status); 256 } 257 258 /* DSDT is always the first AML table */ 259 260 if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT)) 261 { 262 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 263 "\nInitializing Namespace objects:\n")); 264 } 265 266 /* Summary of objects initialized */ 267 268 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 269 "Table [%4.4s: %-8.8s] (id %.2X) - %4u Objects with %3u Devices, " 270 "%3u Regions, %4u Methods (%u/%u/%u Serial/Non/Cvt)\n", 271 Table->Signature, Table->OemTableId, OwnerId, Info.ObjectCount, 272 Info.DeviceCount,Info.OpRegionCount, Info.MethodCount, 273 Info.SerialMethodCount, Info.NonSerialMethodCount, 274 Info.SerializedMethodCount)); 275 276 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "%u Methods, %u Regions\n", 277 Info.MethodCount, Info.OpRegionCount)); 278 279 return_ACPI_STATUS (AE_OK); 280 } 281