nsinit.c revision 193267
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
119193251Sjkim#include "acpi.h"
120193267Sjkim#include "accommon.h"
121193251Sjkim#include "acnamesp.h"
122193251Sjkim#include "acdispat.h"
123193251Sjkim#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
267167802Sjkim    /* Walk namespace to execute all _INIs on present devices */
268167802Sjkim
269123315Snjl    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
270167802Sjkim                ACPI_UINT32_MAX, FALSE, AcpiNsInitOneDevice, &Info, NULL);
271123315Snjl
272167802Sjkim    ACPI_FREE (Info.EvaluateInfo);
27367754Smsmith    if (ACPI_FAILURE (Status))
27467754Smsmith    {
275167802Sjkim        goto ErrorExit;
27667754Smsmith    }
27767754Smsmith
278114237Snjl    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
279193267Sjkim        "\nExecuted %hd _INI methods requiring %hd _STA executions "
280193267Sjkim        "(examined %hd objects)\n",
281167802Sjkim        Info.Num_INI, Info.Num_STA, Info.DeviceCount));
28267754Smsmith
28367754Smsmith    return_ACPI_STATUS (Status);
284167802Sjkim
285167802Sjkim
286167802SjkimErrorExit:
287167802Sjkim    ACPI_EXCEPTION ((AE_INFO, Status, "During device initialization"));
288167802Sjkim    return_ACPI_STATUS (Status);
28967754Smsmith}
29067754Smsmith
29167754Smsmith
29267754Smsmith/*******************************************************************************
29367754Smsmith *
29467754Smsmith * FUNCTION:    AcpiNsInitOneObject
29567754Smsmith *
29667754Smsmith * PARAMETERS:  ObjHandle       - Node
29767754Smsmith *              Level           - Current nesting level
29867754Smsmith *              Context         - Points to a init info struct
29967754Smsmith *              ReturnValue     - Not used
30067754Smsmith *
30167754Smsmith * RETURN:      Status
30267754Smsmith *
30367754Smsmith * DESCRIPTION: Callback from AcpiWalkNamespace.  Invoked for every object
30467754Smsmith *              within the  namespace.
30567754Smsmith *
30667754Smsmith *              Currently, the only objects that require initialization are:
30767754Smsmith *              1) Methods
30867754Smsmith *              2) Op Regions
30967754Smsmith *
31067754Smsmith ******************************************************************************/
31167754Smsmith
312151937Sjkimstatic ACPI_STATUS
31367754SmsmithAcpiNsInitOneObject (
31467754Smsmith    ACPI_HANDLE             ObjHandle,
31567754Smsmith    UINT32                  Level,
31667754Smsmith    void                    *Context,
31767754Smsmith    void                    **ReturnValue)
31867754Smsmith{
31991116Smsmith    ACPI_OBJECT_TYPE        Type;
320167802Sjkim    ACPI_STATUS             Status = AE_OK;
32167754Smsmith    ACPI_INIT_WALK_INFO     *Info = (ACPI_INIT_WALK_INFO *) Context;
32267754Smsmith    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
32367754Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
32467754Smsmith
32567754Smsmith
326167802Sjkim    ACPI_FUNCTION_NAME (NsInitOneObject);
32782367Smsmith
32882367Smsmith
32967754Smsmith    Info->ObjectCount++;
33067754Smsmith
33167754Smsmith    /* And even then, we are only interested in a few object types */
33267754Smsmith
33367754Smsmith    Type = AcpiNsGetType (ObjHandle);
33487031Smsmith    ObjDesc = AcpiNsGetAttachedObject (Node);
33567754Smsmith    if (!ObjDesc)
33667754Smsmith    {
33767754Smsmith        return (AE_OK);
33867754Smsmith    }
33967754Smsmith
34099146Siwasaki    /* Increment counters for object types we are looking for */
34199146Siwasaki
34299146Siwasaki    switch (Type)
34380062Smsmith    {
34499146Siwasaki    case ACPI_TYPE_REGION:
34599146Siwasaki        Info->OpRegionCount++;
34699146Siwasaki        break;
34799146Siwasaki
34899146Siwasaki    case ACPI_TYPE_BUFFER_FIELD:
34999146Siwasaki        Info->FieldCount++;
35099146Siwasaki        break;
35199146Siwasaki
352193267Sjkim    case ACPI_TYPE_LOCAL_BANK_FIELD:
353193267Sjkim        Info->FieldCount++;
354193267Sjkim        break;
355193267Sjkim
35699146Siwasaki    case ACPI_TYPE_BUFFER:
35799146Siwasaki        Info->BufferCount++;
35899146Siwasaki        break;
35999146Siwasaki
36099146Siwasaki    case ACPI_TYPE_PACKAGE:
36199146Siwasaki        Info->PackageCount++;
36299146Siwasaki        break;
36399146Siwasaki
36499146Siwasaki    default:
36599146Siwasaki
36699146Siwasaki        /* No init required, just exit now */
36780062Smsmith        return (AE_OK);
36880062Smsmith    }
36980062Smsmith
370193267Sjkim    /* If the object is already initialized, nothing else to do */
371193267Sjkim
37299146Siwasaki    if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
37399146Siwasaki    {
37499146Siwasaki        return (AE_OK);
37599146Siwasaki    }
37680062Smsmith
377193267Sjkim    /* Must lock the interpreter before executing AML code */
378193267Sjkim
379167802Sjkim    AcpiExEnterInterpreter ();
38080062Smsmith
38199146Siwasaki    /*
382138287Smarks     * Each of these types can contain executable AML code within the
383138287Smarks     * declaration.
38499146Siwasaki     */
38567754Smsmith    switch (Type)
38667754Smsmith    {
38767754Smsmith    case ACPI_TYPE_REGION:
38867754Smsmith
38967754Smsmith        Info->OpRegionInit++;
39067754Smsmith        Status = AcpiDsGetRegionArguments (ObjDesc);
39167754Smsmith        break;
39267754Smsmith
39377424Smsmith    case ACPI_TYPE_BUFFER_FIELD:
39467754Smsmith
39567754Smsmith        Info->FieldInit++;
39677424Smsmith        Status = AcpiDsGetBufferFieldArguments (ObjDesc);
39799146Siwasaki        break;
39867754Smsmith
399193267Sjkim    case ACPI_TYPE_LOCAL_BANK_FIELD:
400193267Sjkim
401193267Sjkim        Info->FieldInit++;
402193267Sjkim        Status = AcpiDsGetBankFieldArguments (ObjDesc);
403193267Sjkim        break;
404193267Sjkim
40599146Siwasaki    case ACPI_TYPE_BUFFER:
40699146Siwasaki
40799146Siwasaki        Info->BufferInit++;
40899146Siwasaki        Status = AcpiDsGetBufferArguments (ObjDesc);
40967754Smsmith        break;
41067754Smsmith
41199146Siwasaki    case ACPI_TYPE_PACKAGE:
41299146Siwasaki
41399146Siwasaki        Info->PackageInit++;
41499146Siwasaki        Status = AcpiDsGetPackageArguments (ObjDesc);
41567754Smsmith        break;
41699679Siwasaki
41799679Siwasaki    default:
41899679Siwasaki        /* No other types can get here */
41999679Siwasaki        break;
42067754Smsmith    }
42167754Smsmith
42299146Siwasaki    if (ACPI_FAILURE (Status))
42399146Siwasaki    {
424167802Sjkim        ACPI_EXCEPTION ((AE_INFO, Status,
425167802Sjkim            "Could not execute arguments for [%4.4s] (%s)",
426167802Sjkim            AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Type)));
42799146Siwasaki    }
42880062Smsmith
429138287Smarks    /*
430138287Smarks     * Print a dot for each object unless we are going to print the entire
431138287Smarks     * pathname
432138287Smarks     */
433114237Snjl    if (!(AcpiDbgLevel & ACPI_LV_INIT_NAMES))
43499146Siwasaki    {
435114237Snjl        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "."));
43699146Siwasaki    }
43799146Siwasaki
43867754Smsmith    /*
439138287Smarks     * We ignore errors from above, and always return OK, since we don't want
440138287Smarks     * to abort the walk on any single error.
44167754Smsmith     */
44280062Smsmith    AcpiExExitInterpreter ();
44367754Smsmith    return (AE_OK);
44467754Smsmith}
44567754Smsmith
44667754Smsmith
44777424Smsmith/*******************************************************************************
44867754Smsmith *
449167802Sjkim * FUNCTION:    AcpiNsFindIniMethods
450167802Sjkim *
451167802Sjkim * PARAMETERS:  ACPI_WALK_CALLBACK
452167802Sjkim *
453167802Sjkim * RETURN:      ACPI_STATUS
454167802Sjkim *
455167802Sjkim * DESCRIPTION: Called during namespace walk. Finds objects named _INI under
456167802Sjkim *              device/processor/thermal objects, and marks the entire subtree
457167802Sjkim *              with a SUBTREE_HAS_INI flag. This flag is used during the
458167802Sjkim *              subsequent device initialization walk to avoid entire subtrees
459167802Sjkim *              that do not contain an _INI.
460167802Sjkim *
461167802Sjkim ******************************************************************************/
462167802Sjkim
463167802Sjkimstatic ACPI_STATUS
464167802SjkimAcpiNsFindIniMethods (
465167802Sjkim    ACPI_HANDLE             ObjHandle,
466167802Sjkim    UINT32                  NestingLevel,
467167802Sjkim    void                    *Context,
468167802Sjkim    void                    **ReturnValue)
469167802Sjkim{
470167802Sjkim    ACPI_DEVICE_WALK_INFO   *Info = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context);
471167802Sjkim    ACPI_NAMESPACE_NODE     *Node;
472167802Sjkim    ACPI_NAMESPACE_NODE     *ParentNode;
473167802Sjkim
474167802Sjkim
475167802Sjkim    /* Keep count of device/processor/thermal objects */
476167802Sjkim
477167802Sjkim    Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
478167802Sjkim    if ((Node->Type == ACPI_TYPE_DEVICE)    ||
479167802Sjkim        (Node->Type == ACPI_TYPE_PROCESSOR) ||
480167802Sjkim        (Node->Type == ACPI_TYPE_THERMAL))
481167802Sjkim    {
482167802Sjkim        Info->DeviceCount++;
483167802Sjkim        return (AE_OK);
484167802Sjkim    }
485167802Sjkim
486167802Sjkim    /* We are only looking for methods named _INI */
487167802Sjkim
488167802Sjkim    if (!ACPI_COMPARE_NAME (Node->Name.Ascii, METHOD_NAME__INI))
489167802Sjkim    {
490167802Sjkim        return (AE_OK);
491167802Sjkim    }
492167802Sjkim
493167802Sjkim    /*
494167802Sjkim     * The only _INI methods that we care about are those that are
495167802Sjkim     * present under Device, Processor, and Thermal objects.
496167802Sjkim     */
497167802Sjkim    ParentNode = AcpiNsGetParentNode (Node);
498167802Sjkim    switch (ParentNode->Type)
499167802Sjkim    {
500167802Sjkim    case ACPI_TYPE_DEVICE:
501167802Sjkim    case ACPI_TYPE_PROCESSOR:
502167802Sjkim    case ACPI_TYPE_THERMAL:
503167802Sjkim
504167802Sjkim        /* Mark parent and bubble up the INI present flag to the root */
505167802Sjkim
506167802Sjkim        while (ParentNode)
507167802Sjkim        {
508167802Sjkim            ParentNode->Flags |= ANOBJ_SUBTREE_HAS_INI;
509167802Sjkim            ParentNode = AcpiNsGetParentNode (ParentNode);
510167802Sjkim        }
511167802Sjkim        break;
512167802Sjkim
513167802Sjkim    default:
514167802Sjkim        break;
515167802Sjkim    }
516167802Sjkim
517167802Sjkim    return (AE_OK);
518167802Sjkim}
519167802Sjkim
520167802Sjkim
521167802Sjkim/*******************************************************************************
522167802Sjkim *
52367754Smsmith * FUNCTION:    AcpiNsInitOneDevice
52467754Smsmith *
52577424Smsmith * PARAMETERS:  ACPI_WALK_CALLBACK
52667754Smsmith *
52767754Smsmith * RETURN:      ACPI_STATUS
52867754Smsmith *
52967754Smsmith * DESCRIPTION: This is called once per device soon after ACPI is enabled
53067754Smsmith *              to initialize each device. It determines if the device is
53167754Smsmith *              present, and if so, calls _INI.
53267754Smsmith *
53377424Smsmith ******************************************************************************/
53467754Smsmith
535151937Sjkimstatic ACPI_STATUS
53667754SmsmithAcpiNsInitOneDevice (
53767754Smsmith    ACPI_HANDLE             ObjHandle,
53867754Smsmith    UINT32                  NestingLevel,
53967754Smsmith    void                    *Context,
54067754Smsmith    void                    **ReturnValue)
54167754Smsmith{
542167802Sjkim    ACPI_DEVICE_WALK_INFO   *WalkInfo = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context);
543167802Sjkim    ACPI_EVALUATE_INFO      *Info = WalkInfo->EvaluateInfo;
544129684Snjl    UINT32                  Flags;
54567754Smsmith    ACPI_STATUS             Status;
546167802Sjkim    ACPI_NAMESPACE_NODE     *DeviceNode;
54767754Smsmith
54867754Smsmith
549167802Sjkim    ACPI_FUNCTION_TRACE (NsInitOneDevice);
55067754Smsmith
55167754Smsmith
552167802Sjkim    /* We are interested in Devices, Processors and ThermalZones only */
553129684Snjl
554167802Sjkim    DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
555167802Sjkim    if ((DeviceNode->Type != ACPI_TYPE_DEVICE)    &&
556167802Sjkim        (DeviceNode->Type != ACPI_TYPE_PROCESSOR) &&
557167802Sjkim        (DeviceNode->Type != ACPI_TYPE_THERMAL))
55873561Smsmith    {
559167802Sjkim        return_ACPI_STATUS (AE_OK);
56073561Smsmith    }
56173561Smsmith
562123315Snjl    /*
563167802Sjkim     * Because of an earlier namespace analysis, all subtrees that contain an
564167802Sjkim     * _INI method are tagged.
565167802Sjkim     *
566167802Sjkim     * If this device subtree does not contain any _INI methods, we
567167802Sjkim     * can exit now and stop traversing this entire subtree.
568123315Snjl     */
569167802Sjkim    if (!(DeviceNode->Flags & ANOBJ_SUBTREE_HAS_INI))
57091116Smsmith    {
571167802Sjkim        return_ACPI_STATUS (AE_CTRL_DEPTH);
57291116Smsmith    }
57367754Smsmith
57467754Smsmith    /*
575167802Sjkim     * Run _STA to determine if this device is present and functioning. We
576167802Sjkim     * must know this information for two important reasons (from ACPI spec):
577167802Sjkim     *
578167802Sjkim     * 1) We can only run _INI if the device is present.
579167802Sjkim     * 2) We must abort the device tree walk on this subtree if the device is
580167802Sjkim     *    not present and is not functional (we will not examine the children)
581167802Sjkim     *
582167802Sjkim     * The _STA method is not required to be present under the device, we
583167802Sjkim     * assume the device is present if _STA does not exist.
58467754Smsmith     */
585167802Sjkim    ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
586167802Sjkim        ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__STA));
587123315Snjl
588167802Sjkim    Status = AcpiUtExecute_STA (DeviceNode, &Flags);
58967754Smsmith    if (ACPI_FAILURE (Status))
59067754Smsmith    {
591167802Sjkim        /* Ignore error and move on to next device */
59271867Smsmith
593167802Sjkim        return_ACPI_STATUS (AE_OK);
594167802Sjkim    }
595123315Snjl
596167802Sjkim    /*
597167802Sjkim     * Flags == -1 means that _STA was not found. In this case, we assume that
598167802Sjkim     * the device is both present and functional.
599167802Sjkim     *
600167802Sjkim     * From the ACPI spec, description of _STA:
601167802Sjkim     *
602167802Sjkim     * "If a device object (including the processor object) does not have an
603167802Sjkim     * _STA object, then OSPM assumes that all of the above bits are set (in
604167802Sjkim     * other words, the device is present, ..., and functioning)"
605167802Sjkim     */
606167802Sjkim    if (Flags != ACPI_UINT32_MAX)
607167802Sjkim    {
608167802Sjkim        WalkInfo->Num_STA++;
60967754Smsmith    }
610167802Sjkim
611167802Sjkim    /*
612167802Sjkim     * Examine the PRESENT and FUNCTIONING status bits
613167802Sjkim     *
614167802Sjkim     * Note: ACPI spec does not seem to specify behavior for the present but
615167802Sjkim     * not functioning case, so we assume functioning if present.
616167802Sjkim     */
617167802Sjkim    if (!(Flags & ACPI_STA_DEVICE_PRESENT))
618123315Snjl    {
619167802Sjkim        /* Device is not present, we must examine the Functioning bit */
62067754Smsmith
621167802Sjkim        if (Flags & ACPI_STA_DEVICE_FUNCTIONING)
622123315Snjl        {
623167802Sjkim            /*
624167802Sjkim             * Device is not present but is "functioning". In this case,
625167802Sjkim             * we will not run _INI, but we continue to examine the children
626167802Sjkim             * of this device.
627167802Sjkim             *
628167802Sjkim             * From the ACPI spec, description of _STA: (Note - no mention
629167802Sjkim             * of whether to run _INI or not on the device in question)
630167802Sjkim             *
631167802Sjkim             * "_STA may return bit 0 clear (not present) with bit 3 set
632167802Sjkim             * (device is functional). This case is used to indicate a valid
633167802Sjkim             * device for which no device driver should be loaded (for example,
634167802Sjkim             * a bridge device.) Children of this device may be present and
635167802Sjkim             * valid. OSPM should continue enumeration below a device whose
636167802Sjkim             * _STA returns this bit combination"
637167802Sjkim             */
638167802Sjkim            return_ACPI_STATUS (AE_OK);
639123315Snjl        }
640167802Sjkim        else
641167802Sjkim        {
642167802Sjkim            /*
643167802Sjkim             * Device is not present and is not functioning. We must abort the
644167802Sjkim             * walk of this subtree immediately -- don't look at the children
645167802Sjkim             * of such a device.
646167802Sjkim             *
647167802Sjkim             * From the ACPI spec, description of _INI:
648167802Sjkim             *
649167802Sjkim             * "If the _STA method indicates that the device is not present,
650167802Sjkim             * OSPM will not run the _INI and will not examine the children
651167802Sjkim             * of the device for _INI methods"
652167802Sjkim             */
653167802Sjkim            return_ACPI_STATUS (AE_CTRL_DEPTH);
654167802Sjkim        }
65567754Smsmith    }
65667754Smsmith
65767754Smsmith    /*
658167802Sjkim     * The device is present or is assumed present if no _STA exists.
659167802Sjkim     * Run the _INI if it exists (not required to exist)
660167802Sjkim     *
661167802Sjkim     * Note: We know there is an _INI within this subtree, but it may not be
662167802Sjkim     * under this particular device, it may be lower in the branch.
66367754Smsmith     */
664167802Sjkim    ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
665167802Sjkim        ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__INI));
666167802Sjkim
667167802Sjkim    Info->PrefixNode = DeviceNode;
668167802Sjkim    Info->Pathname = METHOD_NAME__INI;
669167802Sjkim    Info->Parameters = NULL;
670167802Sjkim    Info->Flags = ACPI_IGNORE_RETURN_VALUE;
671167802Sjkim
672167802Sjkim    Status = AcpiNsEvaluate (Info);
673167802Sjkim    if (ACPI_SUCCESS (Status))
67467754Smsmith    {
675167802Sjkim        WalkInfo->Num_INI++;
67677424Smsmith
677167802Sjkim        if ((AcpiDbgLevel <= ACPI_LV_ALL_EXCEPTIONS) &&
678167802Sjkim            (!(AcpiDbgLevel & ACPI_LV_INFO)))
67999679Siwasaki        {
680167802Sjkim            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "."));
681167802Sjkim        }
682167802Sjkim    }
68367754Smsmith
684129684Snjl#ifdef ACPI_DEBUG_OUTPUT
685167802Sjkim    else if (Status != AE_NOT_FOUND)
686167802Sjkim    {
687167802Sjkim        /* Ignore error and move on to next device */
68871867Smsmith
689167802Sjkim        char *ScopeName = AcpiNsGetExternalPathname (Info->ResolvedNode);
69067754Smsmith
691167802Sjkim        ACPI_EXCEPTION ((AE_INFO, Status, "during %s._INI execution",
692167802Sjkim            ScopeName));
693167802Sjkim        ACPI_FREE (ScopeName);
694167802Sjkim    }
695129684Snjl#endif
69667754Smsmith
697167802Sjkim    /* Ignore errors from above */
698140216Snjl
699167802Sjkim    Status = AE_OK;
700140216Snjl
701167802Sjkim    /*
702167802Sjkim     * The _INI method has been run if present; call the Global Initialization
703167802Sjkim     * Handler for this device.
704167802Sjkim     */
70599679Siwasaki    if (AcpiGbl_InitHandler)
70699679Siwasaki    {
707167802Sjkim        Status = AcpiGbl_InitHandler (DeviceNode, ACPI_INIT_DEVICE_INI);
70899679Siwasaki    }
70999679Siwasaki
71099679Siwasaki    return_ACPI_STATUS (Status);
71167754Smsmith}
712