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
AcpiNsInitializeObjects(void)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
AcpiNsInitializeDevices(UINT32 Flags)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
AcpiNsInitOneObject(ACPI_HANDLE ObjHandle,UINT32 Level,void * Context,void ** ReturnValue)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
AcpiNsFindIniMethods(ACPI_HANDLE ObjHandle,UINT32 NestingLevel,void * Context,void ** ReturnValue)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
AcpiNsInitOneDevice(ACPI_HANDLE ObjHandle,UINT32 NestingLevel,void * Context,void ** ReturnValue)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