uteval.c revision 250838
1219820Sjeff/******************************************************************************
2219820Sjeff *
3219820Sjeff * Module Name: uteval - Object evaluation
4219820Sjeff *
5219820Sjeff *****************************************************************************/
6219820Sjeff
7219820Sjeff/*
8219820Sjeff * Copyright (C) 2000 - 2013, Intel Corp.
9219820Sjeff * All rights reserved.
10219820Sjeff *
11219820Sjeff * Redistribution and use in source and binary forms, with or without
12219820Sjeff * modification, are permitted provided that the following conditions
13219820Sjeff * are met:
14219820Sjeff * 1. Redistributions of source code must retain the above copyright
15219820Sjeff *    notice, this list of conditions, and the following disclaimer,
16219820Sjeff *    without modification.
17219820Sjeff * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18219820Sjeff *    substantially similar to the "NO WARRANTY" disclaimer below
19219820Sjeff *    ("Disclaimer") and any redistribution must be conditioned upon
20219820Sjeff *    including a substantially similar Disclaimer requirement for further
21219820Sjeff *    binary redistribution.
22219820Sjeff * 3. Neither the names of the above-listed copyright holders nor the names
23219820Sjeff *    of any contributors may be used to endorse or promote products derived
24219820Sjeff *    from this software without specific prior written permission.
25219820Sjeff *
26219820Sjeff * Alternatively, this software may be distributed under the terms of the
27219820Sjeff * GNU General Public License ("GPL") version 2 as published by the Free
28219820Sjeff * Software Foundation.
29219820Sjeff *
30219820Sjeff * NO WARRANTY
31219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32219820Sjeff * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33219820Sjeff * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34219820Sjeff * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35219820Sjeff * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36219820Sjeff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37219820Sjeff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38219820Sjeff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39219820Sjeff * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40219820Sjeff * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41219820Sjeff * POSSIBILITY OF SUCH DAMAGES.
42219820Sjeff */
43219820Sjeff
44219820Sjeff#define __UTEVAL_C__
45219820Sjeff
46219820Sjeff#include <contrib/dev/acpica/include/acpi.h>
47219820Sjeff#include <contrib/dev/acpica/include/accommon.h>
48219820Sjeff#include <contrib/dev/acpica/include/acnamesp.h>
49219820Sjeff
50219820Sjeff
51219820Sjeff#define _COMPONENT          ACPI_UTILITIES
52219820Sjeff        ACPI_MODULE_NAME    ("uteval")
53219820Sjeff
54219820Sjeff
55219820Sjeff/*******************************************************************************
56219820Sjeff *
57219820Sjeff * FUNCTION:    AcpiUtEvaluateObject
58219820Sjeff *
59219820Sjeff * PARAMETERS:  PrefixNode          - Starting node
60219820Sjeff *              Path                - Path to object from starting node
61219820Sjeff *              ExpectedReturnTypes - Bitmap of allowed return types
62219820Sjeff *              ReturnDesc          - Where a return value is stored
63219820Sjeff *
64219820Sjeff * RETURN:      Status
65219820Sjeff *
66219820Sjeff * DESCRIPTION: Evaluates a namespace object and verifies the type of the
67219820Sjeff *              return object. Common code that simplifies accessing objects
68219820Sjeff *              that have required return objects of fixed types.
69219820Sjeff *
70219820Sjeff *              NOTE: Internal function, no parameter validation
71219820Sjeff *
72219820Sjeff ******************************************************************************/
73219820Sjeff
74219820SjeffACPI_STATUS
75219820SjeffAcpiUtEvaluateObject (
76219820Sjeff    ACPI_NAMESPACE_NODE     *PrefixNode,
77219820Sjeff    char                    *Path,
78219820Sjeff    UINT32                  ExpectedReturnBtypes,
79219820Sjeff    ACPI_OPERAND_OBJECT     **ReturnDesc)
80219820Sjeff{
81219820Sjeff    ACPI_EVALUATE_INFO      *Info;
82219820Sjeff    ACPI_STATUS             Status;
83219820Sjeff    UINT32                  ReturnBtype;
84219820Sjeff
85219820Sjeff
86219820Sjeff    ACPI_FUNCTION_TRACE (UtEvaluateObject);
87219820Sjeff
88219820Sjeff
89219820Sjeff    /* Allocate the evaluation information block */
90219820Sjeff
91219820Sjeff    Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
92219820Sjeff    if (!Info)
93219820Sjeff    {
94219820Sjeff        return_ACPI_STATUS (AE_NO_MEMORY);
95219820Sjeff    }
96219820Sjeff
97219820Sjeff    Info->PrefixNode = PrefixNode;
98219820Sjeff    Info->RelativePathname = Path;
99219820Sjeff
100219820Sjeff    /* Evaluate the object/method */
101219820Sjeff
102219820Sjeff    Status = AcpiNsEvaluate (Info);
103219820Sjeff    if (ACPI_FAILURE (Status))
104219820Sjeff    {
105219820Sjeff        if (Status == AE_NOT_FOUND)
106219820Sjeff        {
107219820Sjeff            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n",
108219820Sjeff                AcpiUtGetNodeName (PrefixNode), Path));
109219820Sjeff        }
110219820Sjeff        else
111219820Sjeff        {
112219820Sjeff            ACPI_ERROR_METHOD ("Method execution failed",
113219820Sjeff                PrefixNode, Path, Status);
114219820Sjeff        }
115219820Sjeff
116219820Sjeff        goto Cleanup;
117219820Sjeff    }
118219820Sjeff
119219820Sjeff    /* Did we get a return object? */
120219820Sjeff
121219820Sjeff    if (!Info->ReturnObject)
122219820Sjeff    {
123219820Sjeff        if (ExpectedReturnBtypes)
124219820Sjeff        {
125219820Sjeff            ACPI_ERROR_METHOD ("No object was returned from",
126219820Sjeff                PrefixNode, Path, AE_NOT_EXIST);
127219820Sjeff
128219820Sjeff            Status = AE_NOT_EXIST;
129219820Sjeff        }
130219820Sjeff
131219820Sjeff        goto Cleanup;
132219820Sjeff    }
133219820Sjeff
134219820Sjeff    /* Map the return object type to the bitmapped type */
135219820Sjeff
136219820Sjeff    switch ((Info->ReturnObject)->Common.Type)
137219820Sjeff    {
138219820Sjeff    case ACPI_TYPE_INTEGER:
139219820Sjeff
140219820Sjeff        ReturnBtype = ACPI_BTYPE_INTEGER;
141219820Sjeff        break;
142219820Sjeff
143219820Sjeff    case ACPI_TYPE_BUFFER:
144219820Sjeff
145219820Sjeff        ReturnBtype = ACPI_BTYPE_BUFFER;
146219820Sjeff        break;
147219820Sjeff
148219820Sjeff    case ACPI_TYPE_STRING:
149219820Sjeff
150219820Sjeff        ReturnBtype = ACPI_BTYPE_STRING;
151219820Sjeff        break;
152219820Sjeff
153219820Sjeff    case ACPI_TYPE_PACKAGE:
154219820Sjeff
155219820Sjeff        ReturnBtype = ACPI_BTYPE_PACKAGE;
156219820Sjeff        break;
157219820Sjeff
158219820Sjeff    default:
159219820Sjeff
160219820Sjeff        ReturnBtype = 0;
161219820Sjeff        break;
162219820Sjeff    }
163219820Sjeff
164219820Sjeff    if ((AcpiGbl_EnableInterpreterSlack) &&
165219820Sjeff        (!ExpectedReturnBtypes))
166219820Sjeff    {
167219820Sjeff        /*
168219820Sjeff         * We received a return object, but one was not expected. This can
169219820Sjeff         * happen frequently if the "implicit return" feature is enabled.
170219820Sjeff         * Just delete the return object and return AE_OK.
171219820Sjeff         */
172219820Sjeff        AcpiUtRemoveReference (Info->ReturnObject);
173219820Sjeff        goto Cleanup;
174219820Sjeff    }
175219820Sjeff
176219820Sjeff    /* Is the return object one of the expected types? */
177219820Sjeff
178219820Sjeff    if (!(ExpectedReturnBtypes & ReturnBtype))
179219820Sjeff    {
180219820Sjeff        ACPI_ERROR_METHOD ("Return object type is incorrect",
181219820Sjeff            PrefixNode, Path, AE_TYPE);
182219820Sjeff
183219820Sjeff        ACPI_ERROR ((AE_INFO,
184219820Sjeff            "Type returned from %s was incorrect: %s, expected Btypes: 0x%X",
185219820Sjeff            Path, AcpiUtGetObjectTypeName (Info->ReturnObject),
186219820Sjeff            ExpectedReturnBtypes));
187219820Sjeff
188219820Sjeff        /* On error exit, we must delete the return object */
189219820Sjeff
190219820Sjeff        AcpiUtRemoveReference (Info->ReturnObject);
191219820Sjeff        Status = AE_TYPE;
192219820Sjeff        goto Cleanup;
193219820Sjeff    }
194219820Sjeff
195219820Sjeff    /* Object type is OK, return it */
196219820Sjeff
197219820Sjeff    *ReturnDesc = Info->ReturnObject;
198219820Sjeff
199219820SjeffCleanup:
200219820Sjeff    ACPI_FREE (Info);
201219820Sjeff    return_ACPI_STATUS (Status);
202219820Sjeff}
203219820Sjeff
204219820Sjeff
205219820Sjeff/*******************************************************************************
206219820Sjeff *
207219820Sjeff * FUNCTION:    AcpiUtEvaluateNumericObject
208219820Sjeff *
209219820Sjeff * PARAMETERS:  ObjectName          - Object name to be evaluated
210219820Sjeff *              DeviceNode          - Node for the device
211219820Sjeff *              Value               - Where the value is returned
212219820Sjeff *
213219820Sjeff * RETURN:      Status
214219820Sjeff *
215219820Sjeff * DESCRIPTION: Evaluates a numeric namespace object for a selected device
216219820Sjeff *              and stores result in *Value.
217219820Sjeff *
218219820Sjeff *              NOTE: Internal function, no parameter validation
219219820Sjeff *
220219820Sjeff ******************************************************************************/
221219820Sjeff
222219820SjeffACPI_STATUS
223219820SjeffAcpiUtEvaluateNumericObject (
224219820Sjeff    char                    *ObjectName,
225219820Sjeff    ACPI_NAMESPACE_NODE     *DeviceNode,
226219820Sjeff    UINT64                  *Value)
227219820Sjeff{
228219820Sjeff    ACPI_OPERAND_OBJECT     *ObjDesc;
229219820Sjeff    ACPI_STATUS             Status;
230219820Sjeff
231219820Sjeff
232219820Sjeff    ACPI_FUNCTION_TRACE (UtEvaluateNumericObject);
233219820Sjeff
234219820Sjeff
235219820Sjeff    Status = AcpiUtEvaluateObject (DeviceNode, ObjectName,
236219820Sjeff                ACPI_BTYPE_INTEGER, &ObjDesc);
237219820Sjeff    if (ACPI_FAILURE (Status))
238219820Sjeff    {
239219820Sjeff        return_ACPI_STATUS (Status);
240219820Sjeff    }
241219820Sjeff
242219820Sjeff    /* Get the returned Integer */
243219820Sjeff
244219820Sjeff    *Value = ObjDesc->Integer.Value;
245219820Sjeff
246219820Sjeff    /* On exit, we must delete the return object */
247219820Sjeff
248219820Sjeff    AcpiUtRemoveReference (ObjDesc);
249219820Sjeff    return_ACPI_STATUS (Status);
250219820Sjeff}
251219820Sjeff
252219820Sjeff
253219820Sjeff/*******************************************************************************
254219820Sjeff *
255219820Sjeff * FUNCTION:    AcpiUtExecute_STA
256219820Sjeff *
257219820Sjeff * PARAMETERS:  DeviceNode          - Node for the device
258219820Sjeff *              Flags               - Where the status flags are returned
259219820Sjeff *
260219820Sjeff * RETURN:      Status
261219820Sjeff *
262219820Sjeff * DESCRIPTION: Executes _STA for selected device and stores results in
263219820Sjeff *              *Flags.
264219820Sjeff *
265219820Sjeff *              NOTE: Internal function, no parameter validation
266219820Sjeff *
267219820Sjeff ******************************************************************************/
268219820Sjeff
269219820SjeffACPI_STATUS
270219820SjeffAcpiUtExecute_STA (
271219820Sjeff    ACPI_NAMESPACE_NODE     *DeviceNode,
272219820Sjeff    UINT32                  *Flags)
273219820Sjeff{
274219820Sjeff    ACPI_OPERAND_OBJECT     *ObjDesc;
275219820Sjeff    ACPI_STATUS             Status;
276219820Sjeff
277219820Sjeff
278219820Sjeff    ACPI_FUNCTION_TRACE (UtExecute_STA);
279219820Sjeff
280219820Sjeff
281219820Sjeff    Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__STA,
282219820Sjeff                ACPI_BTYPE_INTEGER, &ObjDesc);
283219820Sjeff    if (ACPI_FAILURE (Status))
284219820Sjeff    {
285219820Sjeff        if (AE_NOT_FOUND == Status)
286219820Sjeff        {
287219820Sjeff            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
288219820Sjeff                "_STA on %4.4s was not found, assuming device is present\n",
289219820Sjeff                AcpiUtGetNodeName (DeviceNode)));
290219820Sjeff
291219820Sjeff            *Flags = ACPI_UINT32_MAX;
292219820Sjeff            Status = AE_OK;
293219820Sjeff        }
294219820Sjeff
295219820Sjeff        return_ACPI_STATUS (Status);
296219820Sjeff    }
297219820Sjeff
298219820Sjeff    /* Extract the status flags */
299219820Sjeff
300219820Sjeff    *Flags = (UINT32) ObjDesc->Integer.Value;
301219820Sjeff
302219820Sjeff    /* On exit, we must delete the return object */
303219820Sjeff
304219820Sjeff    AcpiUtRemoveReference (ObjDesc);
305219820Sjeff    return_ACPI_STATUS (Status);
306219820Sjeff}
307219820Sjeff
308219820Sjeff
309219820Sjeff/*******************************************************************************
310219820Sjeff *
311219820Sjeff * FUNCTION:    AcpiUtExecutePowerMethods
312219820Sjeff *
313219820Sjeff * PARAMETERS:  DeviceNode          - Node for the device
314219820Sjeff *              MethodNames         - Array of power method names
315219820Sjeff *              MethodCount         - Number of methods to execute
316219820Sjeff *              OutValues           - Where the power method values are returned
317219820Sjeff *
318219820Sjeff * RETURN:      Status, OutValues
319219820Sjeff *
320219820Sjeff * DESCRIPTION: Executes the specified power methods for the device and returns
321219820Sjeff *              the result(s).
322219820Sjeff *
323219820Sjeff *              NOTE: Internal function, no parameter validation
324219820Sjeff *
325219820Sjeff ******************************************************************************/
326219820Sjeff
327219820SjeffACPI_STATUS
328219820SjeffAcpiUtExecutePowerMethods (
329219820Sjeff    ACPI_NAMESPACE_NODE     *DeviceNode,
330219820Sjeff    const char              **MethodNames,
331219820Sjeff    UINT8                   MethodCount,
332219820Sjeff    UINT8                   *OutValues)
333219820Sjeff{
334219820Sjeff    ACPI_OPERAND_OBJECT     *ObjDesc;
335219820Sjeff    ACPI_STATUS             Status;
336219820Sjeff    ACPI_STATUS             FinalStatus = AE_NOT_FOUND;
337219820Sjeff    UINT32                  i;
338219820Sjeff
339219820Sjeff
340219820Sjeff    ACPI_FUNCTION_TRACE (UtExecutePowerMethods);
341219820Sjeff
342219820Sjeff
343219820Sjeff    for (i = 0; i < MethodCount; i++)
344219820Sjeff    {
345219820Sjeff        /*
346219820Sjeff         * Execute the power method (_SxD or _SxW). The only allowable
347219820Sjeff         * return type is an Integer.
348219820Sjeff         */
349219820Sjeff        Status = AcpiUtEvaluateObject (DeviceNode,
350219820Sjeff                    ACPI_CAST_PTR (char, MethodNames[i]),
351219820Sjeff                    ACPI_BTYPE_INTEGER, &ObjDesc);
352219820Sjeff        if (ACPI_SUCCESS (Status))
353219820Sjeff        {
354219820Sjeff            OutValues[i] = (UINT8) ObjDesc->Integer.Value;
355219820Sjeff
356219820Sjeff            /* Delete the return object */
357219820Sjeff
358219820Sjeff            AcpiUtRemoveReference (ObjDesc);
359219820Sjeff            FinalStatus = AE_OK;            /* At least one value is valid */
360219820Sjeff            continue;
361219820Sjeff        }
362219820Sjeff
363219820Sjeff        OutValues[i] = ACPI_UINT8_MAX;
364219820Sjeff        if (Status == AE_NOT_FOUND)
365219820Sjeff        {
366219820Sjeff            continue; /* Ignore if not found */
367219820Sjeff        }
368219820Sjeff
369219820Sjeff        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Failed %s on Device %4.4s, %s\n",
370219820Sjeff            ACPI_CAST_PTR (char, MethodNames[i]),
371219820Sjeff            AcpiUtGetNodeName (DeviceNode), AcpiFormatException (Status)));
372219820Sjeff    }
373219820Sjeff
374219820Sjeff    return_ACPI_STATUS (FinalStatus);
375219820Sjeff}
376219820Sjeff