diff options
Diffstat (limited to 'drivers/acpi/acpica/nsrepair.c')
-rw-r--r-- | drivers/acpi/acpica/nsrepair.c | 175 |
1 files changed, 174 insertions, 1 deletions
diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index 4fd1bdb056b2..d4be37751be4 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2009, Intel Corp. | 8 | * Copyright (C) 2000 - 2010, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -45,6 +45,7 @@ | |||
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "acnamesp.h" | 46 | #include "acnamesp.h" |
47 | #include "acinterp.h" | 47 | #include "acinterp.h" |
48 | #include "acpredef.h" | ||
48 | 49 | ||
49 | #define _COMPONENT ACPI_NAMESPACE | 50 | #define _COMPONENT ACPI_NAMESPACE |
50 | ACPI_MODULE_NAME("nsrepair") | 51 | ACPI_MODULE_NAME("nsrepair") |
@@ -71,6 +72,12 @@ ACPI_MODULE_NAME("nsrepair") | |||
71 | * Buffer -> Package of Integers | 72 | * Buffer -> Package of Integers |
72 | * Package -> Package of one Package | 73 | * Package -> Package of one Package |
73 | * | 74 | * |
75 | * Additional possible repairs: | ||
76 | * | ||
77 | * Optional/unnecessary NULL package elements removed | ||
78 | * Required package elements that are NULL replaced by Integer/String/Buffer | ||
79 | * Incorrect standalone package wrapped with required outer package | ||
80 | * | ||
74 | ******************************************************************************/ | 81 | ******************************************************************************/ |
75 | /* Local prototypes */ | 82 | /* Local prototypes */ |
76 | static acpi_status | 83 | static acpi_status |
@@ -506,6 +513,172 @@ acpi_ns_convert_to_package(union acpi_operand_object *original_object, | |||
506 | 513 | ||
507 | /******************************************************************************* | 514 | /******************************************************************************* |
508 | * | 515 | * |
516 | * FUNCTION: acpi_ns_repair_null_element | ||
517 | * | ||
518 | * PARAMETERS: Data - Pointer to validation data structure | ||
519 | * expected_btypes - Object types expected | ||
520 | * package_index - Index of object within parent package (if | ||
521 | * applicable - ACPI_NOT_PACKAGE_ELEMENT | ||
522 | * otherwise) | ||
523 | * return_object_ptr - Pointer to the object returned from the | ||
524 | * evaluation of a method or object | ||
525 | * | ||
526 | * RETURN: Status. AE_OK if repair was successful. | ||
527 | * | ||
528 | * DESCRIPTION: Attempt to repair a NULL element of a returned Package object. | ||
529 | * | ||
530 | ******************************************************************************/ | ||
531 | |||
532 | acpi_status | ||
533 | acpi_ns_repair_null_element(struct acpi_predefined_data *data, | ||
534 | u32 expected_btypes, | ||
535 | u32 package_index, | ||
536 | union acpi_operand_object **return_object_ptr) | ||
537 | { | ||
538 | union acpi_operand_object *return_object = *return_object_ptr; | ||
539 | union acpi_operand_object *new_object; | ||
540 | |||
541 | ACPI_FUNCTION_NAME(ns_repair_null_element); | ||
542 | |||
543 | /* No repair needed if return object is non-NULL */ | ||
544 | |||
545 | if (return_object) { | ||
546 | return (AE_OK); | ||
547 | } | ||
548 | |||
549 | /* | ||
550 | * Attempt to repair a NULL element of a Package object. This applies to | ||
551 | * predefined names that return a fixed-length package and each element | ||
552 | * is required. It does not apply to variable-length packages where NULL | ||
553 | * elements are allowed, especially at the end of the package. | ||
554 | */ | ||
555 | if (expected_btypes & ACPI_RTYPE_INTEGER) { | ||
556 | |||
557 | /* Need an Integer - create a zero-value integer */ | ||
558 | |||
559 | new_object = acpi_ut_create_integer_object(0); | ||
560 | } else if (expected_btypes & ACPI_RTYPE_STRING) { | ||
561 | |||
562 | /* Need a String - create a NULL string */ | ||
563 | |||
564 | new_object = acpi_ut_create_string_object(0); | ||
565 | } else if (expected_btypes & ACPI_RTYPE_BUFFER) { | ||
566 | |||
567 | /* Need a Buffer - create a zero-length buffer */ | ||
568 | |||
569 | new_object = acpi_ut_create_buffer_object(0); | ||
570 | } else { | ||
571 | /* Error for all other expected types */ | ||
572 | |||
573 | return (AE_AML_OPERAND_TYPE); | ||
574 | } | ||
575 | |||
576 | if (!new_object) { | ||
577 | return (AE_NO_MEMORY); | ||
578 | } | ||
579 | |||
580 | /* Set the reference count according to the parent Package object */ | ||
581 | |||
582 | new_object->common.reference_count = | ||
583 | data->parent_package->common.reference_count; | ||
584 | |||
585 | ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, | ||
586 | "%s: Converted NULL package element to expected %s at index %u\n", | ||
587 | data->pathname, | ||
588 | acpi_ut_get_object_type_name(new_object), | ||
589 | package_index)); | ||
590 | |||
591 | *return_object_ptr = new_object; | ||
592 | data->flags |= ACPI_OBJECT_REPAIRED; | ||
593 | return (AE_OK); | ||
594 | } | ||
595 | |||
596 | /****************************************************************************** | ||
597 | * | ||
598 | * FUNCTION: acpi_ns_remove_null_elements | ||
599 | * | ||
600 | * PARAMETERS: Data - Pointer to validation data structure | ||
601 | * package_type - An acpi_return_package_types value | ||
602 | * obj_desc - A Package object | ||
603 | * | ||
604 | * RETURN: None. | ||
605 | * | ||
606 | * DESCRIPTION: Remove all NULL package elements from packages that contain | ||
607 | * a variable number of sub-packages. For these types of | ||
608 | * packages, NULL elements can be safely removed. | ||
609 | * | ||
610 | *****************************************************************************/ | ||
611 | |||
612 | void | ||
613 | acpi_ns_remove_null_elements(struct acpi_predefined_data *data, | ||
614 | u8 package_type, | ||
615 | union acpi_operand_object *obj_desc) | ||
616 | { | ||
617 | union acpi_operand_object **source; | ||
618 | union acpi_operand_object **dest; | ||
619 | u32 count; | ||
620 | u32 new_count; | ||
621 | u32 i; | ||
622 | |||
623 | ACPI_FUNCTION_NAME(ns_remove_null_elements); | ||
624 | |||
625 | /* | ||
626 | * PTYPE1 packages contain no subpackages. | ||
627 | * PTYPE2 packages contain a variable number of sub-packages. We can | ||
628 | * safely remove all NULL elements from the PTYPE2 packages. | ||
629 | */ | ||
630 | switch (package_type) { | ||
631 | case ACPI_PTYPE1_FIXED: | ||
632 | case ACPI_PTYPE1_VAR: | ||
633 | case ACPI_PTYPE1_OPTION: | ||
634 | return; | ||
635 | |||
636 | case ACPI_PTYPE2: | ||
637 | case ACPI_PTYPE2_COUNT: | ||
638 | case ACPI_PTYPE2_PKG_COUNT: | ||
639 | case ACPI_PTYPE2_FIXED: | ||
640 | case ACPI_PTYPE2_MIN: | ||
641 | case ACPI_PTYPE2_REV_FIXED: | ||
642 | break; | ||
643 | |||
644 | default: | ||
645 | return; | ||
646 | } | ||
647 | |||
648 | count = obj_desc->package.count; | ||
649 | new_count = count; | ||
650 | |||
651 | source = obj_desc->package.elements; | ||
652 | dest = source; | ||
653 | |||
654 | /* Examine all elements of the package object, remove nulls */ | ||
655 | |||
656 | for (i = 0; i < count; i++) { | ||
657 | if (!*source) { | ||
658 | new_count--; | ||
659 | } else { | ||
660 | *dest = *source; | ||
661 | dest++; | ||
662 | } | ||
663 | source++; | ||
664 | } | ||
665 | |||
666 | /* Update parent package if any null elements were removed */ | ||
667 | |||
668 | if (new_count < count) { | ||
669 | ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, | ||
670 | "%s: Found and removed %u NULL elements\n", | ||
671 | data->pathname, (count - new_count))); | ||
672 | |||
673 | /* NULL terminate list and update the package count */ | ||
674 | |||
675 | *dest = NULL; | ||
676 | obj_desc->package.count = new_count; | ||
677 | } | ||
678 | } | ||
679 | |||
680 | /******************************************************************************* | ||
681 | * | ||
509 | * FUNCTION: acpi_ns_repair_package_list | 682 | * FUNCTION: acpi_ns_repair_package_list |
510 | * | 683 | * |
511 | * PARAMETERS: Data - Pointer to validation data structure | 684 | * PARAMETERS: Data - Pointer to validation data structure |