nsinit.c revision 245582
167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: nsinit - namespace initialization 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8245582Sjkim * Copyright (C) 2000 - 2013, 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, 107245582Sjkim "Completing Region/Field/Buffer/Package initialization:\n")); 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, 124245582Sjkim " Initialized %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 " 175245582Sjkim "and executing _INI/_STA methods:\n")); 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, 233245582Sjkim " Executed %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 * We ignore errors from above, and always return OK, since we don't want 385138287Smarks * to abort the walk on any single error. 38667754Smsmith */ 38780062Smsmith AcpiExExitInterpreter (); 38867754Smsmith return (AE_OK); 38967754Smsmith} 39067754Smsmith 39167754Smsmith 39277424Smsmith/******************************************************************************* 39367754Smsmith * 394167802Sjkim * FUNCTION: AcpiNsFindIniMethods 395167802Sjkim * 396167802Sjkim * PARAMETERS: ACPI_WALK_CALLBACK 397167802Sjkim * 398167802Sjkim * RETURN: ACPI_STATUS 399167802Sjkim * 400167802Sjkim * DESCRIPTION: Called during namespace walk. Finds objects named _INI under 401167802Sjkim * device/processor/thermal objects, and marks the entire subtree 402167802Sjkim * with a SUBTREE_HAS_INI flag. This flag is used during the 403167802Sjkim * subsequent device initialization walk to avoid entire subtrees 404167802Sjkim * that do not contain an _INI. 405167802Sjkim * 406167802Sjkim ******************************************************************************/ 407167802Sjkim 408167802Sjkimstatic ACPI_STATUS 409167802SjkimAcpiNsFindIniMethods ( 410167802Sjkim ACPI_HANDLE ObjHandle, 411167802Sjkim UINT32 NestingLevel, 412167802Sjkim void *Context, 413167802Sjkim void **ReturnValue) 414167802Sjkim{ 415167802Sjkim ACPI_DEVICE_WALK_INFO *Info = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context); 416167802Sjkim ACPI_NAMESPACE_NODE *Node; 417167802Sjkim ACPI_NAMESPACE_NODE *ParentNode; 418167802Sjkim 419167802Sjkim 420167802Sjkim /* Keep count of device/processor/thermal objects */ 421167802Sjkim 422167802Sjkim Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); 423167802Sjkim if ((Node->Type == ACPI_TYPE_DEVICE) || 424167802Sjkim (Node->Type == ACPI_TYPE_PROCESSOR) || 425167802Sjkim (Node->Type == ACPI_TYPE_THERMAL)) 426167802Sjkim { 427167802Sjkim Info->DeviceCount++; 428167802Sjkim return (AE_OK); 429167802Sjkim } 430167802Sjkim 431167802Sjkim /* We are only looking for methods named _INI */ 432167802Sjkim 433167802Sjkim if (!ACPI_COMPARE_NAME (Node->Name.Ascii, METHOD_NAME__INI)) 434167802Sjkim { 435167802Sjkim return (AE_OK); 436167802Sjkim } 437167802Sjkim 438167802Sjkim /* 439167802Sjkim * The only _INI methods that we care about are those that are 440167802Sjkim * present under Device, Processor, and Thermal objects. 441167802Sjkim */ 442209746Sjkim ParentNode = Node->Parent; 443167802Sjkim switch (ParentNode->Type) 444167802Sjkim { 445167802Sjkim case ACPI_TYPE_DEVICE: 446167802Sjkim case ACPI_TYPE_PROCESSOR: 447167802Sjkim case ACPI_TYPE_THERMAL: 448167802Sjkim 449167802Sjkim /* Mark parent and bubble up the INI present flag to the root */ 450167802Sjkim 451167802Sjkim while (ParentNode) 452167802Sjkim { 453167802Sjkim ParentNode->Flags |= ANOBJ_SUBTREE_HAS_INI; 454209746Sjkim ParentNode = ParentNode->Parent; 455167802Sjkim } 456167802Sjkim break; 457167802Sjkim 458167802Sjkim default: 459167802Sjkim break; 460167802Sjkim } 461167802Sjkim 462167802Sjkim return (AE_OK); 463167802Sjkim} 464167802Sjkim 465167802Sjkim 466167802Sjkim/******************************************************************************* 467167802Sjkim * 46867754Smsmith * FUNCTION: AcpiNsInitOneDevice 46967754Smsmith * 47077424Smsmith * PARAMETERS: ACPI_WALK_CALLBACK 47167754Smsmith * 47267754Smsmith * RETURN: ACPI_STATUS 47367754Smsmith * 47467754Smsmith * DESCRIPTION: This is called once per device soon after ACPI is enabled 47567754Smsmith * to initialize each device. It determines if the device is 47667754Smsmith * present, and if so, calls _INI. 47767754Smsmith * 47877424Smsmith ******************************************************************************/ 47967754Smsmith 480151937Sjkimstatic ACPI_STATUS 48167754SmsmithAcpiNsInitOneDevice ( 48267754Smsmith ACPI_HANDLE ObjHandle, 48367754Smsmith UINT32 NestingLevel, 48467754Smsmith void *Context, 48567754Smsmith void **ReturnValue) 48667754Smsmith{ 487167802Sjkim ACPI_DEVICE_WALK_INFO *WalkInfo = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context); 488167802Sjkim ACPI_EVALUATE_INFO *Info = WalkInfo->EvaluateInfo; 489129684Snjl UINT32 Flags; 49067754Smsmith ACPI_STATUS Status; 491167802Sjkim ACPI_NAMESPACE_NODE *DeviceNode; 49267754Smsmith 49367754Smsmith 494167802Sjkim ACPI_FUNCTION_TRACE (NsInitOneDevice); 49567754Smsmith 49667754Smsmith 497167802Sjkim /* We are interested in Devices, Processors and ThermalZones only */ 498129684Snjl 499167802Sjkim DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); 500167802Sjkim if ((DeviceNode->Type != ACPI_TYPE_DEVICE) && 501167802Sjkim (DeviceNode->Type != ACPI_TYPE_PROCESSOR) && 502167802Sjkim (DeviceNode->Type != ACPI_TYPE_THERMAL)) 50373561Smsmith { 504167802Sjkim return_ACPI_STATUS (AE_OK); 50573561Smsmith } 50673561Smsmith 507123315Snjl /* 508167802Sjkim * Because of an earlier namespace analysis, all subtrees that contain an 509167802Sjkim * _INI method are tagged. 510167802Sjkim * 511167802Sjkim * If this device subtree does not contain any _INI methods, we 512167802Sjkim * can exit now and stop traversing this entire subtree. 513123315Snjl */ 514167802Sjkim if (!(DeviceNode->Flags & ANOBJ_SUBTREE_HAS_INI)) 51591116Smsmith { 516167802Sjkim return_ACPI_STATUS (AE_CTRL_DEPTH); 51791116Smsmith } 51867754Smsmith 51967754Smsmith /* 520167802Sjkim * Run _STA to determine if this device is present and functioning. We 521167802Sjkim * must know this information for two important reasons (from ACPI spec): 522167802Sjkim * 523167802Sjkim * 1) We can only run _INI if the device is present. 524167802Sjkim * 2) We must abort the device tree walk on this subtree if the device is 525167802Sjkim * not present and is not functional (we will not examine the children) 526167802Sjkim * 527167802Sjkim * The _STA method is not required to be present under the device, we 528167802Sjkim * assume the device is present if _STA does not exist. 52967754Smsmith */ 530167802Sjkim ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname ( 531167802Sjkim ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__STA)); 532123315Snjl 533167802Sjkim Status = AcpiUtExecute_STA (DeviceNode, &Flags); 53467754Smsmith if (ACPI_FAILURE (Status)) 53567754Smsmith { 536167802Sjkim /* Ignore error and move on to next device */ 53771867Smsmith 538167802Sjkim return_ACPI_STATUS (AE_OK); 539167802Sjkim } 540123315Snjl 541167802Sjkim /* 542167802Sjkim * Flags == -1 means that _STA was not found. In this case, we assume that 543167802Sjkim * the device is both present and functional. 544167802Sjkim * 545167802Sjkim * From the ACPI spec, description of _STA: 546167802Sjkim * 547167802Sjkim * "If a device object (including the processor object) does not have an 548167802Sjkim * _STA object, then OSPM assumes that all of the above bits are set (in 549167802Sjkim * other words, the device is present, ..., and functioning)" 550167802Sjkim */ 551167802Sjkim if (Flags != ACPI_UINT32_MAX) 552167802Sjkim { 553167802Sjkim WalkInfo->Num_STA++; 55467754Smsmith } 555167802Sjkim 556167802Sjkim /* 557167802Sjkim * Examine the PRESENT and FUNCTIONING status bits 558167802Sjkim * 559167802Sjkim * Note: ACPI spec does not seem to specify behavior for the present but 560167802Sjkim * not functioning case, so we assume functioning if present. 561167802Sjkim */ 562167802Sjkim if (!(Flags & ACPI_STA_DEVICE_PRESENT)) 563123315Snjl { 564167802Sjkim /* Device is not present, we must examine the Functioning bit */ 56567754Smsmith 566167802Sjkim if (Flags & ACPI_STA_DEVICE_FUNCTIONING) 567123315Snjl { 568167802Sjkim /* 569167802Sjkim * Device is not present but is "functioning". In this case, 570167802Sjkim * we will not run _INI, but we continue to examine the children 571167802Sjkim * of this device. 572167802Sjkim * 573167802Sjkim * From the ACPI spec, description of _STA: (Note - no mention 574167802Sjkim * of whether to run _INI or not on the device in question) 575167802Sjkim * 576167802Sjkim * "_STA may return bit 0 clear (not present) with bit 3 set 577167802Sjkim * (device is functional). This case is used to indicate a valid 578167802Sjkim * device for which no device driver should be loaded (for example, 579167802Sjkim * a bridge device.) Children of this device may be present and 580167802Sjkim * valid. OSPM should continue enumeration below a device whose 581167802Sjkim * _STA returns this bit combination" 582167802Sjkim */ 583167802Sjkim return_ACPI_STATUS (AE_OK); 584123315Snjl } 585167802Sjkim else 586167802Sjkim { 587167802Sjkim /* 588167802Sjkim * Device is not present and is not functioning. We must abort the 589167802Sjkim * walk of this subtree immediately -- don't look at the children 590167802Sjkim * of such a device. 591167802Sjkim * 592167802Sjkim * From the ACPI spec, description of _INI: 593167802Sjkim * 594167802Sjkim * "If the _STA method indicates that the device is not present, 595167802Sjkim * OSPM will not run the _INI and will not examine the children 596167802Sjkim * of the device for _INI methods" 597167802Sjkim */ 598167802Sjkim return_ACPI_STATUS (AE_CTRL_DEPTH); 599167802Sjkim } 60067754Smsmith } 60167754Smsmith 60267754Smsmith /* 603167802Sjkim * The device is present or is assumed present if no _STA exists. 604167802Sjkim * Run the _INI if it exists (not required to exist) 605167802Sjkim * 606167802Sjkim * Note: We know there is an _INI within this subtree, but it may not be 607167802Sjkim * under this particular device, it may be lower in the branch. 60867754Smsmith */ 609167802Sjkim ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname ( 610167802Sjkim ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__INI)); 611167802Sjkim 612167802Sjkim Info->PrefixNode = DeviceNode; 613167802Sjkim Info->Pathname = METHOD_NAME__INI; 614167802Sjkim Info->Parameters = NULL; 615167802Sjkim Info->Flags = ACPI_IGNORE_RETURN_VALUE; 616167802Sjkim 617167802Sjkim Status = AcpiNsEvaluate (Info); 618167802Sjkim if (ACPI_SUCCESS (Status)) 61967754Smsmith { 620167802Sjkim WalkInfo->Num_INI++; 621167802Sjkim } 62267754Smsmith 623129684Snjl#ifdef ACPI_DEBUG_OUTPUT 624167802Sjkim else if (Status != AE_NOT_FOUND) 625167802Sjkim { 626167802Sjkim /* Ignore error and move on to next device */ 62771867Smsmith 628167802Sjkim char *ScopeName = AcpiNsGetExternalPathname (Info->ResolvedNode); 62967754Smsmith 630167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, "during %s._INI execution", 631167802Sjkim ScopeName)); 632167802Sjkim ACPI_FREE (ScopeName); 633167802Sjkim } 634129684Snjl#endif 63567754Smsmith 636167802Sjkim /* Ignore errors from above */ 637140216Snjl 638167802Sjkim Status = AE_OK; 639140216Snjl 640167802Sjkim /* 641167802Sjkim * The _INI method has been run if present; call the Global Initialization 642167802Sjkim * Handler for this device. 643167802Sjkim */ 64499679Siwasaki if (AcpiGbl_InitHandler) 64599679Siwasaki { 646167802Sjkim Status = AcpiGbl_InitHandler (DeviceNode, ACPI_INIT_DEVICE_INI); 64799679Siwasaki } 64899679Siwasaki 64999679Siwasaki return_ACPI_STATUS (Status); 65067754Smsmith} 651