nsinit.c revision 281075
189051Sjake/****************************************************************************** 289051Sjake * 389051Sjake * Module Name: nsinit - namespace initialization 489051Sjake * 589051Sjake *****************************************************************************/ 689051Sjake 789051Sjake/* 889051Sjake * Copyright (C) 2000 - 2015, Intel Corp. 989051Sjake * All rights reserved. 1089051Sjake * 1189051Sjake * Redistribution and use in source and binary forms, with or without 1289051Sjake * modification, are permitted provided that the following conditions 1389051Sjake * are met: 1489051Sjake * 1. Redistributions of source code must retain the above copyright 1589051Sjake * notice, this list of conditions, and the following disclaimer, 1689051Sjake * without modification. 1789051Sjake * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1889051Sjake * substantially similar to the "NO WARRANTY" disclaimer below 1989051Sjake * ("Disclaimer") and any redistribution must be conditioned upon 2089051Sjake * including a substantially similar Disclaimer requirement for further 2189051Sjake * binary redistribution. 2289051Sjake * 3. Neither the names of the above-listed copyright holders nor the names 2389051Sjake * of any contributors may be used to endorse or promote products derived 2489051Sjake * from this software without specific prior written permission. 2589051Sjake * 2689051Sjake * Alternatively, this software may be distributed under the terms of the 2789051Sjake * GNU General Public License ("GPL") version 2 as published by the Free 2889051Sjake * Software Foundation. 2989051Sjake * 3089051Sjake * NO WARRANTY 3189051Sjake * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32211050Smarius * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3389051Sjake * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3489051Sjake * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3589051Sjake * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3689051Sjake * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3789051Sjake * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3889051Sjake * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3989051Sjake * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4089051Sjake * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4189051Sjake * POSSIBILITY OF SUCH DAMAGES. 4289051Sjake */ 4389051Sjake 4489051Sjake#include <contrib/dev/acpica/include/acpi.h> 4589051Sjake#include <contrib/dev/acpica/include/accommon.h> 4689051Sjake#include <contrib/dev/acpica/include/acnamesp.h> 4789051Sjake#include <contrib/dev/acpica/include/acdispat.h> 4889051Sjake#include <contrib/dev/acpica/include/acinterp.h> 4989051Sjake 5089051Sjake#define _COMPONENT ACPI_NAMESPACE 5189051Sjake ACPI_MODULE_NAME ("nsinit") 5289051Sjake 5389051Sjake/* Local prototypes */ 5489051Sjake 5589051Sjakestatic ACPI_STATUS 5689051SjakeAcpiNsInitOneObject ( 57145150Smarius ACPI_HANDLE ObjHandle, 58145150Smarius UINT32 Level, 59145150Smarius void *Context, 6089051Sjake void **ReturnValue); 6189051Sjake 6289051Sjakestatic ACPI_STATUS 63131950SmarcelAcpiNsInitOneDevice ( 6489051Sjake ACPI_HANDLE ObjHandle, 6589051Sjake UINT32 NestingLevel, 6689051Sjake void *Context, 6789051Sjake void **ReturnValue); 6889051Sjake 69170846Smariusstatic ACPI_STATUS 7089051SjakeAcpiNsFindIniMethods ( 7189051Sjake ACPI_HANDLE ObjHandle, 7289051Sjake UINT32 NestingLevel, 7389051Sjake void *Context, 7489051Sjake void **ReturnValue); 7589051Sjake 7689051Sjake 7789051Sjake/******************************************************************************* 7889051Sjake * 7989051Sjake * FUNCTION: AcpiNsInitializeObjects 8089051Sjake * 8189051Sjake * PARAMETERS: None 8292205Sjake * 83119696Smarcel * RETURN: Status 84182730Smarius * 85285839Smarius * DESCRIPTION: Walk the entire namespace and perform any necessary 8689051Sjake * initialization on the objects found therein 8797511Sjake * 8892205Sjake ******************************************************************************/ 89152022Sjhb 9089051SjakeACPI_STATUS 9195132SjakeAcpiNsInitializeObjects ( 9291617Sjake void) 93216803Smarius{ 9489051Sjake ACPI_STATUS Status; 95170846Smarius ACPI_INIT_WALK_INFO Info; 9689051Sjake 97183142Smarius 98183142Smarius ACPI_FUNCTION_TRACE (NsInitializeObjects); 99183142Smarius 10089051Sjake 101210601Smav ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 102178048Smarius "**** Starting initialization of namespace objects ****\n")); 10389051Sjake ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 10489051Sjake "Completing Region/Field/Buffer/Package initialization:\n")); 10589051Sjake 10689051Sjake /* Set all init info to zero */ 107169796Smarius 108169796Smarius ACPI_MEMSET (&Info, 0, sizeof (ACPI_INIT_WALK_INFO)); 10989051Sjake 11089051Sjake /* Walk entire namespace from the supplied root */ 111182730Smarius 11297001Sjake Status = AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 113211071Smarius ACPI_UINT32_MAX, AcpiNsInitOneObject, NULL, 11491783Sjake &Info, NULL); 115152022Sjhb if (ACPI_FAILURE (Status)) 11689051Sjake { 117285839Smarius ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace")); 118285839Smarius } 119170846Smarius 120211050Smarius ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 12191617Sjake " Initialized %u/%u Regions %u/%u Fields %u/%u " 122170846Smarius "Buffers %u/%u Packages (%u nodes)\n", 123291121Smarius Info.OpRegionInit, Info.OpRegionCount, 124222813Sattilio Info.FieldInit, Info.FieldCount, 125291121Smarius Info.BufferInit, Info.BufferCount, 126291121Smarius Info.PackageInit, Info.PackageCount, Info.ObjectCount)); 12792205Sjake 128204152Smarius ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 129204152Smarius "%u Control Methods found\n%u Op Regions found\n", 130169796Smarius Info.MethodCount, Info.OpRegionCount)); 131203838Smarius 132204152Smarius return_ACPI_STATUS (AE_OK); 133169796Smarius} 134169796Smarius 135170846Smarius 136211050Smarius/******************************************************************************* 137211050Smarius * 138211050Smarius * FUNCTION: AcpiNsInitializeDevices 139170846Smarius * 140211050Smarius * PARAMETERS: None 141170846Smarius * 14291617Sjake * RETURN: ACPI_STATUS 14391617Sjake * 144170846Smarius * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices. 145285839Smarius * This means running _INI on all present devices. 14691617Sjake * 14791617Sjake * Note: We install PCI config space handler on region access, 14891617Sjake * not here. 14991617Sjake * 150170846Smarius ******************************************************************************/ 151170846Smarius 152169796SmariusACPI_STATUS 153170846SmariusAcpiNsInitializeDevices ( 154170846Smarius void) 155170846Smarius{ 156170846Smarius ACPI_STATUS Status; 15797511Sjake ACPI_DEVICE_WALK_INFO Info; 158102042Sjake 15997511Sjake 16097511Sjake ACPI_FUNCTION_TRACE (NsInitializeDevices); 16197511Sjake 162170846Smarius 163170846Smarius /* Init counters */ 16491617Sjake 16591617Sjake Info.DeviceCount = 0; 166203838Smarius Info.Num_STA = 0; 167204152Smarius Info.Num_INI = 0; 168204152Smarius 169203838Smarius ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 170291121Smarius "Initializing Device/Processor/Thermal objects " 171203838Smarius "and executing _INI/_STA methods:\n")); 172291121Smarius 173211050Smarius /* Tree analysis: find all subtrees that contain _INI methods */ 174203838Smarius 175291121Smarius Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 176203838Smarius ACPI_UINT32_MAX, FALSE, AcpiNsFindIniMethods, NULL, &Info, NULL); 177203838Smarius if (ACPI_FAILURE (Status)) 178203838Smarius { 179203838Smarius goto ErrorExit; 180203838Smarius } 181203838Smarius 182203838Smarius /* Allocate the evaluation information block */ 183203838Smarius 184203838Smarius Info.EvaluateInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 185203838Smarius if (!Info.EvaluateInfo) 186203838Smarius { 187203838Smarius Status = AE_NO_MEMORY; 188204152Smarius goto ErrorExit; 189204152Smarius } 190204152Smarius 191204152Smarius /* 192291121Smarius * Execute the "global" _INI method that may appear at the root. This 193291121Smarius * support is provided for Windows compatibility (Vista+) and is not 194291121Smarius * part of the ACPI specification. 195204152Smarius */ 196291121Smarius Info.EvaluateInfo->PrefixNode = AcpiGbl_RootNode; 197203838Smarius Info.EvaluateInfo->RelativePathname = METHOD_NAME__INI; 198291121Smarius Info.EvaluateInfo->Parameters = NULL; 199203838Smarius Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE; 200203838Smarius 201203838Smarius Status = AcpiNsEvaluate (Info.EvaluateInfo); 202203838Smarius if (ACPI_SUCCESS (Status)) 20389051Sjake { 204169796Smarius Info.Num_INI++; 20589051Sjake } 206122947Sjhb 207285839Smarius /* Walk namespace to execute all _INIs on present devices */ 20889051Sjake 20989051Sjake Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 210222813Sattilio ACPI_UINT32_MAX, FALSE, AcpiNsInitOneDevice, NULL, &Info, NULL); 21189051Sjake 21289051Sjake /* 213203838Smarius * Any _OSI requests should be completed by now. If the BIOS has 214291121Smarius * requested any Windows OSI strings, we will always truncate 215291121Smarius * I/O addresses to 16 bits -- for Windows compatibility. 21689051Sjake */ 21789051Sjake if (AcpiGbl_OsiData >= ACPI_OSI_WIN_2000) 218203838Smarius { 219204152Smarius AcpiGbl_TruncateIoAddresses = TRUE; 220203838Smarius } 221203838Smarius 222291121Smarius ACPI_FREE (Info.EvaluateInfo); 223203838Smarius if (ACPI_FAILURE (Status)) 224203838Smarius { 225122947Sjhb goto ErrorExit; 226122947Sjhb } 227122947Sjhb 228122947Sjhb ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 229123126Sjhb " Executed %u _INI methods requiring %u _STA executions " 230122947Sjhb "(examined %u objects)\n", 231122947Sjhb Info.Num_INI, Info.Num_STA, Info.DeviceCount)); 232176734Sjeff 233176734Sjeff return_ACPI_STATUS (Status); 234176734Sjeff 235176734Sjeff 236176994SmariusErrorExit: 237176734Sjeff ACPI_EXCEPTION ((AE_INFO, Status, "During device initialization")); 238176734Sjeff return_ACPI_STATUS (Status); 23991617Sjake} 24091617Sjake 24191617Sjake 24291617Sjake/******************************************************************************* 24391617Sjake * 24491617Sjake * FUNCTION: AcpiNsInitOneObject 24591617Sjake * 24691617Sjake * PARAMETERS: ObjHandle - Node 24791617Sjake * Level - Current nesting level 24891617Sjake * Context - Points to a init info struct 24991617Sjake * ReturnValue - Not used 250183142Smarius * 25191617Sjake * RETURN: Status 25291617Sjake * 25391617Sjake * DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every object 25491617Sjake * within the namespace. 25591617Sjake * 25691617Sjake * Currently, the only objects that require initialization are: 257186347Snwhitehorn * 1) Methods 25891617Sjake * 2) Op Regions 25991617Sjake * 26089051Sjake ******************************************************************************/ 26189051Sjake 26289051Sjakestatic ACPI_STATUS 26389051SjakeAcpiNsInitOneObject ( 26489051Sjake ACPI_HANDLE ObjHandle, 26589051Sjake UINT32 Level, 266285839Smarius void *Context, 26789051Sjake void **ReturnValue) 268285839Smarius{ 269285839Smarius ACPI_OBJECT_TYPE Type; 270285839Smarius ACPI_STATUS Status = AE_OK; 271285839Smarius ACPI_INIT_WALK_INFO *Info = (ACPI_INIT_WALK_INFO *) Context; 272285839Smarius ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 273285839Smarius ACPI_OPERAND_OBJECT *ObjDesc; 274285839Smarius 275285839Smarius 276285839Smarius ACPI_FUNCTION_NAME (NsInitOneObject); 277285839Smarius 278285839Smarius 279285839Smarius Info->ObjectCount++; 280285839Smarius 281285839Smarius /* And even then, we are only interested in a few object types */ 282285839Smarius 283285839Smarius Type = AcpiNsGetType (ObjHandle); 284285839Smarius ObjDesc = AcpiNsGetAttachedObject (Node); 285285839Smarius if (!ObjDesc) 28689051Sjake { 28789051Sjake return (AE_OK); 28889051Sjake } 28989051Sjake 290178048Smarius /* Increment counters for object types we are looking for */ 291210601Smav 29289051Sjake switch (Type) 293169796Smarius { 294157240Smarius case ACPI_TYPE_REGION: 295203838Smarius 296203838Smarius Info->OpRegionCount++; 297203838Smarius break; 298203838Smarius 299203838Smarius case ACPI_TYPE_BUFFER_FIELD: 300203838Smarius 301203838Smarius Info->FieldCount++; 302204152Smarius break; 303203838Smarius 304203838Smarius case ACPI_TYPE_LOCAL_BANK_FIELD: 305203838Smarius 306203838Smarius Info->FieldCount++; 307203838Smarius break; 308203838Smarius 309204152Smarius case ACPI_TYPE_BUFFER: 310203838Smarius 311291121Smarius Info->BufferCount++; 312203838Smarius break; 313203838Smarius 314203838Smarius case ACPI_TYPE_PACKAGE: 315204152Smarius 316203838Smarius Info->PackageCount++; 317214071Smarius break; 318203838Smarius 31989051Sjake default: 320203838Smarius 321203838Smarius /* No init required, just exit now */ 322203838Smarius 323203838Smarius return (AE_OK); 324203838Smarius } 325203838Smarius 326203838Smarius /* If the object is already initialized, nothing else to do */ 327207537Smarius 328207537Smarius if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) 329203838Smarius { 33091617Sjake return (AE_OK); 33191617Sjake } 332203838Smarius 333203838Smarius /* Must lock the interpreter before executing AML code */ 334203838Smarius 335203838Smarius AcpiExEnterInterpreter (); 336203838Smarius 337203838Smarius /* 33891617Sjake * Each of these types can contain executable AML code within the 339291121Smarius * declaration. 340203838Smarius */ 341203838Smarius switch (Type) 34291617Sjake { 343254025Sjeff case ACPI_TYPE_REGION: 344254025Sjeff 345203838Smarius Info->OpRegionInit++; 346203838Smarius Status = AcpiDsGetRegionArguments (ObjDesc); 347254025Sjeff break; 348254025Sjeff 349203838Smarius case ACPI_TYPE_BUFFER_FIELD: 350203838Smarius 351204152Smarius Info->FieldInit++; 352203838Smarius Status = AcpiDsGetBufferFieldArguments (ObjDesc); 353203838Smarius break; 35489051Sjake 355203838Smarius case ACPI_TYPE_LOCAL_BANK_FIELD: 356182689Smarius 357222813Sattilio Info->FieldInit++; 358203838Smarius Status = AcpiDsGetBankFieldArguments (ObjDesc); 35989051Sjake break; 36089051Sjake 36189051Sjake case ACPI_TYPE_BUFFER: 36289051Sjake 36389051Sjake Info->BufferInit++; 364169796Smarius Status = AcpiDsGetBufferArguments (ObjDesc); 36589051Sjake break; 36689051Sjake 367169796Smarius case ACPI_TYPE_PACKAGE: 368285839Smarius 36989051Sjake Info->PackageInit++; 37091617Sjake Status = AcpiDsGetPackageArguments (ObjDesc); 37191617Sjake break; 372169796Smarius 37391617Sjake default: 374113238Sjake 375181701Smarius /* No other types can get here */ 37691617Sjake 37791617Sjake break; 37889051Sjake } 37991783Sjake 38091783Sjake if (ACPI_FAILURE (Status)) 38189051Sjake { 38291783Sjake ACPI_EXCEPTION ((AE_INFO, Status, 383222531Snwhitehorn "Could not execute arguments for [%4.4s] (%s)", 38491617Sjake AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Type))); 38591617Sjake } 38691617Sjake 38791617Sjake /* 38889051Sjake * We ignore errors from above, and always return OK, since we don't want 389169796Smarius * to abort the walk on any single error. 39091617Sjake */ 39191617Sjake AcpiExExitInterpreter (); 392169796Smarius return (AE_OK); 393169796Smarius} 39491617Sjake 39591617Sjake 39691617Sjake/******************************************************************************* 39791617Sjake * 39891617Sjake * FUNCTION: AcpiNsFindIniMethods 399169796Smarius * 400102042Sjake * PARAMETERS: ACPI_WALK_CALLBACK 40191617Sjake * 40291617Sjake * RETURN: ACPI_STATUS 40391617Sjake * 40491617Sjake * DESCRIPTION: Called during namespace walk. Finds objects named _INI under 40591783Sjake * device/processor/thermal objects, and marks the entire subtree 40691617Sjake * with a SUBTREE_HAS_INI flag. This flag is used during the 40791617Sjake * subsequent device initialization walk to avoid entire subtrees 40891617Sjake * that do not contain an _INI. 40991617Sjake * 41091617Sjake ******************************************************************************/ 41191617Sjake 41291783Sjakestatic ACPI_STATUS 41391783SjakeAcpiNsFindIniMethods ( 414169796Smarius ACPI_HANDLE ObjHandle, 41591617Sjake UINT32 NestingLevel, 41689051Sjake void *Context, 41791617Sjake void **ReturnValue) 41891617Sjake{ 41991617Sjake ACPI_DEVICE_WALK_INFO *Info = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context); 42091617Sjake ACPI_NAMESPACE_NODE *Node; 42189051Sjake ACPI_NAMESPACE_NODE *ParentNode; 42291617Sjake 423207248Smarius 424207248Smarius /* Keep count of device/processor/thermal objects */ 425223719Smarius 426204152Smarius Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); 427223719Smarius if ((Node->Type == ACPI_TYPE_DEVICE) || 428223719Smarius (Node->Type == ACPI_TYPE_PROCESSOR) || 429223719Smarius (Node->Type == ACPI_TYPE_THERMAL)) 430207248Smarius { 431207248Smarius Info->DeviceCount++; 432207248Smarius return (AE_OK); 433204152Smarius } 434207248Smarius 435213868Smarius /* We are only looking for methods named _INI */ 436213868Smarius 437213868Smarius if (!ACPI_COMPARE_NAME (Node->Name.Ascii, METHOD_NAME__INI)) 438213868Smarius { 439213868Smarius return (AE_OK); 440213868Smarius } 441216803Smarius 442216803Smarius /* 443207248Smarius * The only _INI methods that we care about are those that are 444216803Smarius * present under Device, Processor, and Thermal objects. 445216803Smarius */ 446216803Smarius ParentNode = Node->Parent; 447216803Smarius switch (ParentNode->Type) 448176994Smarius { 449176994Smarius case ACPI_TYPE_DEVICE: 450176994Smarius case ACPI_TYPE_PROCESSOR: 451176994Smarius case ACPI_TYPE_THERMAL: 452176994Smarius 453207248Smarius /* Mark parent and bubble up the INI present flag to the root */ 454213868Smarius 455213868Smarius while (ParentNode) 456213868Smarius { 457213868Smarius ParentNode->Flags |= ANOBJ_SUBTREE_HAS_INI; 458213868Smarius ParentNode = ParentNode->Parent; 459207248Smarius } 460207248Smarius break; 46189051Sjake 462169796Smarius default: 463169796Smarius 46489051Sjake break; 46591783Sjake } 46691783Sjake 46791617Sjake return (AE_OK); 46891783Sjake} 46991617Sjake 47089051Sjake 471285839Smarius/******************************************************************************* 472285839Smarius * 473285839Smarius * FUNCTION: AcpiNsInitOneDevice 474210601Smav * 475210601Smav * PARAMETERS: ACPI_WALK_CALLBACK 476210601Smav * 477182020Smarius * RETURN: ACPI_STATUS 478170303Sjeff * 47989051Sjake * DESCRIPTION: This is called once per device soon after ACPI is enabled 48089051Sjake * to initialize each device. It determines if the device is 48192205Sjake * present, and if so, calls _INI. 48292205Sjake * 48392205Sjake ******************************************************************************/ 484222813Sattilio 48592205Sjakestatic ACPI_STATUS 48692205SjakeAcpiNsInitOneDevice ( 48792205Sjake ACPI_HANDLE ObjHandle, 488223346Smarius UINT32 NestingLevel, 489223346Smarius void *Context, 490222813Sattilio void **ReturnValue) 491222813Sattilio{ 492222813Sattilio ACPI_DEVICE_WALK_INFO *WalkInfo = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context); 493222813Sattilio ACPI_EVALUATE_INFO *Info = WalkInfo->EvaluateInfo; 494222813Sattilio UINT32 Flags; 495223346Smarius ACPI_STATUS Status; 496222813Sattilio ACPI_NAMESPACE_NODE *DeviceNode; 497222813Sattilio 498222813Sattilio 49992205Sjake ACPI_FUNCTION_TRACE (NsInitOneDevice); 500222813Sattilio 50192205Sjake 50292205Sjake /* We are interested in Devices, Processors and ThermalZones only */ 50392205Sjake 50492205Sjake DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); 50592205Sjake if ((DeviceNode->Type != ACPI_TYPE_DEVICE) && 50692205Sjake (DeviceNode->Type != ACPI_TYPE_PROCESSOR) && 50792205Sjake (DeviceNode->Type != ACPI_TYPE_THERMAL)) 50892205Sjake { 50989051Sjake return_ACPI_STATUS (AE_OK); 510239864Smarius } 51189051Sjake 512169796Smarius /* 51389051Sjake * Because of an earlier namespace analysis, all subtrees that contain an 51489051Sjake * _INI method are tagged. 51589051Sjake * 516239864Smarius * If this device subtree does not contain any _INI methods, we 51789051Sjake * can exit now and stop traversing this entire subtree. 518223346Smarius */ 51992205Sjake if (!(DeviceNode->Flags & ANOBJ_SUBTREE_HAS_INI)) 520169796Smarius { 521222813Sattilio return_ACPI_STATUS (AE_CTRL_DEPTH); 522169796Smarius } 523223346Smarius 524223346Smarius /* 525223346Smarius * Run _STA to determine if this device is present and functioning. We 526223346Smarius * must know this information for two important reasons (from ACPI spec): 527223346Smarius * 528183142Smarius * 1) We can only run _INI if the device is present. 529183142Smarius * 2) We must abort the device tree walk on this subtree if the device is 530183142Smarius * not present and is not functional (we will not examine the children) 53192205Sjake * 53292205Sjake * The _STA method is not required to be present under the device, we 533223346Smarius * assume the device is present if _STA does not exist. 534223346Smarius */ 535222813Sattilio ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname ( 536169796Smarius ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__STA)); 53789051Sjake 53889051Sjake Status = AcpiUtExecute_STA (DeviceNode, &Flags); 539170846Smarius if (ACPI_FAILURE (Status)) 540285839Smarius { 541178048Smarius /* Ignore error and move on to next device */ 542178048Smarius 543178048Smarius return_ACPI_STATUS (AE_OK); 544178048Smarius } 545178048Smarius 546178048Smarius /* 547210601Smav * Flags == -1 means that _STA was not found. In this case, we assume that 548210601Smav * the device is both present and functional. 549212541Smav * 550212541Smav * From the ACPI spec, description of _STA: 551210601Smav * 552212541Smav * "If a device object (including the processor object) does not have an 553212541Smav * _STA object, then OSPM assumes that all of the above bits are set (in 554212541Smav * other words, the device is present, ..., and functioning)" 555212541Smav */ 556212541Smav if (Flags != ACPI_UINT32_MAX) 557212541Smav { 558212541Smav WalkInfo->Num_STA++; 559212541Smav } 560212541Smav 561210601Smav /* 562210601Smav * Examine the PRESENT and FUNCTIONING status bits 563210601Smav * 564222813Sattilio * Note: ACPI spec does not seem to specify behavior for the present but 56589051Sjake * not functioning case, so we assume functioning if present. 56689051Sjake */ 56789051Sjake if (!(Flags & ACPI_STA_DEVICE_PRESENT)) 568251703Sjeff { 569222813Sattilio /* Device is not present, we must examine the Functioning bit */ 570222813Sattilio 571211050Smarius if (Flags & ACPI_STA_DEVICE_FUNCTIONING) 57289051Sjake { 57389051Sjake /* 57489051Sjake * Device is not present but is "functioning". In this case, 575169796Smarius * we will not run _INI, but we continue to examine the children 576211050Smarius * of this device. 57789051Sjake * 578169796Smarius * From the ACPI spec, description of _STA: (Note - no mention 579157240Smarius * of whether to run _INI or not on the device in question) 580211050Smarius * 58189051Sjake * "_STA may return bit 0 clear (not present) with bit 3 set 58289051Sjake * (device is functional). This case is used to indicate a valid 583285839Smarius * device for which no device driver should be loaded (for example, 584211050Smarius * a bridge device.) Children of this device may be present and 58589051Sjake * valid. OSPM should continue enumeration below a device whose 586169796Smarius * _STA returns this bit combination" 587285839Smarius */ 588211050Smarius return_ACPI_STATUS (AE_OK); 58989051Sjake } 59091783Sjake else 59189051Sjake { 59289051Sjake /* 59389051Sjake * Device is not present and is not functioning. We must abort the 594170846Smarius * walk of this subtree immediately -- don't look at the children 595169796Smarius * of such a device. 596169796Smarius * 597157240Smarius * From the ACPI spec, description of _INI: 598157240Smarius * 599157240Smarius * "If the _STA method indicates that the device is not present, 600157240Smarius * OSPM will not run the _INI and will not examine the children 601157240Smarius * of the device for _INI methods" 602157240Smarius */ 603157240Smarius return_ACPI_STATUS (AE_CTRL_DEPTH); 60489051Sjake } 605157240Smarius } 606157240Smarius 607169796Smarius /* 608169796Smarius * The device is present or is assumed present if no _STA exists. 60989051Sjake * Run the _INI if it exists (not required to exist) 61091783Sjake * 611170846Smarius * Note: We know there is an _INI within this subtree, but it may not be 61289051Sjake * under this particular device, it may be lower in the branch. 61389051Sjake */ 614190106Smarius ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname ( 615169796Smarius ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__INI)); 616169796Smarius 61792205Sjake ACPI_MEMSET (Info, 0, sizeof (ACPI_EVALUATE_INFO)); 618186395Smarius Info->PrefixNode = DeviceNode; 619186395Smarius Info->RelativePathname = METHOD_NAME__INI; 62089051Sjake Info->Parameters = NULL; 62189051Sjake Info->Flags = ACPI_IGNORE_RETURN_VALUE; 622170846Smarius 623211050Smarius Status = AcpiNsEvaluate (Info); 624211050Smarius if (ACPI_SUCCESS (Status)) 625211050Smarius { 626211050Smarius WalkInfo->Num_INI++; 627211050Smarius } 628211050Smarius 629211050Smarius#ifdef ACPI_DEBUG_OUTPUT 630285839Smarius else if (Status != AE_NOT_FOUND) 631211050Smarius { 632211050Smarius /* Ignore error and move on to next device */ 633211050Smarius 634211050Smarius char *ScopeName = AcpiNsGetExternalPathname (Info->Node); 635285839Smarius 636211050Smarius ACPI_EXCEPTION ((AE_INFO, Status, "during %s._INI execution", 637211050Smarius ScopeName)); 638211050Smarius ACPI_FREE (ScopeName); 639211050Smarius } 640211050Smarius#endif 641211050Smarius 642211050Smarius /* Ignore errors from above */ 643211050Smarius 644211050Smarius Status = AE_OK; 645211050Smarius 646211050Smarius /* 647211050Smarius * The _INI method has been run if present; call the Global Initialization 648211050Smarius * Handler for this device. 649211050Smarius */ 650211050Smarius if (AcpiGbl_InitHandler) 651211050Smarius { 652211050Smarius Status = AcpiGbl_InitHandler (DeviceNode, ACPI_INIT_DEVICE_INI); 653211050Smarius } 654211050Smarius 655211050Smarius return_ACPI_STATUS (Status); 656211050Smarius} 657211050Smarius