1 | /****************************************************************************** |
2 | * |
3 | * Module Name: uteval - Object evaluation |
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 "acnamesp.h" |
47 | |
48 | |
49 | #define _COMPONENT ACPI_UTILITIES |
50 | ACPI_MODULE_NAME ("uteval" ) |
51 | |
52 | |
53 | /******************************************************************************* |
54 | * |
55 | * FUNCTION: AcpiUtEvaluateObject |
56 | * |
57 | * PARAMETERS: PrefixNode - Starting node |
58 | * Path - Path to object from starting node |
59 | * ExpectedReturnTypes - Bitmap of allowed return types |
60 | * ReturnDesc - Where a return value is stored |
61 | * |
62 | * RETURN: Status |
63 | * |
64 | * DESCRIPTION: Evaluates a namespace object and verifies the type of the |
65 | * return object. Common code that simplifies accessing objects |
66 | * that have required return objects of fixed types. |
67 | * |
68 | * NOTE: Internal function, no parameter validation |
69 | * |
70 | ******************************************************************************/ |
71 | |
72 | ACPI_STATUS |
73 | AcpiUtEvaluateObject ( |
74 | ACPI_NAMESPACE_NODE *PrefixNode, |
75 | const char *Path, |
76 | UINT32 ExpectedReturnBtypes, |
77 | ACPI_OPERAND_OBJECT **ReturnDesc) |
78 | { |
79 | ACPI_EVALUATE_INFO *Info; |
80 | ACPI_STATUS Status; |
81 | UINT32 ReturnBtype; |
82 | |
83 | |
84 | ACPI_FUNCTION_TRACE (UtEvaluateObject); |
85 | |
86 | |
87 | /* Allocate the evaluation information block */ |
88 | |
89 | Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); |
90 | if (!Info) |
91 | { |
92 | return_ACPI_STATUS (AE_NO_MEMORY); |
93 | } |
94 | |
95 | Info->PrefixNode = PrefixNode; |
96 | Info->RelativePathname = __UNCONST(Path); |
97 | |
98 | /* Evaluate the object/method */ |
99 | |
100 | Status = AcpiNsEvaluate (Info); |
101 | if (ACPI_FAILURE (Status)) |
102 | { |
103 | if (Status == AE_NOT_FOUND) |
104 | { |
105 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n" , |
106 | AcpiUtGetNodeName (PrefixNode), Path)); |
107 | } |
108 | else |
109 | { |
110 | ACPI_ERROR_METHOD ("Method execution failed" , |
111 | PrefixNode, Path, Status); |
112 | } |
113 | |
114 | goto Cleanup; |
115 | } |
116 | |
117 | /* Did we get a return object? */ |
118 | |
119 | if (!Info->ReturnObject) |
120 | { |
121 | if (ExpectedReturnBtypes) |
122 | { |
123 | ACPI_ERROR_METHOD ("No object was returned from" , |
124 | PrefixNode, Path, AE_NOT_EXIST); |
125 | |
126 | Status = AE_NOT_EXIST; |
127 | } |
128 | |
129 | goto Cleanup; |
130 | } |
131 | |
132 | /* Map the return object type to the bitmapped type */ |
133 | |
134 | switch ((Info->ReturnObject)->Common.Type) |
135 | { |
136 | case ACPI_TYPE_INTEGER: |
137 | |
138 | ReturnBtype = ACPI_BTYPE_INTEGER; |
139 | break; |
140 | |
141 | case ACPI_TYPE_BUFFER: |
142 | |
143 | ReturnBtype = ACPI_BTYPE_BUFFER; |
144 | break; |
145 | |
146 | case ACPI_TYPE_STRING: |
147 | |
148 | ReturnBtype = ACPI_BTYPE_STRING; |
149 | break; |
150 | |
151 | case ACPI_TYPE_PACKAGE: |
152 | |
153 | ReturnBtype = ACPI_BTYPE_PACKAGE; |
154 | break; |
155 | |
156 | default: |
157 | |
158 | ReturnBtype = 0; |
159 | break; |
160 | } |
161 | |
162 | if ((AcpiGbl_EnableInterpreterSlack) && |
163 | (!ExpectedReturnBtypes)) |
164 | { |
165 | /* |
166 | * We received a return object, but one was not expected. This can |
167 | * happen frequently if the "implicit return" feature is enabled. |
168 | * Just delete the return object and return AE_OK. |
169 | */ |
170 | AcpiUtRemoveReference (Info->ReturnObject); |
171 | goto Cleanup; |
172 | } |
173 | |
174 | /* Is the return object one of the expected types? */ |
175 | |
176 | if (!(ExpectedReturnBtypes & ReturnBtype)) |
177 | { |
178 | ACPI_ERROR_METHOD ("Return object type is incorrect" , |
179 | PrefixNode, Path, AE_TYPE); |
180 | |
181 | ACPI_ERROR ((AE_INFO, |
182 | "Type returned from %s was incorrect: %s, expected Btypes: 0x%X" , |
183 | Path, AcpiUtGetObjectTypeName (Info->ReturnObject), |
184 | ExpectedReturnBtypes)); |
185 | |
186 | /* On error exit, we must delete the return object */ |
187 | |
188 | AcpiUtRemoveReference (Info->ReturnObject); |
189 | Status = AE_TYPE; |
190 | goto Cleanup; |
191 | } |
192 | |
193 | /* Object type is OK, return it */ |
194 | |
195 | *ReturnDesc = Info->ReturnObject; |
196 | |
197 | Cleanup: |
198 | ACPI_FREE (Info); |
199 | return_ACPI_STATUS (Status); |
200 | } |
201 | |
202 | |
203 | /******************************************************************************* |
204 | * |
205 | * FUNCTION: AcpiUtEvaluateNumericObject |
206 | * |
207 | * PARAMETERS: ObjectName - Object name to be evaluated |
208 | * DeviceNode - Node for the device |
209 | * Value - Where the value is returned |
210 | * |
211 | * RETURN: Status |
212 | * |
213 | * DESCRIPTION: Evaluates a numeric namespace object for a selected device |
214 | * and stores result in *Value. |
215 | * |
216 | * NOTE: Internal function, no parameter validation |
217 | * |
218 | ******************************************************************************/ |
219 | |
220 | ACPI_STATUS |
221 | AcpiUtEvaluateNumericObject ( |
222 | const char *ObjectName, |
223 | ACPI_NAMESPACE_NODE *DeviceNode, |
224 | UINT64 *Value) |
225 | { |
226 | ACPI_OPERAND_OBJECT *ObjDesc; |
227 | ACPI_STATUS Status; |
228 | |
229 | |
230 | ACPI_FUNCTION_TRACE (UtEvaluateNumericObject); |
231 | |
232 | |
233 | Status = AcpiUtEvaluateObject (DeviceNode, ObjectName, |
234 | ACPI_BTYPE_INTEGER, &ObjDesc); |
235 | if (ACPI_FAILURE (Status)) |
236 | { |
237 | return_ACPI_STATUS (Status); |
238 | } |
239 | |
240 | /* Get the returned Integer */ |
241 | |
242 | *Value = ObjDesc->Integer.Value; |
243 | |
244 | /* On exit, we must delete the return object */ |
245 | |
246 | AcpiUtRemoveReference (ObjDesc); |
247 | return_ACPI_STATUS (Status); |
248 | } |
249 | |
250 | |
251 | /******************************************************************************* |
252 | * |
253 | * FUNCTION: AcpiUtExecute_STA |
254 | * |
255 | * PARAMETERS: DeviceNode - Node for the device |
256 | * Flags - Where the status flags are returned |
257 | * |
258 | * RETURN: Status |
259 | * |
260 | * DESCRIPTION: Executes _STA for selected device and stores results in |
261 | * *Flags. If _STA does not exist, then the device is assumed |
262 | * to be present/functional/enabled (as per the ACPI spec). |
263 | * |
264 | * NOTE: Internal function, no parameter validation |
265 | * |
266 | ******************************************************************************/ |
267 | |
268 | ACPI_STATUS |
269 | AcpiUtExecute_STA ( |
270 | ACPI_NAMESPACE_NODE *DeviceNode, |
271 | UINT32 *Flags) |
272 | { |
273 | ACPI_OPERAND_OBJECT *ObjDesc; |
274 | ACPI_STATUS Status; |
275 | |
276 | |
277 | ACPI_FUNCTION_TRACE (UtExecute_STA); |
278 | |
279 | |
280 | Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__STA, |
281 | ACPI_BTYPE_INTEGER, &ObjDesc); |
282 | if (ACPI_FAILURE (Status)) |
283 | { |
284 | if (AE_NOT_FOUND == Status) |
285 | { |
286 | /* |
287 | * if _STA does not exist, then (as per the ACPI specification), |
288 | * the returned flags will indicate that the device is present, |
289 | * functional, and enabled. |
290 | */ |
291 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, |
292 | "_STA on %4.4s was not found, assuming device is present\n" , |
293 | AcpiUtGetNodeName (DeviceNode))); |
294 | |
295 | *Flags = ACPI_UINT32_MAX; |
296 | Status = AE_OK; |
297 | } |
298 | |
299 | return_ACPI_STATUS (Status); |
300 | } |
301 | |
302 | /* Extract the status flags */ |
303 | |
304 | *Flags = (UINT32) ObjDesc->Integer.Value; |
305 | |
306 | /* On exit, we must delete the return object */ |
307 | |
308 | AcpiUtRemoveReference (ObjDesc); |
309 | return_ACPI_STATUS (Status); |
310 | } |
311 | |
312 | |
313 | /******************************************************************************* |
314 | * |
315 | * FUNCTION: AcpiUtExecutePowerMethods |
316 | * |
317 | * PARAMETERS: DeviceNode - Node for the device |
318 | * MethodNames - Array of power method names |
319 | * MethodCount - Number of methods to execute |
320 | * OutValues - Where the power method values are returned |
321 | * |
322 | * RETURN: Status, OutValues |
323 | * |
324 | * DESCRIPTION: Executes the specified power methods for the device and returns |
325 | * the result(s). |
326 | * |
327 | * NOTE: Internal function, no parameter validation |
328 | * |
329 | ******************************************************************************/ |
330 | |
331 | ACPI_STATUS |
332 | AcpiUtExecutePowerMethods ( |
333 | ACPI_NAMESPACE_NODE *DeviceNode, |
334 | const char **MethodNames, |
335 | UINT8 MethodCount, |
336 | UINT8 *OutValues) |
337 | { |
338 | ACPI_OPERAND_OBJECT *ObjDesc; |
339 | ACPI_STATUS Status; |
340 | ACPI_STATUS FinalStatus = AE_NOT_FOUND; |
341 | UINT32 i; |
342 | |
343 | |
344 | ACPI_FUNCTION_TRACE (UtExecutePowerMethods); |
345 | |
346 | |
347 | for (i = 0; i < MethodCount; i++) |
348 | { |
349 | /* |
350 | * Execute the power method (_SxD or _SxW). The only allowable |
351 | * return type is an Integer. |
352 | */ |
353 | Status = AcpiUtEvaluateObject (DeviceNode, |
354 | ACPI_CAST_PTR (char, MethodNames[i]), |
355 | ACPI_BTYPE_INTEGER, &ObjDesc); |
356 | if (ACPI_SUCCESS (Status)) |
357 | { |
358 | OutValues[i] = (UINT8) ObjDesc->Integer.Value; |
359 | |
360 | /* Delete the return object */ |
361 | |
362 | AcpiUtRemoveReference (ObjDesc); |
363 | FinalStatus = AE_OK; /* At least one value is valid */ |
364 | continue; |
365 | } |
366 | |
367 | OutValues[i] = ACPI_UINT8_MAX; |
368 | if (Status == AE_NOT_FOUND) |
369 | { |
370 | continue; /* Ignore if not found */ |
371 | } |
372 | |
373 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Failed %s on Device %4.4s, %s\n" , |
374 | ACPI_CAST_PTR (char, MethodNames[i]), |
375 | AcpiUtGetNodeName (DeviceNode), AcpiFormatException (Status))); |
376 | } |
377 | |
378 | return_ACPI_STATUS (FinalStatus); |
379 | } |
380 | |