nsinit.c revision 281075
167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: nsinit - namespace initialization 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8281075Sdim * Copyright (C) 2000 - 2015, 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 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 47193341Sjkim#include <contrib/dev/acpica/include/acdispat.h> 48193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 4967754Smsmith 5077424Smsmith#define _COMPONENT ACPI_NAMESPACE 5191116Smsmith ACPI_MODULE_NAME ("nsinit") 5267754Smsmith 53151937Sjkim/* Local prototypes */ 5467754Smsmith 55151937Sjkimstatic ACPI_STATUS 56151937SjkimAcpiNsInitOneObject ( 57151937Sjkim ACPI_HANDLE ObjHandle, 58151937Sjkim UINT32 Level, 59151937Sjkim void *Context, 60151937Sjkim void **ReturnValue); 61151937Sjkim 62151937Sjkimstatic ACPI_STATUS 63151937SjkimAcpiNsInitOneDevice ( 64151937Sjkim ACPI_HANDLE ObjHandle, 65151937Sjkim UINT32 NestingLevel, 66151937Sjkim void *Context, 67151937Sjkim void **ReturnValue); 68151937Sjkim 69167802Sjkimstatic ACPI_STATUS 70167802SjkimAcpiNsFindIniMethods ( 71167802Sjkim ACPI_HANDLE ObjHandle, 72167802Sjkim UINT32 NestingLevel, 73167802Sjkim void *Context, 74167802Sjkim void **ReturnValue); 75151937Sjkim 76167802Sjkim 7767754Smsmith/******************************************************************************* 7867754Smsmith * 7967754Smsmith * FUNCTION: AcpiNsInitializeObjects 8067754Smsmith * 8167754Smsmith * PARAMETERS: None 8267754Smsmith * 8367754Smsmith * RETURN: Status 8467754Smsmith * 8567754Smsmith * DESCRIPTION: Walk the entire namespace and perform any necessary 8667754Smsmith * initialization on the objects found therein 8767754Smsmith * 8867754Smsmith ******************************************************************************/ 8967754Smsmith 9067754SmsmithACPI_STATUS 9167754SmsmithAcpiNsInitializeObjects ( 9267754Smsmith void) 9367754Smsmith{ 9467754Smsmith ACPI_STATUS Status; 9567754Smsmith ACPI_INIT_WALK_INFO Info; 9667754Smsmith 9767754Smsmith 98167802Sjkim ACPI_FUNCTION_TRACE (NsInitializeObjects); 9967754Smsmith 10067754Smsmith 10182367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 10282367Smsmith "**** Starting initialization of namespace objects ****\n")); 103138287Smarks ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 104245582Sjkim "Completing Region/Field/Buffer/Package initialization:\n")); 10567754Smsmith 10699146Siwasaki /* Set all init info to zero */ 10767754Smsmith 10899146Siwasaki ACPI_MEMSET (&Info, 0, sizeof (ACPI_INIT_WALK_INFO)); 10967754Smsmith 11067754Smsmith /* Walk entire namespace from the supplied root */ 11167754Smsmith 11267754Smsmith Status = AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 113209746Sjkim ACPI_UINT32_MAX, AcpiNsInitOneObject, NULL, 114209746Sjkim &Info, NULL); 11567754Smsmith if (ACPI_FAILURE (Status)) 11667754Smsmith { 117167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace")); 11867754Smsmith } 11967754Smsmith 120114237Snjl ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 121245582Sjkim " Initialized %u/%u Regions %u/%u Fields %u/%u " 122209746Sjkim "Buffers %u/%u Packages (%u nodes)\n", 123102550Siwasaki Info.OpRegionInit, Info.OpRegionCount, 124102550Siwasaki Info.FieldInit, Info.FieldCount, 125102550Siwasaki Info.BufferInit, Info.BufferCount, 12699146Siwasaki Info.PackageInit, Info.PackageCount, Info.ObjectCount)); 127114237Snjl 12882367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 129281075Sdim "%u Control Methods found\n%u Op Regions found\n", 130281075Sdim Info.MethodCount, Info.OpRegionCount)); 13167754Smsmith 13267754Smsmith return_ACPI_STATUS (AE_OK); 13367754Smsmith} 13467754Smsmith 13567754Smsmith 13677424Smsmith/******************************************************************************* 13767754Smsmith * 13867754Smsmith * FUNCTION: AcpiNsInitializeDevices 13967754Smsmith * 14067754Smsmith * PARAMETERS: None 14167754Smsmith * 14267754Smsmith * RETURN: ACPI_STATUS 14367754Smsmith * 14467754Smsmith * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices. 14567754Smsmith * This means running _INI on all present devices. 14667754Smsmith * 14777424Smsmith * Note: We install PCI config space handler on region access, 14877424Smsmith * not here. 14967754Smsmith * 15077424Smsmith ******************************************************************************/ 15167754Smsmith 15267754SmsmithACPI_STATUS 15367754SmsmithAcpiNsInitializeDevices ( 15473561Smsmith void) 15567754Smsmith{ 15667754Smsmith ACPI_STATUS Status; 15767754Smsmith ACPI_DEVICE_WALK_INFO Info; 15867754Smsmith 15967754Smsmith 160167802Sjkim ACPI_FUNCTION_TRACE (NsInitializeDevices); 16167754Smsmith 16267754Smsmith 16399146Siwasaki /* Init counters */ 16499146Siwasaki 16567754Smsmith Info.DeviceCount = 0; 16667754Smsmith Info.Num_STA = 0; 16767754Smsmith Info.Num_INI = 0; 16867754Smsmith 169138287Smarks ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 170193267Sjkim "Initializing Device/Processor/Thermal objects " 171245582Sjkim "and executing _INI/_STA methods:\n")); 17267754Smsmith 173167802Sjkim /* Tree analysis: find all subtrees that contain _INI methods */ 174167802Sjkim 175167802Sjkim Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 176199337Sjkim ACPI_UINT32_MAX, FALSE, AcpiNsFindIniMethods, NULL, &Info, NULL); 177123315Snjl if (ACPI_FAILURE (Status)) 178123315Snjl { 179167802Sjkim goto ErrorExit; 180123315Snjl } 18167754Smsmith 182167802Sjkim /* Allocate the evaluation information block */ 18367754Smsmith 184167802Sjkim Info.EvaluateInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 185167802Sjkim if (!Info.EvaluateInfo) 186167802Sjkim { 187167802Sjkim Status = AE_NO_MEMORY; 188167802Sjkim goto ErrorExit; 189167802Sjkim } 190167802Sjkim 191197104Sjkim /* 192197104Sjkim * Execute the "global" _INI method that may appear at the root. This 193197104Sjkim * support is provided for Windows compatibility (Vista+) and is not 194197104Sjkim * part of the ACPI specification. 195197104Sjkim */ 196197104Sjkim Info.EvaluateInfo->PrefixNode = AcpiGbl_RootNode; 197249663Sjkim Info.EvaluateInfo->RelativePathname = METHOD_NAME__INI; 198197104Sjkim Info.EvaluateInfo->Parameters = NULL; 199197104Sjkim Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE; 200197104Sjkim 201197104Sjkim Status = AcpiNsEvaluate (Info.EvaluateInfo); 202197104Sjkim if (ACPI_SUCCESS (Status)) 203197104Sjkim { 204197104Sjkim Info.Num_INI++; 205197104Sjkim } 206197104Sjkim 207167802Sjkim /* Walk namespace to execute all _INIs on present devices */ 208167802Sjkim 209123315Snjl Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 210199337Sjkim ACPI_UINT32_MAX, FALSE, AcpiNsInitOneDevice, NULL, &Info, NULL); 211123315Snjl 212209746Sjkim /* 213209746Sjkim * Any _OSI requests should be completed by now. If the BIOS has 214209746Sjkim * requested any Windows OSI strings, we will always truncate 215209746Sjkim * I/O addresses to 16 bits -- for Windows compatibility. 216209746Sjkim */ 217209746Sjkim if (AcpiGbl_OsiData >= ACPI_OSI_WIN_2000) 218209746Sjkim { 219209746Sjkim AcpiGbl_TruncateIoAddresses = TRUE; 220209746Sjkim } 221209746Sjkim 222167802Sjkim ACPI_FREE (Info.EvaluateInfo); 22367754Smsmith if (ACPI_FAILURE (Status)) 22467754Smsmith { 225167802Sjkim goto ErrorExit; 22667754Smsmith } 22767754Smsmith 228114237Snjl ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 229245582Sjkim " Executed %u _INI methods requiring %u _STA executions " 230209746Sjkim "(examined %u objects)\n", 231167802Sjkim Info.Num_INI, Info.Num_STA, Info.DeviceCount)); 23267754Smsmith 23367754Smsmith return_ACPI_STATUS (Status); 234167802Sjkim 235167802Sjkim 236167802SjkimErrorExit: 237167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, "During device initialization")); 238167802Sjkim return_ACPI_STATUS (Status); 23967754Smsmith} 24067754Smsmith 24167754Smsmith 24267754Smsmith/******************************************************************************* 24367754Smsmith * 24467754Smsmith * FUNCTION: AcpiNsInitOneObject 24567754Smsmith * 24667754Smsmith * PARAMETERS: ObjHandle - Node 24767754Smsmith * Level - Current nesting level 24867754Smsmith * Context - Points to a init info struct 24967754Smsmith * ReturnValue - Not used 25067754Smsmith * 25167754Smsmith * RETURN: Status 25267754Smsmith * 253241973Sjkim * DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every object 25467754Smsmith * within the namespace. 25567754Smsmith * 25667754Smsmith * Currently, the only objects that require initialization are: 25767754Smsmith * 1) Methods 25867754Smsmith * 2) Op Regions 25967754Smsmith * 26067754Smsmith ******************************************************************************/ 26167754Smsmith 262151937Sjkimstatic ACPI_STATUS 26367754SmsmithAcpiNsInitOneObject ( 26467754Smsmith ACPI_HANDLE ObjHandle, 26567754Smsmith UINT32 Level, 26667754Smsmith void *Context, 26767754Smsmith void **ReturnValue) 26867754Smsmith{ 26991116Smsmith ACPI_OBJECT_TYPE Type; 270167802Sjkim ACPI_STATUS Status = AE_OK; 27167754Smsmith ACPI_INIT_WALK_INFO *Info = (ACPI_INIT_WALK_INFO *) Context; 27267754Smsmith ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 27367754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 27467754Smsmith 27567754Smsmith 276167802Sjkim ACPI_FUNCTION_NAME (NsInitOneObject); 27782367Smsmith 27882367Smsmith 27967754Smsmith Info->ObjectCount++; 28067754Smsmith 28167754Smsmith /* And even then, we are only interested in a few object types */ 28267754Smsmith 28367754Smsmith Type = AcpiNsGetType (ObjHandle); 28487031Smsmith ObjDesc = AcpiNsGetAttachedObject (Node); 28567754Smsmith if (!ObjDesc) 28667754Smsmith { 28767754Smsmith return (AE_OK); 28867754Smsmith } 28967754Smsmith 29099146Siwasaki /* Increment counters for object types we are looking for */ 29199146Siwasaki 29299146Siwasaki switch (Type) 29380062Smsmith { 29499146Siwasaki case ACPI_TYPE_REGION: 295250838Sjkim 29699146Siwasaki Info->OpRegionCount++; 29799146Siwasaki break; 29899146Siwasaki 29999146Siwasaki case ACPI_TYPE_BUFFER_FIELD: 300250838Sjkim 30199146Siwasaki Info->FieldCount++; 30299146Siwasaki break; 30399146Siwasaki 304193267Sjkim case ACPI_TYPE_LOCAL_BANK_FIELD: 305250838Sjkim 306193267Sjkim Info->FieldCount++; 307193267Sjkim break; 308193267Sjkim 30999146Siwasaki case ACPI_TYPE_BUFFER: 310250838Sjkim 31199146Siwasaki Info->BufferCount++; 31299146Siwasaki break; 31399146Siwasaki 31499146Siwasaki case ACPI_TYPE_PACKAGE: 315250838Sjkim 31699146Siwasaki Info->PackageCount++; 31799146Siwasaki break; 31899146Siwasaki 31999146Siwasaki default: 32099146Siwasaki 32199146Siwasaki /* No init required, just exit now */ 322250838Sjkim 32380062Smsmith return (AE_OK); 32480062Smsmith } 32580062Smsmith 326193267Sjkim /* If the object is already initialized, nothing else to do */ 327193267Sjkim 32899146Siwasaki if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) 32999146Siwasaki { 33099146Siwasaki return (AE_OK); 33199146Siwasaki } 33280062Smsmith 333193267Sjkim /* Must lock the interpreter before executing AML code */ 334193267Sjkim 335167802Sjkim AcpiExEnterInterpreter (); 33680062Smsmith 33799146Siwasaki /* 338138287Smarks * Each of these types can contain executable AML code within the 339138287Smarks * declaration. 34099146Siwasaki */ 34167754Smsmith switch (Type) 34267754Smsmith { 34367754Smsmith case ACPI_TYPE_REGION: 34467754Smsmith 34567754Smsmith Info->OpRegionInit++; 34667754Smsmith Status = AcpiDsGetRegionArguments (ObjDesc); 34767754Smsmith break; 34867754Smsmith 34977424Smsmith case ACPI_TYPE_BUFFER_FIELD: 35067754Smsmith 35167754Smsmith Info->FieldInit++; 35277424Smsmith Status = AcpiDsGetBufferFieldArguments (ObjDesc); 35399146Siwasaki break; 35467754Smsmith 355193267Sjkim case ACPI_TYPE_LOCAL_BANK_FIELD: 356193267Sjkim 357193267Sjkim Info->FieldInit++; 358193267Sjkim Status = AcpiDsGetBankFieldArguments (ObjDesc); 359193267Sjkim break; 360193267Sjkim 36199146Siwasaki case ACPI_TYPE_BUFFER: 36299146Siwasaki 36399146Siwasaki Info->BufferInit++; 36499146Siwasaki Status = AcpiDsGetBufferArguments (ObjDesc); 36567754Smsmith break; 36667754Smsmith 36799146Siwasaki case ACPI_TYPE_PACKAGE: 36899146Siwasaki 36999146Siwasaki Info->PackageInit++; 37099146Siwasaki Status = AcpiDsGetPackageArguments (ObjDesc); 37167754Smsmith break; 37299679Siwasaki 37399679Siwasaki default: 374250838Sjkim 37599679Siwasaki /* No other types can get here */ 376250838Sjkim 37799679Siwasaki break; 37867754Smsmith } 37967754Smsmith 38099146Siwasaki if (ACPI_FAILURE (Status)) 38199146Siwasaki { 382167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 383167802Sjkim "Could not execute arguments for [%4.4s] (%s)", 384167802Sjkim AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Type))); 38599146Siwasaki } 38680062Smsmith 387138287Smarks /* 388138287Smarks * We ignore errors from above, and always return OK, since we don't want 389138287Smarks * to abort the walk on any single error. 39067754Smsmith */ 39180062Smsmith AcpiExExitInterpreter (); 39267754Smsmith return (AE_OK); 39367754Smsmith} 39467754Smsmith 39567754Smsmith 39677424Smsmith/******************************************************************************* 39767754Smsmith * 398167802Sjkim * FUNCTION: AcpiNsFindIniMethods 399167802Sjkim * 400167802Sjkim * PARAMETERS: ACPI_WALK_CALLBACK 401167802Sjkim * 402167802Sjkim * RETURN: ACPI_STATUS 403167802Sjkim * 404167802Sjkim * DESCRIPTION: Called during namespace walk. Finds objects named _INI under 405167802Sjkim * device/processor/thermal objects, and marks the entire subtree 406167802Sjkim * with a SUBTREE_HAS_INI flag. This flag is used during the 407167802Sjkim * subsequent device initialization walk to avoid entire subtrees 408167802Sjkim * that do not contain an _INI. 409167802Sjkim * 410167802Sjkim ******************************************************************************/ 411167802Sjkim 412167802Sjkimstatic ACPI_STATUS 413167802SjkimAcpiNsFindIniMethods ( 414167802Sjkim ACPI_HANDLE ObjHandle, 415167802Sjkim UINT32 NestingLevel, 416167802Sjkim void *Context, 417167802Sjkim void **ReturnValue) 418167802Sjkim{ 419167802Sjkim ACPI_DEVICE_WALK_INFO *Info = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context); 420167802Sjkim ACPI_NAMESPACE_NODE *Node; 421167802Sjkim ACPI_NAMESPACE_NODE *ParentNode; 422167802Sjkim 423167802Sjkim 424167802Sjkim /* Keep count of device/processor/thermal objects */ 425167802Sjkim 426167802Sjkim Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); 427167802Sjkim if ((Node->Type == ACPI_TYPE_DEVICE) || 428167802Sjkim (Node->Type == ACPI_TYPE_PROCESSOR) || 429167802Sjkim (Node->Type == ACPI_TYPE_THERMAL)) 430167802Sjkim { 431167802Sjkim Info->DeviceCount++; 432167802Sjkim return (AE_OK); 433167802Sjkim } 434167802Sjkim 435167802Sjkim /* We are only looking for methods named _INI */ 436167802Sjkim 437167802Sjkim if (!ACPI_COMPARE_NAME (Node->Name.Ascii, METHOD_NAME__INI)) 438167802Sjkim { 439167802Sjkim return (AE_OK); 440167802Sjkim } 441167802Sjkim 442167802Sjkim /* 443167802Sjkim * The only _INI methods that we care about are those that are 444167802Sjkim * present under Device, Processor, and Thermal objects. 445167802Sjkim */ 446209746Sjkim ParentNode = Node->Parent; 447167802Sjkim switch (ParentNode->Type) 448167802Sjkim { 449167802Sjkim case ACPI_TYPE_DEVICE: 450167802Sjkim case ACPI_TYPE_PROCESSOR: 451167802Sjkim case ACPI_TYPE_THERMAL: 452167802Sjkim 453167802Sjkim /* Mark parent and bubble up the INI present flag to the root */ 454167802Sjkim 455167802Sjkim while (ParentNode) 456167802Sjkim { 457167802Sjkim ParentNode->Flags |= ANOBJ_SUBTREE_HAS_INI; 458209746Sjkim ParentNode = ParentNode->Parent; 459167802Sjkim } 460167802Sjkim break; 461167802Sjkim 462167802Sjkim default: 463250838Sjkim 464167802Sjkim break; 465167802Sjkim } 466167802Sjkim 467167802Sjkim return (AE_OK); 468167802Sjkim} 469167802Sjkim 470167802Sjkim 471167802Sjkim/******************************************************************************* 472167802Sjkim * 47367754Smsmith * FUNCTION: AcpiNsInitOneDevice 47467754Smsmith * 47577424Smsmith * PARAMETERS: ACPI_WALK_CALLBACK 47667754Smsmith * 47767754Smsmith * RETURN: ACPI_STATUS 47867754Smsmith * 47967754Smsmith * DESCRIPTION: This is called once per device soon after ACPI is enabled 48067754Smsmith * to initialize each device. It determines if the device is 48167754Smsmith * present, and if so, calls _INI. 48267754Smsmith * 48377424Smsmith ******************************************************************************/ 48467754Smsmith 485151937Sjkimstatic ACPI_STATUS 48667754SmsmithAcpiNsInitOneDevice ( 48767754Smsmith ACPI_HANDLE ObjHandle, 48867754Smsmith UINT32 NestingLevel, 48967754Smsmith void *Context, 49067754Smsmith void **ReturnValue) 49167754Smsmith{ 492167802Sjkim ACPI_DEVICE_WALK_INFO *WalkInfo = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context); 493167802Sjkim ACPI_EVALUATE_INFO *Info = WalkInfo->EvaluateInfo; 494129684Snjl UINT32 Flags; 49567754Smsmith ACPI_STATUS Status; 496167802Sjkim ACPI_NAMESPACE_NODE *DeviceNode; 49767754Smsmith 49867754Smsmith 499167802Sjkim ACPI_FUNCTION_TRACE (NsInitOneDevice); 50067754Smsmith 50167754Smsmith 502167802Sjkim /* We are interested in Devices, Processors and ThermalZones only */ 503129684Snjl 504167802Sjkim DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); 505167802Sjkim if ((DeviceNode->Type != ACPI_TYPE_DEVICE) && 506167802Sjkim (DeviceNode->Type != ACPI_TYPE_PROCESSOR) && 507167802Sjkim (DeviceNode->Type != ACPI_TYPE_THERMAL)) 50873561Smsmith { 509167802Sjkim return_ACPI_STATUS (AE_OK); 51073561Smsmith } 51173561Smsmith 512123315Snjl /* 513167802Sjkim * Because of an earlier namespace analysis, all subtrees that contain an 514167802Sjkim * _INI method are tagged. 515167802Sjkim * 516167802Sjkim * If this device subtree does not contain any _INI methods, we 517167802Sjkim * can exit now and stop traversing this entire subtree. 518123315Snjl */ 519167802Sjkim if (!(DeviceNode->Flags & ANOBJ_SUBTREE_HAS_INI)) 52091116Smsmith { 521167802Sjkim return_ACPI_STATUS (AE_CTRL_DEPTH); 52291116Smsmith } 52367754Smsmith 52467754Smsmith /* 525167802Sjkim * Run _STA to determine if this device is present and functioning. We 526167802Sjkim * must know this information for two important reasons (from ACPI spec): 527167802Sjkim * 528167802Sjkim * 1) We can only run _INI if the device is present. 529167802Sjkim * 2) We must abort the device tree walk on this subtree if the device is 530167802Sjkim * not present and is not functional (we will not examine the children) 531167802Sjkim * 532167802Sjkim * The _STA method is not required to be present under the device, we 533167802Sjkim * assume the device is present if _STA does not exist. 53467754Smsmith */ 535167802Sjkim ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname ( 536167802Sjkim ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__STA)); 537123315Snjl 538167802Sjkim Status = AcpiUtExecute_STA (DeviceNode, &Flags); 53967754Smsmith if (ACPI_FAILURE (Status)) 54067754Smsmith { 541167802Sjkim /* Ignore error and move on to next device */ 54271867Smsmith 543167802Sjkim return_ACPI_STATUS (AE_OK); 544167802Sjkim } 545123315Snjl 546167802Sjkim /* 547167802Sjkim * Flags == -1 means that _STA was not found. In this case, we assume that 548167802Sjkim * the device is both present and functional. 549167802Sjkim * 550167802Sjkim * From the ACPI spec, description of _STA: 551167802Sjkim * 552167802Sjkim * "If a device object (including the processor object) does not have an 553167802Sjkim * _STA object, then OSPM assumes that all of the above bits are set (in 554167802Sjkim * other words, the device is present, ..., and functioning)" 555167802Sjkim */ 556167802Sjkim if (Flags != ACPI_UINT32_MAX) 557167802Sjkim { 558167802Sjkim WalkInfo->Num_STA++; 55967754Smsmith } 560167802Sjkim 561167802Sjkim /* 562167802Sjkim * Examine the PRESENT and FUNCTIONING status bits 563167802Sjkim * 564167802Sjkim * Note: ACPI spec does not seem to specify behavior for the present but 565167802Sjkim * not functioning case, so we assume functioning if present. 566167802Sjkim */ 567167802Sjkim if (!(Flags & ACPI_STA_DEVICE_PRESENT)) 568123315Snjl { 569167802Sjkim /* Device is not present, we must examine the Functioning bit */ 57067754Smsmith 571167802Sjkim if (Flags & ACPI_STA_DEVICE_FUNCTIONING) 572123315Snjl { 573167802Sjkim /* 574167802Sjkim * Device is not present but is "functioning". In this case, 575167802Sjkim * we will not run _INI, but we continue to examine the children 576167802Sjkim * of this device. 577167802Sjkim * 578167802Sjkim * From the ACPI spec, description of _STA: (Note - no mention 579167802Sjkim * of whether to run _INI or not on the device in question) 580167802Sjkim * 581167802Sjkim * "_STA may return bit 0 clear (not present) with bit 3 set 582167802Sjkim * (device is functional). This case is used to indicate a valid 583167802Sjkim * device for which no device driver should be loaded (for example, 584167802Sjkim * a bridge device.) Children of this device may be present and 585167802Sjkim * valid. OSPM should continue enumeration below a device whose 586167802Sjkim * _STA returns this bit combination" 587167802Sjkim */ 588167802Sjkim return_ACPI_STATUS (AE_OK); 589123315Snjl } 590167802Sjkim else 591167802Sjkim { 592167802Sjkim /* 593167802Sjkim * Device is not present and is not functioning. We must abort the 594167802Sjkim * walk of this subtree immediately -- don't look at the children 595167802Sjkim * of such a device. 596167802Sjkim * 597167802Sjkim * From the ACPI spec, description of _INI: 598167802Sjkim * 599167802Sjkim * "If the _STA method indicates that the device is not present, 600167802Sjkim * OSPM will not run the _INI and will not examine the children 601167802Sjkim * of the device for _INI methods" 602167802Sjkim */ 603167802Sjkim return_ACPI_STATUS (AE_CTRL_DEPTH); 604167802Sjkim } 60567754Smsmith } 60667754Smsmith 60767754Smsmith /* 608167802Sjkim * The device is present or is assumed present if no _STA exists. 609167802Sjkim * Run the _INI if it exists (not required to exist) 610167802Sjkim * 611167802Sjkim * Note: We know there is an _INI within this subtree, but it may not be 612167802Sjkim * under this particular device, it may be lower in the branch. 61367754Smsmith */ 614167802Sjkim ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname ( 615167802Sjkim ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__INI)); 616167802Sjkim 617250341Sjkim ACPI_MEMSET (Info, 0, sizeof (ACPI_EVALUATE_INFO)); 618167802Sjkim Info->PrefixNode = DeviceNode; 619249663Sjkim Info->RelativePathname = METHOD_NAME__INI; 620167802Sjkim Info->Parameters = NULL; 621167802Sjkim Info->Flags = ACPI_IGNORE_RETURN_VALUE; 622167802Sjkim 623167802Sjkim Status = AcpiNsEvaluate (Info); 624167802Sjkim if (ACPI_SUCCESS (Status)) 62567754Smsmith { 626167802Sjkim WalkInfo->Num_INI++; 627167802Sjkim } 62867754Smsmith 629129684Snjl#ifdef ACPI_DEBUG_OUTPUT 630167802Sjkim else if (Status != AE_NOT_FOUND) 631167802Sjkim { 632167802Sjkim /* Ignore error and move on to next device */ 63371867Smsmith 634249663Sjkim char *ScopeName = AcpiNsGetExternalPathname (Info->Node); 63567754Smsmith 636167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, "during %s._INI execution", 637167802Sjkim ScopeName)); 638167802Sjkim ACPI_FREE (ScopeName); 639167802Sjkim } 640129684Snjl#endif 64167754Smsmith 642167802Sjkim /* Ignore errors from above */ 643140216Snjl 644167802Sjkim Status = AE_OK; 645140216Snjl 646167802Sjkim /* 647167802Sjkim * The _INI method has been run if present; call the Global Initialization 648167802Sjkim * Handler for this device. 649167802Sjkim */ 65099679Siwasaki if (AcpiGbl_InitHandler) 65199679Siwasaki { 652167802Sjkim Status = AcpiGbl_InitHandler (DeviceNode, ACPI_INIT_DEVICE_INI); 65399679Siwasaki } 65499679Siwasaki 65599679Siwasaki return_ACPI_STATUS (Status); 65667754Smsmith} 657