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