diff options
author | Bob Moore <robert.moore@intel.com> | 2008-11-12 22:19:24 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2008-12-29 22:38:39 -0500 |
commit | eeb4437e63c39ce19cf9b2de36a1dddbf12910c4 (patch) | |
tree | f8a03de090080a3a781a927ca13253774aebdfe7 /drivers/acpi/namespace | |
parent | a647b5c34047560d7efe7e53e756c6692ce67dc7 (diff) |
ACPICA: Consolidate method arg count validation code
Merge the code that validates control method argument counts into
the predefined validation module. Eliminates possible multiple
warnings for incorrect counts.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/namespace')
-rw-r--r-- | drivers/acpi/namespace/nseval.c | 69 | ||||
-rw-r--r-- | drivers/acpi/namespace/nspredef.c | 106 |
2 files changed, 101 insertions, 74 deletions
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c index 738a4517b7c..b95bfbbf561 100644 --- a/drivers/acpi/namespace/nseval.c +++ b/drivers/acpi/namespace/nseval.c | |||
@@ -89,6 +89,7 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | |||
89 | /* Initialize the return value to an invalid object */ | 89 | /* Initialize the return value to an invalid object */ |
90 | 90 | ||
91 | info->return_object = NULL; | 91 | info->return_object = NULL; |
92 | info->param_count = 0; | ||
92 | 93 | ||
93 | /* | 94 | /* |
94 | * Get the actual namespace node for the target object. Handles these cases: | 95 | * Get the actual namespace node for the target object. Handles these cases: |
@@ -141,41 +142,17 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | |||
141 | return_ACPI_STATUS(AE_NULL_OBJECT); | 142 | return_ACPI_STATUS(AE_NULL_OBJECT); |
142 | } | 143 | } |
143 | 144 | ||
144 | /* | 145 | /* Count the number of arguments being passed to the method */ |
145 | * Calculate the number of arguments being passed to the method | ||
146 | */ | ||
147 | 146 | ||
148 | info->param_count = 0; | ||
149 | if (info->parameters) { | 147 | if (info->parameters) { |
150 | while (info->parameters[info->param_count]) | 148 | while (info->parameters[info->param_count]) { |
149 | if (info->param_count > ACPI_METHOD_MAX_ARG) { | ||
150 | return_ACPI_STATUS(AE_LIMIT); | ||
151 | } | ||
151 | info->param_count++; | 152 | info->param_count++; |
153 | } | ||
152 | } | 154 | } |
153 | 155 | ||
154 | /* | ||
155 | * Warning if too few or too many arguments have been passed by the | ||
156 | * caller. We don't want to abort here with an error because an | ||
157 | * incorrect number of arguments may not cause the method to fail. | ||
158 | * However, the method will fail if there are too few arguments passed | ||
159 | * and the method attempts to use one of the missing ones. | ||
160 | */ | ||
161 | |||
162 | if (info->param_count < info->obj_desc->method.param_count) { | ||
163 | ACPI_WARNING((AE_INFO, | ||
164 | "Insufficient arguments - " | ||
165 | "method [%4.4s] needs %d, found %d", | ||
166 | acpi_ut_get_node_name(info->resolved_node), | ||
167 | info->obj_desc->method.param_count, | ||
168 | info->param_count)); | ||
169 | } else if (info->param_count > | ||
170 | info->obj_desc->method.param_count) { | ||
171 | ACPI_WARNING((AE_INFO, | ||
172 | "Excess arguments - " | ||
173 | "method [%4.4s] needs %d, found %d", | ||
174 | acpi_ut_get_node_name(info-> | ||
175 | resolved_node), | ||
176 | info->obj_desc->method.param_count, | ||
177 | info->param_count)); | ||
178 | } | ||
179 | 156 | ||
180 | ACPI_DUMP_PATHNAME(info->resolved_node, "Execute Method:", | 157 | ACPI_DUMP_PATHNAME(info->resolved_node, "Execute Method:", |
181 | ACPI_LV_INFO, _COMPONENT); | 158 | ACPI_LV_INFO, _COMPONENT); |
@@ -264,31 +241,13 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | |||
264 | } | 241 | } |
265 | } | 242 | } |
266 | 243 | ||
267 | /* Validation of return values for ACPI-predefined methods and objects */ | 244 | /* |
268 | 245 | * Check input argument count against the ASL-defined count for a method. | |
269 | if ((status == AE_OK) || (status == AE_CTRL_RETURN_VALUE)) { | 246 | * Also check predefined names: argument count and return value against |
270 | /* | 247 | * the ACPI specification. Some incorrect return value types are repaired. |
271 | * If this is the first evaluation, check the return value. This | 248 | */ |
272 | * ensures that any warnings will only be emitted during the very | 249 | (void)acpi_ns_check_predefined_names(node, info->param_count, |
273 | * first evaluation of the object. | 250 | status, &info->return_object); |
274 | */ | ||
275 | if (!(node->flags & ANOBJ_EVALUATED)) { | ||
276 | /* | ||
277 | * Check for a predefined ACPI name. If found, validate the | ||
278 | * returned object. | ||
279 | * | ||
280 | * Note: Ignore return status for now, emit warnings if there are | ||
281 | * problems with the returned object. May change later to abort | ||
282 | * the method on invalid return object. | ||
283 | */ | ||
284 | (void)acpi_ns_check_predefined_names(node, | ||
285 | &info->return_object); | ||
286 | } | ||
287 | |||
288 | /* Mark the node as having been evaluated */ | ||
289 | |||
290 | node->flags |= ANOBJ_EVALUATED; | ||
291 | } | ||
292 | 251 | ||
293 | /* Check if there is a return value that must be dealt with */ | 252 | /* Check if there is a return value that must be dealt with */ |
294 | 253 | ||
diff --git a/drivers/acpi/namespace/nspredef.c b/drivers/acpi/namespace/nspredef.c index 3df17522117..8d354baaed5 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 | } |