Merge branches 'pm-cpufreq', 'pm-cpuidle', 'pm-devfreq', 'pm-opp' and 'pm-tools'
[linux-drm-fsl-dcu.git] / drivers / acpi / acpica / nsarguments.c
1 /******************************************************************************
2  *
3  * Module Name: nsarguments - Validation of args for ACPI predefined methods
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 <acpi/acpi.h>
45 #include "accommon.h"
46 #include "acnamesp.h"
47 #include "acpredef.h"
48
49 #define _COMPONENT          ACPI_NAMESPACE
50 ACPI_MODULE_NAME("nsarguments")
51
52 /*******************************************************************************
53  *
54  * FUNCTION:    acpi_ns_check_argument_types
55  *
56  * PARAMETERS:  info            - Method execution information block
57  *
58  * RETURN:      None
59  *
60  * DESCRIPTION: Check the incoming argument count and all argument types
61  *              against the argument type list for a predefined name.
62  *
63  ******************************************************************************/
64 void acpi_ns_check_argument_types(struct acpi_evaluate_info *info)
65 {
66         u16 arg_type_list;
67         u8 arg_count;
68         u8 arg_type;
69         u8 user_arg_type;
70         u32 i;
71
72         /* If not a predefined name, cannot typecheck args */
73
74         if (!info->predefined) {
75                 return;
76         }
77
78         arg_type_list = info->predefined->info.argument_list;
79         arg_count = METHOD_GET_ARG_COUNT(arg_type_list);
80
81         /* Typecheck all arguments */
82
83         for (i = 0; ((i < arg_count) && (i < info->param_count)); i++) {
84                 arg_type = METHOD_GET_NEXT_TYPE(arg_type_list);
85                 user_arg_type = info->parameters[i]->common.type;
86
87                 if (user_arg_type != arg_type) {
88                         ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
89                                               ACPI_WARN_ALWAYS,
90                                               "Argument #%u type mismatch - "
91                                               "Found [%s], ACPI requires [%s]",
92                                               (i + 1),
93                                               acpi_ut_get_type_name
94                                               (user_arg_type),
95                                               acpi_ut_get_type_name(arg_type)));
96                 }
97         }
98 }
99
100 /*******************************************************************************
101  *
102  * FUNCTION:    acpi_ns_check_acpi_compliance
103  *
104  * PARAMETERS:  pathname        - Full pathname to the node (for error msgs)
105  *              node            - Namespace node for the method/object
106  *              predefined      - Pointer to entry in predefined name table
107  *
108  * RETURN:      None
109  *
110  * DESCRIPTION: Check that the declared parameter count (in ASL/AML) for a
111  *              predefined name is what is expected (matches what is defined in
112  *              the ACPI specification for this predefined name.)
113  *
114  ******************************************************************************/
115
116 void
117 acpi_ns_check_acpi_compliance(char *pathname,
118                               struct acpi_namespace_node *node,
119                               const union acpi_predefined_info *predefined)
120 {
121         u32 aml_param_count;
122         u32 required_param_count;
123
124         if (!predefined) {
125                 return;
126         }
127
128         /* Get the ACPI-required arg count from the predefined info table */
129
130         required_param_count =
131             METHOD_GET_ARG_COUNT(predefined->info.argument_list);
132
133         /*
134          * If this object is not a control method, we can check if the ACPI
135          * spec requires that it be a method.
136          */
137         if (node->type != ACPI_TYPE_METHOD) {
138                 if (required_param_count > 0) {
139
140                         /* Object requires args, must be implemented as a method */
141
142                         ACPI_BIOS_ERROR_PREDEFINED((AE_INFO, pathname,
143                                                     ACPI_WARN_ALWAYS,
144                                                     "Object (%s) must be a control method with %u arguments",
145                                                     acpi_ut_get_type_name(node->
146                                                                           type),
147                                                     required_param_count));
148                 } else if (!required_param_count
149                            && !predefined->info.expected_btypes) {
150
151                         /* Object requires no args and no return value, must be a method */
152
153                         ACPI_BIOS_ERROR_PREDEFINED((AE_INFO, pathname,
154                                                     ACPI_WARN_ALWAYS,
155                                                     "Object (%s) must be a control method "
156                                                     "with no arguments and no return value",
157                                                     acpi_ut_get_type_name(node->
158                                                                           type)));
159                 }
160
161                 return;
162         }
163
164         /*
165          * This is a control method.
166          * Check that the ASL/AML-defined parameter count for this method
167          * matches the ACPI-required parameter count
168          *
169          * Some methods are allowed to have a "minimum" number of args (_SCP)
170          * because their definition in ACPI has changed over time.
171          *
172          * Note: These are BIOS errors in the declaration of the object
173          */
174         aml_param_count = node->object->method.param_count;
175
176         if (aml_param_count < required_param_count) {
177                 ACPI_BIOS_ERROR_PREDEFINED((AE_INFO, pathname, ACPI_WARN_ALWAYS,
178                                             "Insufficient arguments - "
179                                             "ASL declared %u, ACPI requires %u",
180                                             aml_param_count,
181                                             required_param_count));
182         } else if ((aml_param_count > required_param_count)
183                    && !(predefined->info.
184                         argument_list & ARG_COUNT_IS_MINIMUM)) {
185                 ACPI_BIOS_ERROR_PREDEFINED((AE_INFO, pathname, ACPI_WARN_ALWAYS,
186                                             "Excess arguments - "
187                                             "ASL declared %u, ACPI requires %u",
188                                             aml_param_count,
189                                             required_param_count));
190         }
191 }
192
193 /*******************************************************************************
194  *
195  * FUNCTION:    acpi_ns_check_argument_count
196  *
197  * PARAMETERS:  pathname        - Full pathname to the node (for error msgs)
198  *              node            - Namespace node for the method/object
199  *              user_param_count - Number of args passed in by the caller
200  *              predefined      - Pointer to entry in predefined name table
201  *
202  * RETURN:      None
203  *
204  * DESCRIPTION: Check that incoming argument count matches the declared
205  *              parameter count (in the ASL/AML) for an object.
206  *
207  ******************************************************************************/
208
209 void
210 acpi_ns_check_argument_count(char *pathname,
211                              struct acpi_namespace_node *node,
212                              u32 user_param_count,
213                              const union acpi_predefined_info *predefined)
214 {
215         u32 aml_param_count;
216         u32 required_param_count;
217
218         if (!predefined) {
219                 /*
220                  * Not a predefined name. Check the incoming user argument count
221                  * against the count that is specified in the method/object.
222                  */
223                 if (node->type != ACPI_TYPE_METHOD) {
224                         if (user_param_count) {
225                                 ACPI_INFO_PREDEFINED((AE_INFO, pathname,
226                                                       ACPI_WARN_ALWAYS,
227                                                       "%u arguments were passed to a non-method ACPI object (%s)",
228                                                       user_param_count,
229                                                       acpi_ut_get_type_name
230                                                       (node->type)));
231                         }
232
233                         return;
234                 }
235
236                 /*
237                  * This is a control method. Check the parameter count.
238                  * We can only check the incoming argument count against the
239                  * argument count declared for the method in the ASL/AML.
240                  *
241                  * Emit a message if too few or too many arguments have been passed
242                  * by the caller.
243                  *
244                  * Note: Too many arguments will not cause the method to
245                  * fail. However, the method will fail if there are too few
246                  * arguments and the method attempts to use one of the missing ones.
247                  */
248                 aml_param_count = node->object->method.param_count;
249
250                 if (user_param_count < aml_param_count) {
251                         ACPI_WARN_PREDEFINED((AE_INFO, pathname,
252                                               ACPI_WARN_ALWAYS,
253                                               "Insufficient arguments - "
254                                               "Caller passed %u, method requires %u",
255                                               user_param_count,
256                                               aml_param_count));
257                 } else if (user_param_count > aml_param_count) {
258                         ACPI_INFO_PREDEFINED((AE_INFO, pathname,
259                                               ACPI_WARN_ALWAYS,
260                                               "Excess arguments - "
261                                               "Caller passed %u, method requires %u",
262                                               user_param_count,
263                                               aml_param_count));
264                 }
265
266                 return;
267         }
268
269         /*
270          * This is a predefined name. Validate the user-supplied parameter
271          * count against the ACPI specification. We don't validate against
272          * the method itself because what is important here is that the
273          * caller is in conformance with the spec. (The arg count for the
274          * method was checked against the ACPI spec earlier.)
275          *
276          * Some methods are allowed to have a "minimum" number of args (_SCP)
277          * because their definition in ACPI has changed over time.
278          */
279         required_param_count =
280             METHOD_GET_ARG_COUNT(predefined->info.argument_list);
281
282         if (user_param_count < required_param_count) {
283                 ACPI_WARN_PREDEFINED((AE_INFO, pathname, ACPI_WARN_ALWAYS,
284                                       "Insufficient arguments - "
285                                       "Caller passed %u, ACPI requires %u",
286                                       user_param_count, required_param_count));
287         } else if ((user_param_count > required_param_count) &&
288                    !(predefined->info.argument_list & ARG_COUNT_IS_MINIMUM)) {
289                 ACPI_INFO_PREDEFINED((AE_INFO, pathname, ACPI_WARN_ALWAYS,
290                                       "Excess arguments - "
291                                       "Caller passed %u, ACPI requires %u",
292                                       user_param_count, required_param_count));
293         }
294 }