aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/utilities/utresrc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/utilities/utresrc.c')
-rw-r--r--drivers/acpi/utilities/utresrc.c150
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
258acpi_status
259acpi_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}