diff options
author | Bob Moore <robert.moore@intel.com> | 2013-05-29 22:00:01 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-06-01 15:54:30 -0400 |
commit | 29a241cc02110b8b2259fd72719b8cadc03909be (patch) | |
tree | a96c10dd22a35479dc2e1ef140f7d90a442f9c03 /drivers/acpi/acpica/nsxfeval.c | |
parent | e1405ca5ebf1068a0d62afd2fec8f0354038147a (diff) |
ACPICA: Add argument typechecking for all predefined ACPI names
Fully implements typechecking on all incoming arguments for all
predefined names. This ensures that ACPI-related drivers are
passing the correct number of arguments, each of the correct
object type.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Acked-by: Len Brown <len.brown@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/acpica/nsxfeval.c')
-rw-r--r-- | drivers/acpi/acpica/nsxfeval.c | 162 |
1 files changed, 130 insertions, 32 deletions
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index fc69949151bb..82bec40d4508 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c | |||
@@ -187,8 +187,6 @@ acpi_evaluate_object(acpi_handle handle, | |||
187 | return_ACPI_STATUS(AE_NO_MEMORY); | 187 | return_ACPI_STATUS(AE_NO_MEMORY); |
188 | } | 188 | } |
189 | 189 | ||
190 | info->pathname = pathname; | ||
191 | |||
192 | /* Convert and validate the device handle */ | 190 | /* Convert and validate the device handle */ |
193 | 191 | ||
194 | info->prefix_node = acpi_ns_validate_handle(handle); | 192 | info->prefix_node = acpi_ns_validate_handle(handle); |
@@ -198,17 +196,64 @@ acpi_evaluate_object(acpi_handle handle, | |||
198 | } | 196 | } |
199 | 197 | ||
200 | /* | 198 | /* |
201 | * If there are parameters to be passed to a control method, the external | 199 | * Get the actual namespace node for the target object. |
202 | * objects must all be converted to internal objects | 200 | * Handles these cases: |
201 | * | ||
202 | * 1) Null node, valid pathname from root (absolute path) | ||
203 | * 2) Node and valid pathname (path relative to Node) | ||
204 | * 3) Node, Null pathname | ||
205 | */ | ||
206 | if ((pathname) && (ACPI_IS_ROOT_PREFIX(pathname[0]))) { | ||
207 | |||
208 | /* The path is fully qualified, just evaluate by name */ | ||
209 | |||
210 | info->prefix_node = NULL; | ||
211 | } else if (!handle) { | ||
212 | /* | ||
213 | * A handle is optional iff a fully qualified pathname is specified. | ||
214 | * Since we've already handled fully qualified names above, this is | ||
215 | * an error. | ||
216 | */ | ||
217 | if (!pathname) { | ||
218 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
219 | "Both Handle and Pathname are NULL")); | ||
220 | } else { | ||
221 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
222 | "Null Handle with relative pathname [%s]", | ||
223 | pathname)); | ||
224 | } | ||
225 | |||
226 | status = AE_BAD_PARAMETER; | ||
227 | goto cleanup; | ||
228 | } | ||
229 | |||
230 | info->relative_pathname = pathname; | ||
231 | |||
232 | /* | ||
233 | * Convert all external objects passed as arguments to the | ||
234 | * internal version(s). | ||
203 | */ | 235 | */ |
204 | if (external_params && external_params->count) { | 236 | if (external_params && external_params->count) { |
237 | info->param_count = (u16)external_params->count; | ||
238 | |||
239 | /* Warn on impossible argument count */ | ||
240 | |||
241 | if (info->param_count > ACPI_METHOD_NUM_ARGS) { | ||
242 | ACPI_WARN_PREDEFINED((AE_INFO, pathname, | ||
243 | ACPI_WARN_ALWAYS, | ||
244 | "Excess arguments (%u) - using only %u", | ||
245 | info->param_count, | ||
246 | ACPI_METHOD_NUM_ARGS)); | ||
247 | |||
248 | info->param_count = ACPI_METHOD_NUM_ARGS; | ||
249 | } | ||
250 | |||
205 | /* | 251 | /* |
206 | * Allocate a new parameter block for the internal objects | 252 | * Allocate a new parameter block for the internal objects |
207 | * Add 1 to count to allow for null terminated internal list | 253 | * Add 1 to count to allow for null terminated internal list |
208 | */ | 254 | */ |
209 | info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size) | 255 | info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size) info-> |
210 | external_params-> | 256 | param_count + |
211 | count + | ||
212 | 1) * sizeof(void *)); | 257 | 1) * sizeof(void *)); |
213 | if (!info->parameters) { | 258 | if (!info->parameters) { |
214 | status = AE_NO_MEMORY; | 259 | status = AE_NO_MEMORY; |
@@ -217,7 +262,7 @@ acpi_evaluate_object(acpi_handle handle, | |||
217 | 262 | ||
218 | /* Convert each external object in the list to an internal object */ | 263 | /* Convert each external object in the list to an internal object */ |
219 | 264 | ||
220 | for (i = 0; i < external_params->count; i++) { | 265 | for (i = 0; i < info->param_count; i++) { |
221 | status = | 266 | status = |
222 | acpi_ut_copy_eobject_to_iobject(&external_params-> | 267 | acpi_ut_copy_eobject_to_iobject(&external_params-> |
223 | pointer[i], | 268 | pointer[i], |
@@ -227,43 +272,96 @@ acpi_evaluate_object(acpi_handle handle, | |||
227 | goto cleanup; | 272 | goto cleanup; |
228 | } | 273 | } |
229 | } | 274 | } |
230 | info->parameters[external_params->count] = NULL; | 275 | |
276 | info->parameters[info->param_count] = NULL; | ||
231 | } | 277 | } |
232 | 278 | ||
279 | #if 0 | ||
280 | |||
233 | /* | 281 | /* |
234 | * Three major cases: | 282 | * Begin incoming argument count analysis. Check for too few args |
235 | * 1) Fully qualified pathname | 283 | * and too many args. |
236 | * 2) No handle, not fully qualified pathname (error) | ||
237 | * 3) Valid handle | ||
238 | */ | 284 | */ |
239 | if ((pathname) && (ACPI_IS_ROOT_PREFIX(pathname[0]))) { | ||
240 | 285 | ||
241 | /* The path is fully qualified, just evaluate by name */ | 286 | switch (acpi_ns_get_type(info->node)) { |
287 | case ACPI_TYPE_METHOD: | ||
288 | |||
289 | /* Check incoming argument count against the method definition */ | ||
290 | |||
291 | if (info->obj_desc->method.param_count > info->param_count) { | ||
292 | ACPI_ERROR((AE_INFO, | ||
293 | "Insufficient arguments (%u) - %u are required", | ||
294 | info->param_count, | ||
295 | info->obj_desc->method.param_count)); | ||
296 | |||
297 | status = AE_MISSING_ARGUMENTS; | ||
298 | goto cleanup; | ||
299 | } | ||
300 | |||
301 | else if (info->obj_desc->method.param_count < info->param_count) { | ||
302 | ACPI_WARNING((AE_INFO, | ||
303 | "Excess arguments (%u) - only %u are required", | ||
304 | info->param_count, | ||
305 | info->obj_desc->method.param_count)); | ||
306 | |||
307 | /* Just pass the required number of arguments */ | ||
308 | |||
309 | info->param_count = info->obj_desc->method.param_count; | ||
310 | } | ||
242 | 311 | ||
243 | info->prefix_node = NULL; | ||
244 | status = acpi_ns_evaluate(info); | ||
245 | } else if (!handle) { | ||
246 | /* | 312 | /* |
247 | * A handle is optional iff a fully qualified pathname is specified. | 313 | * Any incoming external objects to be passed as arguments to the |
248 | * Since we've already handled fully qualified names above, this is | 314 | * method must be converted to internal objects |
249 | * an error | ||
250 | */ | 315 | */ |
251 | if (!pathname) { | 316 | if (info->param_count) { |
252 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 317 | /* |
253 | "Both Handle and Pathname are NULL")); | 318 | * Allocate a new parameter block for the internal objects |
254 | } else { | 319 | * Add 1 to count to allow for null terminated internal list |
255 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 320 | */ |
256 | "Null Handle with relative pathname [%s]", | 321 | info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size) |
257 | pathname)); | 322 | info-> |
323 | param_count + | ||
324 | 1) * | ||
325 | sizeof(void *)); | ||
326 | if (!info->parameters) { | ||
327 | status = AE_NO_MEMORY; | ||
328 | goto cleanup; | ||
329 | } | ||
330 | |||
331 | /* Convert each external object in the list to an internal object */ | ||
332 | |||
333 | for (i = 0; i < info->param_count; i++) { | ||
334 | status = | ||
335 | acpi_ut_copy_eobject_to_iobject | ||
336 | (&external_params->pointer[i], | ||
337 | &info->parameters[i]); | ||
338 | if (ACPI_FAILURE(status)) { | ||
339 | goto cleanup; | ||
340 | } | ||
341 | } | ||
342 | |||
343 | info->parameters[info->param_count] = NULL; | ||
258 | } | 344 | } |
345 | break; | ||
259 | 346 | ||
260 | status = AE_BAD_PARAMETER; | 347 | default: |
261 | } else { | ||
262 | /* We have a namespace a node and a possible relative path */ | ||
263 | 348 | ||
264 | status = acpi_ns_evaluate(info); | 349 | /* Warn if arguments passed to an object that is not a method */ |
350 | |||
351 | if (info->param_count) { | ||
352 | ACPI_WARNING((AE_INFO, | ||
353 | "%u arguments were passed to a non-method ACPI object", | ||
354 | info->param_count)); | ||
355 | } | ||
356 | break; | ||
265 | } | 357 | } |
266 | 358 | ||
359 | #endif | ||
360 | |||
361 | /* Now we can evaluate the object */ | ||
362 | |||
363 | status = acpi_ns_evaluate(info); | ||
364 | |||
267 | /* | 365 | /* |
268 | * If we are expecting a return value, and all went well above, | 366 | * If we are expecting a return value, and all went well above, |
269 | * copy the return value to an external object. | 367 | * copy the return value to an external object. |