nsinit.c revision 217365
167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: nsinit - namespace initialization 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8229989Sjkim * Copyright (C) 2000 - 2011, Intel Corp. 970243Smsmith * All rights reserved. 1067754Smsmith * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 2567754Smsmith * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 2967754Smsmith * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 4367754Smsmith 4467754Smsmith 4567754Smsmith#define __NSXFINIT_C__ 4667754Smsmith 47193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 48193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 49193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 50193341Sjkim#include <contrib/dev/acpica/include/acdispat.h> 51193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 5267754Smsmith 5377424Smsmith#define _COMPONENT ACPI_NAMESPACE 5491116Smsmith ACPI_MODULE_NAME ("nsinit") 5567754Smsmith 56151937Sjkim/* Local prototypes */ 5767754Smsmith 58151937Sjkimstatic ACPI_STATUS 59151937SjkimAcpiNsInitOneObject ( 60151937Sjkim ACPI_HANDLE ObjHandle, 61151937Sjkim UINT32 Level, 62151937Sjkim void *Context, 63151937Sjkim void **ReturnValue); 64151937Sjkim 65151937Sjkimstatic ACPI_STATUS 66151937SjkimAcpiNsInitOneDevice ( 67151937Sjkim ACPI_HANDLE ObjHandle, 68151937Sjkim UINT32 NestingLevel, 69151937Sjkim void *Context, 70151937Sjkim void **ReturnValue); 71151937Sjkim 72167802Sjkimstatic ACPI_STATUS 73167802SjkimAcpiNsFindIniMethods ( 74167802Sjkim ACPI_HANDLE ObjHandle, 75167802Sjkim UINT32 NestingLevel, 76167802Sjkim void *Context, 77167802Sjkim void **ReturnValue); 78151937Sjkim 79167802Sjkim 8067754Smsmith/******************************************************************************* 8167754Smsmith * 8267754Smsmith * FUNCTION: AcpiNsInitializeObjects 8367754Smsmith * 8467754Smsmith * PARAMETERS: None 8567754Smsmith * 8667754Smsmith * RETURN: Status 8767754Smsmith * 8867754Smsmith * DESCRIPTION: Walk the entire namespace and perform any necessary 8967754Smsmith * initialization on the objects found therein 9067754Smsmith * 9167754Smsmith ******************************************************************************/ 9267754Smsmith 9367754SmsmithACPI_STATUS 9467754SmsmithAcpiNsInitializeObjects ( 9567754Smsmith void) 9667754Smsmith{ 9767754Smsmith ACPI_STATUS Status; 9867754Smsmith ACPI_INIT_WALK_INFO Info; 9967754Smsmith 10067754Smsmith 101167802Sjkim ACPI_FUNCTION_TRACE (NsInitializeObjects); 10267754Smsmith 10367754Smsmith 10482367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 10582367Smsmith "**** Starting initialization of namespace objects ****\n")); 106138287Smarks ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 107138287Smarks "Completing Region/Field/Buffer/Package initialization:")); 10867754Smsmith 10999146Siwasaki /* Set all init info to zero */ 11067754Smsmith 11199146Siwasaki ACPI_MEMSET (&Info, 0, sizeof (ACPI_INIT_WALK_INFO)); 11267754Smsmith 11367754Smsmith /* Walk entire namespace from the supplied root */ 11467754Smsmith 11567754Smsmith Status = AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 116209746Sjkim ACPI_UINT32_MAX, AcpiNsInitOneObject, NULL, 117209746Sjkim &Info, NULL); 11867754Smsmith if (ACPI_FAILURE (Status)) 11967754Smsmith { 120167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace")); 12167754Smsmith } 12267754Smsmith 123114237Snjl ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 124209746Sjkim "\nInitialized %u/%u Regions %u/%u Fields %u/%u " 125209746Sjkim "Buffers %u/%u Packages (%u nodes)\n", 126102550Siwasaki Info.OpRegionInit, Info.OpRegionCount, 127102550Siwasaki Info.FieldInit, Info.FieldCount, 128102550Siwasaki Info.BufferInit, Info.BufferCount, 12999146Siwasaki Info.PackageInit, Info.PackageCount, Info.ObjectCount)); 130114237Snjl 13182367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 132209746Sjkim "%u Control Methods found\n", Info.MethodCount)); 13382367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 134209746Sjkim "%u Op Regions found\n", Info.OpRegionCount)); 13567754Smsmith 13667754Smsmith return_ACPI_STATUS (AE_OK); 13767754Smsmith} 13867754Smsmith 13967754Smsmith 14077424Smsmith/******************************************************************************* 14167754Smsmith * 14267754Smsmith * FUNCTION: AcpiNsInitializeDevices 14367754Smsmith * 14467754Smsmith * PARAMETERS: None 14567754Smsmith * 14667754Smsmith * RETURN: ACPI_STATUS 14767754Smsmith * 14867754Smsmith * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices. 14967754Smsmith * This means running _INI on all present devices. 15067754Smsmith * 15177424Smsmith * Note: We install PCI config space handler on region access, 15277424Smsmith * not here. 15367754Smsmith * 15477424Smsmith ******************************************************************************/ 15567754Smsmith 15667754SmsmithACPI_STATUS 15767754SmsmithAcpiNsInitializeDevices ( 15873561Smsmith void) 15967754Smsmith{ 16067754Smsmith ACPI_STATUS Status; 16167754Smsmith ACPI_DEVICE_WALK_INFO Info; 16267754Smsmith 16367754Smsmith 164167802Sjkim ACPI_FUNCTION_TRACE (NsInitializeDevices); 16567754Smsmith 16667754Smsmith 16799146Siwasaki /* Init counters */ 16899146Siwasaki 16967754Smsmith Info.DeviceCount = 0; 17067754Smsmith Info.Num_STA = 0; 17167754Smsmith Info.Num_INI = 0; 17267754Smsmith 173138287Smarks ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 174193267Sjkim "Initializing Device/Processor/Thermal objects " 175193267Sjkim "by executing _INI methods:")); 17667754Smsmith 177167802Sjkim /* Tree analysis: find all subtrees that contain _INI methods */ 178167802Sjkim 179167802Sjkim Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 180199337Sjkim ACPI_UINT32_MAX, FALSE, AcpiNsFindIniMethods, NULL, &Info, NULL); 181123315Snjl if (ACPI_FAILURE (Status)) 182123315Snjl { 183167802Sjkim goto ErrorExit; 184123315Snjl } 18567754Smsmith 186167802Sjkim /* Allocate the evaluation information block */ 18767754Smsmith 188167802Sjkim Info.EvaluateInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 189167802Sjkim if (!Info.EvaluateInfo) 190167802Sjkim { 191167802Sjkim Status = AE_NO_MEMORY; 192167802Sjkim goto ErrorExit; 193167802Sjkim } 194167802Sjkim 195197104Sjkim /* 196197104Sjkim * Execute the "global" _INI method that may appear at the root. This 197197104Sjkim * support is provided for Windows compatibility (Vista+) and is not 198197104Sjkim * part of the ACPI specification. 199197104Sjkim */ 200197104Sjkim Info.EvaluateInfo->PrefixNode = AcpiGbl_RootNode; 201197104Sjkim Info.EvaluateInfo->Pathname = METHOD_NAME__INI; 202197104Sjkim Info.EvaluateInfo->Parameters = NULL; 203197104Sjkim Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE; 204197104Sjkim 205197104Sjkim Status = AcpiNsEvaluate (Info.EvaluateInfo); 206197104Sjkim if (ACPI_SUCCESS (Status)) 207197104Sjkim { 208197104Sjkim Info.Num_INI++; 209197104Sjkim } 210197104Sjkim 211167802Sjkim /* Walk namespace to execute all _INIs on present devices */ 212167802Sjkim 213123315Snjl Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 214199337Sjkim ACPI_UINT32_MAX, FALSE, AcpiNsInitOneDevice, NULL, &Info, NULL); 215123315Snjl 216209746Sjkim /* 217209746Sjkim * Any _OSI requests should be completed by now. If the BIOS has 218209746Sjkim * requested any Windows OSI strings, we will always truncate 219209746Sjkim * I/O addresses to 16 bits -- for Windows compatibility. 220209746Sjkim */ 221209746Sjkim if (AcpiGbl_OsiData >= ACPI_OSI_WIN_2000) 222209746Sjkim { 223209746Sjkim AcpiGbl_TruncateIoAddresses = TRUE; 224209746Sjkim } 225209746Sjkim 226167802Sjkim ACPI_FREE (Info.EvaluateInfo); 22767754Smsmith if (ACPI_FAILURE (Status)) 22867754Smsmith { 229167802Sjkim goto ErrorExit; 23067754Smsmith } 23167754Smsmith 232114237Snjl ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 233209746Sjkim "\nExecuted %u _INI methods requiring %u _STA executions " 234209746Sjkim "(examined %u objects)\n", 235167802Sjkim Info.Num_INI, Info.Num_STA, Info.DeviceCount)); 23667754Smsmith 23767754Smsmith return_ACPI_STATUS (Status); 238167802Sjkim 239167802Sjkim 240167802SjkimErrorExit: 241167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, "During device initialization")); 242167802Sjkim return_ACPI_STATUS (Status); 24367754Smsmith} 24467754Smsmith 24567754Smsmith 24667754Smsmith/******************************************************************************* 24767754Smsmith * 24867754Smsmith * FUNCTION: AcpiNsInitOneObject 24967754Smsmith * 25067754Smsmith * PARAMETERS: ObjHandle - Node 25167754Smsmith * Level - Current nesting level 25267754Smsmith * Context - Points to a init info struct 25367754Smsmith * ReturnValue - Not used 25467754Smsmith * 25567754Smsmith * RETURN: Status 25667754Smsmith * 257241973Sjkim * DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every object 25867754Smsmith * within the namespace. 25967754Smsmith * 26067754Smsmith * Currently, the only objects that require initialization are: 26167754Smsmith * 1) Methods 26267754Smsmith * 2) Op Regions 26367754Smsmith * 26467754Smsmith ******************************************************************************/ 26567754Smsmith 266151937Sjkimstatic ACPI_STATUS 26767754SmsmithAcpiNsInitOneObject ( 26867754Smsmith ACPI_HANDLE ObjHandle, 26967754Smsmith UINT32 Level, 27067754Smsmith void *Context, 27167754Smsmith void **ReturnValue) 27267754Smsmith{ 27391116Smsmith ACPI_OBJECT_TYPE Type; 274167802Sjkim ACPI_STATUS Status = AE_OK; 27567754Smsmith ACPI_INIT_WALK_INFO *Info = (ACPI_INIT_WALK_INFO *) Context; 27667754Smsmith ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 27767754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 27867754Smsmith 27967754Smsmith 280167802Sjkim ACPI_FUNCTION_NAME (NsInitOneObject); 28182367Smsmith 28282367Smsmith 28367754Smsmith Info->ObjectCount++; 28467754Smsmith 28567754Smsmith /* And even then, we are only interested in a few object types */ 28667754Smsmith 28767754Smsmith Type = AcpiNsGetType (ObjHandle); 28887031Smsmith ObjDesc = AcpiNsGetAttachedObject (Node); 28967754Smsmith if (!ObjDesc) 29067754Smsmith { 29167754Smsmith return (AE_OK); 29267754Smsmith } 29367754Smsmith 29499146Siwasaki /* Increment counters for object types we are looking for */ 29599146Siwasaki 29699146Siwasaki switch (Type) 29780062Smsmith { 29899146Siwasaki case ACPI_TYPE_REGION: 29999146Siwasaki Info->OpRegionCount++; 30099146Siwasaki break; 30199146Siwasaki 30299146Siwasaki case ACPI_TYPE_BUFFER_FIELD: 30399146Siwasaki Info->FieldCount++; 30499146Siwasaki break; 30599146Siwasaki 306193267Sjkim case ACPI_TYPE_LOCAL_BANK_FIELD: 307193267Sjkim Info->FieldCount++; 308193267Sjkim break; 309193267Sjkim 31099146Siwasaki case ACPI_TYPE_BUFFER: 31199146Siwasaki Info->BufferCount++; 31299146Siwasaki break; 31399146Siwasaki 31499146Siwasaki case ACPI_TYPE_PACKAGE: 31599146Siwasaki Info->PackageCount++; 31699146Siwasaki break; 31799146Siwasaki 31899146Siwasaki default: 31999146Siwasaki 32099146Siwasaki /* No init required, just exit now */ 32180062Smsmith return (AE_OK); 32280062Smsmith } 32380062Smsmith 324193267Sjkim /* If the object is already initialized, nothing else to do */ 325193267Sjkim 32699146Siwasaki if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) 32799146Siwasaki { 32899146Siwasaki return (AE_OK); 32999146Siwasaki } 33080062Smsmith 331193267Sjkim /* Must lock the interpreter before executing AML code */ 332193267Sjkim 333167802Sjkim AcpiExEnterInterpreter (); 33480062Smsmith 33599146Siwasaki /* 336138287Smarks * Each of these types can contain executable AML code within the 337138287Smarks * declaration. 33899146Siwasaki */ 33967754Smsmith switch (Type) 34067754Smsmith { 34167754Smsmith case ACPI_TYPE_REGION: 34267754Smsmith 34367754Smsmith Info->OpRegionInit++; 34467754Smsmith Status = AcpiDsGetRegionArguments (ObjDesc); 34567754Smsmith break; 34667754Smsmith 34777424Smsmith case ACPI_TYPE_BUFFER_FIELD: 34867754Smsmith 34967754Smsmith Info->FieldInit++; 35077424Smsmith Status = AcpiDsGetBufferFieldArguments (ObjDesc); 35199146Siwasaki break; 35267754Smsmith 353193267Sjkim case ACPI_TYPE_LOCAL_BANK_FIELD: 354193267Sjkim 355193267Sjkim Info->FieldInit++; 356193267Sjkim Status = AcpiDsGetBankFieldArguments (ObjDesc); 357193267Sjkim break; 358193267Sjkim 35999146Siwasaki case ACPI_TYPE_BUFFER: 36099146Siwasaki 36199146Siwasaki Info->BufferInit++; 36299146Siwasaki Status = AcpiDsGetBufferArguments (ObjDesc); 36367754Smsmith break; 36467754Smsmith 36599146Siwasaki case ACPI_TYPE_PACKAGE: 36699146Siwasaki 36799146Siwasaki Info->PackageInit++; 36899146Siwasaki Status = AcpiDsGetPackageArguments (ObjDesc); 36967754Smsmith break; 37099679Siwasaki 37199679Siwasaki default: 37299679Siwasaki /* No other types can get here */ 37399679Siwasaki break; 37467754Smsmith } 37567754Smsmith 37699146Siwasaki if (ACPI_FAILURE (Status)) 37799146Siwasaki { 378167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 379167802Sjkim "Could not execute arguments for [%4.4s] (%s)", 380167802Sjkim AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Type))); 38199146Siwasaki } 38280062Smsmith 383138287Smarks /* 384138287Smarks * Print a dot for each object unless we are going to print the entire 385138287Smarks * pathname 386138287Smarks */ 387114237Snjl if (!(AcpiDbgLevel & ACPI_LV_INIT_NAMES)) 38899146Siwasaki { 389114237Snjl ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, ".")); 39099146Siwasaki } 39199146Siwasaki 39267754Smsmith /* 393138287Smarks * We ignore errors from above, and always return OK, since we don't want 394138287Smarks * to abort the walk on any single error. 39567754Smsmith */ 39680062Smsmith AcpiExExitInterpreter (); 39767754Smsmith return (AE_OK); 39867754Smsmith} 39967754Smsmith 40067754Smsmith 40177424Smsmith/******************************************************************************* 40267754Smsmith * 403167802Sjkim * FUNCTION: AcpiNsFindIniMethods 404167802Sjkim * 405167802Sjkim * PARAMETERS: ACPI_WALK_CALLBACK 406167802Sjkim * 407167802Sjkim * RETURN: ACPI_STATUS 408167802Sjkim * 409167802Sjkim * DESCRIPTION: Called during namespace walk. Finds objects named _INI under 410167802Sjkim * device/processor/thermal objects, and marks the entire subtree 411167802Sjkim * with a SUBTREE_HAS_INI flag. This flag is used during the 412167802Sjkim * subsequent device initialization walk to avoid entire subtrees 413167802Sjkim * that do not contain an _INI. 414167802Sjkim * 415167802Sjkim ******************************************************************************/ 416167802Sjkim 417167802Sjkimstatic ACPI_STATUS 418167802SjkimAcpiNsFindIniMethods ( 419167802Sjkim ACPI_HANDLE ObjHandle, 420167802Sjkim UINT32 NestingLevel, 421167802Sjkim void *Context, 422167802Sjkim void **ReturnValue) 423167802Sjkim{ 424167802Sjkim ACPI_DEVICE_WALK_INFO *Info = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context); 425167802Sjkim ACPI_NAMESPACE_NODE *Node; 426167802Sjkim ACPI_NAMESPACE_NODE *ParentNode; 427167802Sjkim 428167802Sjkim 429167802Sjkim /* Keep count of device/processor/thermal objects */ 430167802Sjkim 431167802Sjkim Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); 432167802Sjkim if ((Node->Type == ACPI_TYPE_DEVICE) || 433167802Sjkim (Node->Type == ACPI_TYPE_PROCESSOR) || 434167802Sjkim (Node->Type == ACPI_TYPE_THERMAL)) 435167802Sjkim { 436167802Sjkim Info->DeviceCount++; 437167802Sjkim return (AE_OK); 438167802Sjkim } 439167802Sjkim 440167802Sjkim /* We are only looking for methods named _INI */ 441167802Sjkim 442167802Sjkim if (!ACPI_COMPARE_NAME (Node->Name.Ascii, METHOD_NAME__INI)) 443167802Sjkim { 444167802Sjkim return (AE_OK); 445167802Sjkim } 446167802Sjkim 447167802Sjkim /* 448167802Sjkim * The only _INI methods that we care about are those that are 449167802Sjkim * present under Device, Processor, and Thermal objects. 450167802Sjkim */ 451209746Sjkim ParentNode = Node->Parent; 452167802Sjkim switch (ParentNode->Type) 453167802Sjkim { 454167802Sjkim case ACPI_TYPE_DEVICE: 455167802Sjkim case ACPI_TYPE_PROCESSOR: 456167802Sjkim case ACPI_TYPE_THERMAL: 457167802Sjkim 458167802Sjkim /* Mark parent and bubble up the INI present flag to the root */ 459167802Sjkim 460167802Sjkim while (ParentNode) 461167802Sjkim { 462167802Sjkim ParentNode->Flags |= ANOBJ_SUBTREE_HAS_INI; 463209746Sjkim ParentNode = ParentNode->Parent; 464167802Sjkim } 465167802Sjkim break; 466167802Sjkim 467167802Sjkim default: 468167802Sjkim break; 469167802Sjkim } 470167802Sjkim 471167802Sjkim return (AE_OK); 472167802Sjkim} 473167802Sjkim 474167802Sjkim 475167802Sjkim/******************************************************************************* 476167802Sjkim * 47767754Smsmith * FUNCTION: AcpiNsInitOneDevice 47867754Smsmith * 47977424Smsmith * PARAMETERS: ACPI_WALK_CALLBACK 48067754Smsmith * 48167754Smsmith * RETURN: ACPI_STATUS 48267754Smsmith * 48367754Smsmith * DESCRIPTION: This is called once per device soon after ACPI is enabled 48467754Smsmith * to initialize each device. It determines if the device is 48567754Smsmith * present, and if so, calls _INI. 48667754Smsmith * 48777424Smsmith ******************************************************************************/ 48867754Smsmith 489151937Sjkimstatic ACPI_STATUS 49067754SmsmithAcpiNsInitOneDevice ( 49167754Smsmith ACPI_HANDLE ObjHandle, 49267754Smsmith UINT32 NestingLevel, 49367754Smsmith void *Context, 49467754Smsmith void **ReturnValue) 49567754Smsmith{ 496167802Sjkim ACPI_DEVICE_WALK_INFO *WalkInfo = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context); 497167802Sjkim ACPI_EVALUATE_INFO *Info = WalkInfo->EvaluateInfo; 498129684Snjl UINT32 Flags; 49967754Smsmith ACPI_STATUS Status; 500167802Sjkim ACPI_NAMESPACE_NODE *DeviceNode; 50167754Smsmith 50267754Smsmith 503167802Sjkim ACPI_FUNCTION_TRACE (NsInitOneDevice); 50467754Smsmith 50567754Smsmith 506167802Sjkim /* We are interested in Devices, Processors and ThermalZones only */ 507129684Snjl 508167802Sjkim DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); 509167802Sjkim if ((DeviceNode->Type != ACPI_TYPE_DEVICE) && 510167802Sjkim (DeviceNode->Type != ACPI_TYPE_PROCESSOR) && 511167802Sjkim (DeviceNode->Type != ACPI_TYPE_THERMAL)) 51273561Smsmith { 513167802Sjkim return_ACPI_STATUS (AE_OK); 51473561Smsmith } 51573561Smsmith 516123315Snjl /* 517167802Sjkim * Because of an earlier namespace analysis, all subtrees that contain an 518167802Sjkim * _INI method are tagged. 519167802Sjkim * 520167802Sjkim * If this device subtree does not contain any _INI methods, we 521167802Sjkim * can exit now and stop traversing this entire subtree. 522123315Snjl */ 523167802Sjkim if (!(DeviceNode->Flags & ANOBJ_SUBTREE_HAS_INI)) 52491116Smsmith { 525167802Sjkim return_ACPI_STATUS (AE_CTRL_DEPTH); 52691116Smsmith } 52767754Smsmith 52867754Smsmith /* 529167802Sjkim * Run _STA to determine if this device is present and functioning. We 530167802Sjkim * must know this information for two important reasons (from ACPI spec): 531167802Sjkim * 532167802Sjkim * 1) We can only run _INI if the device is present. 533167802Sjkim * 2) We must abort the device tree walk on this subtree if the device is 534167802Sjkim * not present and is not functional (we will not examine the children) 535167802Sjkim * 536167802Sjkim * The _STA method is not required to be present under the device, we 537167802Sjkim * assume the device is present if _STA does not exist. 53867754Smsmith */ 539167802Sjkim ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname ( 540167802Sjkim ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__STA)); 541123315Snjl 542167802Sjkim Status = AcpiUtExecute_STA (DeviceNode, &Flags); 54367754Smsmith if (ACPI_FAILURE (Status)) 54467754Smsmith { 545167802Sjkim /* Ignore error and move on to next device */ 54671867Smsmith 547167802Sjkim return_ACPI_STATUS (AE_OK); 548167802Sjkim } 549123315Snjl 550167802Sjkim /* 551167802Sjkim * Flags == -1 means that _STA was not found. In this case, we assume that 552167802Sjkim * the device is both present and functional. 553167802Sjkim * 554167802Sjkim * From the ACPI spec, description of _STA: 555167802Sjkim * 556167802Sjkim * "If a device object (including the processor object) does not have an 557167802Sjkim * _STA object, then OSPM assumes that all of the above bits are set (in 558167802Sjkim * other words, the device is present, ..., and functioning)" 559167802Sjkim */ 560167802Sjkim if (Flags != ACPI_UINT32_MAX) 561167802Sjkim { 562167802Sjkim WalkInfo->Num_STA++; 56367754Smsmith } 564167802Sjkim 565167802Sjkim /* 566167802Sjkim * Examine the PRESENT and FUNCTIONING status bits 567167802Sjkim * 568167802Sjkim * Note: ACPI spec does not seem to specify behavior for the present but 569167802Sjkim * not functioning case, so we assume functioning if present. 570167802Sjkim */ 571167802Sjkim if (!(Flags & ACPI_STA_DEVICE_PRESENT)) 572123315Snjl { 573167802Sjkim /* Device is not present, we must examine the Functioning bit */ 57467754Smsmith 575167802Sjkim if (Flags & ACPI_STA_DEVICE_FUNCTIONING) 576123315Snjl { 577167802Sjkim /* 578167802Sjkim * Device is not present but is "functioning". In this case, 579167802Sjkim * we will not run _INI, but we continue to examine the children 580167802Sjkim * of this device. 581167802Sjkim * 582167802Sjkim * From the ACPI spec, description of _STA: (Note - no mention 583167802Sjkim * of whether to run _INI or not on the device in question) 584167802Sjkim * 585167802Sjkim * "_STA may return bit 0 clear (not present) with bit 3 set 586167802Sjkim * (device is functional). This case is used to indicate a valid 587167802Sjkim * device for which no device driver should be loaded (for example, 588167802Sjkim * a bridge device.) Children of this device may be present and 589167802Sjkim * valid. OSPM should continue enumeration below a device whose 590167802Sjkim * _STA returns this bit combination" 591167802Sjkim */ 592167802Sjkim return_ACPI_STATUS (AE_OK); 593123315Snjl } 594167802Sjkim else 595167802Sjkim { 596167802Sjkim /* 597167802Sjkim * Device is not present and is not functioning. We must abort the 598167802Sjkim * walk of this subtree immediately -- don't look at the children 599167802Sjkim * of such a device. 600167802Sjkim * 601167802Sjkim * From the ACPI spec, description of _INI: 602167802Sjkim * 603167802Sjkim * "If the _STA method indicates that the device is not present, 604167802Sjkim * OSPM will not run the _INI and will not examine the children 605167802Sjkim * of the device for _INI methods" 606167802Sjkim */ 607167802Sjkim return_ACPI_STATUS (AE_CTRL_DEPTH); 608167802Sjkim } 60967754Smsmith } 61067754Smsmith 61167754Smsmith /* 612167802Sjkim * The device is present or is assumed present if no _STA exists. 613167802Sjkim * Run the _INI if it exists (not required to exist) 614167802Sjkim * 615167802Sjkim * Note: We know there is an _INI within this subtree, but it may not be 616167802Sjkim * under this particular device, it may be lower in the branch. 61767754Smsmith */ 618167802Sjkim ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname ( 619167802Sjkim ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__INI)); 620167802Sjkim 621167802Sjkim Info->PrefixNode = DeviceNode; 622167802Sjkim Info->Pathname = METHOD_NAME__INI; 623167802Sjkim Info->Parameters = NULL; 624167802Sjkim Info->Flags = ACPI_IGNORE_RETURN_VALUE; 625167802Sjkim 626167802Sjkim Status = AcpiNsEvaluate (Info); 627167802Sjkim if (ACPI_SUCCESS (Status)) 62867754Smsmith { 629167802Sjkim WalkInfo->Num_INI++; 63077424Smsmith 631167802Sjkim if ((AcpiDbgLevel <= ACPI_LV_ALL_EXCEPTIONS) && 632167802Sjkim (!(AcpiDbgLevel & ACPI_LV_INFO))) 63399679Siwasaki { 634167802Sjkim ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, ".")); 635167802Sjkim } 636167802Sjkim } 63767754Smsmith 638129684Snjl#ifdef ACPI_DEBUG_OUTPUT 639167802Sjkim else if (Status != AE_NOT_FOUND) 640167802Sjkim { 641167802Sjkim /* Ignore error and move on to next device */ 64271867Smsmith 643167802Sjkim char *ScopeName = AcpiNsGetExternalPathname (Info->ResolvedNode); 64467754Smsmith 645167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, "during %s._INI execution", 646167802Sjkim ScopeName)); 647167802Sjkim ACPI_FREE (ScopeName); 648167802Sjkim } 649129684Snjl#endif 65067754Smsmith 651167802Sjkim /* Ignore errors from above */ 652140216Snjl 653167802Sjkim Status = AE_OK; 654140216Snjl 655167802Sjkim /* 656167802Sjkim * The _INI method has been run if present; call the Global Initialization 657167802Sjkim * Handler for this device. 658167802Sjkim */ 65999679Siwasaki if (AcpiGbl_InitHandler) 66099679Siwasaki { 661167802Sjkim Status = AcpiGbl_InitHandler (DeviceNode, ACPI_INIT_DEVICE_INI); 66299679Siwasaki } 66399679Siwasaki 66499679Siwasaki return_ACPI_STATUS (Status); 66567754Smsmith} 666