uteval.c revision 281075
1/******************************************************************************
2 *
3 * Module Name: uteval - Object evaluation
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2015, 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
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
72ACPI_STATUS
73AcpiUtEvaluateObject (
74    ACPI_NAMESPACE_NODE     *PrefixNode,
75    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 = 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
197Cleanup:
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
220ACPI_STATUS
221AcpiUtEvaluateNumericObject (
222    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
268ACPI_STATUS
269AcpiUtExecute_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
331ACPI_STATUS
332AcpiUtExecutePowerMethods (
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