1/******************************************************************************
2 *
3 * Module Name: nsinit - namespace initialization
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2023, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions, and the following disclaimer,
16 *    without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 *    substantially similar to the "NO WARRANTY" disclaimer below
19 *    ("Disclaimer") and any redistribution must be conditioned upon
20 *    including a substantially similar Disclaimer requirement for further
21 *    binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 *    of any contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include "acpi.h"
45#include "accommon.h"
46#include "acnamesp.h"
47#include "acdispat.h"
48#include "acinterp.h"
49#include "acevents.h"
50
51#define _COMPONENT          ACPI_NAMESPACE
52        ACPI_MODULE_NAME    ("nsinit")
53
54/* Local prototypes */
55
56static ACPI_STATUS
57AcpiNsInitOneObject (
58    ACPI_HANDLE             ObjHandle,
59    UINT32                  Level,
60    void                    *Context,
61    void                    **ReturnValue);
62
63static ACPI_STATUS
64AcpiNsInitOneDevice (
65    ACPI_HANDLE             ObjHandle,
66    UINT32                  NestingLevel,
67    void                    *Context,
68    void                    **ReturnValue);
69
70static ACPI_STATUS
71AcpiNsFindIniMethods (
72    ACPI_HANDLE             ObjHandle,
73    UINT32                  NestingLevel,
74    void                    *Context,
75    void                    **ReturnValue);
76
77
78/*******************************************************************************
79 *
80 * FUNCTION:    AcpiNsInitializeObjects
81 *
82 * PARAMETERS:  None
83 *
84 * RETURN:      Status
85 *
86 * DESCRIPTION: Walk the entire namespace and perform any necessary
87 *              initialization on the objects found therein
88 *
89 ******************************************************************************/
90
91ACPI_STATUS
92AcpiNsInitializeObjects (
93    void)
94{
95    ACPI_STATUS             Status;
96    ACPI_INIT_WALK_INFO     Info;
97
98
99    ACPI_FUNCTION_TRACE (NsInitializeObjects);
100
101
102    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
103        "[Init] Completing Initialization of ACPI Objects\n"));
104    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
105        "**** Starting initialization of namespace objects ****\n"));
106    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
107        "Final data object initialization: "));
108
109    /* Clear the info block */
110
111    memset (&Info, 0, sizeof (ACPI_INIT_WALK_INFO));
112
113    /* Walk entire namespace from the supplied root */
114
115    /*
116     * TBD: will become ACPI_TYPE_PACKAGE as this type object
117     * is now the only one that supports deferred initialization
118     * (forward references).
119     */
120    Status = AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
121        ACPI_UINT32_MAX, AcpiNsInitOneObject, NULL, &Info, NULL);
122    if (ACPI_FAILURE (Status))
123    {
124        ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace"));
125    }
126
127    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
128        "Namespace contains %u (0x%X) objects\n",
129        Info.ObjectCount,
130        Info.ObjectCount));
131
132    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
133        "%u Control Methods found\n%u Op Regions found\n",
134        Info.MethodCount, Info.OpRegionCount));
135
136    return_ACPI_STATUS (AE_OK);
137}
138
139
140/*******************************************************************************
141 *
142 * FUNCTION:    AcpiNsInitializeDevices
143 *
144 * PARAMETERS:  None
145 *
146 * RETURN:      ACPI_STATUS
147 *
148 * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices.
149 *              This means running _INI on all present devices.
150 *
151 *              Note: We install PCI config space handler on region access,
152 *              not here.
153 *
154 ******************************************************************************/
155
156ACPI_STATUS
157AcpiNsInitializeDevices (
158    UINT32                  Flags)
159{
160    ACPI_STATUS             Status = AE_OK;
161    ACPI_DEVICE_WALK_INFO   Info;
162    ACPI_HANDLE             Handle;
163
164
165    ACPI_FUNCTION_TRACE (NsInitializeDevices);
166
167
168    if (!(Flags & ACPI_NO_DEVICE_INIT))
169    {
170        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
171            "[Init] Initializing ACPI Devices\n"));
172
173        /* Init counters */
174
175        Info.DeviceCount = 0;
176        Info.Num_STA = 0;
177        Info.Num_INI = 0;
178
179        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
180            "Initializing Device/Processor/Thermal objects "
181            "and executing _INI/_STA methods:\n"));
182
183        /* Tree analysis: find all subtrees that contain _INI methods */
184
185        Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
186            ACPI_UINT32_MAX, FALSE, AcpiNsFindIniMethods, NULL, &Info, NULL);
187        if (ACPI_FAILURE (Status))
188        {
189            goto ErrorExit;
190        }
191
192        /* Allocate the evaluation information block */
193
194        Info.EvaluateInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
195        if (!Info.EvaluateInfo)
196        {
197            Status = AE_NO_MEMORY;
198            goto ErrorExit;
199        }
200
201        /*
202         * Execute the "global" _INI method that may appear at the root.
203         * This support is provided for Windows compatibility (Vista+) and
204         * is not part of the ACPI specification.
205         */
206        Info.EvaluateInfo->PrefixNode = AcpiGbl_RootNode;
207        Info.EvaluateInfo->RelativePathname = METHOD_NAME__INI;
208        Info.EvaluateInfo->Parameters = NULL;
209        Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE;
210
211        Status = AcpiNsEvaluate (Info.EvaluateInfo);
212        if (ACPI_SUCCESS (Status))
213        {
214            Info.Num_INI++;
215        }
216
217        /*
218         * Execute \_SB._INI.
219         * There appears to be a strict order requirement for \_SB._INI,
220         * which should be evaluated before any _REG evaluations.
221         */
222        Status = AcpiGetHandle (NULL, "\\_SB", &Handle);
223        if (ACPI_SUCCESS (Status))
224        {
225            memset (Info.EvaluateInfo, 0, sizeof (ACPI_EVALUATE_INFO));
226            Info.EvaluateInfo->PrefixNode = Handle;
227            Info.EvaluateInfo->RelativePathname = METHOD_NAME__INI;
228            Info.EvaluateInfo->Parameters = NULL;
229            Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE;
230
231            Status = AcpiNsEvaluate (Info.EvaluateInfo);
232            if (ACPI_SUCCESS (Status))
233            {
234                Info.Num_INI++;
235            }
236        }
237    }
238
239    /*
240     * Run all _REG methods
241     *
242     * Note: Any objects accessed by the _REG methods will be automatically
243     * initialized, even if they contain executable AML (see the call to
244     * AcpiNsInitializeObjects below).
245     *
246     * Note: According to the ACPI specification, we actually needn't execute
247     * _REG for SystemMemory/SystemIo operation regions, but for PCI_Config
248     * operation regions, it is required to evaluate _REG for those on a PCI
249     * root bus that doesn't contain _BBN object. So this code is kept here
250     * in order not to break things.
251     */
252    if (!(Flags & ACPI_NO_ADDRESS_SPACE_INIT))
253    {
254        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
255            "[Init] Executing _REG OpRegion methods\n"));
256
257        Status = AcpiEvInitializeOpRegions ();
258        if (ACPI_FAILURE (Status))
259        {
260            goto ErrorExit;
261        }
262    }
263
264    if (!(Flags & ACPI_NO_DEVICE_INIT))
265    {
266        /* Walk namespace to execute all _INIs on present devices */
267
268        Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
269            ACPI_UINT32_MAX, FALSE, AcpiNsInitOneDevice, NULL, &Info, NULL);
270
271        /*
272         * Any _OSI requests should be completed by now. If the BIOS has
273         * requested any Windows OSI strings, we will always truncate
274         * I/O addresses to 16 bits -- for Windows compatibility.
275         */
276        if (AcpiGbl_OsiData >= ACPI_OSI_WIN_2000)
277        {
278            AcpiGbl_TruncateIoAddresses = TRUE;
279        }
280
281        ACPI_FREE (Info.EvaluateInfo);
282        if (ACPI_FAILURE (Status))
283        {
284            goto ErrorExit;
285        }
286
287        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
288            "    Executed %u _INI methods requiring %u _STA executions "
289            "(examined %u objects)\n",
290            Info.Num_INI, Info.Num_STA, Info.DeviceCount));
291    }
292
293    return_ACPI_STATUS (Status);
294
295
296ErrorExit:
297    ACPI_EXCEPTION ((AE_INFO, Status, "During device initialization"));
298    return_ACPI_STATUS (Status);
299}
300
301
302/*******************************************************************************
303 *
304 * FUNCTION:    AcpiNsInitOnePackage
305 *
306 * PARAMETERS:  ObjHandle       - Node
307 *              Level           - Current nesting level
308 *              Context         - Not used
309 *              ReturnValue     - Not used
310 *
311 * RETURN:      Status
312 *
313 * DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every package
314 *              within the namespace. Used during dynamic load of an SSDT.
315 *
316 ******************************************************************************/
317
318ACPI_STATUS
319AcpiNsInitOnePackage (
320    ACPI_HANDLE             ObjHandle,
321    UINT32                  Level,
322    void                    *Context,
323    void                    **ReturnValue)
324{
325    ACPI_STATUS             Status;
326    ACPI_OPERAND_OBJECT     *ObjDesc;
327    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
328
329
330    ObjDesc = AcpiNsGetAttachedObject (Node);
331    if (!ObjDesc)
332    {
333        return (AE_OK);
334    }
335
336    /* Exit if package is already initialized */
337
338    if (ObjDesc->Package.Flags & AOPOBJ_DATA_VALID)
339    {
340        return (AE_OK);
341    }
342
343    Status = AcpiDsGetPackageArguments (ObjDesc);
344    if (ACPI_FAILURE (Status))
345    {
346        return (AE_OK);
347    }
348
349    Status = AcpiUtWalkPackageTree (ObjDesc, NULL, AcpiDsInitPackageElement,
350        NULL);
351    if (ACPI_FAILURE (Status))
352    {
353        return (AE_OK);
354    }
355
356    ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID;
357    return (AE_OK);
358}
359
360
361/*******************************************************************************
362 *
363 * FUNCTION:    AcpiNsInitOneObject
364 *
365 * PARAMETERS:  ObjHandle       - Node
366 *              Level           - Current nesting level
367 *              Context         - Points to a init info struct
368 *              ReturnValue     - Not used
369 *
370 * RETURN:      Status
371 *
372 * DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every object
373 *              within the namespace.
374 *
375 *              Currently, the only objects that require initialization are:
376 *              1) Methods
377 *              2) Op Regions
378 *
379 ******************************************************************************/
380
381static ACPI_STATUS
382AcpiNsInitOneObject (
383    ACPI_HANDLE             ObjHandle,
384    UINT32                  Level,
385    void                    *Context,
386    void                    **ReturnValue)
387{
388    ACPI_OBJECT_TYPE        Type;
389    ACPI_STATUS             Status = AE_OK;
390    ACPI_INIT_WALK_INFO     *Info = (ACPI_INIT_WALK_INFO *) Context;
391    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
392    ACPI_OPERAND_OBJECT     *ObjDesc;
393
394
395    ACPI_FUNCTION_NAME (NsInitOneObject);
396
397
398    Info->ObjectCount++;
399
400    /* And even then, we are only interested in a few object types */
401
402    Type = AcpiNsGetType (ObjHandle);
403    ObjDesc = AcpiNsGetAttachedObject (Node);
404    if (!ObjDesc)
405    {
406        return (AE_OK);
407    }
408
409    /* Increment counters for object types we are looking for */
410
411    switch (Type)
412    {
413    case ACPI_TYPE_REGION:
414
415        Info->OpRegionCount++;
416        break;
417
418    case ACPI_TYPE_BUFFER_FIELD:
419
420        Info->FieldCount++;
421        break;
422
423    case ACPI_TYPE_LOCAL_BANK_FIELD:
424
425        Info->FieldCount++;
426        break;
427
428    case ACPI_TYPE_BUFFER:
429
430        Info->BufferCount++;
431        break;
432
433    case ACPI_TYPE_PACKAGE:
434
435        Info->PackageCount++;
436        break;
437
438    default:
439
440        /* No init required, just exit now */
441
442        return (AE_OK);
443    }
444
445    /* If the object is already initialized, nothing else to do */
446
447    if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
448    {
449        return (AE_OK);
450    }
451
452    /* Must lock the interpreter before executing AML code */
453
454    AcpiExEnterInterpreter ();
455
456    /*
457     * Only initialization of Package objects can be deferred, in order
458     * to support forward references.
459     */
460    switch (Type)
461    {
462    case ACPI_TYPE_LOCAL_BANK_FIELD:
463
464        /* TBD: BankFields do not require deferred init, remove this code */
465
466        Info->FieldInit++;
467        Status = AcpiDsGetBankFieldArguments (ObjDesc);
468        break;
469
470    case ACPI_TYPE_PACKAGE:
471
472        /* Complete the initialization/resolution of the package object */
473
474        Info->PackageInit++;
475        Status = AcpiNsInitOnePackage (ObjHandle, Level, NULL, NULL);
476        break;
477
478    default:
479
480        /* No other types should get here */
481
482        Status = AE_TYPE;
483        ACPI_EXCEPTION ((AE_INFO, Status,
484            "Opcode is not deferred [%4.4s] (%s)",
485            AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Type)));
486        break;
487    }
488
489    if (ACPI_FAILURE (Status))
490    {
491        ACPI_EXCEPTION ((AE_INFO, Status,
492            "Could not execute arguments for [%4.4s] (%s)",
493            AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Type)));
494    }
495
496    /*
497     * We ignore errors from above, and always return OK, since we don't want
498     * to abort the walk on any single error.
499     */
500    AcpiExExitInterpreter ();
501    return (AE_OK);
502}
503
504
505/*******************************************************************************
506 *
507 * FUNCTION:    AcpiNsFindIniMethods
508 *
509 * PARAMETERS:  ACPI_WALK_CALLBACK
510 *
511 * RETURN:      ACPI_STATUS
512 *
513 * DESCRIPTION: Called during namespace walk. Finds objects named _INI under
514 *              device/processor/thermal objects, and marks the entire subtree
515 *              with a SUBTREE_HAS_INI flag. This flag is used during the
516 *              subsequent device initialization walk to avoid entire subtrees
517 *              that do not contain an _INI.
518 *
519 ******************************************************************************/
520
521static ACPI_STATUS
522AcpiNsFindIniMethods (
523    ACPI_HANDLE             ObjHandle,
524    UINT32                  NestingLevel,
525    void                    *Context,
526    void                    **ReturnValue)
527{
528    ACPI_DEVICE_WALK_INFO   *Info = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context);
529    ACPI_NAMESPACE_NODE     *Node;
530    ACPI_NAMESPACE_NODE     *ParentNode;
531
532
533    /* Keep count of device/processor/thermal objects */
534
535    Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
536    if ((Node->Type == ACPI_TYPE_DEVICE)    ||
537        (Node->Type == ACPI_TYPE_PROCESSOR) ||
538        (Node->Type == ACPI_TYPE_THERMAL))
539    {
540        Info->DeviceCount++;
541        return (AE_OK);
542    }
543
544    /* We are only looking for methods named _INI */
545
546    if (!ACPI_COMPARE_NAMESEG (Node->Name.Ascii, METHOD_NAME__INI))
547    {
548        return (AE_OK);
549    }
550
551    /*
552     * The only _INI methods that we care about are those that are
553     * present under Device, Processor, and Thermal objects.
554     */
555    ParentNode = Node->Parent;
556    switch (ParentNode->Type)
557    {
558    case ACPI_TYPE_DEVICE:
559    case ACPI_TYPE_PROCESSOR:
560    case ACPI_TYPE_THERMAL:
561
562        /* Mark parent and bubble up the INI present flag to the root */
563
564        while (ParentNode)
565        {
566            ParentNode->Flags |= ANOBJ_SUBTREE_HAS_INI;
567            ParentNode = ParentNode->Parent;
568        }
569        break;
570
571    default:
572
573        break;
574    }
575
576    return (AE_OK);
577}
578
579
580/*******************************************************************************
581 *
582 * FUNCTION:    AcpiNsInitOneDevice
583 *
584 * PARAMETERS:  ACPI_WALK_CALLBACK
585 *
586 * RETURN:      ACPI_STATUS
587 *
588 * DESCRIPTION: This is called once per device soon after ACPI is enabled
589 *              to initialize each device. It determines if the device is
590 *              present, and if so, calls _INI.
591 *
592 ******************************************************************************/
593
594static ACPI_STATUS
595AcpiNsInitOneDevice (
596    ACPI_HANDLE             ObjHandle,
597    UINT32                  NestingLevel,
598    void                    *Context,
599    void                    **ReturnValue)
600{
601    ACPI_DEVICE_WALK_INFO   *WalkInfo = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context);
602    ACPI_EVALUATE_INFO      *Info = WalkInfo->EvaluateInfo;
603    UINT32                  Flags;
604    ACPI_STATUS             Status;
605    ACPI_NAMESPACE_NODE     *DeviceNode;
606
607
608    ACPI_FUNCTION_TRACE (NsInitOneDevice);
609
610
611    /* We are interested in Devices, Processors and ThermalZones only */
612
613    DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
614    if ((DeviceNode->Type != ACPI_TYPE_DEVICE)    &&
615        (DeviceNode->Type != ACPI_TYPE_PROCESSOR) &&
616        (DeviceNode->Type != ACPI_TYPE_THERMAL))
617    {
618        return_ACPI_STATUS (AE_OK);
619    }
620
621    /*
622     * Because of an earlier namespace analysis, all subtrees that contain an
623     * _INI method are tagged.
624     *
625     * If this device subtree does not contain any _INI methods, we
626     * can exit now and stop traversing this entire subtree.
627     */
628    if (!(DeviceNode->Flags & ANOBJ_SUBTREE_HAS_INI))
629    {
630        return_ACPI_STATUS (AE_CTRL_DEPTH);
631    }
632
633    /*
634     * Run _STA to determine if this device is present and functioning. We
635     * must know this information for two important reasons (from ACPI spec):
636     *
637     * 1) We can only run _INI if the device is present.
638     * 2) We must abort the device tree walk on this subtree if the device is
639     *    not present and is not functional (we will not examine the children)
640     *
641     * The _STA method is not required to be present under the device, we
642     * assume the device is present if _STA does not exist.
643     */
644    ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
645        ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__STA));
646
647    Status = AcpiUtExecute_STA (DeviceNode, &Flags);
648    if (ACPI_FAILURE (Status))
649    {
650        /* Ignore error and move on to next device */
651
652        return_ACPI_STATUS (AE_OK);
653    }
654
655    /*
656     * Flags == -1 means that _STA was not found. In this case, we assume that
657     * the device is both present and functional.
658     *
659     * From the ACPI spec, description of _STA:
660     *
661     * "If a device object (including the processor object) does not have an
662     * _STA object, then OSPM assumes that all of the above bits are set (in
663     * other words, the device is present, ..., and functioning)"
664     */
665    if (Flags != ACPI_UINT32_MAX)
666    {
667        WalkInfo->Num_STA++;
668    }
669
670    /*
671     * Examine the PRESENT and FUNCTIONING status bits
672     *
673     * Note: ACPI spec does not seem to specify behavior for the present but
674     * not functioning case, so we assume functioning if present.
675     */
676    if (!(Flags & ACPI_STA_DEVICE_PRESENT))
677    {
678        /* Device is not present, we must examine the Functioning bit */
679
680        if (Flags & ACPI_STA_DEVICE_FUNCTIONING)
681        {
682            /*
683             * Device is not present but is "functioning". In this case,
684             * we will not run _INI, but we continue to examine the children
685             * of this device.
686             *
687             * From the ACPI spec, description of _STA: (Note - no mention
688             * of whether to run _INI or not on the device in question)
689             *
690             * "_STA may return bit 0 clear (not present) with bit 3 set
691             * (device is functional). This case is used to indicate a valid
692             * device for which no device driver should be loaded (for example,
693             * a bridge device.) Children of this device may be present and
694             * valid. OSPM should continue enumeration below a device whose
695             * _STA returns this bit combination"
696             */
697            return_ACPI_STATUS (AE_OK);
698        }
699        else
700        {
701            /*
702             * Device is not present and is not functioning. We must abort the
703             * walk of this subtree immediately -- don't look at the children
704             * of such a device.
705             *
706             * From the ACPI spec, description of _INI:
707             *
708             * "If the _STA method indicates that the device is not present,
709             * OSPM will not run the _INI and will not examine the children
710             * of the device for _INI methods"
711             */
712            return_ACPI_STATUS (AE_CTRL_DEPTH);
713        }
714    }
715
716    /*
717     * The device is present or is assumed present if no _STA exists.
718     * Run the _INI if it exists (not required to exist)
719     *
720     * Note: We know there is an _INI within this subtree, but it may not be
721     * under this particular device, it may be lower in the branch.
722     */
723    if (!ACPI_COMPARE_NAMESEG (DeviceNode->Name.Ascii, "_SB_") ||
724        DeviceNode->Parent != AcpiGbl_RootNode)
725    {
726        ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
727            ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__INI));
728
729        memset (Info, 0, sizeof (ACPI_EVALUATE_INFO));
730        Info->PrefixNode = DeviceNode;
731        Info->RelativePathname = METHOD_NAME__INI;
732        Info->Parameters = NULL;
733        Info->Flags = ACPI_IGNORE_RETURN_VALUE;
734
735        Status = AcpiNsEvaluate (Info);
736        if (ACPI_SUCCESS (Status))
737        {
738            WalkInfo->Num_INI++;
739        }
740
741#ifdef ACPI_DEBUG_OUTPUT
742        else if (Status != AE_NOT_FOUND)
743        {
744            /* Ignore error and move on to next device */
745
746            char *ScopeName = AcpiNsGetNormalizedPathname (DeviceNode, TRUE);
747
748            ACPI_EXCEPTION ((AE_INFO, Status, "during %s._INI execution",
749                ScopeName));
750            ACPI_FREE (ScopeName);
751        }
752#endif
753    }
754
755    /* Ignore errors from above */
756
757    Status = AE_OK;
758
759    /*
760     * The _INI method has been run if present; call the Global Initialization
761     * Handler for this device.
762     */
763    if (AcpiGbl_InitHandler)
764    {
765        Status = AcpiGbl_InitHandler (DeviceNode, ACPI_INIT_DEVICE_INI);
766    }
767
768    return_ACPI_STATUS (Status);
769}
770