nsinit.c revision 197104
167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: nsinit - namespace initialization 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 767754Smsmith/****************************************************************************** 867754Smsmith * 967754Smsmith * 1. Copyright Notice 1067754Smsmith * 11193267Sjkim * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 1270243Smsmith * All rights reserved. 1367754Smsmith * 1467754Smsmith * 2. License 1567754Smsmith * 1667754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property 1767754Smsmith * rights. You may have additional license terms from the party that provided 1867754Smsmith * you this software, covering your right to use that party's intellectual 1967754Smsmith * property rights. 2067754Smsmith * 2167754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2267754Smsmith * copy of the source code appearing in this file ("Covered Code") an 2367754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2467754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy, 2567754Smsmith * make derivatives, distribute, use and display any portion of the Covered 2667754Smsmith * Code in any form, with the right to sublicense such rights; and 2767754Smsmith * 2867754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 2967754Smsmith * license (with the right to sublicense), under only those claims of Intel 3067754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell, 3167754Smsmith * offer to sell, and import the Covered Code and derivative works thereof 3267754Smsmith * solely to the minimum extent necessary to exercise the above copyright 3367754Smsmith * license, and in no event shall the patent license extend to any additions 3467754Smsmith * to or modifications of the Original Intel Code. No other license or right 3567754Smsmith * is granted directly or by implication, estoppel or otherwise; 3667754Smsmith * 3767754Smsmith * The above copyright and patent license is granted only if the following 3867754Smsmith * conditions are met: 3967754Smsmith * 4067754Smsmith * 3. Conditions 4167754Smsmith * 4267754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4367754Smsmith * Redistribution of source code of any substantial portion of the Covered 4467754Smsmith * Code or modification with rights to further distribute source must include 4567754Smsmith * the above Copyright Notice, the above License, this list of Conditions, 4667754Smsmith * and the following Disclaimer and Export Compliance provision. In addition, 4767754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to 4867754Smsmith * contain a file documenting the changes Licensee made to create that Covered 4967754Smsmith * Code and the date of any change. Licensee must include in that file the 5067754Smsmith * documentation of any changes made by any predecessor Licensee. Licensee 5167754Smsmith * must include a prominent statement that the modification is derived, 5267754Smsmith * directly or indirectly, from Original Intel Code. 5367754Smsmith * 5467754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5567754Smsmith * Redistribution of source code of any substantial portion of the Covered 5667754Smsmith * Code or modification without rights to further distribute source must 5767754Smsmith * include the following Disclaimer and Export Compliance provision in the 5867754Smsmith * documentation and/or other materials provided with distribution. In 5967754Smsmith * addition, Licensee may not authorize further sublicense of source of any 6067754Smsmith * portion of the Covered Code, and must include terms to the effect that the 6167754Smsmith * license from Licensee to its licensee is limited to the intellectual 6267754Smsmith * property embodied in the software Licensee provides to its licensee, and 6367754Smsmith * not to intellectual property embodied in modifications its licensee may 6467754Smsmith * make. 6567754Smsmith * 6667754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any 6767754Smsmith * substantial portion of the Covered Code or modification must reproduce the 6867754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance 6967754Smsmith * provision in the documentation and/or other materials provided with the 7067754Smsmith * distribution. 7167754Smsmith * 7267754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original 7367754Smsmith * Intel Code. 7467754Smsmith * 7567754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7667754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or 7767754Smsmith * other dealings in products derived from or relating to the Covered Code 7867754Smsmith * without prior written authorization from Intel. 7967754Smsmith * 8067754Smsmith * 4. Disclaimer and Export Compliance 8167754Smsmith * 8267754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8367754Smsmith * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8467754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8567754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8667754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8767754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 8867754Smsmith * PARTICULAR PURPOSE. 8967754Smsmith * 9067754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9167754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9267754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9367754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9467754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9567754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9667754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9767754Smsmith * LIMITED REMEDY. 9867754Smsmith * 9967754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this 10067754Smsmith * software or system incorporating such software without first obtaining any 10167754Smsmith * required license or other approval from the U. S. Department of Commerce or 10267754Smsmith * any other agency or department of the United States Government. In the 10367754Smsmith * event Licensee exports any such software from the United States or 10467754Smsmith * re-exports any such software from a foreign destination, Licensee shall 10567754Smsmith * ensure that the distribution and export/re-export of the software is in 10667754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the 10767754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor 10867754Smsmith * any of its subsidiaries will export/re-export any technical data, process, 10967754Smsmith * software, or service, directly or indirectly, to any country for which the 11067754Smsmith * United States government or any agency thereof requires an export license, 11167754Smsmith * other governmental approval, or letter of assurance, without first obtaining 11267754Smsmith * such license, approval or letter. 11367754Smsmith * 11467754Smsmith *****************************************************************************/ 11567754Smsmith 11667754Smsmith 11767754Smsmith#define __NSXFINIT_C__ 11867754Smsmith 119193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 120193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 121193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 122193341Sjkim#include <contrib/dev/acpica/include/acdispat.h> 123193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 12467754Smsmith 12577424Smsmith#define _COMPONENT ACPI_NAMESPACE 12691116Smsmith ACPI_MODULE_NAME ("nsinit") 12767754Smsmith 128151937Sjkim/* Local prototypes */ 12967754Smsmith 130151937Sjkimstatic ACPI_STATUS 131151937SjkimAcpiNsInitOneObject ( 132151937Sjkim ACPI_HANDLE ObjHandle, 133151937Sjkim UINT32 Level, 134151937Sjkim void *Context, 135151937Sjkim void **ReturnValue); 136151937Sjkim 137151937Sjkimstatic ACPI_STATUS 138151937SjkimAcpiNsInitOneDevice ( 139151937Sjkim ACPI_HANDLE ObjHandle, 140151937Sjkim UINT32 NestingLevel, 141151937Sjkim void *Context, 142151937Sjkim void **ReturnValue); 143151937Sjkim 144167802Sjkimstatic ACPI_STATUS 145167802SjkimAcpiNsFindIniMethods ( 146167802Sjkim ACPI_HANDLE ObjHandle, 147167802Sjkim UINT32 NestingLevel, 148167802Sjkim void *Context, 149167802Sjkim void **ReturnValue); 150151937Sjkim 151167802Sjkim 15267754Smsmith/******************************************************************************* 15367754Smsmith * 15467754Smsmith * FUNCTION: AcpiNsInitializeObjects 15567754Smsmith * 15667754Smsmith * PARAMETERS: None 15767754Smsmith * 15867754Smsmith * RETURN: Status 15967754Smsmith * 16067754Smsmith * DESCRIPTION: Walk the entire namespace and perform any necessary 16167754Smsmith * initialization on the objects found therein 16267754Smsmith * 16367754Smsmith ******************************************************************************/ 16467754Smsmith 16567754SmsmithACPI_STATUS 16667754SmsmithAcpiNsInitializeObjects ( 16767754Smsmith void) 16867754Smsmith{ 16967754Smsmith ACPI_STATUS Status; 17067754Smsmith ACPI_INIT_WALK_INFO Info; 17167754Smsmith 17267754Smsmith 173167802Sjkim ACPI_FUNCTION_TRACE (NsInitializeObjects); 17467754Smsmith 17567754Smsmith 17682367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 17782367Smsmith "**** Starting initialization of namespace objects ****\n")); 178138287Smarks ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 179138287Smarks "Completing Region/Field/Buffer/Package initialization:")); 18067754Smsmith 18199146Siwasaki /* Set all init info to zero */ 18267754Smsmith 18399146Siwasaki ACPI_MEMSET (&Info, 0, sizeof (ACPI_INIT_WALK_INFO)); 18467754Smsmith 18567754Smsmith /* Walk entire namespace from the supplied root */ 18667754Smsmith 18767754Smsmith Status = AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 18867754Smsmith ACPI_UINT32_MAX, AcpiNsInitOneObject, 18967754Smsmith &Info, NULL); 19067754Smsmith if (ACPI_FAILURE (Status)) 19167754Smsmith { 192167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace")); 19367754Smsmith } 19467754Smsmith 195114237Snjl ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 196193267Sjkim "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd " 197193267Sjkim "Buffers %hd/%hd Packages (%hd nodes)\n", 198102550Siwasaki Info.OpRegionInit, Info.OpRegionCount, 199102550Siwasaki Info.FieldInit, Info.FieldCount, 200102550Siwasaki Info.BufferInit, Info.BufferCount, 20199146Siwasaki Info.PackageInit, Info.PackageCount, Info.ObjectCount)); 202114237Snjl 20382367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 20499679Siwasaki "%hd Control Methods found\n", Info.MethodCount)); 20582367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 20699679Siwasaki "%hd Op Regions found\n", Info.OpRegionCount)); 20767754Smsmith 20867754Smsmith return_ACPI_STATUS (AE_OK); 20967754Smsmith} 21067754Smsmith 21167754Smsmith 21277424Smsmith/******************************************************************************* 21367754Smsmith * 21467754Smsmith * FUNCTION: AcpiNsInitializeDevices 21567754Smsmith * 21667754Smsmith * PARAMETERS: None 21767754Smsmith * 21867754Smsmith * RETURN: ACPI_STATUS 21967754Smsmith * 22067754Smsmith * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices. 22167754Smsmith * This means running _INI on all present devices. 22267754Smsmith * 22377424Smsmith * Note: We install PCI config space handler on region access, 22477424Smsmith * not here. 22567754Smsmith * 22677424Smsmith ******************************************************************************/ 22767754Smsmith 22867754SmsmithACPI_STATUS 22967754SmsmithAcpiNsInitializeDevices ( 23073561Smsmith void) 23167754Smsmith{ 23267754Smsmith ACPI_STATUS Status; 23367754Smsmith ACPI_DEVICE_WALK_INFO Info; 23467754Smsmith 23567754Smsmith 236167802Sjkim ACPI_FUNCTION_TRACE (NsInitializeDevices); 23767754Smsmith 23867754Smsmith 23999146Siwasaki /* Init counters */ 24099146Siwasaki 24167754Smsmith Info.DeviceCount = 0; 24267754Smsmith Info.Num_STA = 0; 24367754Smsmith Info.Num_INI = 0; 24467754Smsmith 245138287Smarks ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 246193267Sjkim "Initializing Device/Processor/Thermal objects " 247193267Sjkim "by executing _INI methods:")); 24867754Smsmith 249167802Sjkim /* Tree analysis: find all subtrees that contain _INI methods */ 250167802Sjkim 251167802Sjkim Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 252167802Sjkim ACPI_UINT32_MAX, FALSE, AcpiNsFindIniMethods, &Info, NULL); 253123315Snjl if (ACPI_FAILURE (Status)) 254123315Snjl { 255167802Sjkim goto ErrorExit; 256123315Snjl } 25767754Smsmith 258167802Sjkim /* Allocate the evaluation information block */ 25967754Smsmith 260167802Sjkim Info.EvaluateInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 261167802Sjkim if (!Info.EvaluateInfo) 262167802Sjkim { 263167802Sjkim Status = AE_NO_MEMORY; 264167802Sjkim goto ErrorExit; 265167802Sjkim } 266167802Sjkim 267197104Sjkim /* 268197104Sjkim * Execute the "global" _INI method that may appear at the root. This 269197104Sjkim * support is provided for Windows compatibility (Vista+) and is not 270197104Sjkim * part of the ACPI specification. 271197104Sjkim */ 272197104Sjkim Info.EvaluateInfo->PrefixNode = AcpiGbl_RootNode; 273197104Sjkim Info.EvaluateInfo->Pathname = METHOD_NAME__INI; 274197104Sjkim Info.EvaluateInfo->Parameters = NULL; 275197104Sjkim Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE; 276197104Sjkim 277197104Sjkim Status = AcpiNsEvaluate (Info.EvaluateInfo); 278197104Sjkim if (ACPI_SUCCESS (Status)) 279197104Sjkim { 280197104Sjkim Info.Num_INI++; 281197104Sjkim } 282197104Sjkim 283167802Sjkim /* Walk namespace to execute all _INIs on present devices */ 284167802Sjkim 285123315Snjl Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 286167802Sjkim ACPI_UINT32_MAX, FALSE, AcpiNsInitOneDevice, &Info, NULL); 287123315Snjl 288167802Sjkim ACPI_FREE (Info.EvaluateInfo); 28967754Smsmith if (ACPI_FAILURE (Status)) 29067754Smsmith { 291167802Sjkim goto ErrorExit; 29267754Smsmith } 29367754Smsmith 294114237Snjl ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 295193267Sjkim "\nExecuted %hd _INI methods requiring %hd _STA executions " 296193267Sjkim "(examined %hd objects)\n", 297167802Sjkim Info.Num_INI, Info.Num_STA, Info.DeviceCount)); 29867754Smsmith 29967754Smsmith return_ACPI_STATUS (Status); 300167802Sjkim 301167802Sjkim 302167802SjkimErrorExit: 303167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, "During device initialization")); 304167802Sjkim return_ACPI_STATUS (Status); 30567754Smsmith} 30667754Smsmith 30767754Smsmith 30867754Smsmith/******************************************************************************* 30967754Smsmith * 31067754Smsmith * FUNCTION: AcpiNsInitOneObject 31167754Smsmith * 31267754Smsmith * PARAMETERS: ObjHandle - Node 31367754Smsmith * Level - Current nesting level 31467754Smsmith * Context - Points to a init info struct 31567754Smsmith * ReturnValue - Not used 31667754Smsmith * 31767754Smsmith * RETURN: Status 31867754Smsmith * 31967754Smsmith * DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every object 32067754Smsmith * within the namespace. 32167754Smsmith * 32267754Smsmith * Currently, the only objects that require initialization are: 32367754Smsmith * 1) Methods 32467754Smsmith * 2) Op Regions 32567754Smsmith * 32667754Smsmith ******************************************************************************/ 32767754Smsmith 328151937Sjkimstatic ACPI_STATUS 32967754SmsmithAcpiNsInitOneObject ( 33067754Smsmith ACPI_HANDLE ObjHandle, 33167754Smsmith UINT32 Level, 33267754Smsmith void *Context, 33367754Smsmith void **ReturnValue) 33467754Smsmith{ 33591116Smsmith ACPI_OBJECT_TYPE Type; 336167802Sjkim ACPI_STATUS Status = AE_OK; 33767754Smsmith ACPI_INIT_WALK_INFO *Info = (ACPI_INIT_WALK_INFO *) Context; 33867754Smsmith ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 33967754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 34067754Smsmith 34167754Smsmith 342167802Sjkim ACPI_FUNCTION_NAME (NsInitOneObject); 34382367Smsmith 34482367Smsmith 34567754Smsmith Info->ObjectCount++; 34667754Smsmith 34767754Smsmith /* And even then, we are only interested in a few object types */ 34867754Smsmith 34967754Smsmith Type = AcpiNsGetType (ObjHandle); 35087031Smsmith ObjDesc = AcpiNsGetAttachedObject (Node); 35167754Smsmith if (!ObjDesc) 35267754Smsmith { 35367754Smsmith return (AE_OK); 35467754Smsmith } 35567754Smsmith 35699146Siwasaki /* Increment counters for object types we are looking for */ 35799146Siwasaki 35899146Siwasaki switch (Type) 35980062Smsmith { 36099146Siwasaki case ACPI_TYPE_REGION: 36199146Siwasaki Info->OpRegionCount++; 36299146Siwasaki break; 36399146Siwasaki 36499146Siwasaki case ACPI_TYPE_BUFFER_FIELD: 36599146Siwasaki Info->FieldCount++; 36699146Siwasaki break; 36799146Siwasaki 368193267Sjkim case ACPI_TYPE_LOCAL_BANK_FIELD: 369193267Sjkim Info->FieldCount++; 370193267Sjkim break; 371193267Sjkim 37299146Siwasaki case ACPI_TYPE_BUFFER: 37399146Siwasaki Info->BufferCount++; 37499146Siwasaki break; 37599146Siwasaki 37699146Siwasaki case ACPI_TYPE_PACKAGE: 37799146Siwasaki Info->PackageCount++; 37899146Siwasaki break; 37999146Siwasaki 38099146Siwasaki default: 38199146Siwasaki 38299146Siwasaki /* No init required, just exit now */ 38380062Smsmith return (AE_OK); 38480062Smsmith } 38580062Smsmith 386193267Sjkim /* If the object is already initialized, nothing else to do */ 387193267Sjkim 38899146Siwasaki if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) 38999146Siwasaki { 39099146Siwasaki return (AE_OK); 39199146Siwasaki } 39280062Smsmith 393193267Sjkim /* Must lock the interpreter before executing AML code */ 394193267Sjkim 395167802Sjkim AcpiExEnterInterpreter (); 39680062Smsmith 39799146Siwasaki /* 398138287Smarks * Each of these types can contain executable AML code within the 399138287Smarks * declaration. 40099146Siwasaki */ 40167754Smsmith switch (Type) 40267754Smsmith { 40367754Smsmith case ACPI_TYPE_REGION: 40467754Smsmith 40567754Smsmith Info->OpRegionInit++; 40667754Smsmith Status = AcpiDsGetRegionArguments (ObjDesc); 40767754Smsmith break; 40867754Smsmith 40977424Smsmith case ACPI_TYPE_BUFFER_FIELD: 41067754Smsmith 41167754Smsmith Info->FieldInit++; 41277424Smsmith Status = AcpiDsGetBufferFieldArguments (ObjDesc); 41399146Siwasaki break; 41467754Smsmith 415193267Sjkim case ACPI_TYPE_LOCAL_BANK_FIELD: 416193267Sjkim 417193267Sjkim Info->FieldInit++; 418193267Sjkim Status = AcpiDsGetBankFieldArguments (ObjDesc); 419193267Sjkim break; 420193267Sjkim 42199146Siwasaki case ACPI_TYPE_BUFFER: 42299146Siwasaki 42399146Siwasaki Info->BufferInit++; 42499146Siwasaki Status = AcpiDsGetBufferArguments (ObjDesc); 42567754Smsmith break; 42667754Smsmith 42799146Siwasaki case ACPI_TYPE_PACKAGE: 42899146Siwasaki 42999146Siwasaki Info->PackageInit++; 43099146Siwasaki Status = AcpiDsGetPackageArguments (ObjDesc); 43167754Smsmith break; 43299679Siwasaki 43399679Siwasaki default: 43499679Siwasaki /* No other types can get here */ 43599679Siwasaki break; 43667754Smsmith } 43767754Smsmith 43899146Siwasaki if (ACPI_FAILURE (Status)) 43999146Siwasaki { 440167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 441167802Sjkim "Could not execute arguments for [%4.4s] (%s)", 442167802Sjkim AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Type))); 44399146Siwasaki } 44480062Smsmith 445138287Smarks /* 446138287Smarks * Print a dot for each object unless we are going to print the entire 447138287Smarks * pathname 448138287Smarks */ 449114237Snjl if (!(AcpiDbgLevel & ACPI_LV_INIT_NAMES)) 45099146Siwasaki { 451114237Snjl ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, ".")); 45299146Siwasaki } 45399146Siwasaki 45467754Smsmith /* 455138287Smarks * We ignore errors from above, and always return OK, since we don't want 456138287Smarks * to abort the walk on any single error. 45767754Smsmith */ 45880062Smsmith AcpiExExitInterpreter (); 45967754Smsmith return (AE_OK); 46067754Smsmith} 46167754Smsmith 46267754Smsmith 46377424Smsmith/******************************************************************************* 46467754Smsmith * 465167802Sjkim * FUNCTION: AcpiNsFindIniMethods 466167802Sjkim * 467167802Sjkim * PARAMETERS: ACPI_WALK_CALLBACK 468167802Sjkim * 469167802Sjkim * RETURN: ACPI_STATUS 470167802Sjkim * 471167802Sjkim * DESCRIPTION: Called during namespace walk. Finds objects named _INI under 472167802Sjkim * device/processor/thermal objects, and marks the entire subtree 473167802Sjkim * with a SUBTREE_HAS_INI flag. This flag is used during the 474167802Sjkim * subsequent device initialization walk to avoid entire subtrees 475167802Sjkim * that do not contain an _INI. 476167802Sjkim * 477167802Sjkim ******************************************************************************/ 478167802Sjkim 479167802Sjkimstatic ACPI_STATUS 480167802SjkimAcpiNsFindIniMethods ( 481167802Sjkim ACPI_HANDLE ObjHandle, 482167802Sjkim UINT32 NestingLevel, 483167802Sjkim void *Context, 484167802Sjkim void **ReturnValue) 485167802Sjkim{ 486167802Sjkim ACPI_DEVICE_WALK_INFO *Info = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context); 487167802Sjkim ACPI_NAMESPACE_NODE *Node; 488167802Sjkim ACPI_NAMESPACE_NODE *ParentNode; 489167802Sjkim 490167802Sjkim 491167802Sjkim /* Keep count of device/processor/thermal objects */ 492167802Sjkim 493167802Sjkim Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); 494167802Sjkim if ((Node->Type == ACPI_TYPE_DEVICE) || 495167802Sjkim (Node->Type == ACPI_TYPE_PROCESSOR) || 496167802Sjkim (Node->Type == ACPI_TYPE_THERMAL)) 497167802Sjkim { 498167802Sjkim Info->DeviceCount++; 499167802Sjkim return (AE_OK); 500167802Sjkim } 501167802Sjkim 502167802Sjkim /* We are only looking for methods named _INI */ 503167802Sjkim 504167802Sjkim if (!ACPI_COMPARE_NAME (Node->Name.Ascii, METHOD_NAME__INI)) 505167802Sjkim { 506167802Sjkim return (AE_OK); 507167802Sjkim } 508167802Sjkim 509167802Sjkim /* 510167802Sjkim * The only _INI methods that we care about are those that are 511167802Sjkim * present under Device, Processor, and Thermal objects. 512167802Sjkim */ 513167802Sjkim ParentNode = AcpiNsGetParentNode (Node); 514167802Sjkim switch (ParentNode->Type) 515167802Sjkim { 516167802Sjkim case ACPI_TYPE_DEVICE: 517167802Sjkim case ACPI_TYPE_PROCESSOR: 518167802Sjkim case ACPI_TYPE_THERMAL: 519167802Sjkim 520167802Sjkim /* Mark parent and bubble up the INI present flag to the root */ 521167802Sjkim 522167802Sjkim while (ParentNode) 523167802Sjkim { 524167802Sjkim ParentNode->Flags |= ANOBJ_SUBTREE_HAS_INI; 525167802Sjkim ParentNode = AcpiNsGetParentNode (ParentNode); 526167802Sjkim } 527167802Sjkim break; 528167802Sjkim 529167802Sjkim default: 530167802Sjkim break; 531167802Sjkim } 532167802Sjkim 533167802Sjkim return (AE_OK); 534167802Sjkim} 535167802Sjkim 536167802Sjkim 537167802Sjkim/******************************************************************************* 538167802Sjkim * 53967754Smsmith * FUNCTION: AcpiNsInitOneDevice 54067754Smsmith * 54177424Smsmith * PARAMETERS: ACPI_WALK_CALLBACK 54267754Smsmith * 54367754Smsmith * RETURN: ACPI_STATUS 54467754Smsmith * 54567754Smsmith * DESCRIPTION: This is called once per device soon after ACPI is enabled 54667754Smsmith * to initialize each device. It determines if the device is 54767754Smsmith * present, and if so, calls _INI. 54867754Smsmith * 54977424Smsmith ******************************************************************************/ 55067754Smsmith 551151937Sjkimstatic ACPI_STATUS 55267754SmsmithAcpiNsInitOneDevice ( 55367754Smsmith ACPI_HANDLE ObjHandle, 55467754Smsmith UINT32 NestingLevel, 55567754Smsmith void *Context, 55667754Smsmith void **ReturnValue) 55767754Smsmith{ 558167802Sjkim ACPI_DEVICE_WALK_INFO *WalkInfo = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context); 559167802Sjkim ACPI_EVALUATE_INFO *Info = WalkInfo->EvaluateInfo; 560129684Snjl UINT32 Flags; 56167754Smsmith ACPI_STATUS Status; 562167802Sjkim ACPI_NAMESPACE_NODE *DeviceNode; 56367754Smsmith 56467754Smsmith 565167802Sjkim ACPI_FUNCTION_TRACE (NsInitOneDevice); 56667754Smsmith 56767754Smsmith 568167802Sjkim /* We are interested in Devices, Processors and ThermalZones only */ 569129684Snjl 570167802Sjkim DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); 571167802Sjkim if ((DeviceNode->Type != ACPI_TYPE_DEVICE) && 572167802Sjkim (DeviceNode->Type != ACPI_TYPE_PROCESSOR) && 573167802Sjkim (DeviceNode->Type != ACPI_TYPE_THERMAL)) 57473561Smsmith { 575167802Sjkim return_ACPI_STATUS (AE_OK); 57673561Smsmith } 57773561Smsmith 578123315Snjl /* 579167802Sjkim * Because of an earlier namespace analysis, all subtrees that contain an 580167802Sjkim * _INI method are tagged. 581167802Sjkim * 582167802Sjkim * If this device subtree does not contain any _INI methods, we 583167802Sjkim * can exit now and stop traversing this entire subtree. 584123315Snjl */ 585167802Sjkim if (!(DeviceNode->Flags & ANOBJ_SUBTREE_HAS_INI)) 58691116Smsmith { 587167802Sjkim return_ACPI_STATUS (AE_CTRL_DEPTH); 58891116Smsmith } 58967754Smsmith 59067754Smsmith /* 591167802Sjkim * Run _STA to determine if this device is present and functioning. We 592167802Sjkim * must know this information for two important reasons (from ACPI spec): 593167802Sjkim * 594167802Sjkim * 1) We can only run _INI if the device is present. 595167802Sjkim * 2) We must abort the device tree walk on this subtree if the device is 596167802Sjkim * not present and is not functional (we will not examine the children) 597167802Sjkim * 598167802Sjkim * The _STA method is not required to be present under the device, we 599167802Sjkim * assume the device is present if _STA does not exist. 60067754Smsmith */ 601167802Sjkim ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname ( 602167802Sjkim ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__STA)); 603123315Snjl 604167802Sjkim Status = AcpiUtExecute_STA (DeviceNode, &Flags); 60567754Smsmith if (ACPI_FAILURE (Status)) 60667754Smsmith { 607167802Sjkim /* Ignore error and move on to next device */ 60871867Smsmith 609167802Sjkim return_ACPI_STATUS (AE_OK); 610167802Sjkim } 611123315Snjl 612167802Sjkim /* 613167802Sjkim * Flags == -1 means that _STA was not found. In this case, we assume that 614167802Sjkim * the device is both present and functional. 615167802Sjkim * 616167802Sjkim * From the ACPI spec, description of _STA: 617167802Sjkim * 618167802Sjkim * "If a device object (including the processor object) does not have an 619167802Sjkim * _STA object, then OSPM assumes that all of the above bits are set (in 620167802Sjkim * other words, the device is present, ..., and functioning)" 621167802Sjkim */ 622167802Sjkim if (Flags != ACPI_UINT32_MAX) 623167802Sjkim { 624167802Sjkim WalkInfo->Num_STA++; 62567754Smsmith } 626167802Sjkim 627167802Sjkim /* 628167802Sjkim * Examine the PRESENT and FUNCTIONING status bits 629167802Sjkim * 630167802Sjkim * Note: ACPI spec does not seem to specify behavior for the present but 631167802Sjkim * not functioning case, so we assume functioning if present. 632167802Sjkim */ 633167802Sjkim if (!(Flags & ACPI_STA_DEVICE_PRESENT)) 634123315Snjl { 635167802Sjkim /* Device is not present, we must examine the Functioning bit */ 63667754Smsmith 637167802Sjkim if (Flags & ACPI_STA_DEVICE_FUNCTIONING) 638123315Snjl { 639167802Sjkim /* 640167802Sjkim * Device is not present but is "functioning". In this case, 641167802Sjkim * we will not run _INI, but we continue to examine the children 642167802Sjkim * of this device. 643167802Sjkim * 644167802Sjkim * From the ACPI spec, description of _STA: (Note - no mention 645167802Sjkim * of whether to run _INI or not on the device in question) 646167802Sjkim * 647167802Sjkim * "_STA may return bit 0 clear (not present) with bit 3 set 648167802Sjkim * (device is functional). This case is used to indicate a valid 649167802Sjkim * device for which no device driver should be loaded (for example, 650167802Sjkim * a bridge device.) Children of this device may be present and 651167802Sjkim * valid. OSPM should continue enumeration below a device whose 652167802Sjkim * _STA returns this bit combination" 653167802Sjkim */ 654167802Sjkim return_ACPI_STATUS (AE_OK); 655123315Snjl } 656167802Sjkim else 657167802Sjkim { 658167802Sjkim /* 659167802Sjkim * Device is not present and is not functioning. We must abort the 660167802Sjkim * walk of this subtree immediately -- don't look at the children 661167802Sjkim * of such a device. 662167802Sjkim * 663167802Sjkim * From the ACPI spec, description of _INI: 664167802Sjkim * 665167802Sjkim * "If the _STA method indicates that the device is not present, 666167802Sjkim * OSPM will not run the _INI and will not examine the children 667167802Sjkim * of the device for _INI methods" 668167802Sjkim */ 669167802Sjkim return_ACPI_STATUS (AE_CTRL_DEPTH); 670167802Sjkim } 67167754Smsmith } 67267754Smsmith 67367754Smsmith /* 674167802Sjkim * The device is present or is assumed present if no _STA exists. 675167802Sjkim * Run the _INI if it exists (not required to exist) 676167802Sjkim * 677167802Sjkim * Note: We know there is an _INI within this subtree, but it may not be 678167802Sjkim * under this particular device, it may be lower in the branch. 67967754Smsmith */ 680167802Sjkim ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname ( 681167802Sjkim ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__INI)); 682167802Sjkim 683167802Sjkim Info->PrefixNode = DeviceNode; 684167802Sjkim Info->Pathname = METHOD_NAME__INI; 685167802Sjkim Info->Parameters = NULL; 686167802Sjkim Info->Flags = ACPI_IGNORE_RETURN_VALUE; 687167802Sjkim 688167802Sjkim Status = AcpiNsEvaluate (Info); 689167802Sjkim if (ACPI_SUCCESS (Status)) 69067754Smsmith { 691167802Sjkim WalkInfo->Num_INI++; 69277424Smsmith 693167802Sjkim if ((AcpiDbgLevel <= ACPI_LV_ALL_EXCEPTIONS) && 694167802Sjkim (!(AcpiDbgLevel & ACPI_LV_INFO))) 69599679Siwasaki { 696167802Sjkim ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, ".")); 697167802Sjkim } 698167802Sjkim } 69967754Smsmith 700129684Snjl#ifdef ACPI_DEBUG_OUTPUT 701167802Sjkim else if (Status != AE_NOT_FOUND) 702167802Sjkim { 703167802Sjkim /* Ignore error and move on to next device */ 70471867Smsmith 705167802Sjkim char *ScopeName = AcpiNsGetExternalPathname (Info->ResolvedNode); 70667754Smsmith 707167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, "during %s._INI execution", 708167802Sjkim ScopeName)); 709167802Sjkim ACPI_FREE (ScopeName); 710167802Sjkim } 711129684Snjl#endif 71267754Smsmith 713167802Sjkim /* Ignore errors from above */ 714140216Snjl 715167802Sjkim Status = AE_OK; 716140216Snjl 717167802Sjkim /* 718167802Sjkim * The _INI method has been run if present; call the Global Initialization 719167802Sjkim * Handler for this device. 720167802Sjkim */ 72199679Siwasaki if (AcpiGbl_InitHandler) 72299679Siwasaki { 723167802Sjkim Status = AcpiGbl_InitHandler (DeviceNode, ACPI_INIT_DEVICE_INI); 72499679Siwasaki } 72599679Siwasaki 72699679Siwasaki return_ACPI_STATUS (Status); 72767754Smsmith} 728