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