diff options
Diffstat (limited to 'drivers/acpi/namespace/nspredef.c')
-rw-r--r-- | drivers/acpi/namespace/nspredef.c | 106 |
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 | ||
125 | acpi_status | 125 | acpi_status |
126 | acpi_ns_check_predefined_names(struct acpi_namespace_node *node, | 126 | acpi_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, | |||
230 | void | 254 | void |
231 | acpi_ns_check_parameter_count(char *pathname, | 255 | acpi_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 | } |