aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/namespace/nspredef.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/namespace/nspredef.c')
-rw-r--r--drivers/acpi/namespace/nspredef.c106
1 files changed, 87 insertions, 19 deletions
diff --git a/drivers/acpi/namespace/nspredef.c b/drivers/acpi/namespace/nspredef.c
index 3df17522117f..8d354baaed53 100644
--- a/drivers/acpi/namespace/nspredef.c
+++ b/drivers/acpi/namespace/nspredef.c
@@ -124,6 +124,8 @@ static const char *acpi_rtype_names[] = {
124 124
125acpi_status 125acpi_status
126acpi_ns_check_predefined_names(struct acpi_namespace_node *node, 126acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
127 u32 user_param_count,
128 acpi_status return_status,
127 union acpi_operand_object **return_object_ptr) 129 union acpi_operand_object **return_object_ptr)
128{ 130{
129 union acpi_operand_object *return_object = *return_object_ptr; 131 union acpi_operand_object *return_object = *return_object_ptr;
@@ -134,12 +136,6 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
134 /* Match the name for this method/object against the predefined list */ 136 /* Match the name for this method/object against the predefined list */
135 137
136 predefined = acpi_ns_check_for_predefined_name(node); 138 predefined = acpi_ns_check_for_predefined_name(node);
137 if (!predefined) {
138
139 /* Name was not one of the predefined names */
140
141 return (AE_OK);
142 }
143 139
144 /* Get the full pathname to the object, for use in error messages */ 140 /* Get the full pathname to the object, for use in error messages */
145 141
@@ -149,10 +145,37 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
149 } 145 }
150 146
151 /* 147 /*
152 * Check that the parameter count for this method is in accordance 148 * Check that the parameter count for this method matches the ASL
153 * with the ACPI specification. 149 * definition. For predefined names, ensure that both the caller and
150 * the method itself are in accordance with the ACPI specification.
154 */ 151 */
155 acpi_ns_check_parameter_count(pathname, node, predefined); 152 acpi_ns_check_parameter_count(pathname, node, user_param_count,
153 predefined);
154
155 /* If not a predefined name, we cannot validate the return object */
156
157 if (!predefined) {
158 goto exit;
159 }
160
161 /* If the method failed, we cannot validate the return object */
162
163 if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) {
164 goto exit;
165 }
166
167 /*
168 * Only validate the return value on the first successful evaluation of
169 * the method. This ensures that any warnings will only be emitted during
170 * the very first evaluation of the method/object.
171 */
172 if (node->flags & ANOBJ_EVALUATED) {
173 goto exit;
174 }
175
176 /* Mark the node as having been successfully evaluated */
177
178 node->flags |= ANOBJ_EVALUATED;
156 179
157 /* 180 /*
158 * If there is no return value, check if we require a return value for 181 * If there is no return value, check if we require a return value for
@@ -177,7 +200,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
177 * We have a return value, but if one wasn't expected, just exit, this is 200 * We have a return value, but if one wasn't expected, just exit, this is
178 * not a problem 201 * not a problem
179 * 202 *
180 * For example, if "Implicit return value" is enabled, methods will 203 * For example, if the "Implicit Return" feature is enabled, methods will
181 * always return a value 204 * always return a value
182 */ 205 */
183 if (!predefined->info.expected_btypes) { 206 if (!predefined->info.expected_btypes) {
@@ -204,7 +227,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
204 } 227 }
205 228
206 exit: 229 exit:
207 if (pathname) { 230 if (pathname != predefined->info.name) {
208 ACPI_FREE(pathname); 231 ACPI_FREE(pathname);
209 } 232 }
210 233
@@ -217,6 +240,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
217 * 240 *
218 * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 241 * PARAMETERS: Pathname - Full pathname to the node (for error msgs)
219 * Node - Namespace node for the method/object 242 * Node - Namespace node for the method/object
243 * user_param_count - Number of args passed in by the caller
220 * Predefined - Pointer to entry in predefined name table 244 * Predefined - Pointer to entry in predefined name table
221 * 245 *
222 * RETURN: None 246 * RETURN: None
@@ -230,32 +254,76 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
230void 254void
231acpi_ns_check_parameter_count(char *pathname, 255acpi_ns_check_parameter_count(char *pathname,
232 struct acpi_namespace_node *node, 256 struct acpi_namespace_node *node,
257 u32 user_param_count,
233 const union acpi_predefined_info *predefined) 258 const union acpi_predefined_info *predefined)
234{ 259{
235 u32 param_count; 260 u32 param_count;
236 u32 required_params_current; 261 u32 required_params_current;
237 u32 required_params_old; 262 u32 required_params_old;
238 263
239 /* 264 /* Methods have 0-7 parameters. All other types have zero. */
240 * Check that the ASL-defined parameter count is what is expected for 265
241 * this predefined name.
242 *
243 * Methods have 0-7 parameters. All other types have zero.
244 */
245 param_count = 0; 266 param_count = 0;
246 if (node->type == ACPI_TYPE_METHOD) { 267 if (node->type == ACPI_TYPE_METHOD) {
247 param_count = node->object->method.param_count; 268 param_count = node->object->method.param_count;
248 } 269 }
249 270
250 /* Validate parameter count - allow two different legal counts (_SCP) */ 271 /* Argument count check for non-predefined methods/objects */
272
273 if (!predefined) {
274 /*
275 * Warning if too few or too many arguments have been passed by the
276 * caller. An incorrect number of arguments may not cause the method
277 * to fail. However, the method will fail if there are too few
278 * arguments and the method attempts to use one of the missing ones.
279 */
280 if (user_param_count < param_count) {
281 ACPI_WARNING((AE_INFO,
282 "%s: Insufficient arguments - needs %d, found %d",
283 pathname, param_count, user_param_count));
284 } else if (user_param_count > param_count) {
285 ACPI_WARNING((AE_INFO,
286 "%s: Excess arguments - needs %d, found %d",
287 pathname, param_count, user_param_count));
288 }
289 return;
290 }
291
292 /* Allow two different legal argument counts (_SCP, etc.) */
251 293
252 required_params_current = predefined->info.param_count & 0x0F; 294 required_params_current = predefined->info.param_count & 0x0F;
253 required_params_old = predefined->info.param_count >> 4; 295 required_params_old = predefined->info.param_count >> 4;
254 296
297 if (user_param_count != ACPI_UINT32_MAX) {
298
299 /* Validate the user-supplied parameter count */
300
301 if ((user_param_count != required_params_current) &&
302 (user_param_count != required_params_old)) {
303 ACPI_WARNING((AE_INFO,
304 "%s: Parameter count mismatch - caller passed %d, ACPI requires %d",
305 pathname, user_param_count,
306 required_params_current));
307 }
308 }
309
310 /*
311 * Only validate the argument count on the first successful evaluation of
312 * the method. This ensures that any warnings will only be emitted during
313 * the very first evaluation of the method/object.
314 */
315 if (node->flags & ANOBJ_EVALUATED) {
316 return;
317 }
318
319 /*
320 * Check that the ASL-defined parameter count is what is expected for
321 * this predefined name.
322 */
255 if ((param_count != required_params_current) && 323 if ((param_count != required_params_current) &&
256 (param_count != required_params_old)) { 324 (param_count != required_params_old)) {
257 ACPI_WARNING((AE_INFO, 325 ACPI_WARNING((AE_INFO,
258 "%s: Parameter count mismatch - ASL declared %d, expected %d", 326 "%s: Parameter count mismatch - ASL declared %d, ACPI requires %d",
259 pathname, param_count, required_params_current)); 327 pathname, param_count, required_params_current));
260 } 328 }
261} 329}