diff options
Diffstat (limited to 'drivers/acpi/utilities/utresrc.c')
-rw-r--r-- | drivers/acpi/utilities/utresrc.c | 150 |
1 files changed, 104 insertions, 46 deletions
diff --git a/drivers/acpi/utilities/utresrc.c b/drivers/acpi/utilities/utresrc.c index 27158dd0f877..4c24e6d5400a 100644 --- a/drivers/acpi/utilities/utresrc.c +++ b/drivers/acpi/utilities/utresrc.c | |||
@@ -240,6 +240,104 @@ static const u8 acpi_gbl_resource_types[] = { | |||
240 | 240 | ||
241 | /******************************************************************************* | 241 | /******************************************************************************* |
242 | * | 242 | * |
243 | * FUNCTION: acpi_ut_walk_aml_resources | ||
244 | * | ||
245 | * PARAMETERS: Aml - Pointer to the raw AML resource template | ||
246 | * aml_length - Length of the entire template | ||
247 | * user_function - Called once for each descriptor found. If | ||
248 | * NULL, a pointer to the end_tag is returned | ||
249 | * Context - Passed to user_function | ||
250 | * | ||
251 | * RETURN: Status | ||
252 | * | ||
253 | * DESCRIPTION: Walk a raw AML resource list(buffer). User function called | ||
254 | * once for each resource found. | ||
255 | * | ||
256 | ******************************************************************************/ | ||
257 | |||
258 | acpi_status | ||
259 | acpi_ut_walk_aml_resources(u8 * aml, | ||
260 | acpi_size aml_length, | ||
261 | acpi_walk_aml_callback user_function, void *context) | ||
262 | { | ||
263 | acpi_status status; | ||
264 | u8 *end_aml; | ||
265 | u8 resource_index; | ||
266 | u32 length; | ||
267 | u32 offset = 0; | ||
268 | |||
269 | ACPI_FUNCTION_TRACE("ut_walk_aml_resources"); | ||
270 | |||
271 | /* The absolute minimum resource template is one end_tag descriptor */ | ||
272 | |||
273 | if (aml_length < sizeof(struct aml_resource_end_tag)) { | ||
274 | return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); | ||
275 | } | ||
276 | |||
277 | /* Point to the end of the resource template buffer */ | ||
278 | |||
279 | end_aml = aml + aml_length; | ||
280 | |||
281 | /* Walk the byte list, abort on any invalid descriptor type or length */ | ||
282 | |||
283 | while (aml < end_aml) { | ||
284 | |||
285 | /* Validate the Resource Type and Resource Length */ | ||
286 | |||
287 | status = acpi_ut_validate_resource(aml, &resource_index); | ||
288 | if (ACPI_FAILURE(status)) { | ||
289 | return_ACPI_STATUS(status); | ||
290 | } | ||
291 | |||
292 | /* Get the length of this descriptor */ | ||
293 | |||
294 | length = acpi_ut_get_descriptor_length(aml); | ||
295 | |||
296 | /* Invoke the user function */ | ||
297 | |||
298 | if (user_function) { | ||
299 | status = | ||
300 | user_function(aml, length, offset, resource_index, | ||
301 | context); | ||
302 | if (ACPI_FAILURE(status)) { | ||
303 | return (status); | ||
304 | } | ||
305 | } | ||
306 | |||
307 | /* An end_tag descriptor terminates this resource template */ | ||
308 | |||
309 | if (acpi_ut_get_resource_type(aml) == | ||
310 | ACPI_RESOURCE_NAME_END_TAG) { | ||
311 | /* | ||
312 | * There must be at least one more byte in the buffer for | ||
313 | * the 2nd byte of the end_tag | ||
314 | */ | ||
315 | if ((aml + 1) >= end_aml) { | ||
316 | return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); | ||
317 | } | ||
318 | |||
319 | /* Return the pointer to the end_tag if requested */ | ||
320 | |||
321 | if (!user_function) { | ||
322 | *(void **)context = aml; | ||
323 | } | ||
324 | |||
325 | /* Normal exit */ | ||
326 | |||
327 | return_ACPI_STATUS(AE_OK); | ||
328 | } | ||
329 | |||
330 | aml += length; | ||
331 | offset += length; | ||
332 | } | ||
333 | |||
334 | /* Did not find an end_tag descriptor */ | ||
335 | |||
336 | return (AE_AML_NO_RESOURCE_END_TAG); | ||
337 | } | ||
338 | |||
339 | /******************************************************************************* | ||
340 | * | ||
243 | * FUNCTION: acpi_ut_validate_resource | 341 | * FUNCTION: acpi_ut_validate_resource |
244 | * | 342 | * |
245 | * PARAMETERS: Aml - Pointer to the raw AML resource descriptor | 343 | * PARAMETERS: Aml - Pointer to the raw AML resource descriptor |
@@ -498,61 +596,21 @@ acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc, | |||
498 | u8 ** end_tag) | 596 | u8 ** end_tag) |
499 | { | 597 | { |
500 | acpi_status status; | 598 | acpi_status status; |
501 | u8 *aml; | ||
502 | u8 *end_aml; | ||
503 | 599 | ||
504 | ACPI_FUNCTION_TRACE("ut_get_resource_end_tag"); | 600 | ACPI_FUNCTION_TRACE("ut_get_resource_end_tag"); |
505 | 601 | ||
506 | /* Get start and end pointers */ | ||
507 | |||
508 | aml = obj_desc->buffer.pointer; | ||
509 | end_aml = aml + obj_desc->buffer.length; | ||
510 | |||
511 | /* Allow a buffer length of zero */ | 602 | /* Allow a buffer length of zero */ |
512 | 603 | ||
513 | if (!obj_desc->buffer.length) { | 604 | if (!obj_desc->buffer.length) { |
514 | *end_tag = aml; | 605 | *end_tag = obj_desc->buffer.pointer; |
515 | return_ACPI_STATUS(AE_OK); | 606 | return_ACPI_STATUS(AE_OK); |
516 | } | 607 | } |
517 | 608 | ||
518 | /* Walk the resource template, one descriptor per iteration */ | 609 | /* Validate the template and get a pointer to the end_tag */ |
519 | |||
520 | while (aml < end_aml) { | ||
521 | |||
522 | /* Validate the Resource Type and Resource Length */ | ||
523 | |||
524 | status = acpi_ut_validate_resource(aml, NULL); | ||
525 | if (ACPI_FAILURE(status)) { | ||
526 | return_ACPI_STATUS(status); | ||
527 | } | ||
528 | |||
529 | /* end_tag resource indicates the end of the resource template */ | ||
530 | |||
531 | if (acpi_ut_get_resource_type(aml) == | ||
532 | ACPI_RESOURCE_NAME_END_TAG) { | ||
533 | /* | ||
534 | * There must be at least one more byte in the buffer for | ||
535 | * the 2nd byte of the end_tag | ||
536 | */ | ||
537 | if ((aml + 1) >= end_aml) { | ||
538 | return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); | ||
539 | } | ||
540 | |||
541 | /* Return the pointer to the end_tag */ | ||
542 | |||
543 | *end_tag = aml; | ||
544 | return_ACPI_STATUS(AE_OK); | ||
545 | } | ||
546 | |||
547 | /* | ||
548 | * Point to the next resource descriptor in the AML buffer. The | ||
549 | * descriptor length is guaranteed to be non-zero by resource | ||
550 | * validation above. | ||
551 | */ | ||
552 | aml += acpi_ut_get_descriptor_length(aml); | ||
553 | } | ||
554 | 610 | ||
555 | /* Did not find an end_tag resource descriptor */ | 611 | status = acpi_ut_walk_aml_resources(obj_desc->buffer.pointer, |
612 | obj_desc->buffer.length, NULL, | ||
613 | end_tag); | ||
556 | 614 | ||
557 | return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); | 615 | return_ACPI_STATUS(status); |
558 | } | 616 | } |