nsinit.c revision 306536
1/******************************************************************************
2 *
3 * Module Name: nsinit - namespace initialization
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2016, 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 MERCHANTIBILITY 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 <contrib/dev/acpica/include/acpi.h>
45#include <contrib/dev/acpica/include/accommon.h>
46#include <contrib/dev/acpica/include/acnamesp.h>
47#include <contrib/dev/acpica/include/acdispat.h>
48#include <contrib/dev/acpica/include/acinterp.h>
49#include <contrib/dev/acpica/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        "Completing Region/Field/Buffer/Package initialization:\n"));
108
109    /* Set all init info to zero */
110
111    memset (&Info, 0, sizeof (ACPI_INIT_WALK_INFO));
112
113    /* Walk entire namespace from the supplied root */
114
115    Status = AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
116        ACPI_UINT32_MAX, AcpiNsInitOneObject, NULL,
117        &Info, NULL);
118    if (ACPI_FAILURE (Status))
119    {
120        ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace"));
121    }
122
123    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
124        "    Initialized %u/%u Regions %u/%u Fields %u/%u "
125        "Buffers %u/%u Packages (%u nodes)\n",
126        Info.OpRegionInit,  Info.OpRegionCount,
127        Info.FieldInit,     Info.FieldCount,
128        Info.BufferInit,    Info.BufferCount,
129        Info.PackageInit,   Info.PackageCount, Info.ObjectCount));
130
131    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
132        "%u Control Methods found\n%u Op Regions found\n",
133        Info.MethodCount, Info.OpRegionCount));
134
135    return_ACPI_STATUS (AE_OK);
136}
137
138
139/*******************************************************************************
140 *
141 * FUNCTION:    AcpiNsInitializeDevices
142 *
143 * PARAMETERS:  None
144 *
145 * RETURN:      ACPI_STATUS
146 *
147 * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices.
148 *              This means running _INI on all present devices.
149 *
150 *              Note: We install PCI config space handler on region access,
151 *              not here.
152 *
153 ******************************************************************************/
154
155ACPI_STATUS
156AcpiNsInitializeDevices (
157    UINT32                  Flags)
158{
159    ACPI_STATUS             Status = AE_OK;
160    ACPI_DEVICE_WALK_INFO   Info;
161    ACPI_HANDLE             Handle;
162
163
164    ACPI_FUNCTION_TRACE (NsInitializeDevices);
165
166
167    if (!(Flags & ACPI_NO_DEVICE_INIT))
168    {
169        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
170            "[Init] Initializing ACPI Devices\n"));
171
172        /* Init counters */
173
174        Info.DeviceCount = 0;
175        Info.Num_STA = 0;
176        Info.Num_INI = 0;
177
178        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
179            "Initializing Device/Processor/Thermal objects "
180            "and executing _INI/_STA methods:\n"));
181
182        /* Tree analysis: find all subtrees that contain _INI methods */
183
184        Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
185            ACPI_UINT32_MAX, FALSE, AcpiNsFindIniMethods, NULL, &Info, NULL);
186        if (ACPI_FAILURE (Status))
187        {
188            goto ErrorExit;
189        }
190
191        /* Allocate the evaluation information block */
192
193        Info.EvaluateInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
194        if (!Info.EvaluateInfo)
195        {
196            Status = AE_NO_MEMORY;
197            goto ErrorExit;
198        }
199
200        /*
201         * Execute the "global" _INI method that may appear at the root.
202         * This support is provided for Windows compatibility (Vista+) and
203         * is not part of the ACPI specification.
204         */
205        Info.EvaluateInfo->PrefixNode = AcpiGbl_RootNode;
206        Info.EvaluateInfo->RelativePathname = METHOD_NAME__INI;
207        Info.EvaluateInfo->Parameters = NULL;
208        Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE;
209
210        Status = AcpiNsEvaluate (Info.EvaluateInfo);
211        if (ACPI_SUCCESS (Status))
212        {
213            Info.Num_INI++;
214        }
215
216        /*
217         * Execute \_SB._INI.
218         * There appears to be a strict order requirement for \_SB._INI,
219         * which should be evaluated before any _REG evaluations.
220         */
221        Status = AcpiGetHandle (NULL, "\\_SB", &Handle);
222        if (ACPI_SUCCESS (Status))
223        {
224            memset (Info.EvaluateInfo, 0, sizeof (ACPI_EVALUATE_INFO));
225            Info.EvaluateInfo->PrefixNode = Handle;
226            Info.EvaluateInfo->RelativePathname = METHOD_NAME__INI;
227            Info.EvaluateInfo->Parameters = NULL;
228            Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE;
229
230            Status = AcpiNsEvaluate (Info.EvaluateInfo);
231            if (ACPI_SUCCESS (Status))
232            {
233                Info.Num_INI++;
234            }
235        }
236    }
237
238    /*
239     * Run all _REG methods
240     *
241     * Note: Any objects accessed by the _REG methods will be automatically
242     * initialized, even if they contain executable AML (see the call to
243     * AcpiNsInitializeObjects below).
244     *
245     * Note: According to the ACPI specification, we actually needn't execute
246     * _REG for SystemMemory/SystemIo operation regions, but for PCI_Config
247     * operation regions, it is required to evaluate _REG for those on a PCI
248     * root bus that doesn't contain _BBN object. So this code is kept here
249     * in order not to break things.
250     */
251    if (!(Flags & ACPI_NO_ADDRESS_SPACE_INIT))
252    {
253        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
254            "[Init] Executing _REG OpRegion methods\n"));
255
256        Status = AcpiEvInitializeOpRegions ();
257        if (ACPI_FAILURE (Status))
258        {
259            goto ErrorExit;
260        }
261    }
262
263    if (!(Flags & ACPI_NO_DEVICE_INIT))
264    {
265        /* Walk namespace to execute all _INIs on present devices */
266
267        Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
268            ACPI_UINT32_MAX, FALSE, AcpiNsInitOneDevice, NULL, &Info, NULL);
269
270        /*
271         * Any _OSI requests should be completed by now. If the BIOS has
272         * requested any Windows OSI strings, we will always truncate
273         * I/O addresses to 16 bits -- for Windows compatibility.
274         */
275        if (AcpiGbl_OsiData >= ACPI_OSI_WIN_2000)
276        {
277            AcpiGbl_TruncateIoAddresses = TRUE;
278        }
279
280        ACPI_FREE (Info.EvaluateInfo);
281        if (ACPI_FAILURE (Status))
282        {
283            goto ErrorExit;
284        }
285
286        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
287            "    Executed %u _INI methods requiring %u _STA executions "
288            "(examined %u objects)\n",
289            Info.Num_INI, Info.Num_STA, Info.DeviceCount));
290    }
291
292    return_ACPI_STATUS (Status);
293
294
295ErrorExit:
296    ACPI_EXCEPTION ((AE_INFO, Status, "During device initialization"));
297    return_ACPI_STATUS (Status);
298}
299
300
301/*******************************************************************************
302 *
303 * FUNCTION:    AcpiNsInitOneObject
304 *
305 * PARAMETERS:  ObjHandle       - Node
306 *              Level           - Current nesting level
307 *              Context         - Points to a init info struct
308 *              ReturnValue     - Not used
309 *
310 * RETURN:      Status
311 *
312 * DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every object
313 *              within the  namespace.
314 *
315 *              Currently, the only objects that require initialization are:
316 *              1) Methods
317 *              2) Op Regions
318 *
319 ******************************************************************************/
320
321static ACPI_STATUS
322AcpiNsInitOneObject (
323    ACPI_HANDLE             ObjHandle,
324    UINT32                  Level,
325    void                    *Context,
326    void                    **ReturnValue)
327{
328    ACPI_OBJECT_TYPE        Type;
329    ACPI_STATUS             Status = AE_OK;
330    ACPI_INIT_WALK_INFO     *Info = (ACPI_INIT_WALK_INFO *) Context;
331    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
332    ACPI_OPERAND_OBJECT     *ObjDesc;
333
334
335    ACPI_FUNCTION_NAME (NsInitOneObject);
336
337
338    Info->ObjectCount++;
339
340    /* And even then, we are only interested in a few object types */
341
342    Type = AcpiNsGetType (ObjHandle);
343    ObjDesc = AcpiNsGetAttachedObject (Node);
344    if (!ObjDesc)
345    {
346        return (AE_OK);
347    }
348
349    /* Increment counters for object types we are looking for */
350
351    switch (Type)
352    {
353    case ACPI_TYPE_REGION:
354
355        Info->OpRegionCount++;
356        break;
357
358    case ACPI_TYPE_BUFFER_FIELD:
359
360        Info->FieldCount++;
361        break;
362
363    case ACPI_TYPE_LOCAL_BANK_FIELD:
364
365        Info->FieldCount++;
366        break;
367
368    case ACPI_TYPE_BUFFER:
369
370        Info->BufferCount++;
371        break;
372
373    case ACPI_TYPE_PACKAGE:
374
375        Info->PackageCount++;
376        break;
377
378    default:
379
380        /* No init required, just exit now */
381
382        return (AE_OK);
383    }
384
385    /* If the object is already initialized, nothing else to do */
386
387    if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
388    {
389        return (AE_OK);
390    }
391
392    /* Must lock the interpreter before executing AML code */
393
394    AcpiExEnterInterpreter ();
395
396    /*
397     * Each of these types can contain executable AML code within the
398     * declaration.
399     */
400    switch (Type)
401    {
402    case ACPI_TYPE_REGION:
403
404        Info->OpRegionInit++;
405        Status = AcpiDsGetRegionArguments (ObjDesc);
406        break;
407
408    case ACPI_TYPE_BUFFER_FIELD:
409
410        Info->FieldInit++;
411        Status = AcpiDsGetBufferFieldArguments (ObjDesc);
412        break;
413
414    case ACPI_TYPE_LOCAL_BANK_FIELD:
415
416        Info->FieldInit++;
417        Status = AcpiDsGetBankFieldArguments (ObjDesc);
418        break;
419
420    case ACPI_TYPE_BUFFER:
421
422        Info->BufferInit++;
423        Status = AcpiDsGetBufferArguments (ObjDesc);
424        break;
425
426    case ACPI_TYPE_PACKAGE:
427
428        Info->PackageInit++;
429        Status = AcpiDsGetPackageArguments (ObjDesc);
430        break;
431
432    default:
433
434        /* No other types can get here */
435
436        break;
437    }
438
439    if (ACPI_FAILURE (Status))
440    {
441        ACPI_EXCEPTION ((AE_INFO, Status,
442            "Could not execute arguments for [%4.4s] (%s)",
443            AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Type)));
444    }
445
446    /*
447     * We ignore errors from above, and always return OK, since we don't want
448     * to abort the walk on any single error.
449     */
450    AcpiExExitInterpreter ();
451    return (AE_OK);
452}
453
454
455/*******************************************************************************
456 *
457 * FUNCTION:    AcpiNsFindIniMethods
458 *
459 * PARAMETERS:  ACPI_WALK_CALLBACK
460 *
461 * RETURN:      ACPI_STATUS
462 *
463 * DESCRIPTION: Called during namespace walk. Finds objects named _INI under
464 *              device/processor/thermal objects, and marks the entire subtree
465 *              with a SUBTREE_HAS_INI flag. This flag is used during the
466 *              subsequent device initialization walk to avoid entire subtrees
467 *              that do not contain an _INI.
468 *
469 ******************************************************************************/
470
471static ACPI_STATUS
472AcpiNsFindIniMethods (
473    ACPI_HANDLE             ObjHandle,
474    UINT32                  NestingLevel,
475    void                    *Context,
476    void                    **ReturnValue)
477{
478    ACPI_DEVICE_WALK_INFO   *Info = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context);
479    ACPI_NAMESPACE_NODE     *Node;
480    ACPI_NAMESPACE_NODE     *ParentNode;
481
482
483    /* Keep count of device/processor/thermal objects */
484
485    Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
486    if ((Node->Type == ACPI_TYPE_DEVICE)    ||
487        (Node->Type == ACPI_TYPE_PROCESSOR) ||
488        (Node->Type == ACPI_TYPE_THERMAL))
489    {
490        Info->DeviceCount++;
491        return (AE_OK);
492    }
493
494    /* We are only looking for methods named _INI */
495
496    if (!ACPI_COMPARE_NAME (Node->Name.Ascii, METHOD_NAME__INI))
497    {
498        return (AE_OK);
499    }
500
501    /*
502     * The only _INI methods that we care about are those that are
503     * present under Device, Processor, and Thermal objects.
504     */
505    ParentNode = Node->Parent;
506    switch (ParentNode->Type)
507    {
508    case ACPI_TYPE_DEVICE:
509    case ACPI_TYPE_PROCESSOR:
510    case ACPI_TYPE_THERMAL:
511
512        /* Mark parent and bubble up the INI present flag to the root */
513
514        while (ParentNode)
515        {
516            ParentNode->Flags |= ANOBJ_SUBTREE_HAS_INI;
517            ParentNode = ParentNode->Parent;
518        }
519        break;
520
521    default:
522
523        break;
524    }
525
526    return (AE_OK);
527}
528
529
530/*******************************************************************************
531 *
532 * FUNCTION:    AcpiNsInitOneDevice
533 *
534 * PARAMETERS:  ACPI_WALK_CALLBACK
535 *
536 * RETURN:      ACPI_STATUS
537 *
538 * DESCRIPTION: This is called once per device soon after ACPI is enabled
539 *              to initialize each device. It determines if the device is
540 *              present, and if so, calls _INI.
541 *
542 ******************************************************************************/
543
544static ACPI_STATUS
545AcpiNsInitOneDevice (
546    ACPI_HANDLE             ObjHandle,
547    UINT32                  NestingLevel,
548    void                    *Context,
549    void                    **ReturnValue)
550{
551    ACPI_DEVICE_WALK_INFO   *WalkInfo = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context);
552    ACPI_EVALUATE_INFO      *Info = WalkInfo->EvaluateInfo;
553    UINT32                  Flags;
554    ACPI_STATUS             Status;
555    ACPI_NAMESPACE_NODE     *DeviceNode;
556
557
558    ACPI_FUNCTION_TRACE (NsInitOneDevice);
559
560
561    /* We are interested in Devices, Processors and ThermalZones only */
562
563    DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
564    if ((DeviceNode->Type != ACPI_TYPE_DEVICE)    &&
565        (DeviceNode->Type != ACPI_TYPE_PROCESSOR) &&
566        (DeviceNode->Type != ACPI_TYPE_THERMAL))
567    {
568        return_ACPI_STATUS (AE_OK);
569    }
570
571    /*
572     * Because of an earlier namespace analysis, all subtrees that contain an
573     * _INI method are tagged.
574     *
575     * If this device subtree does not contain any _INI methods, we
576     * can exit now and stop traversing this entire subtree.
577     */
578    if (!(DeviceNode->Flags & ANOBJ_SUBTREE_HAS_INI))
579    {
580        return_ACPI_STATUS (AE_CTRL_DEPTH);
581    }
582
583    /*
584     * Run _STA to determine if this device is present and functioning. We
585     * must know this information for two important reasons (from ACPI spec):
586     *
587     * 1) We can only run _INI if the device is present.
588     * 2) We must abort the device tree walk on this subtree if the device is
589     *    not present and is not functional (we will not examine the children)
590     *
591     * The _STA method is not required to be present under the device, we
592     * assume the device is present if _STA does not exist.
593     */
594    ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
595        ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__STA));
596
597    Status = AcpiUtExecute_STA (DeviceNode, &Flags);
598    if (ACPI_FAILURE (Status))
599    {
600        /* Ignore error and move on to next device */
601
602        return_ACPI_STATUS (AE_OK);
603    }
604
605    /*
606     * Flags == -1 means that _STA was not found. In this case, we assume that
607     * the device is both present and functional.
608     *
609     * From the ACPI spec, description of _STA:
610     *
611     * "If a device object (including the processor object) does not have an
612     * _STA object, then OSPM assumes that all of the above bits are set (in
613     * other words, the device is present, ..., and functioning)"
614     */
615    if (Flags != ACPI_UINT32_MAX)
616    {
617        WalkInfo->Num_STA++;
618    }
619
620    /*
621     * Examine the PRESENT and FUNCTIONING status bits
622     *
623     * Note: ACPI spec does not seem to specify behavior for the present but
624     * not functioning case, so we assume functioning if present.
625     */
626    if (!(Flags & ACPI_STA_DEVICE_PRESENT))
627    {
628        /* Device is not present, we must examine the Functioning bit */
629
630        if (Flags & ACPI_STA_DEVICE_FUNCTIONING)
631        {
632            /*
633             * Device is not present but is "functioning". In this case,
634             * we will not run _INI, but we continue to examine the children
635             * of this device.
636             *
637             * From the ACPI spec, description of _STA: (Note - no mention
638             * of whether to run _INI or not on the device in question)
639             *
640             * "_STA may return bit 0 clear (not present) with bit 3 set
641             * (device is functional). This case is used to indicate a valid
642             * device for which no device driver should be loaded (for example,
643             * a bridge device.) Children of this device may be present and
644             * valid. OSPM should continue enumeration below a device whose
645             * _STA returns this bit combination"
646             */
647            return_ACPI_STATUS (AE_OK);
648        }
649        else
650        {
651            /*
652             * Device is not present and is not functioning. We must abort the
653             * walk of this subtree immediately -- don't look at the children
654             * of such a device.
655             *
656             * From the ACPI spec, description of _INI:
657             *
658             * "If the _STA method indicates that the device is not present,
659             * OSPM will not run the _INI and will not examine the children
660             * of the device for _INI methods"
661             */
662            return_ACPI_STATUS (AE_CTRL_DEPTH);
663        }
664    }
665
666    /*
667     * The device is present or is assumed present if no _STA exists.
668     * Run the _INI if it exists (not required to exist)
669     *
670     * Note: We know there is an _INI within this subtree, but it may not be
671     * under this particular device, it may be lower in the branch.
672     */
673    if (!ACPI_COMPARE_NAME (DeviceNode->Name.Ascii, "_SB_") ||
674        DeviceNode->Parent != AcpiGbl_RootNode)
675    {
676        ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
677            ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__INI));
678
679        memset (Info, 0, sizeof (ACPI_EVALUATE_INFO));
680        Info->PrefixNode = DeviceNode;
681        Info->RelativePathname = METHOD_NAME__INI;
682        Info->Parameters = NULL;
683        Info->Flags = ACPI_IGNORE_RETURN_VALUE;
684
685        Status = AcpiNsEvaluate (Info);
686        if (ACPI_SUCCESS (Status))
687        {
688            WalkInfo->Num_INI++;
689        }
690
691#ifdef ACPI_DEBUG_OUTPUT
692        else if (Status != AE_NOT_FOUND)
693        {
694            /* Ignore error and move on to next device */
695
696            char *ScopeName = AcpiNsGetNormalizedPathname (DeviceNode, TRUE);
697
698            ACPI_EXCEPTION ((AE_INFO, Status, "during %s._INI execution",
699                ScopeName));
700            ACPI_FREE (ScopeName);
701        }
702#endif
703    }
704
705    /* Ignore errors from above */
706
707    Status = AE_OK;
708
709    /*
710     * The _INI method has been run if present; call the Global Initialization
711     * Handler for this device.
712     */
713    if (AcpiGbl_InitHandler)
714    {
715        Status = AcpiGbl_InitHandler (DeviceNode, ACPI_INIT_DEVICE_INI);
716    }
717
718    return_ACPI_STATUS (Status);
719}
720