167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: nsinit - namespace initialization 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, 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> 49306536Sjkim#include <contrib/dev/acpica/include/acevents.h> 5067754Smsmith 5177424Smsmith#define _COMPONENT ACPI_NAMESPACE 5291116Smsmith ACPI_MODULE_NAME ("nsinit") 5367754Smsmith 54151937Sjkim/* Local prototypes */ 5567754Smsmith 56151937Sjkimstatic ACPI_STATUS 57151937SjkimAcpiNsInitOneObject ( 58151937Sjkim ACPI_HANDLE ObjHandle, 59151937Sjkim UINT32 Level, 60151937Sjkim void *Context, 61151937Sjkim void **ReturnValue); 62151937Sjkim 63151937Sjkimstatic ACPI_STATUS 64151937SjkimAcpiNsInitOneDevice ( 65151937Sjkim ACPI_HANDLE ObjHandle, 66151937Sjkim UINT32 NestingLevel, 67151937Sjkim void *Context, 68151937Sjkim void **ReturnValue); 69151937Sjkim 70167802Sjkimstatic ACPI_STATUS 71167802SjkimAcpiNsFindIniMethods ( 72167802Sjkim ACPI_HANDLE ObjHandle, 73167802Sjkim UINT32 NestingLevel, 74167802Sjkim void *Context, 75167802Sjkim void **ReturnValue); 76151937Sjkim 77167802Sjkim 7867754Smsmith/******************************************************************************* 7967754Smsmith * 8067754Smsmith * FUNCTION: AcpiNsInitializeObjects 8167754Smsmith * 8267754Smsmith * PARAMETERS: None 8367754Smsmith * 8467754Smsmith * RETURN: Status 8567754Smsmith * 8667754Smsmith * DESCRIPTION: Walk the entire namespace and perform any necessary 8767754Smsmith * initialization on the objects found therein 8867754Smsmith * 8967754Smsmith ******************************************************************************/ 9067754Smsmith 9167754SmsmithACPI_STATUS 9267754SmsmithAcpiNsInitializeObjects ( 9367754Smsmith void) 9467754Smsmith{ 9567754Smsmith ACPI_STATUS Status; 9667754Smsmith ACPI_INIT_WALK_INFO Info; 9767754Smsmith 9867754Smsmith 99167802Sjkim ACPI_FUNCTION_TRACE (NsInitializeObjects); 10067754Smsmith 10167754Smsmith 102306536Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 103306536Sjkim "[Init] Completing Initialization of ACPI Objects\n")); 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 111306536Sjkim 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, 116306536Sjkim ACPI_UINT32_MAX, AcpiNsInitOneObject, NULL, 117306536Sjkim &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, 132281075Sdim "%u Control Methods found\n%u Op Regions found\n", 133281075Sdim Info.MethodCount, Info.OpRegionCount)); 13467754Smsmith 13567754Smsmith return_ACPI_STATUS (AE_OK); 13667754Smsmith} 13767754Smsmith 13867754Smsmith 13977424Smsmith/******************************************************************************* 14067754Smsmith * 14167754Smsmith * FUNCTION: AcpiNsInitializeDevices 14267754Smsmith * 14367754Smsmith * PARAMETERS: None 14467754Smsmith * 14567754Smsmith * RETURN: ACPI_STATUS 14667754Smsmith * 14767754Smsmith * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices. 14867754Smsmith * This means running _INI on all present devices. 14967754Smsmith * 15077424Smsmith * Note: We install PCI config space handler on region access, 15177424Smsmith * not here. 15267754Smsmith * 15377424Smsmith ******************************************************************************/ 15467754Smsmith 15567754SmsmithACPI_STATUS 15667754SmsmithAcpiNsInitializeDevices ( 157306536Sjkim UINT32 Flags) 15867754Smsmith{ 159306536Sjkim ACPI_STATUS Status = AE_OK; 16067754Smsmith ACPI_DEVICE_WALK_INFO Info; 161306536Sjkim ACPI_HANDLE Handle; 16267754Smsmith 16367754Smsmith 164167802Sjkim ACPI_FUNCTION_TRACE (NsInitializeDevices); 16567754Smsmith 16667754Smsmith 167306536Sjkim if (!(Flags & ACPI_NO_DEVICE_INIT)) 168306536Sjkim { 169306536Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 170306536Sjkim "[Init] Initializing ACPI Devices\n")); 17199146Siwasaki 172306536Sjkim /* Init counters */ 17367754Smsmith 174306536Sjkim Info.DeviceCount = 0; 175306536Sjkim Info.Num_STA = 0; 176306536Sjkim Info.Num_INI = 0; 17767754Smsmith 178306536Sjkim ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 179306536Sjkim "Initializing Device/Processor/Thermal objects " 180306536Sjkim "and executing _INI/_STA methods:\n")); 181167802Sjkim 182306536Sjkim /* Tree analysis: find all subtrees that contain _INI methods */ 18367754Smsmith 184306536Sjkim Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 185306536Sjkim ACPI_UINT32_MAX, FALSE, AcpiNsFindIniMethods, NULL, &Info, NULL); 186306536Sjkim if (ACPI_FAILURE (Status)) 187306536Sjkim { 188306536Sjkim goto ErrorExit; 189306536Sjkim } 19067754Smsmith 191306536Sjkim /* Allocate the evaluation information block */ 192167802Sjkim 193306536Sjkim Info.EvaluateInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 194306536Sjkim if (!Info.EvaluateInfo) 195306536Sjkim { 196306536Sjkim Status = AE_NO_MEMORY; 197306536Sjkim goto ErrorExit; 198306536Sjkim } 199197104Sjkim 200306536Sjkim /* 201306536Sjkim * Execute the "global" _INI method that may appear at the root. 202306536Sjkim * This support is provided for Windows compatibility (Vista+) and 203306536Sjkim * is not part of the ACPI specification. 204306536Sjkim */ 205306536Sjkim Info.EvaluateInfo->PrefixNode = AcpiGbl_RootNode; 206306536Sjkim Info.EvaluateInfo->RelativePathname = METHOD_NAME__INI; 207306536Sjkim Info.EvaluateInfo->Parameters = NULL; 208306536Sjkim Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE; 209197104Sjkim 210306536Sjkim Status = AcpiNsEvaluate (Info.EvaluateInfo); 211306536Sjkim if (ACPI_SUCCESS (Status)) 212306536Sjkim { 213306536Sjkim Info.Num_INI++; 214306536Sjkim } 215167802Sjkim 216306536Sjkim /* 217306536Sjkim * Execute \_SB._INI. 218306536Sjkim * There appears to be a strict order requirement for \_SB._INI, 219306536Sjkim * which should be evaluated before any _REG evaluations. 220306536Sjkim */ 221306536Sjkim Status = AcpiGetHandle (NULL, "\\_SB", &Handle); 222306536Sjkim if (ACPI_SUCCESS (Status)) 223306536Sjkim { 224306536Sjkim memset (Info.EvaluateInfo, 0, sizeof (ACPI_EVALUATE_INFO)); 225306536Sjkim Info.EvaluateInfo->PrefixNode = Handle; 226306536Sjkim Info.EvaluateInfo->RelativePathname = METHOD_NAME__INI; 227306536Sjkim Info.EvaluateInfo->Parameters = NULL; 228306536Sjkim Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE; 229123315Snjl 230306536Sjkim Status = AcpiNsEvaluate (Info.EvaluateInfo); 231306536Sjkim if (ACPI_SUCCESS (Status)) 232306536Sjkim { 233306536Sjkim Info.Num_INI++; 234306536Sjkim } 235306536Sjkim } 236306536Sjkim } 237306536Sjkim 238209746Sjkim /* 239306536Sjkim * Run all _REG methods 240306536Sjkim * 241306536Sjkim * Note: Any objects accessed by the _REG methods will be automatically 242306536Sjkim * initialized, even if they contain executable AML (see the call to 243306536Sjkim * AcpiNsInitializeObjects below). 244306536Sjkim * 245306536Sjkim * Note: According to the ACPI specification, we actually needn't execute 246306536Sjkim * _REG for SystemMemory/SystemIo operation regions, but for PCI_Config 247306536Sjkim * operation regions, it is required to evaluate _REG for those on a PCI 248306536Sjkim * root bus that doesn't contain _BBN object. So this code is kept here 249306536Sjkim * in order not to break things. 250209746Sjkim */ 251306536Sjkim if (!(Flags & ACPI_NO_ADDRESS_SPACE_INIT)) 252209746Sjkim { 253306536Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 254306536Sjkim "[Init] Executing _REG OpRegion methods\n")); 255306536Sjkim 256306536Sjkim Status = AcpiEvInitializeOpRegions (); 257306536Sjkim if (ACPI_FAILURE (Status)) 258306536Sjkim { 259306536Sjkim goto ErrorExit; 260306536Sjkim } 261209746Sjkim } 262209746Sjkim 263306536Sjkim if (!(Flags & ACPI_NO_DEVICE_INIT)) 26467754Smsmith { 265306536Sjkim /* Walk namespace to execute all _INIs on present devices */ 266306536Sjkim 267306536Sjkim Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 268306536Sjkim ACPI_UINT32_MAX, FALSE, AcpiNsInitOneDevice, NULL, &Info, NULL); 269306536Sjkim 270306536Sjkim /* 271306536Sjkim * Any _OSI requests should be completed by now. If the BIOS has 272306536Sjkim * requested any Windows OSI strings, we will always truncate 273306536Sjkim * I/O addresses to 16 bits -- for Windows compatibility. 274306536Sjkim */ 275306536Sjkim if (AcpiGbl_OsiData >= ACPI_OSI_WIN_2000) 276306536Sjkim { 277306536Sjkim AcpiGbl_TruncateIoAddresses = TRUE; 278306536Sjkim } 279306536Sjkim 280306536Sjkim ACPI_FREE (Info.EvaluateInfo); 281306536Sjkim if (ACPI_FAILURE (Status)) 282306536Sjkim { 283306536Sjkim goto ErrorExit; 284306536Sjkim } 285306536Sjkim 286306536Sjkim ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 287306536Sjkim " Executed %u _INI methods requiring %u _STA executions " 288306536Sjkim "(examined %u objects)\n", 289306536Sjkim Info.Num_INI, Info.Num_STA, Info.DeviceCount)); 29067754Smsmith } 29167754Smsmith 29267754Smsmith return_ACPI_STATUS (Status); 293167802Sjkim 294167802Sjkim 295167802SjkimErrorExit: 296167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, "During device initialization")); 297167802Sjkim return_ACPI_STATUS (Status); 29867754Smsmith} 29967754Smsmith 30067754Smsmith 30167754Smsmith/******************************************************************************* 30267754Smsmith * 30367754Smsmith * FUNCTION: AcpiNsInitOneObject 30467754Smsmith * 30567754Smsmith * PARAMETERS: ObjHandle - Node 30667754Smsmith * Level - Current nesting level 30767754Smsmith * Context - Points to a init info struct 30867754Smsmith * ReturnValue - Not used 30967754Smsmith * 31067754Smsmith * RETURN: Status 31167754Smsmith * 312241973Sjkim * DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every object 31367754Smsmith * within the namespace. 31467754Smsmith * 31567754Smsmith * Currently, the only objects that require initialization are: 31667754Smsmith * 1) Methods 31767754Smsmith * 2) Op Regions 31867754Smsmith * 31967754Smsmith ******************************************************************************/ 32067754Smsmith 321151937Sjkimstatic ACPI_STATUS 32267754SmsmithAcpiNsInitOneObject ( 32367754Smsmith ACPI_HANDLE ObjHandle, 32467754Smsmith UINT32 Level, 32567754Smsmith void *Context, 32667754Smsmith void **ReturnValue) 32767754Smsmith{ 32891116Smsmith ACPI_OBJECT_TYPE Type; 329167802Sjkim ACPI_STATUS Status = AE_OK; 33067754Smsmith ACPI_INIT_WALK_INFO *Info = (ACPI_INIT_WALK_INFO *) Context; 33167754Smsmith ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 33267754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 33367754Smsmith 33467754Smsmith 335167802Sjkim ACPI_FUNCTION_NAME (NsInitOneObject); 33682367Smsmith 33782367Smsmith 33867754Smsmith Info->ObjectCount++; 33967754Smsmith 34067754Smsmith /* And even then, we are only interested in a few object types */ 34167754Smsmith 34267754Smsmith Type = AcpiNsGetType (ObjHandle); 34387031Smsmith ObjDesc = AcpiNsGetAttachedObject (Node); 34467754Smsmith if (!ObjDesc) 34567754Smsmith { 34667754Smsmith return (AE_OK); 34767754Smsmith } 34867754Smsmith 34999146Siwasaki /* Increment counters for object types we are looking for */ 35099146Siwasaki 35199146Siwasaki switch (Type) 35280062Smsmith { 35399146Siwasaki case ACPI_TYPE_REGION: 354250838Sjkim 35599146Siwasaki Info->OpRegionCount++; 35699146Siwasaki break; 35799146Siwasaki 35899146Siwasaki case ACPI_TYPE_BUFFER_FIELD: 359250838Sjkim 36099146Siwasaki Info->FieldCount++; 36199146Siwasaki break; 36299146Siwasaki 363193267Sjkim case ACPI_TYPE_LOCAL_BANK_FIELD: 364250838Sjkim 365193267Sjkim Info->FieldCount++; 366193267Sjkim break; 367193267Sjkim 36899146Siwasaki case ACPI_TYPE_BUFFER: 369250838Sjkim 37099146Siwasaki Info->BufferCount++; 37199146Siwasaki break; 37299146Siwasaki 37399146Siwasaki case ACPI_TYPE_PACKAGE: 374250838Sjkim 37599146Siwasaki Info->PackageCount++; 37699146Siwasaki break; 37799146Siwasaki 37899146Siwasaki default: 37999146Siwasaki 38099146Siwasaki /* No init required, just exit now */ 381250838Sjkim 38280062Smsmith return (AE_OK); 38380062Smsmith } 38480062Smsmith 385193267Sjkim /* If the object is already initialized, nothing else to do */ 386193267Sjkim 38799146Siwasaki if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) 38899146Siwasaki { 38999146Siwasaki return (AE_OK); 39099146Siwasaki } 39180062Smsmith 392193267Sjkim /* Must lock the interpreter before executing AML code */ 393193267Sjkim 394167802Sjkim AcpiExEnterInterpreter (); 39580062Smsmith 39699146Siwasaki /* 397138287Smarks * Each of these types can contain executable AML code within the 398138287Smarks * declaration. 39999146Siwasaki */ 40067754Smsmith switch (Type) 40167754Smsmith { 40267754Smsmith case ACPI_TYPE_REGION: 40367754Smsmith 40467754Smsmith Info->OpRegionInit++; 40567754Smsmith Status = AcpiDsGetRegionArguments (ObjDesc); 40667754Smsmith break; 40767754Smsmith 40877424Smsmith case ACPI_TYPE_BUFFER_FIELD: 40967754Smsmith 41067754Smsmith Info->FieldInit++; 41177424Smsmith Status = AcpiDsGetBufferFieldArguments (ObjDesc); 41299146Siwasaki break; 41367754Smsmith 414193267Sjkim case ACPI_TYPE_LOCAL_BANK_FIELD: 415193267Sjkim 416193267Sjkim Info->FieldInit++; 417193267Sjkim Status = AcpiDsGetBankFieldArguments (ObjDesc); 418193267Sjkim break; 419193267Sjkim 42099146Siwasaki case ACPI_TYPE_BUFFER: 42199146Siwasaki 42299146Siwasaki Info->BufferInit++; 42399146Siwasaki Status = AcpiDsGetBufferArguments (ObjDesc); 42467754Smsmith break; 42567754Smsmith 42699146Siwasaki case ACPI_TYPE_PACKAGE: 42799146Siwasaki 42899146Siwasaki Info->PackageInit++; 42999146Siwasaki Status = AcpiDsGetPackageArguments (ObjDesc); 43067754Smsmith break; 43199679Siwasaki 43299679Siwasaki default: 433250838Sjkim 43499679Siwasaki /* No other types can get here */ 435250838Sjkim 43699679Siwasaki break; 43767754Smsmith } 43867754Smsmith 43999146Siwasaki if (ACPI_FAILURE (Status)) 44099146Siwasaki { 441167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 442167802Sjkim "Could not execute arguments for [%4.4s] (%s)", 443167802Sjkim AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Type))); 44499146Siwasaki } 44580062Smsmith 446138287Smarks /* 447138287Smarks * We ignore errors from above, and always return OK, since we don't want 448138287Smarks * to abort the walk on any single error. 44967754Smsmith */ 45080062Smsmith AcpiExExitInterpreter (); 45167754Smsmith return (AE_OK); 45267754Smsmith} 45367754Smsmith 45467754Smsmith 45577424Smsmith/******************************************************************************* 45667754Smsmith * 457167802Sjkim * FUNCTION: AcpiNsFindIniMethods 458167802Sjkim * 459167802Sjkim * PARAMETERS: ACPI_WALK_CALLBACK 460167802Sjkim * 461167802Sjkim * RETURN: ACPI_STATUS 462167802Sjkim * 463167802Sjkim * DESCRIPTION: Called during namespace walk. Finds objects named _INI under 464167802Sjkim * device/processor/thermal objects, and marks the entire subtree 465167802Sjkim * with a SUBTREE_HAS_INI flag. This flag is used during the 466167802Sjkim * subsequent device initialization walk to avoid entire subtrees 467167802Sjkim * that do not contain an _INI. 468167802Sjkim * 469167802Sjkim ******************************************************************************/ 470167802Sjkim 471167802Sjkimstatic ACPI_STATUS 472167802SjkimAcpiNsFindIniMethods ( 473167802Sjkim ACPI_HANDLE ObjHandle, 474167802Sjkim UINT32 NestingLevel, 475167802Sjkim void *Context, 476167802Sjkim void **ReturnValue) 477167802Sjkim{ 478167802Sjkim ACPI_DEVICE_WALK_INFO *Info = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context); 479167802Sjkim ACPI_NAMESPACE_NODE *Node; 480167802Sjkim ACPI_NAMESPACE_NODE *ParentNode; 481167802Sjkim 482167802Sjkim 483167802Sjkim /* Keep count of device/processor/thermal objects */ 484167802Sjkim 485167802Sjkim Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); 486167802Sjkim if ((Node->Type == ACPI_TYPE_DEVICE) || 487167802Sjkim (Node->Type == ACPI_TYPE_PROCESSOR) || 488167802Sjkim (Node->Type == ACPI_TYPE_THERMAL)) 489167802Sjkim { 490167802Sjkim Info->DeviceCount++; 491167802Sjkim return (AE_OK); 492167802Sjkim } 493167802Sjkim 494167802Sjkim /* We are only looking for methods named _INI */ 495167802Sjkim 496167802Sjkim if (!ACPI_COMPARE_NAME (Node->Name.Ascii, METHOD_NAME__INI)) 497167802Sjkim { 498167802Sjkim return (AE_OK); 499167802Sjkim } 500167802Sjkim 501167802Sjkim /* 502167802Sjkim * The only _INI methods that we care about are those that are 503167802Sjkim * present under Device, Processor, and Thermal objects. 504167802Sjkim */ 505209746Sjkim ParentNode = Node->Parent; 506167802Sjkim switch (ParentNode->Type) 507167802Sjkim { 508167802Sjkim case ACPI_TYPE_DEVICE: 509167802Sjkim case ACPI_TYPE_PROCESSOR: 510167802Sjkim case ACPI_TYPE_THERMAL: 511167802Sjkim 512167802Sjkim /* Mark parent and bubble up the INI present flag to the root */ 513167802Sjkim 514167802Sjkim while (ParentNode) 515167802Sjkim { 516167802Sjkim ParentNode->Flags |= ANOBJ_SUBTREE_HAS_INI; 517209746Sjkim ParentNode = ParentNode->Parent; 518167802Sjkim } 519167802Sjkim break; 520167802Sjkim 521167802Sjkim default: 522250838Sjkim 523167802Sjkim break; 524167802Sjkim } 525167802Sjkim 526167802Sjkim return (AE_OK); 527167802Sjkim} 528167802Sjkim 529167802Sjkim 530167802Sjkim/******************************************************************************* 531167802Sjkim * 53267754Smsmith * FUNCTION: AcpiNsInitOneDevice 53367754Smsmith * 53477424Smsmith * PARAMETERS: ACPI_WALK_CALLBACK 53567754Smsmith * 53667754Smsmith * RETURN: ACPI_STATUS 53767754Smsmith * 53867754Smsmith * DESCRIPTION: This is called once per device soon after ACPI is enabled 53967754Smsmith * to initialize each device. It determines if the device is 54067754Smsmith * present, and if so, calls _INI. 54167754Smsmith * 54277424Smsmith ******************************************************************************/ 54367754Smsmith 544151937Sjkimstatic ACPI_STATUS 54567754SmsmithAcpiNsInitOneDevice ( 54667754Smsmith ACPI_HANDLE ObjHandle, 54767754Smsmith UINT32 NestingLevel, 54867754Smsmith void *Context, 54967754Smsmith void **ReturnValue) 55067754Smsmith{ 551167802Sjkim ACPI_DEVICE_WALK_INFO *WalkInfo = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context); 552167802Sjkim ACPI_EVALUATE_INFO *Info = WalkInfo->EvaluateInfo; 553129684Snjl UINT32 Flags; 55467754Smsmith ACPI_STATUS Status; 555167802Sjkim ACPI_NAMESPACE_NODE *DeviceNode; 55667754Smsmith 55767754Smsmith 558167802Sjkim ACPI_FUNCTION_TRACE (NsInitOneDevice); 55967754Smsmith 56067754Smsmith 561167802Sjkim /* We are interested in Devices, Processors and ThermalZones only */ 562129684Snjl 563167802Sjkim DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); 564167802Sjkim if ((DeviceNode->Type != ACPI_TYPE_DEVICE) && 565167802Sjkim (DeviceNode->Type != ACPI_TYPE_PROCESSOR) && 566167802Sjkim (DeviceNode->Type != ACPI_TYPE_THERMAL)) 56773561Smsmith { 568167802Sjkim return_ACPI_STATUS (AE_OK); 56973561Smsmith } 57073561Smsmith 571123315Snjl /* 572167802Sjkim * Because of an earlier namespace analysis, all subtrees that contain an 573167802Sjkim * _INI method are tagged. 574167802Sjkim * 575167802Sjkim * If this device subtree does not contain any _INI methods, we 576167802Sjkim * can exit now and stop traversing this entire subtree. 577123315Snjl */ 578167802Sjkim if (!(DeviceNode->Flags & ANOBJ_SUBTREE_HAS_INI)) 57991116Smsmith { 580167802Sjkim return_ACPI_STATUS (AE_CTRL_DEPTH); 58191116Smsmith } 58267754Smsmith 58367754Smsmith /* 584167802Sjkim * Run _STA to determine if this device is present and functioning. We 585167802Sjkim * must know this information for two important reasons (from ACPI spec): 586167802Sjkim * 587167802Sjkim * 1) We can only run _INI if the device is present. 588167802Sjkim * 2) We must abort the device tree walk on this subtree if the device is 589167802Sjkim * not present and is not functional (we will not examine the children) 590167802Sjkim * 591167802Sjkim * The _STA method is not required to be present under the device, we 592167802Sjkim * assume the device is present if _STA does not exist. 59367754Smsmith */ 594167802Sjkim ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname ( 595167802Sjkim ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__STA)); 596123315Snjl 597167802Sjkim Status = AcpiUtExecute_STA (DeviceNode, &Flags); 59867754Smsmith if (ACPI_FAILURE (Status)) 59967754Smsmith { 600167802Sjkim /* Ignore error and move on to next device */ 60171867Smsmith 602167802Sjkim return_ACPI_STATUS (AE_OK); 603167802Sjkim } 604123315Snjl 605167802Sjkim /* 606167802Sjkim * Flags == -1 means that _STA was not found. In this case, we assume that 607167802Sjkim * the device is both present and functional. 608167802Sjkim * 609167802Sjkim * From the ACPI spec, description of _STA: 610167802Sjkim * 611167802Sjkim * "If a device object (including the processor object) does not have an 612167802Sjkim * _STA object, then OSPM assumes that all of the above bits are set (in 613167802Sjkim * other words, the device is present, ..., and functioning)" 614167802Sjkim */ 615167802Sjkim if (Flags != ACPI_UINT32_MAX) 616167802Sjkim { 617167802Sjkim WalkInfo->Num_STA++; 61867754Smsmith } 619167802Sjkim 620167802Sjkim /* 621167802Sjkim * Examine the PRESENT and FUNCTIONING status bits 622167802Sjkim * 623167802Sjkim * Note: ACPI spec does not seem to specify behavior for the present but 624167802Sjkim * not functioning case, so we assume functioning if present. 625167802Sjkim */ 626167802Sjkim if (!(Flags & ACPI_STA_DEVICE_PRESENT)) 627123315Snjl { 628167802Sjkim /* Device is not present, we must examine the Functioning bit */ 62967754Smsmith 630167802Sjkim if (Flags & ACPI_STA_DEVICE_FUNCTIONING) 631123315Snjl { 632167802Sjkim /* 633167802Sjkim * Device is not present but is "functioning". In this case, 634167802Sjkim * we will not run _INI, but we continue to examine the children 635167802Sjkim * of this device. 636167802Sjkim * 637167802Sjkim * From the ACPI spec, description of _STA: (Note - no mention 638167802Sjkim * of whether to run _INI or not on the device in question) 639167802Sjkim * 640167802Sjkim * "_STA may return bit 0 clear (not present) with bit 3 set 641167802Sjkim * (device is functional). This case is used to indicate a valid 642167802Sjkim * device for which no device driver should be loaded (for example, 643167802Sjkim * a bridge device.) Children of this device may be present and 644167802Sjkim * valid. OSPM should continue enumeration below a device whose 645167802Sjkim * _STA returns this bit combination" 646167802Sjkim */ 647167802Sjkim return_ACPI_STATUS (AE_OK); 648123315Snjl } 649167802Sjkim else 650167802Sjkim { 651167802Sjkim /* 652167802Sjkim * Device is not present and is not functioning. We must abort the 653167802Sjkim * walk of this subtree immediately -- don't look at the children 654167802Sjkim * of such a device. 655167802Sjkim * 656167802Sjkim * From the ACPI spec, description of _INI: 657167802Sjkim * 658167802Sjkim * "If the _STA method indicates that the device is not present, 659167802Sjkim * OSPM will not run the _INI and will not examine the children 660167802Sjkim * of the device for _INI methods" 661167802Sjkim */ 662167802Sjkim return_ACPI_STATUS (AE_CTRL_DEPTH); 663167802Sjkim } 66467754Smsmith } 66567754Smsmith 66667754Smsmith /* 667167802Sjkim * The device is present or is assumed present if no _STA exists. 668167802Sjkim * Run the _INI if it exists (not required to exist) 669167802Sjkim * 670167802Sjkim * Note: We know there is an _INI within this subtree, but it may not be 671167802Sjkim * under this particular device, it may be lower in the branch. 67267754Smsmith */ 673306536Sjkim if (!ACPI_COMPARE_NAME (DeviceNode->Name.Ascii, "_SB_") || 674306536Sjkim DeviceNode->Parent != AcpiGbl_RootNode) 675306536Sjkim { 676306536Sjkim ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname ( 677306536Sjkim ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__INI)); 678167802Sjkim 679306536Sjkim memset (Info, 0, sizeof (ACPI_EVALUATE_INFO)); 680306536Sjkim Info->PrefixNode = DeviceNode; 681306536Sjkim Info->RelativePathname = METHOD_NAME__INI; 682306536Sjkim Info->Parameters = NULL; 683306536Sjkim Info->Flags = ACPI_IGNORE_RETURN_VALUE; 684167802Sjkim 685306536Sjkim Status = AcpiNsEvaluate (Info); 686306536Sjkim if (ACPI_SUCCESS (Status)) 687306536Sjkim { 688306536Sjkim WalkInfo->Num_INI++; 689306536Sjkim } 69067754Smsmith 691129684Snjl#ifdef ACPI_DEBUG_OUTPUT 692306536Sjkim else if (Status != AE_NOT_FOUND) 693306536Sjkim { 694306536Sjkim /* Ignore error and move on to next device */ 69571867Smsmith 696306536Sjkim char *ScopeName = AcpiNsGetNormalizedPathname (DeviceNode, TRUE); 69767754Smsmith 698306536Sjkim ACPI_EXCEPTION ((AE_INFO, Status, "during %s._INI execution", 699306536Sjkim ScopeName)); 700306536Sjkim ACPI_FREE (ScopeName); 701306536Sjkim } 702306536Sjkim#endif 703167802Sjkim } 70467754Smsmith 705167802Sjkim /* Ignore errors from above */ 706140216Snjl 707167802Sjkim Status = AE_OK; 708140216Snjl 709167802Sjkim /* 710167802Sjkim * The _INI method has been run if present; call the Global Initialization 711167802Sjkim * Handler for this device. 712167802Sjkim */ 71399679Siwasaki if (AcpiGbl_InitHandler) 71499679Siwasaki { 715167802Sjkim Status = AcpiGbl_InitHandler (DeviceNode, ACPI_INIT_DEVICE_INI); 71699679Siwasaki } 71799679Siwasaki 71899679Siwasaki return_ACPI_STATUS (Status); 71967754Smsmith} 720