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