1 | /****************************************************************************** |
2 | * |
3 | * Module Name: dsinit - Object initialization namespace walk |
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 "acpi.h" |
45 | #include "accommon.h" |
46 | #include "acdispat.h" |
47 | #include "acnamesp.h" |
48 | #include "actables.h" |
49 | |
50 | #define _COMPONENT ACPI_DISPATCHER |
51 | ACPI_MODULE_NAME ("dsinit" ) |
52 | |
53 | |
54 | /* Local prototypes */ |
55 | |
56 | static ACPI_STATUS |
57 | AcpiDsInitOneObject ( |
58 | ACPI_HANDLE ObjHandle, |
59 | UINT32 Level, |
60 | void *Context, |
61 | void **ReturnValue); |
62 | |
63 | |
64 | /******************************************************************************* |
65 | * |
66 | * FUNCTION: AcpiDsInitOneObject |
67 | * |
68 | * PARAMETERS: ObjHandle - Node for the object |
69 | * Level - Current nesting level |
70 | * Context - Points to a init info struct |
71 | * ReturnValue - Not used |
72 | * |
73 | * RETURN: Status |
74 | * |
75 | * DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every object |
76 | * within the namespace. |
77 | * |
78 | * Currently, the only objects that require initialization are: |
79 | * 1) Methods |
80 | * 2) Operation Regions |
81 | * |
82 | ******************************************************************************/ |
83 | |
84 | static ACPI_STATUS |
85 | AcpiDsInitOneObject ( |
86 | ACPI_HANDLE ObjHandle, |
87 | UINT32 Level, |
88 | void *Context, |
89 | void **ReturnValue) |
90 | { |
91 | ACPI_INIT_WALK_INFO *Info = (ACPI_INIT_WALK_INFO *) Context; |
92 | ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; |
93 | ACPI_STATUS Status; |
94 | ACPI_OPERAND_OBJECT *ObjDesc; |
95 | |
96 | |
97 | ACPI_FUNCTION_ENTRY (); |
98 | |
99 | |
100 | /* |
101 | * We are only interested in NS nodes owned by the table that |
102 | * was just loaded |
103 | */ |
104 | if (Node->OwnerId != Info->OwnerId) |
105 | { |
106 | return (AE_OK); |
107 | } |
108 | |
109 | Info->ObjectCount++; |
110 | |
111 | /* And even then, we are only interested in a few object types */ |
112 | |
113 | switch (AcpiNsGetType (ObjHandle)) |
114 | { |
115 | case ACPI_TYPE_REGION: |
116 | |
117 | Status = AcpiDsInitializeRegion (ObjHandle); |
118 | if (ACPI_FAILURE (Status)) |
119 | { |
120 | ACPI_EXCEPTION ((AE_INFO, Status, |
121 | "During Region initialization %p [%4.4s]" , |
122 | ObjHandle, AcpiUtGetNodeName (ObjHandle))); |
123 | } |
124 | |
125 | Info->OpRegionCount++; |
126 | break; |
127 | |
128 | case ACPI_TYPE_METHOD: |
129 | /* |
130 | * Auto-serialization support. We will examine each method that is |
131 | * NotSerialized to determine if it creates any Named objects. If |
132 | * it does, it will be marked serialized to prevent problems if |
133 | * the method is entered by two or more threads and an attempt is |
134 | * made to create the same named object twice -- which results in |
135 | * an AE_ALREADY_EXISTS exception and method abort. |
136 | */ |
137 | Info->MethodCount++; |
138 | ObjDesc = AcpiNsGetAttachedObject (Node); |
139 | if (!ObjDesc) |
140 | { |
141 | break; |
142 | } |
143 | |
144 | /* Ignore if already serialized */ |
145 | |
146 | if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED) |
147 | { |
148 | Info->SerialMethodCount++; |
149 | break; |
150 | } |
151 | |
152 | if (AcpiGbl_AutoSerializeMethods) |
153 | { |
154 | /* Parse/scan method and serialize it if necessary */ |
155 | |
156 | AcpiDsAutoSerializeMethod (Node, ObjDesc); |
157 | if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED) |
158 | { |
159 | /* Method was just converted to Serialized */ |
160 | |
161 | Info->SerialMethodCount++; |
162 | Info->SerializedMethodCount++; |
163 | break; |
164 | } |
165 | } |
166 | |
167 | Info->NonSerialMethodCount++; |
168 | break; |
169 | |
170 | case ACPI_TYPE_DEVICE: |
171 | |
172 | Info->DeviceCount++; |
173 | break; |
174 | |
175 | default: |
176 | |
177 | break; |
178 | } |
179 | |
180 | /* |
181 | * We ignore errors from above, and always return OK, since |
182 | * we don't want to abort the walk on a single error. |
183 | */ |
184 | return (AE_OK); |
185 | } |
186 | |
187 | |
188 | /******************************************************************************* |
189 | * |
190 | * FUNCTION: AcpiDsInitializeObjects |
191 | * |
192 | * PARAMETERS: TableDesc - Descriptor for parent ACPI table |
193 | * StartNode - Root of subtree to be initialized. |
194 | * |
195 | * RETURN: Status |
196 | * |
197 | * DESCRIPTION: Walk the namespace starting at "StartNode" and perform any |
198 | * necessary initialization on the objects found therein |
199 | * |
200 | ******************************************************************************/ |
201 | |
202 | ACPI_STATUS |
203 | AcpiDsInitializeObjects ( |
204 | UINT32 TableIndex, |
205 | ACPI_NAMESPACE_NODE *StartNode) |
206 | { |
207 | ACPI_STATUS Status; |
208 | ACPI_INIT_WALK_INFO Info; |
209 | ACPI_TABLE_HEADER *Table; |
210 | ACPI_OWNER_ID OwnerId; |
211 | |
212 | |
213 | ACPI_FUNCTION_TRACE (DsInitializeObjects); |
214 | |
215 | |
216 | Status = AcpiTbGetOwnerId (TableIndex, &OwnerId); |
217 | if (ACPI_FAILURE (Status)) |
218 | { |
219 | return_ACPI_STATUS (Status); |
220 | } |
221 | |
222 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, |
223 | "**** Starting initialization of namespace objects ****\n" )); |
224 | |
225 | /* Set all init info to zero */ |
226 | |
227 | memset (&Info, 0, sizeof (ACPI_INIT_WALK_INFO)); |
228 | |
229 | Info.OwnerId = OwnerId; |
230 | Info.TableIndex = TableIndex; |
231 | |
232 | /* Walk entire namespace from the supplied root */ |
233 | |
234 | Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); |
235 | if (ACPI_FAILURE (Status)) |
236 | { |
237 | return_ACPI_STATUS (Status); |
238 | } |
239 | |
240 | /* |
241 | * We don't use AcpiWalkNamespace since we do not want to acquire |
242 | * the namespace reader lock. |
243 | */ |
244 | Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, StartNode, ACPI_UINT32_MAX, |
245 | ACPI_NS_WALK_UNLOCK, AcpiDsInitOneObject, NULL, &Info, NULL); |
246 | if (ACPI_FAILURE (Status)) |
247 | { |
248 | ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace" )); |
249 | } |
250 | (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); |
251 | |
252 | Status = AcpiGetTableByIndex (TableIndex, &Table); |
253 | if (ACPI_FAILURE (Status)) |
254 | { |
255 | return_ACPI_STATUS (Status); |
256 | } |
257 | |
258 | /* DSDT is always the first AML table */ |
259 | |
260 | if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT)) |
261 | { |
262 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, |
263 | "\nInitializing Namespace objects:\n" )); |
264 | } |
265 | |
266 | /* Summary of objects initialized */ |
267 | |
268 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, |
269 | "Table [%4.4s: %-8.8s] (id %.2X) - %4u Objects with %3u Devices, " |
270 | "%3u Regions, %4u Methods (%u/%u/%u Serial/Non/Cvt)\n" , |
271 | Table->Signature, Table->OemTableId, OwnerId, Info.ObjectCount, |
272 | Info.DeviceCount,Info.OpRegionCount, Info.MethodCount, |
273 | Info.SerialMethodCount, Info.NonSerialMethodCount, |
274 | Info.SerializedMethodCount)); |
275 | |
276 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "%u Methods, %u Regions\n" , |
277 | Info.MethodCount, Info.OpRegionCount)); |
278 | |
279 | return_ACPI_STATUS (AE_OK); |
280 | } |
281 | |