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