diff options
Diffstat (limited to 'drivers/acpi/utilities/utmisc.c')
-rw-r--r-- | drivers/acpi/utilities/utmisc.c | 146 |
1 files changed, 123 insertions, 23 deletions
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index b57afa7421e8..e9058d4da122 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c | |||
@@ -43,6 +43,7 @@ | |||
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acnamesp.h> | 45 | #include <acpi/acnamesp.h> |
46 | #include <acpi/amlresrc.h> | ||
46 | 47 | ||
47 | #define _COMPONENT ACPI_UTILITIES | 48 | #define _COMPONENT ACPI_UTILITIES |
48 | ACPI_MODULE_NAME("utmisc") | 49 | ACPI_MODULE_NAME("utmisc") |
@@ -790,48 +791,147 @@ u8 acpi_ut_generate_checksum(u8 * buffer, u32 length) | |||
790 | 791 | ||
791 | /******************************************************************************* | 792 | /******************************************************************************* |
792 | * | 793 | * |
794 | * FUNCTION: acpi_ut_get_resource_type | ||
795 | * | ||
796 | * PARAMETERS: Aml - Pointer to the raw AML resource descriptor | ||
797 | * | ||
798 | * RETURN: The Resource Type with no extraneous bits (except the | ||
799 | * Large/Small descriptor bit -- this is left alone) | ||
800 | * | ||
801 | * DESCRIPTION: Extract the Resource Type/Name from the first byte of | ||
802 | * a resource descriptor. | ||
803 | * | ||
804 | ******************************************************************************/ | ||
805 | |||
806 | u8 acpi_ut_get_resource_type(void *aml) | ||
807 | { | ||
808 | ACPI_FUNCTION_ENTRY(); | ||
809 | |||
810 | /* | ||
811 | * Byte 0 contains the descriptor name (Resource Type) | ||
812 | * Determine if this is a small or large resource | ||
813 | */ | ||
814 | if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { | ||
815 | /* Large Resource Type -- bits 6:0 contain the name */ | ||
816 | |||
817 | return (*((u8 *) aml)); | ||
818 | } else { | ||
819 | /* Small Resource Type -- bits 6:3 contain the name */ | ||
820 | |||
821 | return ((u8) (*((u8 *) aml) & ACPI_RESOURCE_NAME_SMALL_MASK)); | ||
822 | } | ||
823 | } | ||
824 | |||
825 | /******************************************************************************* | ||
826 | * | ||
827 | * FUNCTION: acpi_ut_get_resource_length | ||
828 | * | ||
829 | * PARAMETERS: Aml - Pointer to the raw AML resource descriptor | ||
830 | * | ||
831 | * RETURN: Byte Length | ||
832 | * | ||
833 | * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By | ||
834 | * definition, this does not include the size of the descriptor | ||
835 | * header or the length field itself. | ||
836 | * | ||
837 | ******************************************************************************/ | ||
838 | |||
839 | u16 acpi_ut_get_resource_length(void *aml) | ||
840 | { | ||
841 | u16 resource_length; | ||
842 | |||
843 | ACPI_FUNCTION_ENTRY(); | ||
844 | |||
845 | /* | ||
846 | * Byte 0 contains the descriptor name (Resource Type) | ||
847 | * Determine if this is a small or large resource | ||
848 | */ | ||
849 | if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { | ||
850 | /* Large Resource type -- bytes 1-2 contain the 16-bit length */ | ||
851 | |||
852 | ACPI_MOVE_16_TO_16(&resource_length, &((u8 *) aml)[1]); | ||
853 | |||
854 | } else { | ||
855 | /* Small Resource type -- bits 2:0 of byte 0 contain the length */ | ||
856 | |||
857 | resource_length = (u16) (*((u8 *) aml) & | ||
858 | ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK); | ||
859 | } | ||
860 | |||
861 | return (resource_length); | ||
862 | } | ||
863 | |||
864 | /******************************************************************************* | ||
865 | * | ||
866 | * FUNCTION: acpi_ut_get_descriptor_length | ||
867 | * | ||
868 | * PARAMETERS: Aml - Pointer to the raw AML resource descriptor | ||
869 | * | ||
870 | * RETURN: Byte length | ||
871 | * | ||
872 | * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the | ||
873 | * length of the descriptor header and the length field itself. | ||
874 | * Used to walk descriptor lists. | ||
875 | * | ||
876 | ******************************************************************************/ | ||
877 | |||
878 | u32 acpi_ut_get_descriptor_length(void *aml) | ||
879 | { | ||
880 | u32 descriptor_length; | ||
881 | |||
882 | ACPI_FUNCTION_ENTRY(); | ||
883 | |||
884 | /* First get the Resource Length (Does not include header length) */ | ||
885 | |||
886 | descriptor_length = acpi_ut_get_resource_length(aml); | ||
887 | |||
888 | /* Determine if this is a small or large resource */ | ||
889 | |||
890 | if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { | ||
891 | descriptor_length += sizeof(struct aml_resource_large_header); | ||
892 | } else { | ||
893 | descriptor_length += sizeof(struct aml_resource_small_header); | ||
894 | } | ||
895 | |||
896 | return (descriptor_length); | ||
897 | } | ||
898 | |||
899 | /******************************************************************************* | ||
900 | * | ||
793 | * FUNCTION: acpi_ut_get_resource_end_tag | 901 | * FUNCTION: acpi_ut_get_resource_end_tag |
794 | * | 902 | * |
795 | * PARAMETERS: obj_desc - The resource template buffer object | 903 | * PARAMETERS: obj_desc - The resource template buffer object |
796 | * | 904 | * |
797 | * RETURN: Pointer to the end tag | 905 | * RETURN: Pointer to the end tag |
798 | * | 906 | * |
799 | * DESCRIPTION: Find the END_TAG resource descriptor in a resource template | 907 | * DESCRIPTION: Find the END_TAG resource descriptor in an AML resource template |
800 | * | 908 | * |
801 | ******************************************************************************/ | 909 | ******************************************************************************/ |
802 | 910 | ||
803 | u8 *acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc) | 911 | u8 *acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc) |
804 | { | 912 | { |
805 | u8 buffer_byte; | 913 | u8 *aml; |
806 | u8 *buffer; | 914 | u8 *end_aml; |
807 | u8 *end_buffer; | ||
808 | |||
809 | buffer = obj_desc->buffer.pointer; | ||
810 | end_buffer = buffer + obj_desc->buffer.length; | ||
811 | 915 | ||
812 | while (buffer < end_buffer) { | 916 | aml = obj_desc->buffer.pointer; |
813 | buffer_byte = *buffer; | 917 | end_aml = aml + obj_desc->buffer.length; |
814 | if (buffer_byte & ACPI_RESOURCE_NAME_LARGE) { | ||
815 | /* Large Descriptor - Length is next 2 bytes */ | ||
816 | 918 | ||
817 | buffer += ((*(buffer + 1) | (*(buffer + 2) << 8)) + 3); | 919 | /* Walk the resource template, one descriptor per loop */ |
818 | } else { | ||
819 | /* Small Descriptor. End Tag will be found here */ | ||
820 | 920 | ||
821 | if ((buffer_byte & ACPI_RESOURCE_NAME_SMALL_MASK) == | 921 | while (aml < end_aml) { |
822 | ACPI_RESOURCE_NAME_END_TAG) { | 922 | if (acpi_ut_get_resource_type(aml) == |
823 | /* Found the end tag descriptor, all done. */ | 923 | ACPI_RESOURCE_NAME_END_TAG) { |
924 | /* Found the end_tag descriptor, all done */ | ||
824 | 925 | ||
825 | return (buffer); | 926 | return (aml); |
826 | } | 927 | } |
827 | 928 | ||
828 | /* Length is in the header */ | 929 | /* Point to the next resource descriptor */ |
829 | 930 | ||
830 | buffer += ((buffer_byte & 0x07) + 1); | 931 | aml += acpi_ut_get_resource_length(aml); |
831 | } | ||
832 | } | 932 | } |
833 | 933 | ||
834 | /* End tag not found */ | 934 | /* End tag was not found */ |
835 | 935 | ||
836 | return (NULL); | 936 | return (NULL); |
837 | } | 937 | } |