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 | } |
