Path: blob/main/sys/contrib/dev/acpica/components/namespace/nsinit.c
48524 views
/******************************************************************************1*2* Module Name: nsinit - namespace initialization3*4*****************************************************************************/56/******************************************************************************7*8* 1. Copyright Notice9*10* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.11* All rights reserved.12*13* 2. License14*15* 2.1. This is your license from Intel Corp. under its intellectual property16* rights. You may have additional license terms from the party that provided17* you this software, covering your right to use that party's intellectual18* property rights.19*20* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a21* copy of the source code appearing in this file ("Covered Code") an22* irrevocable, perpetual, worldwide license under Intel's copyrights in the23* base code distributed originally by Intel ("Original Intel Code") to copy,24* make derivatives, distribute, use and display any portion of the Covered25* Code in any form, with the right to sublicense such rights; and26*27* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent28* license (with the right to sublicense), under only those claims of Intel29* patents that are infringed by the Original Intel Code, to make, use, sell,30* offer to sell, and import the Covered Code and derivative works thereof31* solely to the minimum extent necessary to exercise the above copyright32* license, and in no event shall the patent license extend to any additions33* to or modifications of the Original Intel Code. No other license or right34* is granted directly or by implication, estoppel or otherwise;35*36* The above copyright and patent license is granted only if the following37* conditions are met:38*39* 3. Conditions40*41* 3.1. Redistribution of Source with Rights to Further Distribute Source.42* Redistribution of source code of any substantial portion of the Covered43* Code or modification with rights to further distribute source must include44* the above Copyright Notice, the above License, this list of Conditions,45* and the following Disclaimer and Export Compliance provision. In addition,46* Licensee must cause all Covered Code to which Licensee contributes to47* contain a file documenting the changes Licensee made to create that Covered48* Code and the date of any change. Licensee must include in that file the49* documentation of any changes made by any predecessor Licensee. Licensee50* must include a prominent statement that the modification is derived,51* directly or indirectly, from Original Intel Code.52*53* 3.2. Redistribution of Source with no Rights to Further Distribute Source.54* Redistribution of source code of any substantial portion of the Covered55* Code or modification without rights to further distribute source must56* include the following Disclaimer and Export Compliance provision in the57* documentation and/or other materials provided with distribution. In58* addition, Licensee may not authorize further sublicense of source of any59* portion of the Covered Code, and must include terms to the effect that the60* license from Licensee to its licensee is limited to the intellectual61* property embodied in the software Licensee provides to its licensee, and62* not to intellectual property embodied in modifications its licensee may63* make.64*65* 3.3. Redistribution of Executable. Redistribution in executable form of any66* substantial portion of the Covered Code or modification must reproduce the67* above Copyright Notice, and the following Disclaimer and Export Compliance68* provision in the documentation and/or other materials provided with the69* distribution.70*71* 3.4. Intel retains all right, title, and interest in and to the Original72* Intel Code.73*74* 3.5. Neither the name Intel nor any other trademark owned or controlled by75* Intel shall be used in advertising or otherwise to promote the sale, use or76* other dealings in products derived from or relating to the Covered Code77* without prior written authorization from Intel.78*79* 4. Disclaimer and Export Compliance80*81* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED82* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE83* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,84* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY85* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY86* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A87* PARTICULAR PURPOSE.88*89* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES90* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR91* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,92* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY93* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL94* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS95* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY96* LIMITED REMEDY.97*98* 4.3. Licensee shall not export, either directly or indirectly, any of this99* software or system incorporating such software without first obtaining any100* required license or other approval from the U. S. Department of Commerce or101* any other agency or department of the United States Government. In the102* event Licensee exports any such software from the United States or103* re-exports any such software from a foreign destination, Licensee shall104* ensure that the distribution and export/re-export of the software is in105* compliance with all laws, regulations, orders, or other restrictions of the106* U.S. Export Administration Regulations. Licensee agrees that neither it nor107* any of its subsidiaries will export/re-export any technical data, process,108* software, or service, directly or indirectly, to any country for which the109* United States government or any agency thereof requires an export license,110* other governmental approval, or letter of assurance, without first obtaining111* such license, approval or letter.112*113*****************************************************************************114*115* Alternatively, you may choose to be licensed under the terms of the116* following license:117*118* Redistribution and use in source and binary forms, with or without119* modification, are permitted provided that the following conditions120* are met:121* 1. Redistributions of source code must retain the above copyright122* notice, this list of conditions, and the following disclaimer,123* without modification.124* 2. Redistributions in binary form must reproduce at minimum a disclaimer125* substantially similar to the "NO WARRANTY" disclaimer below126* ("Disclaimer") and any redistribution must be conditioned upon127* including a substantially similar Disclaimer requirement for further128* binary redistribution.129* 3. Neither the names of the above-listed copyright holders nor the names130* of any contributors may be used to endorse or promote products derived131* from this software without specific prior written permission.132*133* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS134* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT135* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR136* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT137* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,138* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT139* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,140* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY141* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT142* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE143* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.144*145* Alternatively, you may choose to be licensed under the terms of the146* GNU General Public License ("GPL") version 2 as published by the Free147* Software Foundation.148*149*****************************************************************************/150151#include <contrib/dev/acpica/include/acpi.h>152#include <contrib/dev/acpica/include/accommon.h>153#include <contrib/dev/acpica/include/acnamesp.h>154#include <contrib/dev/acpica/include/acdispat.h>155#include <contrib/dev/acpica/include/acinterp.h>156#include <contrib/dev/acpica/include/acevents.h>157158#define _COMPONENT ACPI_NAMESPACE159ACPI_MODULE_NAME ("nsinit")160161/* Local prototypes */162163static ACPI_STATUS164AcpiNsInitOneObject (165ACPI_HANDLE ObjHandle,166UINT32 Level,167void *Context,168void **ReturnValue);169170static ACPI_STATUS171AcpiNsInitOneDevice (172ACPI_HANDLE ObjHandle,173UINT32 NestingLevel,174void *Context,175void **ReturnValue);176177static ACPI_STATUS178AcpiNsFindIniMethods (179ACPI_HANDLE ObjHandle,180UINT32 NestingLevel,181void *Context,182void **ReturnValue);183184185/*******************************************************************************186*187* FUNCTION: AcpiNsInitializeObjects188*189* PARAMETERS: None190*191* RETURN: Status192*193* DESCRIPTION: Walk the entire namespace and perform any necessary194* initialization on the objects found therein195*196******************************************************************************/197198ACPI_STATUS199AcpiNsInitializeObjects (200void)201{202ACPI_STATUS Status;203ACPI_INIT_WALK_INFO Info;204205206ACPI_FUNCTION_TRACE (NsInitializeObjects);207208209ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,210"[Init] Completing Initialization of ACPI Objects\n"));211ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,212"**** Starting initialization of namespace objects ****\n"));213ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,214"Final data object initialization: "));215216/* Clear the info block */217218memset (&Info, 0, sizeof (ACPI_INIT_WALK_INFO));219220/* Walk entire namespace from the supplied root */221222/*223* TBD: will become ACPI_TYPE_PACKAGE as this type object224* is now the only one that supports deferred initialization225* (forward references).226*/227Status = AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,228ACPI_UINT32_MAX, AcpiNsInitOneObject, NULL, &Info, NULL);229if (ACPI_FAILURE (Status))230{231ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace"));232}233234ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,235"Namespace contains %u (0x%X) objects\n",236Info.ObjectCount,237Info.ObjectCount));238239ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,240"%u Control Methods found\n%u Op Regions found\n",241Info.MethodCount, Info.OpRegionCount));242243return_ACPI_STATUS (AE_OK);244}245246247/*******************************************************************************248*249* FUNCTION: AcpiNsInitializeDevices250*251* PARAMETERS: None252*253* RETURN: ACPI_STATUS254*255* DESCRIPTION: Walk the entire namespace and initialize all ACPI devices.256* This means running _INI on all present devices.257*258* Note: We install PCI config space handler on region access,259* not here.260*261******************************************************************************/262263ACPI_STATUS264AcpiNsInitializeDevices (265UINT32 Flags)266{267ACPI_STATUS Status = AE_OK;268ACPI_DEVICE_WALK_INFO Info;269ACPI_HANDLE Handle;270271272ACPI_FUNCTION_TRACE (NsInitializeDevices);273274275if (!(Flags & ACPI_NO_DEVICE_INIT))276{277ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,278"[Init] Initializing ACPI Devices\n"));279280/* Init counters */281282Info.DeviceCount = 0;283Info.Num_STA = 0;284Info.Num_INI = 0;285286ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,287"Initializing Device/Processor/Thermal objects "288"and executing _INI/_STA methods:\n"));289290/* Tree analysis: find all subtrees that contain _INI methods */291292Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,293ACPI_UINT32_MAX, FALSE, AcpiNsFindIniMethods, NULL, &Info, NULL);294if (ACPI_FAILURE (Status))295{296goto ErrorExit;297}298299/* Allocate the evaluation information block */300301Info.EvaluateInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));302if (!Info.EvaluateInfo)303{304Status = AE_NO_MEMORY;305goto ErrorExit;306}307308/*309* Execute the "global" _INI method that may appear at the root.310* This support is provided for Windows compatibility (Vista+) and311* is not part of the ACPI specification.312*/313Info.EvaluateInfo->PrefixNode = AcpiGbl_RootNode;314Info.EvaluateInfo->RelativePathname = METHOD_NAME__INI;315Info.EvaluateInfo->Parameters = NULL;316Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE;317318Status = AcpiNsEvaluate (Info.EvaluateInfo);319if (ACPI_SUCCESS (Status))320{321Info.Num_INI++;322}323324/*325* Execute \_SB._INI.326* There appears to be a strict order requirement for \_SB._INI,327* which should be evaluated before any _REG evaluations.328*/329Status = AcpiGetHandle (NULL, "\\_SB", &Handle);330if (ACPI_SUCCESS (Status))331{332memset (Info.EvaluateInfo, 0, sizeof (ACPI_EVALUATE_INFO));333Info.EvaluateInfo->PrefixNode = Handle;334Info.EvaluateInfo->RelativePathname = METHOD_NAME__INI;335Info.EvaluateInfo->Parameters = NULL;336Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE;337338Status = AcpiNsEvaluate (Info.EvaluateInfo);339if (ACPI_SUCCESS (Status))340{341Info.Num_INI++;342}343}344}345346/*347* Run all _REG methods348*349* Note: Any objects accessed by the _REG methods will be automatically350* initialized, even if they contain executable AML (see the call to351* AcpiNsInitializeObjects below).352*353* Note: According to the ACPI specification, we actually needn't execute354* _REG for SystemMemory/SystemIo operation regions, but for PCI_Config355* operation regions, it is required to evaluate _REG for those on a PCI356* root bus that doesn't contain _BBN object. So this code is kept here357* in order not to break things.358*/359if (!(Flags & ACPI_NO_ADDRESS_SPACE_INIT))360{361ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,362"[Init] Executing _REG OpRegion methods\n"));363364Status = AcpiEvInitializeOpRegions ();365if (ACPI_FAILURE (Status))366{367goto ErrorExit;368}369}370371if (!(Flags & ACPI_NO_DEVICE_INIT))372{373/* Walk namespace to execute all _INIs on present devices */374375Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,376ACPI_UINT32_MAX, FALSE, AcpiNsInitOneDevice, NULL, &Info, NULL);377378/*379* Any _OSI requests should be completed by now. If the BIOS has380* requested any Windows OSI strings, we will always truncate381* I/O addresses to 16 bits -- for Windows compatibility.382*/383if (AcpiGbl_OsiData >= ACPI_OSI_WIN_2000)384{385AcpiGbl_TruncateIoAddresses = TRUE;386}387388ACPI_FREE (Info.EvaluateInfo);389if (ACPI_FAILURE (Status))390{391goto ErrorExit;392}393394ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,395" Executed %u _INI methods requiring %u _STA executions "396"(examined %u objects)\n",397Info.Num_INI, Info.Num_STA, Info.DeviceCount));398}399400return_ACPI_STATUS (Status);401402403ErrorExit:404ACPI_EXCEPTION ((AE_INFO, Status, "During device initialization"));405return_ACPI_STATUS (Status);406}407408409/*******************************************************************************410*411* FUNCTION: AcpiNsInitOnePackage412*413* PARAMETERS: ObjHandle - Node414* Level - Current nesting level415* Context - Not used416* ReturnValue - Not used417*418* RETURN: Status419*420* DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every package421* within the namespace. Used during dynamic load of an SSDT.422*423******************************************************************************/424425ACPI_STATUS426AcpiNsInitOnePackage (427ACPI_HANDLE ObjHandle,428UINT32 Level,429void *Context,430void **ReturnValue)431{432ACPI_STATUS Status;433ACPI_OPERAND_OBJECT *ObjDesc;434ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;435436437ObjDesc = AcpiNsGetAttachedObject (Node);438if (!ObjDesc)439{440return (AE_OK);441}442443/* Exit if package is already initialized */444445if (ObjDesc->Package.Flags & AOPOBJ_DATA_VALID)446{447return (AE_OK);448}449450Status = AcpiDsGetPackageArguments (ObjDesc);451if (ACPI_FAILURE (Status))452{453return (AE_OK);454}455456Status = AcpiUtWalkPackageTree (ObjDesc, NULL, AcpiDsInitPackageElement,457NULL);458if (ACPI_FAILURE (Status))459{460return (AE_OK);461}462463ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID;464return (AE_OK);465}466467468/*******************************************************************************469*470* FUNCTION: AcpiNsInitOneObject471*472* PARAMETERS: ObjHandle - Node473* Level - Current nesting level474* Context - Points to a init info struct475* ReturnValue - Not used476*477* RETURN: Status478*479* DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every object480* within the namespace.481*482* Currently, the only objects that require initialization are:483* 1) Methods484* 2) Op Regions485*486******************************************************************************/487488static ACPI_STATUS489AcpiNsInitOneObject (490ACPI_HANDLE ObjHandle,491UINT32 Level,492void *Context,493void **ReturnValue)494{495ACPI_OBJECT_TYPE Type;496ACPI_STATUS Status = AE_OK;497ACPI_INIT_WALK_INFO *Info = (ACPI_INIT_WALK_INFO *) Context;498ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;499ACPI_OPERAND_OBJECT *ObjDesc;500501502ACPI_FUNCTION_NAME (NsInitOneObject);503504505Info->ObjectCount++;506507/* And even then, we are only interested in a few object types */508509Type = AcpiNsGetType (ObjHandle);510ObjDesc = AcpiNsGetAttachedObject (Node);511if (!ObjDesc)512{513return (AE_OK);514}515516/* Increment counters for object types we are looking for */517518switch (Type)519{520case ACPI_TYPE_REGION:521522Info->OpRegionCount++;523break;524525case ACPI_TYPE_BUFFER_FIELD:526527Info->FieldCount++;528break;529530case ACPI_TYPE_LOCAL_BANK_FIELD:531532Info->FieldCount++;533break;534535case ACPI_TYPE_BUFFER:536537Info->BufferCount++;538break;539540case ACPI_TYPE_PACKAGE:541542Info->PackageCount++;543break;544545default:546547/* No init required, just exit now */548549return (AE_OK);550}551552/* If the object is already initialized, nothing else to do */553554if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)555{556return (AE_OK);557}558559/* Must lock the interpreter before executing AML code */560561AcpiExEnterInterpreter ();562563/*564* Only initialization of Package objects can be deferred, in order565* to support forward references.566*/567switch (Type)568{569case ACPI_TYPE_LOCAL_BANK_FIELD:570571/* TBD: BankFields do not require deferred init, remove this code */572573Info->FieldInit++;574Status = AcpiDsGetBankFieldArguments (ObjDesc);575break;576577case ACPI_TYPE_PACKAGE:578579/* Complete the initialization/resolution of the package object */580581Info->PackageInit++;582Status = AcpiNsInitOnePackage (ObjHandle, Level, NULL, NULL);583break;584585default:586587/* No other types should get here */588589Status = AE_TYPE;590ACPI_EXCEPTION ((AE_INFO, Status,591"Opcode is not deferred [%4.4s] (%s)",592AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Type)));593break;594}595596if (ACPI_FAILURE (Status))597{598ACPI_EXCEPTION ((AE_INFO, Status,599"Could not execute arguments for [%4.4s] (%s)",600AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Type)));601}602603/*604* We ignore errors from above, and always return OK, since we don't want605* to abort the walk on any single error.606*/607AcpiExExitInterpreter ();608return (AE_OK);609}610611612/*******************************************************************************613*614* FUNCTION: AcpiNsFindIniMethods615*616* PARAMETERS: ACPI_WALK_CALLBACK617*618* RETURN: ACPI_STATUS619*620* DESCRIPTION: Called during namespace walk. Finds objects named _INI under621* device/processor/thermal objects, and marks the entire subtree622* with a SUBTREE_HAS_INI flag. This flag is used during the623* subsequent device initialization walk to avoid entire subtrees624* that do not contain an _INI.625*626******************************************************************************/627628static ACPI_STATUS629AcpiNsFindIniMethods (630ACPI_HANDLE ObjHandle,631UINT32 NestingLevel,632void *Context,633void **ReturnValue)634{635ACPI_DEVICE_WALK_INFO *Info = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context);636ACPI_NAMESPACE_NODE *Node;637ACPI_NAMESPACE_NODE *ParentNode;638639640/* Keep count of device/processor/thermal objects */641642Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);643if ((Node->Type == ACPI_TYPE_DEVICE) ||644(Node->Type == ACPI_TYPE_PROCESSOR) ||645(Node->Type == ACPI_TYPE_THERMAL))646{647Info->DeviceCount++;648return (AE_OK);649}650651/* We are only looking for methods named _INI */652653if (!ACPI_COMPARE_NAMESEG (Node->Name.Ascii, METHOD_NAME__INI))654{655return (AE_OK);656}657658/*659* The only _INI methods that we care about are those that are660* present under Device, Processor, and Thermal objects.661*/662ParentNode = Node->Parent;663switch (ParentNode->Type)664{665case ACPI_TYPE_DEVICE:666case ACPI_TYPE_PROCESSOR:667case ACPI_TYPE_THERMAL:668669/* Mark parent and bubble up the INI present flag to the root */670671while (ParentNode)672{673ParentNode->Flags |= ANOBJ_SUBTREE_HAS_INI;674ParentNode = ParentNode->Parent;675}676break;677678default:679680break;681}682683return (AE_OK);684}685686687/*******************************************************************************688*689* FUNCTION: AcpiNsInitOneDevice690*691* PARAMETERS: ACPI_WALK_CALLBACK692*693* RETURN: ACPI_STATUS694*695* DESCRIPTION: This is called once per device soon after ACPI is enabled696* to initialize each device. It determines if the device is697* present, and if so, calls _INI.698*699******************************************************************************/700701static ACPI_STATUS702AcpiNsInitOneDevice (703ACPI_HANDLE ObjHandle,704UINT32 NestingLevel,705void *Context,706void **ReturnValue)707{708ACPI_DEVICE_WALK_INFO *WalkInfo = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context);709ACPI_EVALUATE_INFO *Info = WalkInfo->EvaluateInfo;710UINT32 Flags;711ACPI_STATUS Status;712ACPI_NAMESPACE_NODE *DeviceNode;713714715ACPI_FUNCTION_TRACE (NsInitOneDevice);716717718/* We are interested in Devices, Processors and ThermalZones only */719720DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);721if ((DeviceNode->Type != ACPI_TYPE_DEVICE) &&722(DeviceNode->Type != ACPI_TYPE_PROCESSOR) &&723(DeviceNode->Type != ACPI_TYPE_THERMAL))724{725return_ACPI_STATUS (AE_OK);726}727728/*729* Because of an earlier namespace analysis, all subtrees that contain an730* _INI method are tagged.731*732* If this device subtree does not contain any _INI methods, we733* can exit now and stop traversing this entire subtree.734*/735if (!(DeviceNode->Flags & ANOBJ_SUBTREE_HAS_INI))736{737return_ACPI_STATUS (AE_CTRL_DEPTH);738}739740/*741* Run _STA to determine if this device is present and functioning. We742* must know this information for two important reasons (from ACPI spec):743*744* 1) We can only run _INI if the device is present.745* 2) We must abort the device tree walk on this subtree if the device is746* not present and is not functional (we will not examine the children)747*748* The _STA method is not required to be present under the device, we749* assume the device is present if _STA does not exist.750*/751ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (752ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__STA));753754Status = AcpiUtExecute_STA (DeviceNode, &Flags);755if (ACPI_FAILURE (Status))756{757/* Ignore error and move on to next device */758759return_ACPI_STATUS (AE_OK);760}761762/*763* Flags == -1 means that _STA was not found. In this case, we assume that764* the device is both present and functional.765*766* From the ACPI spec, description of _STA:767*768* "If a device object (including the processor object) does not have an769* _STA object, then OSPM assumes that all of the above bits are set (in770* other words, the device is present, ..., and functioning)"771*/772if (Flags != ACPI_UINT32_MAX)773{774WalkInfo->Num_STA++;775}776777/*778* Examine the PRESENT and FUNCTIONING status bits779*780* Note: ACPI spec does not seem to specify behavior for the present but781* not functioning case, so we assume functioning if present.782*/783if (!(Flags & ACPI_STA_DEVICE_PRESENT))784{785/* Device is not present, we must examine the Functioning bit */786787if (Flags & ACPI_STA_DEVICE_FUNCTIONING)788{789/*790* Device is not present but is "functioning". In this case,791* we will not run _INI, but we continue to examine the children792* of this device.793*794* From the ACPI spec, description of _STA: (Note - no mention795* of whether to run _INI or not on the device in question)796*797* "_STA may return bit 0 clear (not present) with bit 3 set798* (device is functional). This case is used to indicate a valid799* device for which no device driver should be loaded (for example,800* a bridge device.) Children of this device may be present and801* valid. OSPM should continue enumeration below a device whose802* _STA returns this bit combination"803*/804return_ACPI_STATUS (AE_OK);805}806else807{808/*809* Device is not present and is not functioning. We must abort the810* walk of this subtree immediately -- don't look at the children811* of such a device.812*813* From the ACPI spec, description of _INI:814*815* "If the _STA method indicates that the device is not present,816* OSPM will not run the _INI and will not examine the children817* of the device for _INI methods"818*/819return_ACPI_STATUS (AE_CTRL_DEPTH);820}821}822823/*824* The device is present or is assumed present if no _STA exists.825* Run the _INI if it exists (not required to exist)826*827* Note: We know there is an _INI within this subtree, but it may not be828* under this particular device, it may be lower in the branch.829*/830if (!ACPI_COMPARE_NAMESEG (DeviceNode->Name.Ascii, "_SB_") ||831DeviceNode->Parent != AcpiGbl_RootNode)832{833ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (834ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__INI));835836memset (Info, 0, sizeof (ACPI_EVALUATE_INFO));837Info->PrefixNode = DeviceNode;838Info->RelativePathname = METHOD_NAME__INI;839Info->Parameters = NULL;840Info->Flags = ACPI_IGNORE_RETURN_VALUE;841842Status = AcpiNsEvaluate (Info);843if (ACPI_SUCCESS (Status))844{845WalkInfo->Num_INI++;846}847848#ifdef ACPI_DEBUG_OUTPUT849else if (Status != AE_NOT_FOUND)850{851/* Ignore error and move on to next device */852853char *ScopeName = AcpiNsGetNormalizedPathname (DeviceNode, TRUE);854855ACPI_EXCEPTION ((AE_INFO, Status, "during %s._INI execution",856ScopeName));857ACPI_FREE (ScopeName);858}859#endif860}861862/* Ignore errors from above */863864Status = AE_OK;865866/*867* The _INI method has been run if present; call the Global Initialization868* Handler for this device.869*/870if (AcpiGbl_InitHandler)871{872Status = AcpiGbl_InitHandler (DeviceNode, ACPI_INIT_DEVICE_INI);873}874875return_ACPI_STATUS (Status);876}877878879