diff options
Diffstat (limited to 'drivers/acpi/resources')
-rw-r--r-- | drivers/acpi/resources/Makefile | 2 | ||||
-rw-r--r-- | drivers/acpi/resources/rsaddr.c | 1164 | ||||
-rw-r--r-- | drivers/acpi/resources/rscalc.c | 831 | ||||
-rw-r--r-- | drivers/acpi/resources/rscreate.c | 231 | ||||
-rw-r--r-- | drivers/acpi/resources/rsdump.c | 1399 | ||||
-rw-r--r-- | drivers/acpi/resources/rsinfo.c | 204 | ||||
-rw-r--r-- | drivers/acpi/resources/rsio.c | 544 | ||||
-rw-r--r-- | drivers/acpi/resources/rsirq.c | 568 | ||||
-rw-r--r-- | drivers/acpi/resources/rslist.c | 534 | ||||
-rw-r--r-- | drivers/acpi/resources/rsmemory.c | 517 | ||||
-rw-r--r-- | drivers/acpi/resources/rsmisc.c | 860 | ||||
-rw-r--r-- | drivers/acpi/resources/rsutils.c | 390 | ||||
-rw-r--r-- | drivers/acpi/resources/rsxface.c | 230 |
13 files changed, 2887 insertions, 4587 deletions
diff --git a/drivers/acpi/resources/Makefile b/drivers/acpi/resources/Makefile index 2130b74170c3..8de4f69dfa09 100644 --- a/drivers/acpi/resources/Makefile +++ b/drivers/acpi/resources/Makefile @@ -2,7 +2,7 @@ # Makefile for all Linux ACPI interpreter subdirectories # -obj-y := rsaddr.o rscreate.o rsio.o rslist.o rsmisc.o rsxface.o \ +obj-y := rsaddr.o rscreate.o rsinfo.o rsio.o rslist.o rsmisc.o rsxface.o \ rscalc.o rsirq.o rsmemory.o rsutils.o obj-$(ACPI_FUTURE_USAGE) += rsdump.o diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c index 23b54baa0cb2..8fa3213ce000 100644 --- a/drivers/acpi/resources/rsaddr.c +++ b/drivers/acpi/resources/rsaddr.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,1072 +47,334 @@ #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rsaddr") -/* Local prototypes */ -static void -acpi_rs_decode_general_flags(union acpi_resource_data *resource, u8 flags); - -static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource); - -static void -acpi_rs_decode_specific_flags(union acpi_resource_data *resource, u8 flags); - -static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource); - /******************************************************************************* * - * FUNCTION: acpi_rs_decode_general_flags - * - * PARAMETERS: Resource - Address resource data struct - * Flags - Actual flag byte - * - * RETURN: Decoded flag bits in resource struct - * - * DESCRIPTION: Decode a general flag byte to an address resource struct + * acpi_rs_convert_address16 - All WORD (16-bit) address resources * ******************************************************************************/ +struct acpi_rsconvert_info acpi_rs_convert_address16[5] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS16, + ACPI_RS_SIZE(struct acpi_resource_address16), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address16)}, -static void -acpi_rs_decode_general_flags(union acpi_resource_data *resource, u8 flags) -{ - ACPI_FUNCTION_ENTRY(); - - /* Producer / Consumer - flag bit[0] */ - - resource->address.producer_consumer = (u32) (flags & 0x01); + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS16, + sizeof(struct aml_resource_address16), + 0}, - /* Decode (_DEC) - flag bit[1] */ + /* Resource Type, General Flags, and Type-Specific Flags */ - resource->address.decode = (u32) ((flags >> 1) & 0x01); + {ACPI_RSC_ADDRESS, 0, 0, 0}, - /* Min Address Fixed (_MIF) - flag bit[2] */ + /* + * These fields are contiguous in both the source and destination: + * Address Granularity + * Address Range Minimum + * Address Range Maximum + * Address Translation Offset + * Address Length + */ + {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.address16.granularity), + AML_OFFSET(address16.granularity), + 5}, - resource->address.min_address_fixed = (u32) ((flags >> 2) & 0x01); + /* Optional resource_source (Index and String) */ - /* Max Address Fixed (_MAF) - flag bit[3] */ - - resource->address.max_address_fixed = (u32) ((flags >> 3) & 0x01); -} + {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address16.resource_source), + 0, + sizeof(struct aml_resource_address16)} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_encode_general_flags - * - * PARAMETERS: Resource - Address resource data struct - * - * RETURN: Encoded general flag byte - * - * DESCRIPTION: Construct a general flag byte from an address resource struct + * acpi_rs_convert_address32 - All DWORD (32-bit) address resources * ******************************************************************************/ -static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource) -{ - u8 flags; - - ACPI_FUNCTION_ENTRY(); - - /* Producer / Consumer - flag bit[0] */ - - flags = (u8) (resource->address.producer_consumer & 0x01); - - /* Decode (_DEC) - flag bit[1] */ - - flags |= (u8) ((resource->address.decode & 0x01) << 1); - - /* Min Address Fixed (_MIF) - flag bit[2] */ - - flags |= (u8) ((resource->address.min_address_fixed & 0x01) << 2); +struct acpi_rsconvert_info acpi_rs_convert_address32[5] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS32, + ACPI_RS_SIZE(struct acpi_resource_address32), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address32)}, - /* Max Address Fixed (_MAF) - flag bit[3] */ + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS32, + sizeof(struct aml_resource_address32), + 0}, - flags |= (u8) ((resource->address.max_address_fixed & 0x01) << 3); + /* Resource Type, General Flags, and Type-Specific Flags */ - return (flags); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_decode_specific_flags - * - * PARAMETERS: Resource - Address resource data struct - * Flags - Actual flag byte - * - * RETURN: Decoded flag bits in attribute struct - * - * DESCRIPTION: Decode a type-specific flag byte to an attribute struct. - * Type-specific flags are only defined for the Memory and IO - * resource types. - * - ******************************************************************************/ + {ACPI_RSC_ADDRESS, 0, 0, 0}, -static void -acpi_rs_decode_specific_flags(union acpi_resource_data *resource, u8 flags) -{ - ACPI_FUNCTION_ENTRY(); - - if (resource->address.resource_type == ACPI_MEMORY_RANGE) { - /* Write Status (_RW) - flag bit[0] */ - - resource->address.attribute.memory.read_write_attribute = - (u16) (flags & 0x01); - - /* Memory Attributes (_MEM) - flag bits[2:1] */ - - resource->address.attribute.memory.cache_attribute = - (u16) ((flags >> 1) & 0x03); - } else if (resource->address.resource_type == ACPI_IO_RANGE) { - /* Ranges (_RNG) - flag bits[1:0] */ - - resource->address.attribute.io.range_attribute = - (u16) (flags & 0x03); + /* + * These fields are contiguous in both the source and destination: + * Address Granularity + * Address Range Minimum + * Address Range Maximum + * Address Translation Offset + * Address Length + */ + {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.address32.granularity), + AML_OFFSET(address32.granularity), + 5}, - /* Translations (_TTP and _TRS) - flag bits[5:4] */ + /* Optional resource_source (Index and String) */ - resource->address.attribute.io.translation_attribute = - (u16) ((flags >> 4) & 0x03); - } -} + {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address32.resource_source), + 0, + sizeof(struct aml_resource_address32)} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_encode_specific_flags - * - * PARAMETERS: Resource - Address resource data struct - * - * RETURN: Encoded type-specific flag byte - * - * DESCRIPTION: Construct a type-specific flag byte from an attribute struct. - * Type-specific flags are only defined for the Memory and IO - * resource types. + * acpi_rs_convert_address64 - All QWORD (64-bit) address resources * ******************************************************************************/ -static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource) -{ - u8 flags = 0; - - ACPI_FUNCTION_ENTRY(); - - if (resource->address.resource_type == ACPI_MEMORY_RANGE) { - /* Write Status (_RW) - flag bit[0] */ +struct acpi_rsconvert_info acpi_rs_convert_address64[5] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS64, + ACPI_RS_SIZE(struct acpi_resource_address64), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address64)}, - flags = (u8) - (resource->address.attribute.memory. - read_write_attribute & 0x01); + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS64, + sizeof(struct aml_resource_address64), + 0}, - /* Memory Attributes (_MEM) - flag bits[2:1] */ + /* Resource Type, General Flags, and Type-Specific Flags */ - flags |= (u8) - ((resource->address.attribute.memory. - cache_attribute & 0x03) << 1); - } else if (resource->address.resource_type == ACPI_IO_RANGE) { - /* Ranges (_RNG) - flag bits[1:0] */ + {ACPI_RSC_ADDRESS, 0, 0, 0}, - flags = (u8) - (resource->address.attribute.io.range_attribute & 0x03); + /* + * These fields are contiguous in both the source and destination: + * Address Granularity + * Address Range Minimum + * Address Range Maximum + * Address Translation Offset + * Address Length + */ + {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.address64.granularity), + AML_OFFSET(address64.granularity), + 5}, - /* Translations (_TTP and _TRS) - flag bits[5:4] */ + /* Optional resource_source (Index and String) */ - flags |= (u8) - ((resource->address.attribute.io. - translation_attribute & 0x03) << 4); - } - - return (flags); -} + {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address64.resource_source), + 0, + sizeof(struct aml_resource_address64)} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_address16_resource - * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * acpi_rs_convert_ext_address64 - All Extended (64-bit) address resources * ******************************************************************************/ -acpi_status -acpi_rs_address16_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) -{ - u32 index; - u16 temp16; - u8 temp8; - u8 *temp_ptr; - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16); - - ACPI_FUNCTION_TRACE("rs_address16_resource"); - - /* Get the Descriptor Length field */ - - buffer += 1; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - /* Validate minimum descriptor length */ - - if (temp16 < 13) { - return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); - } - - *bytes_consumed = temp16 + 3; - output_struct->id = ACPI_RSTYPE_ADDRESS16; - - /* Get the Resource Type (Byte3) */ +struct acpi_rsconvert_info acpi_rs_convert_ext_address64[5] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64, + ACPI_RS_SIZE(struct acpi_resource_extended_address64), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_address64)}, - buffer += 2; - temp8 = *buffer; + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64, + sizeof(struct aml_resource_extended_address64), + 0}, - /* Values 0-2 and 0xC0-0xFF are valid */ + /* Resource Type, General Flags, and Type-Specific Flags */ - if ((temp8 > 2) && (temp8 < 0xC0)) { - return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); - } - - output_struct->data.address16.resource_type = temp8; - - /* Get the General Flags (Byte4) */ - - buffer += 1; - acpi_rs_decode_general_flags(&output_struct->data, *buffer); - - /* Get the Type Specific Flags (Byte5) */ - - buffer += 1; - acpi_rs_decode_specific_flags(&output_struct->data, *buffer); - - /* Get Granularity (Bytes 6-7) */ - - buffer += 1; - ACPI_MOVE_16_TO_32(&output_struct->data.address16.granularity, buffer); - - /* Get min_address_range (Bytes 8-9) */ + {ACPI_RSC_ADDRESS, 0, 0, 0}, - buffer += 2; - ACPI_MOVE_16_TO_32(&output_struct->data.address16.min_address_range, - buffer); - - /* Get max_address_range (Bytes 10-11) */ - - buffer += 2; - ACPI_MOVE_16_TO_32(&output_struct->data.address16.max_address_range, - buffer); - - /* Get address_translation_offset (Bytes 12-13) */ - - buffer += 2; - ACPI_MOVE_16_TO_32(&output_struct->data.address16. - address_translation_offset, buffer); - - /* Get address_length (Bytes 14-15) */ - - buffer += 2; - ACPI_MOVE_16_TO_32(&output_struct->data.address16.address_length, - buffer); - - /* Resource Source Index (if present) */ - - buffer += 2; + /* Revision ID */ + {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.ext_address64.revision_iD), + AML_OFFSET(ext_address64.revision_iD), + 1}, /* - * This will leave us pointing to the Resource Source Index - * If it is present, then save it off and calculate the - * pointer to where the null terminated string goes: - * Each Interrupt takes 32-bits + the 5 bytes of the - * stream that are default. - * - * Note: Some resource descriptors will have an additional null, so - * we add 1 to the length. + * These fields are contiguous in both the source and destination: + * Address Granularity + * Address Range Minimum + * Address Range Maximum + * Address Translation Offset + * Address Length + * Type-Specific Attribute */ - if (*bytes_consumed > (16 + 1)) { - /* Dereference the Index */ - - output_struct->data.address16.resource_source.index = - (u32) * buffer; - - /* Point to the String */ - - buffer += 1; - - /* Point the String pointer to the end of this structure */ - - output_struct->data.address16.resource_source.string_ptr = - (char *)((u8 *) output_struct + struct_size); - - temp_ptr = (u8 *) - output_struct->data.address16.resource_source.string_ptr; - - /* Copy the resource_source string into the buffer */ - - index = 0; - while (*buffer) { - *temp_ptr = *buffer; - - temp_ptr++; - buffer++; - index++; - } - - /* Add the terminating null and set the string length */ - - *temp_ptr = 0; - output_struct->data.address16.resource_source.string_length = - index + 1; - - /* - * In order for the struct_size to fall on a 32-bit boundary, - * calculate the length of the string and expand the - * struct_size to the next 32-bit boundary. - */ - temp8 = (u8) (index + 1); - struct_size += ACPI_ROUND_UP_to_32_bITS(temp8); - } else { - output_struct->data.address16.resource_source.index = 0; - output_struct->data.address16.resource_source.string_length = 0; - output_struct->data.address16.resource_source.string_ptr = NULL; - } - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.ext_address64.granularity), + AML_OFFSET(ext_address64.granularity), + 6} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_address16_stream - * - * PARAMETERS: linked_list - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * acpi_rs_convert_general_flags - Flags common to all address descriptors * ******************************************************************************/ -acpi_status -acpi_rs_address16_stream(struct acpi_resource *linked_list, - u8 ** output_buffer, acpi_size * bytes_consumed) -{ - u8 *buffer = *output_buffer; - u8 *length_field; - acpi_size actual_bytes; - - ACPI_FUNCTION_TRACE("rs_address16_stream"); - - /* Set the Descriptor Type field */ - - *buffer = ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE; - buffer += 1; - - /* Save a pointer to the Length field - to be filled in later */ - - length_field = buffer; - buffer += 2; - - /* Set the Resource Type (Memory, Io, bus_number) */ - - *buffer = (u8) (linked_list->data.address16.resource_type & 0x03); - buffer += 1; - - /* Set the general flags */ - - *buffer = acpi_rs_encode_general_flags(&linked_list->data); - buffer += 1; - - /* Set the type specific flags */ - - *buffer = acpi_rs_encode_specific_flags(&linked_list->data); - buffer += 1; - - /* Set the address space granularity */ - - ACPI_MOVE_32_TO_16(buffer, &linked_list->data.address16.granularity); - buffer += 2; - - /* Set the address range minimum */ +static struct acpi_rsconvert_info acpi_rs_convert_general_flags[6] = { + {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.flags), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_general_flags)}, - ACPI_MOVE_32_TO_16(buffer, - &linked_list->data.address16.min_address_range); - buffer += 2; + /* Resource Type (Memory, Io, bus_number, etc.) */ - /* Set the address range maximum */ + {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.address.resource_type), + AML_OFFSET(address.resource_type), + 1}, - ACPI_MOVE_32_TO_16(buffer, - &linked_list->data.address16.max_address_range); - buffer += 2; + /* General Flags - Consume, Decode, min_fixed, max_fixed */ - /* Set the address translation offset */ + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.producer_consumer), + AML_OFFSET(address.flags), + 0}, - ACPI_MOVE_32_TO_16(buffer, - &linked_list->data.address16. - address_translation_offset); - buffer += 2; + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.decode), + AML_OFFSET(address.flags), + 1}, - /* Set the address length */ + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.min_address_fixed), + AML_OFFSET(address.flags), + 2}, - ACPI_MOVE_32_TO_16(buffer, &linked_list->data.address16.address_length); - buffer += 2; - - /* Resource Source Index and Resource Source are optional */ - - if (linked_list->data.address16.resource_source.string_length) { - *buffer = - (u8) linked_list->data.address16.resource_source.index; - buffer += 1; - - /* Copy the resource_source string */ - - ACPI_STRCPY((char *)buffer, - linked_list->data.address16.resource_source. - string_ptr); - - /* - * Buffer needs to be set to the length of the string + one for the - * terminating null - */ - buffer += - (acpi_size) (ACPI_STRLEN - (linked_list->data.address16.resource_source. - string_ptr) + 1); - } - - /* Return the number of bytes consumed in this operation */ - - actual_bytes = ACPI_PTR_DIFF(buffer, *output_buffer); - *bytes_consumed = actual_bytes; - - /* - * Set the length field to the number of bytes consumed - * minus the header size (3 bytes) - */ - actual_bytes -= 3; - ACPI_MOVE_SIZE_TO_16(length_field, &actual_bytes); - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.max_address_fixed), + AML_OFFSET(address.flags), + 3} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_address32_resource - * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * acpi_rs_convert_mem_flags - Flags common to Memory address descriptors * ******************************************************************************/ -acpi_status -acpi_rs_address32_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) -{ - u16 temp16; - u8 temp8; - u8 *temp_ptr; - u32 index; - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32); +static struct acpi_rsconvert_info acpi_rs_convert_mem_flags[5] = { + {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_mem_flags)}, - ACPI_FUNCTION_TRACE("rs_address32_resource"); + /* Memory-specific flags */ - /* Get the Descriptor Length field */ + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.write_protect), + AML_OFFSET(address.specific_flags), + 0}, - buffer += 1; - ACPI_MOVE_16_TO_16(&temp16, buffer); + {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.caching), + AML_OFFSET(address.specific_flags), + 1}, - /* Validate minimum descriptor length */ + {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.range_type), + AML_OFFSET(address.specific_flags), + 3}, - if (temp16 < 23) { - return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); - } - - *bytes_consumed = temp16 + 3; - output_struct->id = ACPI_RSTYPE_ADDRESS32; - - /* Get the Resource Type (Byte3) */ - - buffer += 2; - temp8 = *buffer; - - /* Values 0-2 and 0xC0-0xFF are valid */ - - if ((temp8 > 2) && (temp8 < 0xC0)) { - return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); - } - - output_struct->data.address32.resource_type = temp8; - - /* Get the General Flags (Byte4) */ - - buffer += 1; - acpi_rs_decode_general_flags(&output_struct->data, *buffer); - - /* Get the Type Specific Flags (Byte5) */ - - buffer += 1; - acpi_rs_decode_specific_flags(&output_struct->data, *buffer); - - /* Get Granularity (Bytes 6-9) */ - - buffer += 1; - ACPI_MOVE_32_TO_32(&output_struct->data.address32.granularity, buffer); - - /* Get min_address_range (Bytes 10-13) */ - - buffer += 4; - ACPI_MOVE_32_TO_32(&output_struct->data.address32.min_address_range, - buffer); - - /* Get max_address_range (Bytes 14-17) */ - - buffer += 4; - ACPI_MOVE_32_TO_32(&output_struct->data.address32.max_address_range, - buffer); - - /* Get address_translation_offset (Bytes 18-21) */ - - buffer += 4; - ACPI_MOVE_32_TO_32(&output_struct->data.address32. - address_translation_offset, buffer); - - /* Get address_length (Bytes 22-25) */ - - buffer += 4; - ACPI_MOVE_32_TO_32(&output_struct->data.address32.address_length, - buffer); - - /* Resource Source Index (if present) */ - - buffer += 4; - - /* - * This will leave us pointing to the Resource Source Index - * If it is present, then save it off and calculate the - * pointer to where the null terminated string goes: - * - * Note: Some resource descriptors will have an additional null, so - * we add 1 to the length. - */ - if (*bytes_consumed > (26 + 1)) { - /* Dereference the Index */ - - output_struct->data.address32.resource_source.index = - (u32) * buffer; - - /* Point to the String */ - - buffer += 1; - - /* Point the String pointer to the end of this structure */ - - output_struct->data.address32.resource_source.string_ptr = - (char *)((u8 *) output_struct + struct_size); - - temp_ptr = (u8 *) - output_struct->data.address32.resource_source.string_ptr; - - /* Copy the resource_source string into the buffer */ - - index = 0; - while (*buffer) { - *temp_ptr = *buffer; - - temp_ptr++; - buffer++; - index++; - } - - /* Add the terminating null and set the string length */ - - *temp_ptr = 0; - output_struct->data.address32.resource_source.string_length = - index + 1; - - /* - * In order for the struct_size to fall on a 32-bit boundary, - * calculate the length of the string and expand the - * struct_size to the next 32-bit boundary. - */ - temp8 = (u8) (index + 1); - struct_size += ACPI_ROUND_UP_to_32_bITS(temp8); - } else { - output_struct->data.address32.resource_source.index = 0; - output_struct->data.address32.resource_source.string_length = 0; - output_struct->data.address32.resource_source.string_ptr = NULL; - } - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.translation), + AML_OFFSET(address.specific_flags), + 5} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_address32_stream - * - * PARAMETERS: linked_list - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * acpi_rs_convert_io_flags - Flags common to I/O address descriptors * ******************************************************************************/ -acpi_status -acpi_rs_address32_stream(struct acpi_resource *linked_list, - u8 ** output_buffer, acpi_size * bytes_consumed) -{ - u8 *buffer; - u16 *length_field; - - ACPI_FUNCTION_TRACE("rs_address32_stream"); - - buffer = *output_buffer; - - /* Set the Descriptor Type field */ - - *buffer = ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE; - buffer += 1; - - /* Save a pointer to the Length field - to be filled in later */ - - length_field = ACPI_CAST_PTR(u16, buffer); - buffer += 2; - - /* Set the Resource Type (Memory, Io, bus_number) */ - - *buffer = (u8) (linked_list->data.address32.resource_type & 0x03); - buffer += 1; - - /* Set the general flags */ - - *buffer = acpi_rs_encode_general_flags(&linked_list->data); - buffer += 1; - - /* Set the type specific flags */ - - *buffer = acpi_rs_encode_specific_flags(&linked_list->data); - buffer += 1; - - /* Set the address space granularity */ - - ACPI_MOVE_32_TO_32(buffer, &linked_list->data.address32.granularity); - buffer += 4; - - /* Set the address range minimum */ - - ACPI_MOVE_32_TO_32(buffer, - &linked_list->data.address32.min_address_range); - buffer += 4; - - /* Set the address range maximum */ - - ACPI_MOVE_32_TO_32(buffer, - &linked_list->data.address32.max_address_range); - buffer += 4; - - /* Set the address translation offset */ - - ACPI_MOVE_32_TO_32(buffer, - &linked_list->data.address32. - address_translation_offset); - buffer += 4; - - /* Set the address length */ - - ACPI_MOVE_32_TO_32(buffer, &linked_list->data.address32.address_length); - buffer += 4; +static struct acpi_rsconvert_info acpi_rs_convert_io_flags[4] = { + {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_io_flags)}, - /* Resource Source Index and Resource Source are optional */ + /* I/O-specific flags */ - if (linked_list->data.address32.resource_source.string_length) { - *buffer = - (u8) linked_list->data.address32.resource_source.index; - buffer += 1; + {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.io.range_type), + AML_OFFSET(address.specific_flags), + 0}, - /* Copy the resource_source string */ + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.io.translation), + AML_OFFSET(address.specific_flags), + 4}, - ACPI_STRCPY((char *)buffer, - linked_list->data.address32.resource_source. - string_ptr); - - /* - * Buffer needs to be set to the length of the string + one for the - * terminating null - */ - buffer += - (acpi_size) (ACPI_STRLEN - (linked_list->data.address32.resource_source. - string_ptr) + 1); - } - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); - - /* - * Set the length field to the number of bytes consumed - * minus the header size (3 bytes) - */ - *length_field = (u16) (*bytes_consumed - 3); - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_1BITFLAG, + ACPI_RS_OFFSET(data.address.info.io.translation_type), + AML_OFFSET(address.specific_flags), + 5} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_address64_resource + * FUNCTION: acpi_rs_get_address_common * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned + * PARAMETERS: Resource - Pointer to the internal resource struct + * Aml - Pointer to the AML resource descriptor * - * RETURN: Status + * RETURN: TRUE if the resource_type field is OK, FALSE otherwise * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor + * to an internal resource descriptor * ******************************************************************************/ -acpi_status -acpi_rs_address64_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) +u8 +acpi_rs_get_address_common(struct acpi_resource *resource, + union aml_resource *aml) { - u16 temp16; - u8 temp8; - u8 resource_type; - u8 *temp_ptr; - u32 index; - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64); - - ACPI_FUNCTION_TRACE("rs_address64_resource"); - - /* Get the Descriptor Type */ - - resource_type = *buffer; - - /* Get the Descriptor Length field */ - - buffer += 1; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - /* Validate minimum descriptor length */ - - if (temp16 < 43) { - return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); - } - - *bytes_consumed = temp16 + 3; - output_struct->id = ACPI_RSTYPE_ADDRESS64; - - /* Get the Resource Type (Byte3) */ - - buffer += 2; - temp8 = *buffer; - - /* Values 0-2 and 0xC0-0xFF are valid */ - - if ((temp8 > 2) && (temp8 < 0xC0)) { - return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); - } - - output_struct->data.address64.resource_type = temp8; - - /* Get the General Flags (Byte4) */ - - buffer += 1; - acpi_rs_decode_general_flags(&output_struct->data, *buffer); - - /* Get the Type Specific Flags (Byte5) */ - - buffer += 1; - acpi_rs_decode_specific_flags(&output_struct->data, *buffer); + ACPI_FUNCTION_ENTRY(); - if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) { - /* Move past revision_id and Reserved byte */ + /* Validate the Resource Type */ - buffer += 2; + if ((aml->address.resource_type > 2) + && (aml->address.resource_type < 0xC0)) { + return (FALSE); } - /* Get Granularity (Bytes 6-13) or (Bytes 8-15) */ - - buffer += 1; - ACPI_MOVE_64_TO_64(&output_struct->data.address64.granularity, buffer); - - /* Get min_address_range (Bytes 14-21) or (Bytes 16-23) */ - - buffer += 8; - ACPI_MOVE_64_TO_64(&output_struct->data.address64.min_address_range, - buffer); - - /* Get max_address_range (Bytes 22-29) or (Bytes 24-31) */ - - buffer += 8; - ACPI_MOVE_64_TO_64(&output_struct->data.address64.max_address_range, - buffer); - - /* Get address_translation_offset (Bytes 30-37) or (Bytes 32-39) */ - - buffer += 8; - ACPI_MOVE_64_TO_64(&output_struct->data.address64. - address_translation_offset, buffer); + /* Get the Resource Type and General Flags */ - /* Get address_length (Bytes 38-45) or (Bytes 40-47) */ + (void)acpi_rs_convert_aml_to_resource(resource, aml, + acpi_rs_convert_general_flags); - buffer += 8; - ACPI_MOVE_64_TO_64(&output_struct->data.address64.address_length, - buffer); + /* Get the Type-Specific Flags (Memory and I/O descriptors only) */ - output_struct->data.address64.resource_source.index = 0; - output_struct->data.address64.resource_source.string_length = 0; - output_struct->data.address64.resource_source.string_ptr = NULL; - - if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) { - /* Get type_specific_attribute (Bytes 48-55) */ - - buffer += 8; - ACPI_MOVE_64_TO_64(&output_struct->data.address64. - type_specific_attributes, buffer); + if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) { + (void)acpi_rs_convert_aml_to_resource(resource, aml, + acpi_rs_convert_mem_flags); + } else if (resource->data.address.resource_type == ACPI_IO_RANGE) { + (void)acpi_rs_convert_aml_to_resource(resource, aml, + acpi_rs_convert_io_flags); } else { - output_struct->data.address64.type_specific_attributes = 0; - - /* Resource Source Index (if present) */ - - buffer += 8; - - /* - * This will leave us pointing to the Resource Source Index - * If it is present, then save it off and calculate the - * pointer to where the null terminated string goes: - * Each Interrupt takes 32-bits + the 5 bytes of the - * stream that are default. - * - * Note: Some resource descriptors will have an additional null, so - * we add 1 to the length. - */ - if (*bytes_consumed > (46 + 1)) { - /* Dereference the Index */ - - output_struct->data.address64.resource_source.index = - (u32) * buffer; - - /* Point to the String */ - - buffer += 1; - - /* Point the String pointer to the end of this structure */ - - output_struct->data.address64.resource_source. - string_ptr = - (char *)((u8 *) output_struct + struct_size); - - temp_ptr = (u8 *) - output_struct->data.address64.resource_source. - string_ptr; - - /* Copy the resource_source string into the buffer */ - - index = 0; - while (*buffer) { - *temp_ptr = *buffer; - - temp_ptr++; - buffer++; - index++; - } - - /* - * Add the terminating null and set the string length - */ - *temp_ptr = 0; - output_struct->data.address64.resource_source. - string_length = index + 1; - - /* - * In order for the struct_size to fall on a 32-bit boundary, - * calculate the length of the string and expand the - * struct_size to the next 32-bit boundary. - */ - temp8 = (u8) (index + 1); - struct_size += ACPI_ROUND_UP_to_32_bITS(temp8); - } - } - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; + /* Generic resource type, just grab the type_specific byte */ - /* Return the final size of the structure */ + resource->data.address.info.type_specific = + aml->address.specific_flags; + } - *structure_size = struct_size; - return_ACPI_STATUS(AE_OK); + return (TRUE); } /******************************************************************************* * - * FUNCTION: acpi_rs_address64_stream + * FUNCTION: acpi_rs_set_address_common * - * PARAMETERS: linked_list - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned + * PARAMETERS: Aml - Pointer to the AML resource descriptor + * Resource - Pointer to the internal resource struct * - * RETURN: Status + * RETURN: None * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * DESCRIPTION: Convert common flag fields from a resource descriptor to an + * AML descriptor * ******************************************************************************/ -acpi_status -acpi_rs_address64_stream(struct acpi_resource *linked_list, - u8 ** output_buffer, acpi_size * bytes_consumed) +void +acpi_rs_set_address_common(union aml_resource *aml, + struct acpi_resource *resource) { - u8 *buffer; - u16 *length_field; - - ACPI_FUNCTION_TRACE("rs_address64_stream"); - - buffer = *output_buffer; - - /* Set the Descriptor Type field */ - - *buffer = ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE; - buffer += 1; - - /* Save a pointer to the Length field - to be filled in later */ - - length_field = ACPI_CAST_PTR(u16, buffer); - buffer += 2; - - /* Set the Resource Type (Memory, Io, bus_number) */ - - *buffer = (u8) (linked_list->data.address64.resource_type & 0x03); - buffer += 1; - - /* Set the general flags */ - - *buffer = acpi_rs_encode_general_flags(&linked_list->data); - buffer += 1; - - /* Set the type specific flags */ - - *buffer = acpi_rs_encode_specific_flags(&linked_list->data); - buffer += 1; - - /* Set the address space granularity */ - - ACPI_MOVE_64_TO_64(buffer, &linked_list->data.address64.granularity); - buffer += 8; - - /* Set the address range minimum */ - - ACPI_MOVE_64_TO_64(buffer, - &linked_list->data.address64.min_address_range); - buffer += 8; - - /* Set the address range maximum */ - - ACPI_MOVE_64_TO_64(buffer, - &linked_list->data.address64.max_address_range); - buffer += 8; - - /* Set the address translation offset */ - - ACPI_MOVE_64_TO_64(buffer, - &linked_list->data.address64. - address_translation_offset); - buffer += 8; - - /* Set the address length */ - - ACPI_MOVE_64_TO_64(buffer, &linked_list->data.address64.address_length); - buffer += 8; + ACPI_FUNCTION_ENTRY(); - /* Resource Source Index and Resource Source are optional */ + /* Set the Resource Type and General Flags */ - if (linked_list->data.address64.resource_source.string_length) { - *buffer = - (u8) linked_list->data.address64.resource_source.index; - buffer += 1; + (void)acpi_rs_convert_resource_to_aml(resource, aml, + acpi_rs_convert_general_flags); - /* Copy the resource_source string */ + /* Set the Type-Specific Flags (Memory and I/O descriptors only) */ - ACPI_STRCPY((char *)buffer, - linked_list->data.address64.resource_source. - string_ptr); + if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) { + (void)acpi_rs_convert_resource_to_aml(resource, aml, + acpi_rs_convert_mem_flags); + } else if (resource->data.address.resource_type == ACPI_IO_RANGE) { + (void)acpi_rs_convert_resource_to_aml(resource, aml, + acpi_rs_convert_io_flags); + } else { + /* Generic resource type, just copy the type_specific byte */ - /* - * Buffer needs to be set to the length of the string + one for the - * terminating null - */ - buffer += - (acpi_size) (ACPI_STRLEN - (linked_list->data.address64.resource_source. - string_ptr) + 1); + aml->address.specific_flags = + resource->data.address.info.type_specific; } - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); - - /* - * Set the length field to the number of bytes consumed - * minus the header size (3 bytes) - */ - *length_field = (u16) (*bytes_consumed - 3); - return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index 378f58390fc1..7d6481d9fbec 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,652 +49,433 @@ #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rscalc") +/* Local prototypes */ +static u8 acpi_rs_count_set_bits(u16 bit_field); + +static acpi_rs_length +acpi_rs_struct_option_length(struct acpi_resource_source *resource_source); + +static u32 +acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length); + /******************************************************************************* * - * FUNCTION: acpi_rs_get_byte_stream_length + * FUNCTION: acpi_rs_count_set_bits * - * PARAMETERS: linked_list - Pointer to the resource linked list - * size_needed - u32 pointer of the size buffer needed - * to properly return the parsed data + * PARAMETERS: bit_field - Field in which to count bits * - * RETURN: Status + * RETURN: Number of bits set within the field * - * DESCRIPTION: Takes the resource byte stream and parses it once, calculating - * the size buffer needed to hold the linked list that conveys - * the resource data. + * DESCRIPTION: Count the number of bits set in a resource field. Used for + * (Short descriptor) interrupt and DMA lists. * ******************************************************************************/ -acpi_status -acpi_rs_get_byte_stream_length(struct acpi_resource *linked_list, - acpi_size * size_needed) -{ - acpi_size byte_stream_size_needed = 0; - acpi_size segment_size; - u8 done = FALSE; - - ACPI_FUNCTION_TRACE("rs_get_byte_stream_length"); - - while (!done) { - /* Init the variable that will hold the size to add to the total. */ - - segment_size = 0; - - switch (linked_list->id) { - case ACPI_RSTYPE_IRQ: - /* - * IRQ Resource - * For an IRQ Resource, Byte 3, although optional, will always be - * created - it holds IRQ information. - */ - segment_size = 4; - break; - - case ACPI_RSTYPE_DMA: - /* - * DMA Resource - * For this resource the size is static - */ - segment_size = 3; - break; - - case ACPI_RSTYPE_START_DPF: - /* - * Start Dependent Functions Resource - * For a start_dependent_functions Resource, Byte 1, although - * optional, will always be created. - */ - segment_size = 2; - break; - - case ACPI_RSTYPE_END_DPF: - /* - * End Dependent Functions Resource - * For this resource the size is static - */ - segment_size = 1; - break; - - case ACPI_RSTYPE_IO: - /* - * IO Port Resource - * For this resource the size is static - */ - segment_size = 8; - break; - case ACPI_RSTYPE_FIXED_IO: - /* - * Fixed IO Port Resource - * For this resource the size is static - */ - segment_size = 4; - break; - - case ACPI_RSTYPE_VENDOR: - /* - * Vendor Defined Resource - * For a Vendor Specific resource, if the Length is between 1 and 7 - * it will be created as a Small Resource data type, otherwise it - * is a Large Resource data type. - */ - if (linked_list->data.vendor_specific.length > 7) { - segment_size = 3; - } else { - segment_size = 1; - } - segment_size += - linked_list->data.vendor_specific.length; - break; - - case ACPI_RSTYPE_END_TAG: - /* - * End Tag - * For this resource the size is static - */ - segment_size = 2; - done = TRUE; - break; - - case ACPI_RSTYPE_MEM24: - /* - * 24-Bit Memory Resource - * For this resource the size is static - */ - segment_size = 12; - break; +static u8 acpi_rs_count_set_bits(u16 bit_field) +{ + u8 bits_set; - case ACPI_RSTYPE_MEM32: - /* - * 32-Bit Memory Range Resource - * For this resource the size is static - */ - segment_size = 20; - break; + ACPI_FUNCTION_ENTRY(); - case ACPI_RSTYPE_FIXED_MEM32: - /* - * 32-Bit Fixed Memory Resource - * For this resource the size is static - */ - segment_size = 12; - break; + for (bits_set = 0; bit_field; bits_set++) { + /* Zero the least significant bit that is set */ - case ACPI_RSTYPE_ADDRESS16: - /* - * 16-Bit Address Resource - * The base size of this byte stream is 16. If a Resource Source - * string is not NULL, add 1 for the Index + the length of the null - * terminated string Resource Source + 1 for the null. - */ - segment_size = 16; - - if (linked_list->data.address16.resource_source. - string_ptr) { - segment_size += - linked_list->data.address16.resource_source. - string_length; - segment_size++; - } - break; + bit_field &= (bit_field - 1); + } - case ACPI_RSTYPE_ADDRESS32: - /* - * 32-Bit Address Resource - * The base size of this byte stream is 26. If a Resource - * Source string is not NULL, add 1 for the Index + the - * length of the null terminated string Resource Source + - * 1 for the null. - */ - segment_size = 26; - - if (linked_list->data.address32.resource_source. - string_ptr) { - segment_size += - linked_list->data.address32.resource_source. - string_length; - segment_size++; - } - break; + return (bits_set); +} - case ACPI_RSTYPE_ADDRESS64: - /* - * 64-Bit Address Resource - * The base size of this byte stream is 46. If a resource_source - * string is not NULL, add 1 for the Index + the length of the null - * terminated string Resource Source + 1 for the null. - */ - segment_size = 46; - - if (linked_list->data.address64.resource_source. - string_ptr) { - segment_size += - linked_list->data.address64.resource_source. - string_length; - segment_size++; - } - break; +/******************************************************************************* + * + * FUNCTION: acpi_rs_struct_option_length + * + * PARAMETERS: resource_source - Pointer to optional descriptor field + * + * RETURN: Status + * + * DESCRIPTION: Common code to handle optional resource_source_index and + * resource_source fields in some Large descriptors. Used during + * list-to-stream conversion + * + ******************************************************************************/ - case ACPI_RSTYPE_EXT_IRQ: - /* - * Extended IRQ Resource - * The base size of this byte stream is 9. This is for an Interrupt - * table length of 1. For each additional interrupt, add 4. - * If a Resource Source string is not NULL, add 1 for the - * Index + the length of the null terminated string - * Resource Source + 1 for the null. - */ - segment_size = 9 + (((acpi_size) - linked_list->data.extended_irq. - number_of_interrupts - 1) * 4); - - if (linked_list->data.extended_irq.resource_source. - string_ptr) { - segment_size += - linked_list->data.extended_irq. - resource_source.string_length; - segment_size++; - } - break; +static acpi_rs_length +acpi_rs_struct_option_length(struct acpi_resource_source *resource_source) +{ + ACPI_FUNCTION_ENTRY(); - default: + /* + * If the resource_source string is valid, return the size of the string + * (string_length includes the NULL terminator) plus the size of the + * resource_source_index (1). + */ + if (resource_source->string_ptr) { + return ((acpi_rs_length) (resource_source->string_length + 1)); + } - /* If we get here, everything is out of sync, exit with error */ + return (0); +} - return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); +/******************************************************************************* + * + * FUNCTION: acpi_rs_stream_option_length + * + * PARAMETERS: resource_length - Length from the resource header + * minimum_total_length - Minimum length of this resource, before + * any optional fields. Includes header size + * + * RETURN: Length of optional string (0 if no string present) + * + * DESCRIPTION: Common code to handle optional resource_source_index and + * resource_source fields in some Large descriptors. Used during + * stream-to-list conversion + * + ******************************************************************************/ - } /* switch (linked_list->Id) */ +static u32 +acpi_rs_stream_option_length(u32 resource_length, + u32 minimum_aml_resource_length) +{ + u32 string_length = 0; - /* Update the total */ + ACPI_FUNCTION_ENTRY(); - byte_stream_size_needed += segment_size; + /* + * The resource_source_index and resource_source are optional elements of some + * Large-type resource descriptors. + */ - /* Point to the next object */ + /* + * If the length of the actual resource descriptor is greater than the ACPI + * spec-defined minimum length, it means that a resource_source_index exists + * and is followed by a (required) null terminated string. The string length + * (including the null terminator) is the resource length minus the minimum + * length, minus one byte for the resource_source_index itself. + */ + if (resource_length > minimum_aml_resource_length) { + /* Compute the length of the optional string */ - linked_list = ACPI_PTR_ADD(struct acpi_resource, - linked_list, linked_list->length); + string_length = + resource_length - minimum_aml_resource_length - 1; } - /* This is the data the caller needs */ + /* Round up length to 32 bits for internal structure alignment */ - *size_needed = byte_stream_size_needed; - return_ACPI_STATUS(AE_OK); + return (ACPI_ROUND_UP_to_32_bITS(string_length)); } /******************************************************************************* * - * FUNCTION: acpi_rs_get_list_length + * FUNCTION: acpi_rs_get_aml_length * - * PARAMETERS: byte_stream_buffer - Pointer to the resource byte stream - * byte_stream_buffer_length - Size of byte_stream_buffer - * size_needed - u32 pointer of the size buffer - * needed to properly return the - * parsed data + * PARAMETERS: Resource - Pointer to the resource linked list + * size_needed - Where the required size is returned * * RETURN: Status * - * DESCRIPTION: Takes the resource byte stream and parses it once, calculating - * the size buffer needed to hold the linked list that conveys - * the resource data. + * DESCRIPTION: Takes a linked list of internal resource descriptors and + * calculates the size buffer needed to hold the corresponding + * external resource byte stream. * ******************************************************************************/ acpi_status -acpi_rs_get_list_length(u8 * byte_stream_buffer, - u32 byte_stream_buffer_length, acpi_size * size_needed) +acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) { - u32 buffer_size = 0; - u32 bytes_parsed = 0; - u8 number_of_interrupts = 0; - u8 number_of_channels = 0; - u8 resource_type; - u32 structure_size; - u32 bytes_consumed; - u8 *buffer; - u8 temp8; - u16 temp16; - u8 index; - u8 additional_bytes; - - ACPI_FUNCTION_TRACE("rs_get_list_length"); + acpi_size aml_size_needed = 0; + acpi_rs_length total_size; - while (bytes_parsed < byte_stream_buffer_length) { - /* The next byte in the stream is the resource type */ + ACPI_FUNCTION_TRACE("rs_get_aml_length"); - resource_type = acpi_rs_get_resource_type(*byte_stream_buffer); + /* Traverse entire list of internal resource descriptors */ - switch (resource_type) { - case ACPI_RDESC_TYPE_MEMORY_24: - /* - * 24-Bit Memory Resource - */ - bytes_consumed = 12; - - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem24); - break; + while (resource) { + /* Validate the descriptor type */ - case ACPI_RDESC_TYPE_LARGE_VENDOR: - /* - * Vendor Defined Resource - */ - buffer = byte_stream_buffer; - ++buffer; - - ACPI_MOVE_16_TO_16(&temp16, buffer); - bytes_consumed = temp16 + 3; - - /* Ensure a 32-bit boundary for the structure */ + if (resource->type > ACPI_RESOURCE_TYPE_MAX) { + return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); + } - temp16 = (u16) ACPI_ROUND_UP_to_32_bITS(temp16); + /* Get the base size of the (external stream) resource descriptor */ - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor) + - (temp16 * sizeof(u8)); - break; + total_size = acpi_gbl_aml_resource_sizes[resource->type]; - case ACPI_RDESC_TYPE_MEMORY_32: + /* + * Augment the base size for descriptors with optional and/or + * variable-length fields + */ + switch (resource->type) { + case ACPI_RESOURCE_TYPE_VENDOR: /* - * 32-Bit Memory Range Resource + * Vendor Defined Resource: + * For a Vendor Specific resource, if the Length is between 1 and 7 + * it will be created as a Small Resource data type, otherwise it + * is a Large Resource data type. */ - bytes_consumed = 20; + if (resource->data.vendor.byte_length > 7) { + /* Base size of a Large resource descriptor */ - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem32); - break; + total_size = + sizeof(struct aml_resource_large_header); + } - case ACPI_RDESC_TYPE_FIXED_MEMORY_32: - /* - * 32-Bit Fixed Memory Resource - */ - bytes_consumed = 12; + /* Add the size of the vendor-specific data */ - structure_size = - ACPI_SIZEOF_RESOURCE(struct - acpi_resource_fixed_mem32); + total_size = (acpi_rs_length) + (total_size + resource->data.vendor.byte_length); break; - case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE: + case ACPI_RESOURCE_TYPE_END_TAG: /* - * 64-Bit Address Resource + * End Tag: + * We are done -- return the accumulated total size. */ - buffer = byte_stream_buffer; + *size_needed = aml_size_needed + total_size; - ++buffer; - ACPI_MOVE_16_TO_16(&temp16, buffer); + /* Normal exit */ - bytes_consumed = temp16 + 3; - structure_size = - ACPI_SIZEOF_RESOURCE(struct - acpi_resource_address64); - break; + return_ACPI_STATUS(AE_OK); - case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE: + case ACPI_RESOURCE_TYPE_ADDRESS16: /* - * 64-Bit Address Resource + * 16-Bit Address Resource: + * Add the size of the optional resource_source info */ - buffer = byte_stream_buffer; - - ++buffer; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - bytes_consumed = temp16 + 3; + total_size = (acpi_rs_length) + (total_size + + acpi_rs_struct_option_length(&resource->data. + address16. + resource_source)); + break; + case ACPI_RESOURCE_TYPE_ADDRESS32: /* - * Resource Source Index and Resource Source are optional elements. - * Check the length of the Bytestream. If it is greater than 43, - * that means that an Index exists and is followed by a null - * terminated string. Therefore, set the temp variable to the - * length minus the minimum byte stream length plus the byte for - * the Index to determine the size of the NULL terminated string. + * 32-Bit Address Resource: + * Add the size of the optional resource_source info */ - if (43 < temp16) { - temp8 = (u8) (temp16 - 44); - } else { - temp8 = 0; - } - - /* Ensure a 64-bit boundary for the structure */ - - temp8 = (u8) ACPI_ROUND_UP_to_64_bITS(temp8); - - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64) - + (temp8 * sizeof(u8)); + total_size = (acpi_rs_length) + (total_size + + acpi_rs_struct_option_length(&resource->data. + address32. + resource_source)); break; - case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE: + case ACPI_RESOURCE_TYPE_ADDRESS64: /* - * 32-Bit Address Resource + * 64-Bit Address Resource: + * Add the size of the optional resource_source info */ - buffer = byte_stream_buffer; - - ++buffer; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - bytes_consumed = temp16 + 3; + total_size = (acpi_rs_length) + (total_size + + acpi_rs_struct_option_length(&resource->data. + address64. + resource_source)); + break; + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: /* - * Resource Source Index and Resource Source are optional elements. - * Check the length of the Bytestream. If it is greater than 23, - * that means that an Index exists and is followed by a null - * terminated string. Therefore, set the temp variable to the - * length minus the minimum byte stream length plus the byte for - * the Index to determine the size of the NULL terminated string. + * Extended IRQ Resource: + * Add the size of each additional optional interrupt beyond the + * required 1 (4 bytes for each u32 interrupt number) */ - if (23 < temp16) { - temp8 = (u8) (temp16 - 24); - } else { - temp8 = 0; - } - - /* Ensure a 32-bit boundary for the structure */ - - temp8 = (u8) ACPI_ROUND_UP_to_32_bITS(temp8); + total_size = (acpi_rs_length) + (total_size + + ((resource->data.extended_irq.interrupt_count - + 1) * 4) + + /* Add the size of the optional resource_source info */ + acpi_rs_struct_option_length(&resource->data. + extended_irq. + resource_source)); + break; - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32) - + (temp8 * sizeof(u8)); + default: break; + } - case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE: - /* - * 16-Bit Address Resource - */ - buffer = byte_stream_buffer; + /* Update the total */ - ++buffer; - ACPI_MOVE_16_TO_16(&temp16, buffer); + aml_size_needed += total_size; - bytes_consumed = temp16 + 3; + /* Point to the next object */ - /* - * Resource Source Index and Resource Source are optional elements. - * Check the length of the Bytestream. If it is greater than 13, - * that means that an Index exists and is followed by a null - * terminated string. Therefore, set the temp variable to the - * length minus the minimum byte stream length plus the byte for - * the Index to determine the size of the NULL terminated string. - */ - if (13 < temp16) { - temp8 = (u8) (temp16 - 14); - } else { - temp8 = 0; - } + resource = + ACPI_ADD_PTR(struct acpi_resource, resource, + resource->length); + } - /* Ensure a 32-bit boundary for the structure */ + /* Did not find an end_tag resource descriptor */ - temp8 = (u8) ACPI_ROUND_UP_to_32_bITS(temp8); + return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); +} - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16) - + (temp8 * sizeof(u8)); - break; +/******************************************************************************* + * + * FUNCTION: acpi_rs_get_list_length + * + * PARAMETERS: aml_buffer - Pointer to the resource byte stream + * aml_buffer_length - Size of aml_buffer + * size_needed - Where the size needed is returned + * + * RETURN: Status + * + * DESCRIPTION: Takes an external resource byte stream and calculates the size + * buffer needed to hold the corresponding internal resource + * descriptor linked list. + * + ******************************************************************************/ - case ACPI_RDESC_TYPE_EXTENDED_XRUPT: - /* - * Extended IRQ - */ - buffer = byte_stream_buffer; +acpi_status +acpi_rs_get_list_length(u8 * aml_buffer, + u32 aml_buffer_length, acpi_size * size_needed) +{ + acpi_status status; + u8 *end_aml; + u8 *buffer; + u32 buffer_size = 0; + u16 temp16; + u16 resource_length; + u32 extra_struct_bytes; + u8 resource_index; + u8 minimum_aml_resource_length; - ++buffer; - ACPI_MOVE_16_TO_16(&temp16, buffer); + ACPI_FUNCTION_TRACE("rs_get_list_length"); - bytes_consumed = temp16 + 3; + end_aml = aml_buffer + aml_buffer_length; - /* - * Point past the length field and the Interrupt vector flags to - * save off the Interrupt table length to the Temp8 variable. - */ - buffer += 3; - temp8 = *buffer; + /* Walk the list of AML resource descriptors */ - /* - * To compensate for multiple interrupt numbers, add 4 bytes for - * each additional interrupts greater than 1 - */ - additional_bytes = (u8) ((temp8 - 1) * 4); + while (aml_buffer < end_aml) { + /* Validate the Resource Type and Resource Length */ - /* - * Resource Source Index and Resource Source are optional elements. - * Check the length of the Bytestream. If it is greater than 9, - * that means that an Index exists and is followed by a null - * terminated string. Therefore, set the temp variable to the - * length minus the minimum byte stream length plus the byte for - * the Index to determine the size of the NULL terminated string. - */ - if (9 + additional_bytes < temp16) { - temp8 = (u8) (temp16 - (9 + additional_bytes)); - } else { - temp8 = 0; - } + status = acpi_ut_validate_resource(aml_buffer, &resource_index); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } - /* Ensure a 32-bit boundary for the structure */ + /* Get the resource length and base (minimum) AML size */ - temp8 = (u8) ACPI_ROUND_UP_to_32_bITS(temp8); + resource_length = acpi_ut_get_resource_length(aml_buffer); + minimum_aml_resource_length = + acpi_gbl_resource_aml_sizes[resource_index]; - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_ext_irq) + - (additional_bytes * sizeof(u8)) + - (temp8 * sizeof(u8)); - break; + /* + * Augment the size for descriptors with optional + * and/or variable length fields + */ + extra_struct_bytes = 0; + buffer = + aml_buffer + acpi_ut_get_resource_header_length(aml_buffer); - case ACPI_RDESC_TYPE_IRQ_FORMAT: + switch (acpi_ut_get_resource_type(aml_buffer)) { + case ACPI_RESOURCE_NAME_IRQ: /* - * IRQ Resource. - * Determine if it there are two or three trailing bytes + * IRQ Resource: + * Get the number of bits set in the 16-bit IRQ mask */ - buffer = byte_stream_buffer; - temp8 = *buffer; - - if (temp8 & 0x01) { - bytes_consumed = 4; - } else { - bytes_consumed = 3; - } - - /* Point past the descriptor */ - - ++buffer; - - /* Look at the number of bits set */ - ACPI_MOVE_16_TO_16(&temp16, buffer); - - for (index = 0; index < 16; index++) { - if (temp16 & 0x1) { - ++number_of_interrupts; - } - - temp16 >>= 1; - } - - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_io) + - (number_of_interrupts * sizeof(u32)); + extra_struct_bytes = acpi_rs_count_set_bits(temp16); break; - case ACPI_RDESC_TYPE_DMA_FORMAT: + case ACPI_RESOURCE_NAME_DMA: /* - * DMA Resource + * DMA Resource: + * Get the number of bits set in the 8-bit DMA mask */ - buffer = byte_stream_buffer; - bytes_consumed = 3; - - /* Point past the descriptor */ - - ++buffer; - - /* Look at the number of bits set */ - - temp8 = *buffer; - - for (index = 0; index < 8; index++) { - if (temp8 & 0x1) { - ++number_of_channels; - } - - temp8 >>= 1; - } - - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_dma) + - (number_of_channels * sizeof(u32)); + extra_struct_bytes = acpi_rs_count_set_bits(*buffer); break; - case ACPI_RDESC_TYPE_START_DEPENDENT: + case ACPI_RESOURCE_NAME_VENDOR_SMALL: /* - * Start Dependent Functions Resource - * Determine if it there are two or three trailing bytes + * Vendor Resource: + * Ensure a 32-bit boundary for the structure */ - buffer = byte_stream_buffer; - temp8 = *buffer; - - if (temp8 & 0x01) { - bytes_consumed = 2; - } else { - bytes_consumed = 1; - } - - structure_size = - ACPI_SIZEOF_RESOURCE(struct - acpi_resource_start_dpf); + extra_struct_bytes = + ACPI_ROUND_UP_to_32_bITS(resource_length) - + resource_length; break; - case ACPI_RDESC_TYPE_END_DEPENDENT: + case ACPI_RESOURCE_NAME_END_TAG: /* - * End Dependent Functions Resource + * End Tag: This is the normal exit, add size of end_tag */ - bytes_consumed = 1; - structure_size = ACPI_RESOURCE_LENGTH; - break; + *size_needed = buffer_size + ACPI_RS_SIZE_MIN; + return_ACPI_STATUS(AE_OK); - case ACPI_RDESC_TYPE_IO_PORT: + case ACPI_RESOURCE_NAME_VENDOR_LARGE: /* - * IO Port Resource + * Vendor Resource: + * Add vendor data and ensure a 32-bit boundary for the structure */ - bytes_consumed = 8; - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_io); + extra_struct_bytes = + ACPI_ROUND_UP_to_32_bITS(resource_length) - + resource_length; break; - case ACPI_RDESC_TYPE_FIXED_IO_PORT: + case ACPI_RESOURCE_NAME_ADDRESS32: + case ACPI_RESOURCE_NAME_ADDRESS16: /* - * Fixed IO Port Resource + * 32-Bit or 16-bit Address Resource: + * Add the size of any optional data (resource_source) */ - bytes_consumed = 4; - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_io); + extra_struct_bytes = + acpi_rs_stream_option_length(resource_length, + minimum_aml_resource_length); break; - case ACPI_RDESC_TYPE_SMALL_VENDOR: + case ACPI_RESOURCE_NAME_EXTENDED_IRQ: /* - * Vendor Specific Resource + * Extended IRQ: + * Point past the interrupt_vector_flags to get the + * interrupt_table_length. */ - buffer = byte_stream_buffer; + buffer++; - temp8 = *buffer; - temp8 = (u8) (temp8 & 0x7); - bytes_consumed = temp8 + 1; - - /* Ensure a 32-bit boundary for the structure */ - - temp8 = (u8) ACPI_ROUND_UP_to_32_bITS(temp8); - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor) + - (temp8 * sizeof(u8)); + extra_struct_bytes = + /* + * Add 4 bytes for each additional interrupt. Note: at + * least one interrupt is required and is included in + * the minimum descriptor size + */ + ((*buffer - 1) * sizeof(u32)) + + /* Add the size of any optional data (resource_source) */ + acpi_rs_stream_option_length(resource_length - + extra_struct_bytes, + minimum_aml_resource_length); break; - case ACPI_RDESC_TYPE_END_TAG: + case ACPI_RESOURCE_NAME_ADDRESS64: /* - * End Tag + * 64-Bit Address Resource: + * Add the size of any optional data (resource_source) + * Ensure a 64-bit boundary for the structure */ - bytes_consumed = 2; - structure_size = ACPI_RESOURCE_LENGTH; - byte_stream_buffer_length = bytes_parsed; + extra_struct_bytes = + ACPI_ROUND_UP_to_64_bITS + (acpi_rs_stream_option_length + (resource_length, minimum_aml_resource_length)); break; default: - /* - * If we get here, everything is out of sync, - * exit with an error - */ - return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); + break; } - /* Update the return value and counter */ - - buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE(structure_size); - bytes_parsed += bytes_consumed; + /* Update the required buffer size for the internal descriptor structs */ - /* Set the byte stream to point to the next resource */ + temp16 = (u16) (acpi_gbl_resource_struct_sizes[resource_index] + + extra_struct_bytes); + buffer_size += (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(temp16); - byte_stream_buffer += bytes_consumed; + /* + * Point to the next resource within the stream + * using the size of the header plus the length contained in the header + */ + aml_buffer += acpi_ut_get_descriptor_length(aml_buffer); } - /* This is the data the caller needs */ + /* Did not find an end_tag resource descriptor */ - *size_needed = buffer_size; - return_ACPI_STATUS(AE_OK); + return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); } /******************************************************************************* @@ -760,13 +541,13 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, for (table_index = 0; table_index < 4 && !name_found; table_index++) { - if ((ACPI_TYPE_STRING == - ACPI_GET_OBJECT_TYPE(*sub_object_list)) - || - ((ACPI_TYPE_LOCAL_REFERENCE == - ACPI_GET_OBJECT_TYPE(*sub_object_list)) - && ((*sub_object_list)->reference.opcode == - AML_INT_NAMEPATH_OP))) { + if (*sub_object_list && /* Null object allowed */ + ((ACPI_TYPE_STRING == + ACPI_GET_OBJECT_TYPE(*sub_object_list)) || + ((ACPI_TYPE_LOCAL_REFERENCE == + ACPI_GET_OBJECT_TYPE(*sub_object_list)) && + ((*sub_object_list)->reference.opcode == + AML_INT_NAMEPATH_OP)))) { name_found = TRUE; } else { /* Look at the next element */ diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c index 0911526b7ad8..8c128dea3252 100644 --- a/drivers/acpi/resources/rscreate.c +++ b/drivers/acpi/resources/rscreate.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -53,10 +53,10 @@ ACPI_MODULE_NAME("rscreate") * * FUNCTION: acpi_rs_create_resource_list * - * PARAMETERS: byte_stream_buffer - Pointer to the resource byte stream - * output_buffer - Pointer to the user's buffer + * PARAMETERS: aml_buffer - Pointer to the resource byte stream + * output_buffer - Pointer to the user's buffer * - * RETURN: Status - AE_OK if okay, else a valid acpi_status code + * RETURN: Status: AE_OK if okay, else a valid acpi_status code * If output_buffer is not large enough, output_buffer_length * indicates how large output_buffer should be, else it * indicates how may u8 elements of output_buffer are valid. @@ -67,33 +67,30 @@ ACPI_MODULE_NAME("rscreate") * ******************************************************************************/ acpi_status -acpi_rs_create_resource_list(union acpi_operand_object *byte_stream_buffer, +acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer, struct acpi_buffer *output_buffer) { acpi_status status; - u8 *byte_stream_start; + u8 *aml_start; acpi_size list_size_needed = 0; - u32 byte_stream_buffer_length; + u32 aml_buffer_length; ACPI_FUNCTION_TRACE("rs_create_resource_list"); - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "byte_stream_buffer = %p\n", - byte_stream_buffer)); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "aml_buffer = %p\n", aml_buffer)); /* Params already validated, so we don't re-validate here */ - byte_stream_buffer_length = byte_stream_buffer->buffer.length; - byte_stream_start = byte_stream_buffer->buffer.pointer; + aml_buffer_length = aml_buffer->buffer.length; + aml_start = aml_buffer->buffer.pointer; /* - * Pass the byte_stream_buffer into a module that can calculate + * Pass the aml_buffer into a module that can calculate * the buffer size needed for the linked list */ - status = - acpi_rs_get_list_length(byte_stream_start, - byte_stream_buffer_length, - &list_size_needed); + status = acpi_rs_get_list_length(aml_start, aml_buffer_length, + &list_size_needed); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Status=%X list_size_needed=%X\n", status, (u32) list_size_needed)); @@ -110,10 +107,8 @@ acpi_rs_create_resource_list(union acpi_operand_object *byte_stream_buffer, /* Do the conversion */ - status = - acpi_rs_byte_stream_to_list(byte_stream_start, - byte_stream_buffer_length, - output_buffer->pointer); + status = acpi_rs_convert_aml_to_resources(aml_start, aml_buffer_length, + output_buffer->pointer); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -212,21 +207,20 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, /* Each element of the top-level package must also be a package */ if (ACPI_GET_OBJECT_TYPE(*top_object_list) != ACPI_TYPE_PACKAGE) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "(PRT[%X]) Need sub-package, found %s\n", - index, - acpi_ut_get_object_type_name - (*top_object_list))); + ACPI_ERROR((AE_INFO, + "(PRT[%X]) Need sub-package, found %s", + index, + acpi_ut_get_object_type_name + (*top_object_list))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } /* Each sub-package must be of length 4 */ if ((*top_object_list)->package.count != 4) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "(PRT[%X]) Need package of length 4, found length %d\n", - index, - (*top_object_list)->package.count)); + ACPI_ERROR((AE_INFO, + "(PRT[%X]) Need package of length 4, found length %d", + index, (*top_object_list)->package.count)); return_ACPI_STATUS(AE_AML_PACKAGE_LIMIT); } @@ -243,11 +237,10 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { user_prt->address = obj_desc->integer.value; } else { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "(PRT[%X].Address) Need Integer, found %s\n", - index, - acpi_ut_get_object_type_name - (obj_desc))); + ACPI_ERROR((AE_INFO, + "(PRT[%X].Address) Need Integer, found %s", + index, + acpi_ut_get_object_type_name(obj_desc))); return_ACPI_STATUS(AE_BAD_DATA); } @@ -257,76 +250,83 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { user_prt->pin = (u32) obj_desc->integer.value; } else { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "(PRT[%X].Pin) Need Integer, found %s\n", - index, - acpi_ut_get_object_type_name - (obj_desc))); + ACPI_ERROR((AE_INFO, + "(PRT[%X].Pin) Need Integer, found %s", + index, + acpi_ut_get_object_type_name(obj_desc))); return_ACPI_STATUS(AE_BAD_DATA); } - /* 3) Third subobject: Dereference the PRT.source_name */ - + /* + * 3) Third subobject: Dereference the PRT.source_name + * The name may be unresolved (slack mode), so allow a null object + */ obj_desc = sub_object_list[2]; - switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { - case ACPI_TYPE_LOCAL_REFERENCE: - - if (obj_desc->reference.opcode != AML_INT_NAMEPATH_OP) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "(PRT[%X].Source) Need name, found reference op %X\n", - index, - obj_desc->reference.opcode)); + if (obj_desc) { + switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { + case ACPI_TYPE_LOCAL_REFERENCE: + + if (obj_desc->reference.opcode != + AML_INT_NAMEPATH_OP) { + ACPI_ERROR((AE_INFO, + "(PRT[%X].Source) Need name, found reference op %X", + index, + obj_desc->reference. + opcode)); + return_ACPI_STATUS(AE_BAD_DATA); + } + + node = obj_desc->reference.node; + + /* Use *remaining* length of the buffer as max for pathname */ + + path_buffer.length = output_buffer->length - + (u32) ((u8 *) user_prt->source - + (u8 *) output_buffer->pointer); + path_buffer.pointer = user_prt->source; + + status = + acpi_ns_handle_to_pathname((acpi_handle) + node, + &path_buffer); + + /* +1 to include null terminator */ + + user_prt->length += + (u32) ACPI_STRLEN(user_prt->source) + 1; + break; + + case ACPI_TYPE_STRING: + + ACPI_STRCPY(user_prt->source, + obj_desc->string.pointer); + + /* + * Add to the Length field the length of the string + * (add 1 for terminator) + */ + user_prt->length += obj_desc->string.length + 1; + break; + + case ACPI_TYPE_INTEGER: + /* + * If this is a number, then the Source Name is NULL, since the + * entire buffer was zeroed out, we can leave this alone. + * + * Add to the Length field the length of the u32 NULL + */ + user_prt->length += sizeof(u32); + break; + + default: + + ACPI_ERROR((AE_INFO, + "(PRT[%X].Source) Need Ref/String/Integer, found %s", + index, + acpi_ut_get_object_type_name + (obj_desc))); return_ACPI_STATUS(AE_BAD_DATA); } - - node = obj_desc->reference.node; - - /* Use *remaining* length of the buffer as max for pathname */ - - path_buffer.length = output_buffer->length - - (u32) ((u8 *) user_prt->source - - (u8 *) output_buffer->pointer); - path_buffer.pointer = user_prt->source; - - status = - acpi_ns_handle_to_pathname((acpi_handle) node, - &path_buffer); - - /* +1 to include null terminator */ - - user_prt->length += - (u32) ACPI_STRLEN(user_prt->source) + 1; - break; - - case ACPI_TYPE_STRING: - - ACPI_STRCPY(user_prt->source, obj_desc->string.pointer); - - /* - * Add to the Length field the length of the string - * (add 1 for terminator) - */ - user_prt->length += obj_desc->string.length + 1; - break; - - case ACPI_TYPE_INTEGER: - /* - * If this is a number, then the Source Name is NULL, since the - * entire buffer was zeroed out, we can leave this alone. - * - * Add to the Length field the length of the u32 NULL - */ - user_prt->length += sizeof(u32); - break; - - default: - - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "(PRT[%X].Source) Need Ref/String/Integer, found %s\n", - index, - acpi_ut_get_object_type_name - (obj_desc))); - return_ACPI_STATUS(AE_BAD_DATA); } /* Now align the current length */ @@ -340,11 +340,10 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { user_prt->source_index = (u32) obj_desc->integer.value; } else { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "(PRT[%X].source_index) Need Integer, found %s\n", - index, - acpi_ut_get_object_type_name - (obj_desc))); + ACPI_ERROR((AE_INFO, + "(PRT[%X].source_index) Need Integer, found %s", + index, + acpi_ut_get_object_type_name(obj_desc))); return_ACPI_STATUS(AE_BAD_DATA); } @@ -360,7 +359,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, /******************************************************************************* * - * FUNCTION: acpi_rs_create_byte_stream + * FUNCTION: acpi_rs_create_aml_resources * * PARAMETERS: linked_list_buffer - Pointer to the resource linked list * output_buffer - Pointer to the user's buffer @@ -377,13 +376,13 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, ******************************************************************************/ acpi_status -acpi_rs_create_byte_stream(struct acpi_resource *linked_list_buffer, - struct acpi_buffer *output_buffer) +acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer, + struct acpi_buffer *output_buffer) { acpi_status status; - acpi_size byte_stream_size_needed = 0; + acpi_size aml_size_needed = 0; - ACPI_FUNCTION_TRACE("rs_create_byte_stream"); + ACPI_FUNCTION_TRACE("rs_create_aml_resources"); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "linked_list_buffer = %p\n", linked_list_buffer)); @@ -394,11 +393,10 @@ acpi_rs_create_byte_stream(struct acpi_resource *linked_list_buffer, * Pass the linked_list_buffer into a module that calculates * the buffer size needed for the byte stream. */ - status = acpi_rs_get_byte_stream_length(linked_list_buffer, - &byte_stream_size_needed); + status = acpi_rs_get_aml_length(linked_list_buffer, &aml_size_needed); - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "byte_stream_size_needed=%X, %s\n", - (u32) byte_stream_size_needed, + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "aml_size_needed=%X, %s\n", + (u32) aml_size_needed, acpi_format_exception(status))); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); @@ -406,8 +404,7 @@ acpi_rs_create_byte_stream(struct acpi_resource *linked_list_buffer, /* Validate/Allocate/Clear caller buffer */ - status = - acpi_ut_initialize_buffer(output_buffer, byte_stream_size_needed); + status = acpi_ut_initialize_buffer(output_buffer, aml_size_needed); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -415,9 +412,9 @@ acpi_rs_create_byte_stream(struct acpi_resource *linked_list_buffer, /* Do the conversion */ status = - acpi_rs_list_to_byte_stream(linked_list_buffer, - byte_stream_size_needed, - output_buffer->pointer); + acpi_rs_convert_resources_to_aml(linked_list_buffer, + aml_size_needed, + output_buffer->pointer); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c index 75bd34d1783f..e7de061cf883 100644 --- a/drivers/acpi/resources/rsdump.c +++ b/drivers/acpi/resources/rsdump.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,1063 +49,720 @@ ACPI_MODULE_NAME("rsdump") #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) /* Local prototypes */ -static void acpi_rs_dump_irq(union acpi_resource_data *data); +static void acpi_rs_out_string(char *title, char *value); -static void acpi_rs_dump_address16(union acpi_resource_data *data); +static void acpi_rs_out_integer8(char *title, u8 value); -static void acpi_rs_dump_address32(union acpi_resource_data *data); +static void acpi_rs_out_integer16(char *title, u16 value); -static void acpi_rs_dump_address64(union acpi_resource_data *data); +static void acpi_rs_out_integer32(char *title, u32 value); -static void acpi_rs_dump_dma(union acpi_resource_data *data); +static void acpi_rs_out_integer64(char *title, u64 value); -static void acpi_rs_dump_io(union acpi_resource_data *data); +static void acpi_rs_out_title(char *title); -static void acpi_rs_dump_extended_irq(union acpi_resource_data *data); +static void acpi_rs_dump_byte_list(u16 length, u8 * data); -static void acpi_rs_dump_fixed_io(union acpi_resource_data *data); +static void acpi_rs_dump_dword_list(u8 length, u32 * data); -static void acpi_rs_dump_fixed_memory32(union acpi_resource_data *data); +static void acpi_rs_dump_short_byte_list(u8 length, u8 * data); -static void acpi_rs_dump_memory24(union acpi_resource_data *data); +static void +acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source); -static void acpi_rs_dump_memory32(union acpi_resource_data *data); +static void acpi_rs_dump_address_common(union acpi_resource_data *resource); -static void acpi_rs_dump_start_depend_fns(union acpi_resource_data *data); +static void +acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table); -static void acpi_rs_dump_vendor_specific(union acpi_resource_data *data); +#define ACPI_RSD_OFFSET(f) (u8) ACPI_OFFSET (union acpi_resource_data,f) +#define ACPI_PRT_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_pci_routing_table,f) +#define ACPI_RSD_TABLE_SIZE(name) (sizeof(name) / sizeof (struct acpi_rsdump_info)) /******************************************************************************* * - * FUNCTION: acpi_rs_dump_irq + * Resource Descriptor info tables * - * PARAMETERS: Data - pointer to the resource structure to dump. - * - * RETURN: None - * - * DESCRIPTION: Prints out the various members of the Data structure type. + * Note: The first table entry must be a Title or Literal and must contain + * the table length (number of table entries) * ******************************************************************************/ -static void acpi_rs_dump_irq(union acpi_resource_data *data) -{ - struct acpi_resource_irq *irq_data = (struct acpi_resource_irq *)data; - u8 index = 0; - - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("IRQ Resource\n"); +struct acpi_rsdump_info acpi_rs_dump_irq[6] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_irq), "IRQ", NULL}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.triggering), "Triggering", + acpi_gbl_HEdecode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.polarity), "Polarity", + acpi_gbl_LLdecode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.sharable), "Sharing", + acpi_gbl_SHRdecode}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(irq.interrupt_count), + "Interrupt Count", NULL}, + {ACPI_RSD_SHORTLIST, ACPI_RSD_OFFSET(irq.interrupts[0]), + "Interrupt List", NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_dma[6] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_dma), "DMA", NULL}, + {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(dma.type), "Speed", + acpi_gbl_TYPdecode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(dma.bus_master), "Mastering", + acpi_gbl_BMdecode}, + {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(dma.transfer), "Transfer Type", + acpi_gbl_SIZdecode}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(dma.channel_count), "Channel Count", + NULL}, + {ACPI_RSD_SHORTLIST, ACPI_RSD_OFFSET(dma.channels[0]), "Channel List", + NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_start_dpf[3] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_start_dpf), + "Start-Dependent-Functions", NULL}, + {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.compatibility_priority), + "Compatibility Priority", acpi_gbl_config_decode}, + {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.performance_robustness), + "Performance/Robustness", acpi_gbl_config_decode} +}; + +struct acpi_rsdump_info acpi_rs_dump_end_dpf[1] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_end_dpf), + "End-Dependent-Functions", NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_io[6] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io), "I/O", NULL}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(io.io_decode), "Address Decoding", + acpi_gbl_io_decode}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(io.minimum), "Address Minimum", NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(io.maximum), "Address Maximum", NULL}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(io.alignment), "Alignment", NULL}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(io.address_length), "Address Length", + NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_fixed_io[3] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_io), + "Fixed I/O", NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(fixed_io.address), "Address", NULL}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(fixed_io.address_length), + "Address Length", NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_vendor[3] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_vendor), + "Vendor Specific", NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(vendor.byte_length), "Length", NULL}, + {ACPI_RSD_LONGLIST, ACPI_RSD_OFFSET(vendor.byte_data[0]), "Vendor Data", + NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_end_tag[1] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_end_tag), "end_tag", + NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_memory24[6] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory24), + "24-Bit Memory Range", NULL}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(memory24.write_protect), + "Write Protect", acpi_gbl_RWdecode}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.minimum), "Address Minimum", + NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.maximum), "Address Maximum", + NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.alignment), "Alignment", + NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.address_length), + "Address Length", NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_memory32[6] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory32), + "32-Bit Memory Range", NULL}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(memory32.write_protect), + "Write Protect", acpi_gbl_RWdecode}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.minimum), "Address Minimum", + NULL}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.maximum), "Address Maximum", + NULL}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.alignment), "Alignment", + NULL}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.address_length), + "Address Length", NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_fixed_memory32[4] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_memory32), + "32-Bit Fixed Memory Range", NULL}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(fixed_memory32.write_protect), + "Write Protect", acpi_gbl_RWdecode}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(fixed_memory32.address), "Address", + NULL}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(fixed_memory32.address_length), + "Address Length", NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_address16[8] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address16), + "16-Bit WORD Address Space", NULL}, + {ACPI_RSD_ADDRESS, 0, NULL, NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.granularity), "Granularity", + NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.minimum), "Address Minimum", + NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.maximum), "Address Maximum", + NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.translation_offset), + "Translation Offset", NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.address_length), + "Address Length", NULL}, + {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address16.resource_source), NULL, NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_address32[8] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address32), + "32-Bit DWORD Address Space", NULL}, + {ACPI_RSD_ADDRESS, 0, NULL, NULL}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.granularity), "Granularity", + NULL}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.minimum), "Address Minimum", + NULL}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.maximum), "Address Maximum", + NULL}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.translation_offset), + "Translation Offset", NULL}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.address_length), + "Address Length", NULL}, + {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address32.resource_source), NULL, NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_address64[8] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address64), + "64-Bit QWORD Address Space", NULL}, + {ACPI_RSD_ADDRESS, 0, NULL, NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.granularity), "Granularity", + NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.minimum), "Address Minimum", + NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.maximum), "Address Maximum", + NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.translation_offset), + "Translation Offset", NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.address_length), + "Address Length", NULL}, + {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address64.resource_source), NULL, NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_ext_address64[8] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_ext_address64), + "64-Bit Extended Address Space", NULL}, + {ACPI_RSD_ADDRESS, 0, NULL, NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.granularity), + "Granularity", NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.minimum), + "Address Minimum", NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.maximum), + "Address Maximum", NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.translation_offset), + "Translation Offset", NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.address_length), + "Address Length", NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.type_specific), + "Type-Specific Attribute", NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_ext_irq[8] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_ext_irq), + "Extended IRQ", NULL}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.producer_consumer), + "Type", acpi_gbl_consume_decode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.triggering), + "Triggering", acpi_gbl_HEdecode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.polarity), "Polarity", + acpi_gbl_LLdecode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.sharable), "Sharing", + acpi_gbl_SHRdecode}, + {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(extended_irq.resource_source), NULL, + NULL}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(extended_irq.interrupt_count), + "Interrupt Count", NULL}, + {ACPI_RSD_DWORDLIST, ACPI_RSD_OFFSET(extended_irq.interrupts[0]), + "Interrupt List", NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_generic_reg[6] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_generic_reg), + "Generic Register", NULL}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.space_id), "Space ID", + NULL}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.bit_width), "Bit Width", + NULL}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.bit_offset), "Bit Offset", + NULL}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.access_size), + "Access Size", NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(generic_reg.address), "Address", NULL} +}; - acpi_os_printf(" %s Triggered\n", - ACPI_LEVEL_SENSITIVE == - irq_data->edge_level ? "Level" : "Edge"); - - acpi_os_printf(" Active %s\n", - ACPI_ACTIVE_LOW == - irq_data->active_high_low ? "Low" : "High"); - - acpi_os_printf(" %s\n", - ACPI_SHARED == - irq_data->shared_exclusive ? "Shared" : "Exclusive"); - - acpi_os_printf(" %X Interrupts ( ", irq_data->number_of_interrupts); - - for (index = 0; index < irq_data->number_of_interrupts; index++) { - acpi_os_printf("%X ", irq_data->interrupts[index]); - } +/* + * Tables used for common address descriptor flag fields + */ +static struct acpi_rsdump_info acpi_rs_dump_general_flags[5] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_general_flags), NULL, + NULL}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.producer_consumer), + "Consumer/Producer", acpi_gbl_consume_decode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.decode), "Address Decode", + acpi_gbl_DECdecode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.min_address_fixed), + "Min Relocatability", acpi_gbl_min_decode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.max_address_fixed), + "Max Relocatability", acpi_gbl_max_decode} +}; + +static struct acpi_rsdump_info acpi_rs_dump_memory_flags[5] = { + {ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory_flags), + "Resource Type", (void *)"Memory Range"}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.write_protect), + "Write Protect", acpi_gbl_RWdecode}, + {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.caching), + "Caching", acpi_gbl_MEMdecode}, + {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.range_type), + "Range Type", acpi_gbl_MTPdecode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.translation), + "Translation", acpi_gbl_TTPdecode} +}; + +static struct acpi_rsdump_info acpi_rs_dump_io_flags[4] = { + {ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io_flags), + "Resource Type", (void *)"I/O Range"}, + {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.io.range_type), + "Range Type", acpi_gbl_RNGdecode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation), + "Translation", acpi_gbl_TTPdecode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation_type), + "Translation Type", acpi_gbl_TRSdecode} +}; - acpi_os_printf(")\n"); - return; -} +/* + * Table used to dump _PRT contents + */ +static struct acpi_rsdump_info acpi_rs_dump_prt[5] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_prt), NULL, NULL}, + {ACPI_RSD_UINT64, ACPI_PRT_OFFSET(address), "Address", NULL}, + {ACPI_RSD_UINT32, ACPI_PRT_OFFSET(pin), "Pin", NULL}, + {ACPI_RSD_STRING, ACPI_PRT_OFFSET(source[0]), "Source", NULL}, + {ACPI_RSD_UINT32, ACPI_PRT_OFFSET(source_index), "Source Index", NULL} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_dump_dma + * FUNCTION: acpi_rs_dump_descriptor * - * PARAMETERS: Data - pointer to the resource structure to dump. + * PARAMETERS: Resource * * RETURN: None * - * DESCRIPTION: Prints out the various members of the Data structure type. + * DESCRIPTION: * ******************************************************************************/ -static void acpi_rs_dump_dma(union acpi_resource_data *data) +static void +acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) { - struct acpi_resource_dma *dma_data = (struct acpi_resource_dma *)data; - u8 index = 0; - - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("DMA Resource\n"); - - switch (dma_data->type) { - case ACPI_COMPATIBILITY: - acpi_os_printf(" Compatibility mode\n"); - break; - - case ACPI_TYPE_A: - acpi_os_printf(" Type A\n"); - break; - - case ACPI_TYPE_B: - acpi_os_printf(" Type B\n"); - break; - - case ACPI_TYPE_F: - acpi_os_printf(" Type F\n"); - break; - - default: - acpi_os_printf(" Invalid DMA type\n"); - break; - } - - acpi_os_printf(" %sBus Master\n", - ACPI_BUS_MASTER == dma_data->bus_master ? "" : "Not a "); - - switch (dma_data->transfer) { - case ACPI_TRANSFER_8: - acpi_os_printf(" 8-bit only transfer\n"); - break; + u8 *target = NULL; + u8 *previous_target; + char *name; + u8 count; + + /* First table entry must contain the table length (# of table entries) */ + + count = table->offset; + + while (count) { + previous_target = target; + target = ACPI_ADD_PTR(u8, resource, table->offset); + name = table->name; + + switch (table->opcode) { + case ACPI_RSD_TITLE: + /* + * Optional resource title + */ + if (table->name) { + acpi_os_printf("%s Resource\n", name); + } + break; - case ACPI_TRANSFER_8_16: - acpi_os_printf(" 8 and 16-bit transfer\n"); - break; + /* Strings */ - case ACPI_TRANSFER_16: - acpi_os_printf(" 16 bit only transfer\n"); - break; + case ACPI_RSD_LITERAL: + acpi_rs_out_string(name, + ACPI_CAST_PTR(char, table->pointer)); + break; - default: - acpi_os_printf(" Invalid transfer preference\n"); - break; - } + case ACPI_RSD_STRING: + acpi_rs_out_string(name, ACPI_CAST_PTR(char, target)); + break; - acpi_os_printf(" Number of Channels: %X ( ", - dma_data->number_of_channels); + /* Data items, 8/16/32/64 bit */ - for (index = 0; index < dma_data->number_of_channels; index++) { - acpi_os_printf("%X ", dma_data->channels[index]); - } + case ACPI_RSD_UINT8: + acpi_rs_out_integer8(name, ACPI_GET8(target)); + break; - acpi_os_printf(")\n"); - return; -} + case ACPI_RSD_UINT16: + acpi_rs_out_integer16(name, ACPI_GET16(target)); + break; -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_start_depend_fns - * - * PARAMETERS: Data - pointer to the resource structure to dump. - * - * RETURN: None - * - * DESCRIPTION: Prints out the various members of the Data structure type. - * - ******************************************************************************/ + case ACPI_RSD_UINT32: + acpi_rs_out_integer32(name, ACPI_GET32(target)); + break; -static void acpi_rs_dump_start_depend_fns(union acpi_resource_data *data) -{ - struct acpi_resource_start_dpf *sdf_data = - (struct acpi_resource_start_dpf *)data; + case ACPI_RSD_UINT64: + acpi_rs_out_integer64(name, ACPI_GET64(target)); + break; - ACPI_FUNCTION_ENTRY(); + /* Flags: 1-bit and 2-bit flags supported */ - acpi_os_printf("Start Dependent Functions Resource\n"); + case ACPI_RSD_1BITFLAG: + acpi_rs_out_string(name, ACPI_CAST_PTR(char, + table-> + pointer[*target & + 0x01])); + break; - switch (sdf_data->compatibility_priority) { - case ACPI_GOOD_CONFIGURATION: - acpi_os_printf(" Good configuration\n"); - break; + case ACPI_RSD_2BITFLAG: + acpi_rs_out_string(name, ACPI_CAST_PTR(char, + table-> + pointer[*target & + 0x03])); + break; - case ACPI_ACCEPTABLE_CONFIGURATION: - acpi_os_printf(" Acceptable configuration\n"); - break; + case ACPI_RSD_SHORTLIST: + /* + * Short byte list (single line output) for DMA and IRQ resources + * Note: The list length is obtained from the previous table entry + */ + if (previous_target) { + acpi_rs_out_title(name); + acpi_rs_dump_short_byte_list(*previous_target, + target); + } + break; - case ACPI_SUB_OPTIMAL_CONFIGURATION: - acpi_os_printf(" Sub-optimal configuration\n"); - break; + case ACPI_RSD_LONGLIST: + /* + * Long byte list for Vendor resource data + * Note: The list length is obtained from the previous table entry + */ + if (previous_target) { + acpi_rs_dump_byte_list(ACPI_GET16 + (previous_target), + target); + } + break; - default: - acpi_os_printf(" Invalid compatibility priority\n"); - break; - } + case ACPI_RSD_DWORDLIST: + /* + * Dword list for Extended Interrupt resources + * Note: The list length is obtained from the previous table entry + */ + if (previous_target) { + acpi_rs_dump_dword_list(*previous_target, + ACPI_CAST_PTR(u32, + target)); + } + break; - switch (sdf_data->performance_robustness) { - case ACPI_GOOD_CONFIGURATION: - acpi_os_printf(" Good configuration\n"); - break; + case ACPI_RSD_ADDRESS: + /* + * Common flags for all Address resources + */ + acpi_rs_dump_address_common(ACPI_CAST_PTR + (union acpi_resource_data, + target)); + break; - case ACPI_ACCEPTABLE_CONFIGURATION: - acpi_os_printf(" Acceptable configuration\n"); - break; + case ACPI_RSD_SOURCE: + /* + * Optional resource_source for Address resources + */ + acpi_rs_dump_resource_source(ACPI_CAST_PTR + (struct + acpi_resource_source, + target)); + break; - case ACPI_SUB_OPTIMAL_CONFIGURATION: - acpi_os_printf(" Sub-optimal configuration\n"); - break; + default: + acpi_os_printf("**** Invalid table opcode [%X] ****\n", + table->opcode); + return; + } - default: - acpi_os_printf(" Invalid performance robustness preference\n"); - break; + table++; + count--; } - - return; -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_io - * - * PARAMETERS: Data - pointer to the resource structure to dump. - * - * RETURN: None - * - * DESCRIPTION: Prints out the various members of the Data structure type. - * - ******************************************************************************/ - -static void acpi_rs_dump_io(union acpi_resource_data *data) -{ - struct acpi_resource_io *io_data = (struct acpi_resource_io *)data; - - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("Io Resource\n"); - - acpi_os_printf(" %d bit decode\n", - ACPI_DECODE_16 == io_data->io_decode ? 16 : 10); - - acpi_os_printf(" Range minimum base: %08X\n", - io_data->min_base_address); - - acpi_os_printf(" Range maximum base: %08X\n", - io_data->max_base_address); - - acpi_os_printf(" Alignment: %08X\n", io_data->alignment); - - acpi_os_printf(" Range Length: %08X\n", io_data->range_length); - - return; -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_fixed_io - * - * PARAMETERS: Data - pointer to the resource structure to dump. - * - * RETURN: None - * - * DESCRIPTION: Prints out the various members of the Data structure type. - * - ******************************************************************************/ - -static void acpi_rs_dump_fixed_io(union acpi_resource_data *data) -{ - struct acpi_resource_fixed_io *fixed_io_data = - (struct acpi_resource_fixed_io *)data; - - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("Fixed Io Resource\n"); - acpi_os_printf(" Range base address: %08X", - fixed_io_data->base_address); - - acpi_os_printf(" Range length: %08X", fixed_io_data->range_length); - - return; } /******************************************************************************* * - * FUNCTION: acpi_rs_dump_vendor_specific + * FUNCTION: acpi_rs_dump_resource_source * - * PARAMETERS: Data - pointer to the resource structure to dump. + * PARAMETERS: resource_source - Pointer to a Resource Source struct * * RETURN: None * - * DESCRIPTION: Prints out the various members of the Data structure type. + * DESCRIPTION: Common routine for dumping the optional resource_source and the + * corresponding resource_source_index. * ******************************************************************************/ -static void acpi_rs_dump_vendor_specific(union acpi_resource_data *data) +static void +acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source) { - struct acpi_resource_vendor *vendor_data = - (struct acpi_resource_vendor *)data; - u16 index = 0; - ACPI_FUNCTION_ENTRY(); - acpi_os_printf("Vendor Specific Resource\n"); - - acpi_os_printf(" Length: %08X\n", vendor_data->length); - - for (index = 0; index < vendor_data->length; index++) { - acpi_os_printf(" Byte %X: %08X\n", - index, vendor_data->reserved[index]); + if (resource_source->index == 0xFF) { + return; } - return; -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_memory24 - * - * PARAMETERS: Data - pointer to the resource structure to dump. - * - * RETURN: None - * - * DESCRIPTION: Prints out the various members of the Data structure type. - * - ******************************************************************************/ - -static void acpi_rs_dump_memory24(union acpi_resource_data *data) -{ - struct acpi_resource_mem24 *memory24_data = - (struct acpi_resource_mem24 *)data; - - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("24-Bit Memory Range Resource\n"); - - acpi_os_printf(" Read%s\n", - ACPI_READ_WRITE_MEMORY == - memory24_data->read_write_attribute ? - "/Write" : " only"); - - acpi_os_printf(" Range minimum base: %08X\n", - memory24_data->min_base_address); - - acpi_os_printf(" Range maximum base: %08X\n", - memory24_data->max_base_address); - - acpi_os_printf(" Alignment: %08X\n", memory24_data->alignment); - - acpi_os_printf(" Range length: %08X\n", memory24_data->range_length); - - return; -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_memory32 - * - * PARAMETERS: Data - pointer to the resource structure to dump. - * - * RETURN: None - * - * DESCRIPTION: Prints out the various members of the Data structure type. - * - ******************************************************************************/ - -static void acpi_rs_dump_memory32(union acpi_resource_data *data) -{ - struct acpi_resource_mem32 *memory32_data = - (struct acpi_resource_mem32 *)data; - - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("32-Bit Memory Range Resource\n"); - - acpi_os_printf(" Read%s\n", - ACPI_READ_WRITE_MEMORY == - memory32_data->read_write_attribute ? - "/Write" : " only"); - - acpi_os_printf(" Range minimum base: %08X\n", - memory32_data->min_base_address); - - acpi_os_printf(" Range maximum base: %08X\n", - memory32_data->max_base_address); - - acpi_os_printf(" Alignment: %08X\n", memory32_data->alignment); - - acpi_os_printf(" Range length: %08X\n", memory32_data->range_length); + acpi_rs_out_integer8("Resource Source Index", resource_source->index); - return; + acpi_rs_out_string("Resource Source", + resource_source->string_ptr ? + resource_source->string_ptr : "[Not Specified]"); } /******************************************************************************* * - * FUNCTION: acpi_rs_dump_fixed_memory32 + * FUNCTION: acpi_rs_dump_address_common * - * PARAMETERS: Data - pointer to the resource structure to dump. - * - * RETURN: - * - * DESCRIPTION: Prints out the various members of the Data structure type. - * - ******************************************************************************/ - -static void acpi_rs_dump_fixed_memory32(union acpi_resource_data *data) -{ - struct acpi_resource_fixed_mem32 *fixed_memory32_data = - (struct acpi_resource_fixed_mem32 *)data; - - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("32-Bit Fixed Location Memory Range Resource\n"); - - acpi_os_printf(" Read%s\n", - ACPI_READ_WRITE_MEMORY == - fixed_memory32_data-> - read_write_attribute ? "/Write" : " Only"); - - acpi_os_printf(" Range base address: %08X\n", - fixed_memory32_data->range_base_address); - - acpi_os_printf(" Range length: %08X\n", - fixed_memory32_data->range_length); - - return; -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_address16 - * - * PARAMETERS: Data - pointer to the resource structure to dump. + * PARAMETERS: Resource - Pointer to an internal resource descriptor * * RETURN: None * - * DESCRIPTION: Prints out the various members of the Data structure type. + * DESCRIPTION: Dump the fields that are common to all Address resource + * descriptors * ******************************************************************************/ -static void acpi_rs_dump_address16(union acpi_resource_data *data) +static void acpi_rs_dump_address_common(union acpi_resource_data *resource) { - struct acpi_resource_address16 *address16_data = - (struct acpi_resource_address16 *)data; - ACPI_FUNCTION_ENTRY(); - acpi_os_printf("16-Bit Address Space Resource\n"); - acpi_os_printf(" Resource Type: "); + /* Decode the type-specific flags */ - switch (address16_data->resource_type) { + switch (resource->address.resource_type) { case ACPI_MEMORY_RANGE: - acpi_os_printf("Memory Range\n"); - - switch (address16_data->attribute.memory.cache_attribute) { - case ACPI_NON_CACHEABLE_MEMORY: - acpi_os_printf - (" Type Specific: Noncacheable memory\n"); - break; - - case ACPI_CACHABLE_MEMORY: - acpi_os_printf(" Type Specific: Cacheable memory\n"); - break; - - case ACPI_WRITE_COMBINING_MEMORY: - acpi_os_printf - (" Type Specific: Write-combining memory\n"); - break; - - case ACPI_PREFETCHABLE_MEMORY: - acpi_os_printf - (" Type Specific: Prefetchable memory\n"); - break; - - default: - acpi_os_printf - (" Type Specific: Invalid cache attribute\n"); - break; - } - - acpi_os_printf(" Type Specific: Read%s\n", - ACPI_READ_WRITE_MEMORY == - address16_data->attribute.memory. - read_write_attribute ? "/Write" : " Only"); + acpi_rs_dump_descriptor(resource, acpi_rs_dump_memory_flags); break; case ACPI_IO_RANGE: - acpi_os_printf("I/O Range\n"); - - switch (address16_data->attribute.io.range_attribute) { - case ACPI_NON_ISA_ONLY_RANGES: - acpi_os_printf - (" Type Specific: Non-ISA Io Addresses\n"); - break; - - case ACPI_ISA_ONLY_RANGES: - acpi_os_printf(" Type Specific: ISA Io Addresses\n"); - break; - - case ACPI_ENTIRE_RANGE: - acpi_os_printf - (" Type Specific: ISA and non-ISA Io Addresses\n"); - break; - - default: - acpi_os_printf - (" Type Specific: Invalid range attribute\n"); - break; - } - - acpi_os_printf(" Type Specific: %s Translation\n", - ACPI_SPARSE_TRANSLATION == - address16_data->attribute.io. - translation_attribute ? "Sparse" : "Dense"); + acpi_rs_dump_descriptor(resource, acpi_rs_dump_io_flags); break; case ACPI_BUS_NUMBER_RANGE: - acpi_os_printf("Bus Number Range\n"); + acpi_rs_out_string("Resource Type", "Bus Number Range"); break; default: - acpi_os_printf("0x%2.2X\n", address16_data->resource_type); + acpi_rs_out_integer8("Resource Type", + (u8) resource->address.resource_type); break; } - acpi_os_printf(" Resource %s\n", - ACPI_CONSUMER == address16_data->producer_consumer ? - "Consumer" : "Producer"); - - acpi_os_printf(" %s decode\n", - ACPI_SUB_DECODE == address16_data->decode ? - "Subtractive" : "Positive"); + /* Decode the general flags */ - acpi_os_printf(" Min address is %s fixed\n", - ACPI_ADDRESS_FIXED == address16_data->min_address_fixed ? - "" : "not"); - - acpi_os_printf(" Max address is %s fixed\n", - ACPI_ADDRESS_FIXED == address16_data->max_address_fixed ? - "" : "not"); - - acpi_os_printf(" Granularity: %08X\n", address16_data->granularity); - - acpi_os_printf(" Address range min: %08X\n", - address16_data->min_address_range); - - acpi_os_printf(" Address range max: %08X\n", - address16_data->max_address_range); - - acpi_os_printf(" Address translation offset: %08X\n", - address16_data->address_translation_offset); - - acpi_os_printf(" Address Length: %08X\n", - address16_data->address_length); - - if (0xFF != address16_data->resource_source.index) { - acpi_os_printf(" Resource Source Index: %X\n", - address16_data->resource_source.index); - - acpi_os_printf(" Resource Source: %s\n", - address16_data->resource_source.string_ptr); - } - - return; + acpi_rs_dump_descriptor(resource, acpi_rs_dump_general_flags); } /******************************************************************************* * - * FUNCTION: acpi_rs_dump_address32 + * FUNCTION: acpi_rs_dump_resource_list * - * PARAMETERS: Data - pointer to the resource structure to dump. + * PARAMETERS: resource_list - Pointer to a resource descriptor list * * RETURN: None * - * DESCRIPTION: Prints out the various members of the Data structure type. + * DESCRIPTION: Dispatches the structure to the correct dump routine. * ******************************************************************************/ -static void acpi_rs_dump_address32(union acpi_resource_data *data) +void acpi_rs_dump_resource_list(struct acpi_resource *resource_list) { - struct acpi_resource_address32 *address32_data = - (struct acpi_resource_address32 *)data; + u32 count = 0; + u32 type; ACPI_FUNCTION_ENTRY(); - acpi_os_printf("32-Bit Address Space Resource\n"); - - switch (address32_data->resource_type) { - case ACPI_MEMORY_RANGE: - - acpi_os_printf(" Resource Type: Memory Range\n"); - - switch (address32_data->attribute.memory.cache_attribute) { - case ACPI_NON_CACHEABLE_MEMORY: - acpi_os_printf - (" Type Specific: Noncacheable memory\n"); - break; - - case ACPI_CACHABLE_MEMORY: - acpi_os_printf(" Type Specific: Cacheable memory\n"); - break; - - case ACPI_WRITE_COMBINING_MEMORY: - acpi_os_printf - (" Type Specific: Write-combining memory\n"); - break; - - case ACPI_PREFETCHABLE_MEMORY: - acpi_os_printf - (" Type Specific: Prefetchable memory\n"); - break; - - default: - acpi_os_printf - (" Type Specific: Invalid cache attribute\n"); - break; - } - - acpi_os_printf(" Type Specific: Read%s\n", - ACPI_READ_WRITE_MEMORY == - address32_data->attribute.memory. - read_write_attribute ? "/Write" : " Only"); - break; - - case ACPI_IO_RANGE: - - acpi_os_printf(" Resource Type: Io Range\n"); + if (!(acpi_dbg_level & ACPI_LV_RESOURCES) + || !(_COMPONENT & acpi_dbg_layer)) { + return; + } - switch (address32_data->attribute.io.range_attribute) { - case ACPI_NON_ISA_ONLY_RANGES: - acpi_os_printf - (" Type Specific: Non-ISA Io Addresses\n"); - break; + /* Walk list and dump all resource descriptors (END_TAG terminates) */ - case ACPI_ISA_ONLY_RANGES: - acpi_os_printf(" Type Specific: ISA Io Addresses\n"); - break; + do { + acpi_os_printf("\n[%02X] ", count); + count++; - case ACPI_ENTIRE_RANGE: - acpi_os_printf - (" Type Specific: ISA and non-ISA Io Addresses\n"); - break; + /* Validate Type before dispatch */ - default: + type = resource_list->type; + if (type > ACPI_RESOURCE_TYPE_MAX) { acpi_os_printf - (" Type Specific: Invalid Range attribute"); - break; + ("Invalid descriptor type (%X) in resource list\n", + resource_list->type); + return; } - acpi_os_printf(" Type Specific: %s Translation\n", - ACPI_SPARSE_TRANSLATION == - address32_data->attribute.io. - translation_attribute ? "Sparse" : "Dense"); - break; - - case ACPI_BUS_NUMBER_RANGE: - - acpi_os_printf(" Resource Type: Bus Number Range\n"); - break; - - default: - - acpi_os_printf(" Resource Type: 0x%2.2X\n", - address32_data->resource_type); - break; - } - - acpi_os_printf(" Resource %s\n", - ACPI_CONSUMER == address32_data->producer_consumer ? - "Consumer" : "Producer"); - - acpi_os_printf(" %s decode\n", - ACPI_SUB_DECODE == address32_data->decode ? - "Subtractive" : "Positive"); - - acpi_os_printf(" Min address is %s fixed\n", - ACPI_ADDRESS_FIXED == address32_data->min_address_fixed ? - "" : "not "); - - acpi_os_printf(" Max address is %s fixed\n", - ACPI_ADDRESS_FIXED == address32_data->max_address_fixed ? - "" : "not "); + /* Dump the resource descriptor */ - acpi_os_printf(" Granularity: %08X\n", address32_data->granularity); + acpi_rs_dump_descriptor(&resource_list->data, + acpi_gbl_dump_resource_dispatch[type]); - acpi_os_printf(" Address range min: %08X\n", - address32_data->min_address_range); + /* Point to the next resource structure */ - acpi_os_printf(" Address range max: %08X\n", - address32_data->max_address_range); + resource_list = + ACPI_ADD_PTR(struct acpi_resource, resource_list, + resource_list->length); - acpi_os_printf(" Address translation offset: %08X\n", - address32_data->address_translation_offset); + /* Exit when END_TAG descriptor is reached */ - acpi_os_printf(" Address Length: %08X\n", - address32_data->address_length); - - if (0xFF != address32_data->resource_source.index) { - acpi_os_printf(" Resource Source Index: %X\n", - address32_data->resource_source.index); - - acpi_os_printf(" Resource Source: %s\n", - address32_data->resource_source.string_ptr); - } - - return; + } while (type != ACPI_RESOURCE_TYPE_END_TAG); } /******************************************************************************* * - * FUNCTION: acpi_rs_dump_address64 + * FUNCTION: acpi_rs_dump_irq_list * - * PARAMETERS: Data - pointer to the resource structure to dump. + * PARAMETERS: route_table - Pointer to the routing table to dump. * * RETURN: None * - * DESCRIPTION: Prints out the various members of the Data structure type. + * DESCRIPTION: Print IRQ routing table * ******************************************************************************/ -static void acpi_rs_dump_address64(union acpi_resource_data *data) +void acpi_rs_dump_irq_list(u8 * route_table) { - struct acpi_resource_address64 *address64_data = - (struct acpi_resource_address64 *)data; + struct acpi_pci_routing_table *prt_element; + u8 count; ACPI_FUNCTION_ENTRY(); - acpi_os_printf("64-Bit Address Space Resource\n"); - - switch (address64_data->resource_type) { - case ACPI_MEMORY_RANGE: - - acpi_os_printf(" Resource Type: Memory Range\n"); - - switch (address64_data->attribute.memory.cache_attribute) { - case ACPI_NON_CACHEABLE_MEMORY: - acpi_os_printf - (" Type Specific: Noncacheable memory\n"); - break; - - case ACPI_CACHABLE_MEMORY: - acpi_os_printf(" Type Specific: Cacheable memory\n"); - break; - - case ACPI_WRITE_COMBINING_MEMORY: - acpi_os_printf - (" Type Specific: Write-combining memory\n"); - break; - - case ACPI_PREFETCHABLE_MEMORY: - acpi_os_printf - (" Type Specific: Prefetchable memory\n"); - break; - - default: - acpi_os_printf - (" Type Specific: Invalid cache attribute\n"); - break; - } - - acpi_os_printf(" Type Specific: Read%s\n", - ACPI_READ_WRITE_MEMORY == - address64_data->attribute.memory. - read_write_attribute ? "/Write" : " Only"); - break; - - case ACPI_IO_RANGE: - - acpi_os_printf(" Resource Type: Io Range\n"); - - switch (address64_data->attribute.io.range_attribute) { - case ACPI_NON_ISA_ONLY_RANGES: - acpi_os_printf - (" Type Specific: Non-ISA Io Addresses\n"); - break; - - case ACPI_ISA_ONLY_RANGES: - acpi_os_printf(" Type Specific: ISA Io Addresses\n"); - break; - - case ACPI_ENTIRE_RANGE: - acpi_os_printf - (" Type Specific: ISA and non-ISA Io Addresses\n"); - break; - - default: - acpi_os_printf - (" Type Specific: Invalid Range attribute"); - break; - } - - acpi_os_printf(" Type Specific: %s Translation\n", - ACPI_SPARSE_TRANSLATION == - address64_data->attribute.io. - translation_attribute ? "Sparse" : "Dense"); - break; - - case ACPI_BUS_NUMBER_RANGE: - - acpi_os_printf(" Resource Type: Bus Number Range\n"); - break; - - default: - - acpi_os_printf(" Resource Type: 0x%2.2X\n", - address64_data->resource_type); - break; + if (!(acpi_dbg_level & ACPI_LV_RESOURCES) + || !(_COMPONENT & acpi_dbg_layer)) { + return; } - acpi_os_printf(" Resource %s\n", - ACPI_CONSUMER == address64_data->producer_consumer ? - "Consumer" : "Producer"); - - acpi_os_printf(" %s decode\n", - ACPI_SUB_DECODE == address64_data->decode ? - "Subtractive" : "Positive"); - - acpi_os_printf(" Min address is %s fixed\n", - ACPI_ADDRESS_FIXED == address64_data->min_address_fixed ? - "" : "not "); - - acpi_os_printf(" Max address is %s fixed\n", - ACPI_ADDRESS_FIXED == address64_data->max_address_fixed ? - "" : "not "); + prt_element = ACPI_CAST_PTR(struct acpi_pci_routing_table, route_table); - acpi_os_printf(" Granularity: %8.8X%8.8X\n", - ACPI_FORMAT_UINT64(address64_data->granularity)); + /* Dump all table elements, Exit on zero length element */ - acpi_os_printf(" Address range min: %8.8X%8.8X\n", - ACPI_FORMAT_UINT64(address64_data->min_address_range)); + for (count = 0; prt_element->length; count++) { + acpi_os_printf("\n[%02X] PCI IRQ Routing Table Package\n", + count); + acpi_rs_dump_descriptor(prt_element, acpi_rs_dump_prt); - acpi_os_printf(" Address range max: %8.8X%8.8X\n", - ACPI_FORMAT_UINT64(address64_data->max_address_range)); - - acpi_os_printf(" Address translation offset: %8.8X%8.8X\n", - ACPI_FORMAT_UINT64(address64_data-> - address_translation_offset)); - - acpi_os_printf(" Address Length: %8.8X%8.8X\n", - ACPI_FORMAT_UINT64(address64_data->address_length)); - - acpi_os_printf(" Type Specific Attributes: %8.8X%8.8X\n", - ACPI_FORMAT_UINT64(address64_data-> - type_specific_attributes)); - - if (0xFF != address64_data->resource_source.index) { - acpi_os_printf(" Resource Source Index: %X\n", - address64_data->resource_source.index); - - acpi_os_printf(" Resource Source: %s\n", - address64_data->resource_source.string_ptr); + prt_element = ACPI_ADD_PTR(struct acpi_pci_routing_table, + prt_element, prt_element->length); } - - return; } /******************************************************************************* * - * FUNCTION: acpi_rs_dump_extended_irq + * FUNCTION: acpi_rs_out* * - * PARAMETERS: Data - pointer to the resource structure to dump. + * PARAMETERS: Title - Name of the resource field + * Value - Value of the resource field * * RETURN: None * - * DESCRIPTION: Prints out the various members of the Data structure type. + * DESCRIPTION: Miscellaneous helper functions to consistently format the + * output of the resource dump routines * ******************************************************************************/ -static void acpi_rs_dump_extended_irq(union acpi_resource_data *data) +static void acpi_rs_out_string(char *title, char *value) { - struct acpi_resource_ext_irq *ext_irq_data = - (struct acpi_resource_ext_irq *)data; - u8 index = 0; - - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("Extended IRQ Resource\n"); - - acpi_os_printf(" Resource %s\n", - ACPI_CONSUMER == ext_irq_data->producer_consumer ? - "Consumer" : "Producer"); - - acpi_os_printf(" %s\n", - ACPI_LEVEL_SENSITIVE == ext_irq_data->edge_level ? - "Level" : "Edge"); - - acpi_os_printf(" Active %s\n", - ACPI_ACTIVE_LOW == ext_irq_data->active_high_low ? - "low" : "high"); - - acpi_os_printf(" %s\n", - ACPI_SHARED == ext_irq_data->shared_exclusive ? - "Shared" : "Exclusive"); - - acpi_os_printf(" Interrupts : %X ( ", - ext_irq_data->number_of_interrupts); - - for (index = 0; index < ext_irq_data->number_of_interrupts; index++) { - acpi_os_printf("%X ", ext_irq_data->interrupts[index]); - } - - acpi_os_printf(")\n"); - - if (0xFF != ext_irq_data->resource_source.index) { - acpi_os_printf(" Resource Source Index: %X", - ext_irq_data->resource_source.index); - - acpi_os_printf(" Resource Source: %s", - ext_irq_data->resource_source.string_ptr); + acpi_os_printf("%27s : %s", title, value); + if (!*value) { + acpi_os_printf("[NULL NAMESTRING]"); } - - return; + acpi_os_printf("\n"); } -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_resource_list - * - * PARAMETERS: Resource - pointer to the resource structure to dump. - * - * RETURN: None - * - * DESCRIPTION: Dispatches the structure to the correct dump routine. - * - ******************************************************************************/ - -void acpi_rs_dump_resource_list(struct acpi_resource *resource) +static void acpi_rs_out_integer8(char *title, u8 value) { - u8 count = 0; - u8 done = FALSE; - - ACPI_FUNCTION_ENTRY(); - - if (acpi_dbg_level & ACPI_LV_RESOURCES && _COMPONENT & acpi_dbg_layer) { - while (!done) { - acpi_os_printf("Resource structure %X.\n", count++); - - switch (resource->id) { - case ACPI_RSTYPE_IRQ: - acpi_rs_dump_irq(&resource->data); - break; - - case ACPI_RSTYPE_DMA: - acpi_rs_dump_dma(&resource->data); - break; - - case ACPI_RSTYPE_START_DPF: - acpi_rs_dump_start_depend_fns(&resource->data); - break; - - case ACPI_RSTYPE_END_DPF: - acpi_os_printf - ("end_dependent_functions Resource\n"); - /* acpi_rs_dump_end_dependent_functions (Resource->Data); */ - break; - - case ACPI_RSTYPE_IO: - acpi_rs_dump_io(&resource->data); - break; - - case ACPI_RSTYPE_FIXED_IO: - acpi_rs_dump_fixed_io(&resource->data); - break; - - case ACPI_RSTYPE_VENDOR: - acpi_rs_dump_vendor_specific(&resource->data); - break; - - case ACPI_RSTYPE_END_TAG: - /*rs_dump_end_tag (Resource->Data); */ - acpi_os_printf("end_tag Resource\n"); - done = TRUE; - break; - - case ACPI_RSTYPE_MEM24: - acpi_rs_dump_memory24(&resource->data); - break; - - case ACPI_RSTYPE_MEM32: - acpi_rs_dump_memory32(&resource->data); - break; - - case ACPI_RSTYPE_FIXED_MEM32: - acpi_rs_dump_fixed_memory32(&resource->data); - break; - - case ACPI_RSTYPE_ADDRESS16: - acpi_rs_dump_address16(&resource->data); - break; - - case ACPI_RSTYPE_ADDRESS32: - acpi_rs_dump_address32(&resource->data); - break; - - case ACPI_RSTYPE_ADDRESS64: - acpi_rs_dump_address64(&resource->data); - break; - - case ACPI_RSTYPE_EXT_IRQ: - acpi_rs_dump_extended_irq(&resource->data); - break; + acpi_os_printf("%27s : %2.2X\n", title, value); +} - default: - acpi_os_printf("Invalid resource type\n"); - break; +static void acpi_rs_out_integer16(char *title, u16 value) +{ + acpi_os_printf("%27s : %4.4X\n", title, value); +} - } +static void acpi_rs_out_integer32(char *title, u32 value) +{ + acpi_os_printf("%27s : %8.8X\n", title, value); +} - resource = - ACPI_PTR_ADD(struct acpi_resource, resource, - resource->length); - } - } +static void acpi_rs_out_integer64(char *title, u64 value) +{ + acpi_os_printf("%27s : %8.8X%8.8X\n", title, ACPI_FORMAT_UINT64(value)); +} - return; +static void acpi_rs_out_title(char *title) +{ + acpi_os_printf("%27s : ", title); } /******************************************************************************* * - * FUNCTION: acpi_rs_dump_irq_list + * FUNCTION: acpi_rs_dump*List * - * PARAMETERS: route_table - pointer to the routing table to dump. + * PARAMETERS: Length - Number of elements in the list + * Data - Start of the list * * RETURN: None * - * DESCRIPTION: Dispatches the structures to the correct dump routine. + * DESCRIPTION: Miscellaneous functions to dump lists of raw data * ******************************************************************************/ -void acpi_rs_dump_irq_list(u8 * route_table) +static void acpi_rs_dump_byte_list(u16 length, u8 * data) { - u8 *buffer = route_table; - u8 count = 0; - u8 done = FALSE; - struct acpi_pci_routing_table *prt_element; + u8 i; - ACPI_FUNCTION_ENTRY(); - - if (acpi_dbg_level & ACPI_LV_RESOURCES && _COMPONENT & acpi_dbg_layer) { - prt_element = - ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer); - - while (!done) { - acpi_os_printf("PCI IRQ Routing Table structure %X.\n", - count++); - - acpi_os_printf(" Address: %8.8X%8.8X\n", - ACPI_FORMAT_UINT64(prt_element-> - address)); + for (i = 0; i < length; i++) { + acpi_os_printf("%25s%2.2X : %2.2X\n", "Byte", i, data[i]); + } +} - acpi_os_printf(" Pin: %X\n", prt_element->pin); +static void acpi_rs_dump_short_byte_list(u8 length, u8 * data) +{ + u8 i; - acpi_os_printf(" Source: %s\n", prt_element->source); + for (i = 0; i < length; i++) { + acpi_os_printf("%X ", data[i]); + } + acpi_os_printf("\n"); +} - acpi_os_printf(" source_index: %X\n", - prt_element->source_index); +static void acpi_rs_dump_dword_list(u8 length, u32 * data) +{ + u8 i; - buffer += prt_element->length; - prt_element = - ACPI_CAST_PTR(struct acpi_pci_routing_table, - buffer); - if (0 == prt_element->length) { - done = TRUE; - } - } + for (i = 0; i < length; i++) { + acpi_os_printf("%25s%2.2X : %8.8X\n", "Dword", i, data[i]); } - - return; } #endif diff --git a/drivers/acpi/resources/rsinfo.c b/drivers/acpi/resources/rsinfo.c new file mode 100644 index 000000000000..d9ae64b77bd9 --- /dev/null +++ b/drivers/acpi/resources/rsinfo.c @@ -0,0 +1,204 @@ +/******************************************************************************* + * + * Module Name: rsinfo - Dispatch and Info tables + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2006, R. Byron Moore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include <acpi/acpi.h> +#include <acpi/acresrc.h> + +#define _COMPONENT ACPI_RESOURCES +ACPI_MODULE_NAME("rsinfo") + +/* + * Resource dispatch and information tables. Any new resource types (either + * Large or Small) must be reflected in each of these tables, so they are here + * in one place. + * + * The tables for Large descriptors are indexed by bits 6:0 of the AML + * descriptor type byte. The tables for Small descriptors are indexed by + * bits 6:3 of the descriptor byte. The tables for internal resource + * descriptors are indexed by the acpi_resource_type field. + */ +/* Dispatch table for resource-to-AML (Set Resource) conversion functions */ +struct acpi_rsconvert_info *acpi_gbl_set_resource_dispatch[] = { + acpi_rs_set_irq, /* 0x00, ACPI_RESOURCE_TYPE_IRQ */ + acpi_rs_convert_dma, /* 0x01, ACPI_RESOURCE_TYPE_DMA */ + acpi_rs_set_start_dpf, /* 0x02, ACPI_RESOURCE_TYPE_START_DEPENDENT */ + acpi_rs_convert_end_dpf, /* 0x03, ACPI_RESOURCE_TYPE_END_DEPENDENT */ + acpi_rs_convert_io, /* 0x04, ACPI_RESOURCE_TYPE_IO */ + acpi_rs_convert_fixed_io, /* 0x05, ACPI_RESOURCE_TYPE_FIXED_IO */ + acpi_rs_set_vendor, /* 0x06, ACPI_RESOURCE_TYPE_VENDOR */ + acpi_rs_convert_end_tag, /* 0x07, ACPI_RESOURCE_TYPE_END_TAG */ + acpi_rs_convert_memory24, /* 0x08, ACPI_RESOURCE_TYPE_MEMORY24 */ + acpi_rs_convert_memory32, /* 0x09, ACPI_RESOURCE_TYPE_MEMORY32 */ + acpi_rs_convert_fixed_memory32, /* 0x0A, ACPI_RESOURCE_TYPE_FIXED_MEMORY32 */ + acpi_rs_convert_address16, /* 0x0B, ACPI_RESOURCE_TYPE_ADDRESS16 */ + acpi_rs_convert_address32, /* 0x0C, ACPI_RESOURCE_TYPE_ADDRESS32 */ + acpi_rs_convert_address64, /* 0x0D, ACPI_RESOURCE_TYPE_ADDRESS64 */ + acpi_rs_convert_ext_address64, /* 0x0E, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */ + acpi_rs_convert_ext_irq, /* 0x0F, ACPI_RESOURCE_TYPE_EXTENDED_IRQ */ + acpi_rs_convert_generic_reg /* 0x10, ACPI_RESOURCE_TYPE_GENERIC_REGISTER */ +}; + +/* Dispatch tables for AML-to-resource (Get Resource) conversion functions */ + +struct acpi_rsconvert_info *acpi_gbl_get_resource_dispatch[] = { + /* Small descriptors */ + + NULL, /* 0x00, Reserved */ + NULL, /* 0x01, Reserved */ + NULL, /* 0x02, Reserved */ + NULL, /* 0x03, Reserved */ + acpi_rs_get_irq, /* 0x04, ACPI_RESOURCE_NAME_IRQ */ + acpi_rs_convert_dma, /* 0x05, ACPI_RESOURCE_NAME_DMA */ + acpi_rs_get_start_dpf, /* 0x06, ACPI_RESOURCE_NAME_START_DEPENDENT */ + acpi_rs_convert_end_dpf, /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */ + acpi_rs_convert_io, /* 0x08, ACPI_RESOURCE_NAME_IO */ + acpi_rs_convert_fixed_io, /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO */ + NULL, /* 0x0A, Reserved */ + NULL, /* 0x0B, Reserved */ + NULL, /* 0x0C, Reserved */ + NULL, /* 0x0D, Reserved */ + acpi_rs_get_vendor_small, /* 0x0E, ACPI_RESOURCE_NAME_VENDOR_SMALL */ + acpi_rs_convert_end_tag, /* 0x0F, ACPI_RESOURCE_NAME_END_TAG */ + + /* Large descriptors */ + + NULL, /* 0x00, Reserved */ + acpi_rs_convert_memory24, /* 0x01, ACPI_RESOURCE_NAME_MEMORY24 */ + acpi_rs_convert_generic_reg, /* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */ + NULL, /* 0x03, Reserved */ + acpi_rs_get_vendor_large, /* 0x04, ACPI_RESOURCE_NAME_VENDOR_LARGE */ + acpi_rs_convert_memory32, /* 0x05, ACPI_RESOURCE_NAME_MEMORY32 */ + acpi_rs_convert_fixed_memory32, /* 0x06, ACPI_RESOURCE_NAME_FIXED_MEMORY32 */ + acpi_rs_convert_address32, /* 0x07, ACPI_RESOURCE_NAME_ADDRESS32 */ + acpi_rs_convert_address16, /* 0x08, ACPI_RESOURCE_NAME_ADDRESS16 */ + acpi_rs_convert_ext_irq, /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_IRQ */ + acpi_rs_convert_address64, /* 0x0A, ACPI_RESOURCE_NAME_ADDRESS64 */ + acpi_rs_convert_ext_address64 /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64 */ +}; + +#ifdef ACPI_FUTURE_USAGE +#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) + +/* Dispatch table for resource dump functions */ + +struct acpi_rsdump_info *acpi_gbl_dump_resource_dispatch[] = { + acpi_rs_dump_irq, /* ACPI_RESOURCE_TYPE_IRQ */ + acpi_rs_dump_dma, /* ACPI_RESOURCE_TYPE_DMA */ + acpi_rs_dump_start_dpf, /* ACPI_RESOURCE_TYPE_START_DEPENDENT */ + acpi_rs_dump_end_dpf, /* ACPI_RESOURCE_TYPE_END_DEPENDENT */ + acpi_rs_dump_io, /* ACPI_RESOURCE_TYPE_IO */ + acpi_rs_dump_fixed_io, /* ACPI_RESOURCE_TYPE_FIXED_IO */ + acpi_rs_dump_vendor, /* ACPI_RESOURCE_TYPE_VENDOR */ + acpi_rs_dump_end_tag, /* ACPI_RESOURCE_TYPE_END_TAG */ + acpi_rs_dump_memory24, /* ACPI_RESOURCE_TYPE_MEMORY24 */ + acpi_rs_dump_memory32, /* ACPI_RESOURCE_TYPE_MEMORY32 */ + acpi_rs_dump_fixed_memory32, /* ACPI_RESOURCE_TYPE_FIXED_MEMORY32 */ + acpi_rs_dump_address16, /* ACPI_RESOURCE_TYPE_ADDRESS16 */ + acpi_rs_dump_address32, /* ACPI_RESOURCE_TYPE_ADDRESS32 */ + acpi_rs_dump_address64, /* ACPI_RESOURCE_TYPE_ADDRESS64 */ + acpi_rs_dump_ext_address64, /* ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */ + acpi_rs_dump_ext_irq, /* ACPI_RESOURCE_TYPE_EXTENDED_IRQ */ + acpi_rs_dump_generic_reg, /* ACPI_RESOURCE_TYPE_GENERIC_REGISTER */ +}; +#endif +#endif /* ACPI_FUTURE_USAGE */ +/* + * Base sizes for external AML resource descriptors, indexed by internal type. + * Includes size of the descriptor header (1 byte for small descriptors, + * 3 bytes for large descriptors) + */ +const u8 acpi_gbl_aml_resource_sizes[] = { + sizeof(struct aml_resource_irq), /* ACPI_RESOURCE_TYPE_IRQ (optional Byte 3 always created) */ + sizeof(struct aml_resource_dma), /* ACPI_RESOURCE_TYPE_DMA */ + sizeof(struct aml_resource_start_dependent), /* ACPI_RESOURCE_TYPE_START_DEPENDENT (optional Byte 1 always created) */ + sizeof(struct aml_resource_end_dependent), /* ACPI_RESOURCE_TYPE_END_DEPENDENT */ + sizeof(struct aml_resource_io), /* ACPI_RESOURCE_TYPE_IO */ + sizeof(struct aml_resource_fixed_io), /* ACPI_RESOURCE_TYPE_FIXED_IO */ + sizeof(struct aml_resource_vendor_small), /* ACPI_RESOURCE_TYPE_VENDOR */ + sizeof(struct aml_resource_end_tag), /* ACPI_RESOURCE_TYPE_END_TAG */ + sizeof(struct aml_resource_memory24), /* ACPI_RESOURCE_TYPE_MEMORY24 */ + sizeof(struct aml_resource_memory32), /* ACPI_RESOURCE_TYPE_MEMORY32 */ + sizeof(struct aml_resource_fixed_memory32), /* ACPI_RESOURCE_TYPE_FIXED_MEMORY32 */ + sizeof(struct aml_resource_address16), /* ACPI_RESOURCE_TYPE_ADDRESS16 */ + sizeof(struct aml_resource_address32), /* ACPI_RESOURCE_TYPE_ADDRESS32 */ + sizeof(struct aml_resource_address64), /* ACPI_RESOURCE_TYPE_ADDRESS64 */ + sizeof(struct aml_resource_extended_address64), /*ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */ + sizeof(struct aml_resource_extended_irq), /* ACPI_RESOURCE_TYPE_EXTENDED_IRQ */ + sizeof(struct aml_resource_generic_register) /* ACPI_RESOURCE_TYPE_GENERIC_REGISTER */ +}; + +const u8 acpi_gbl_resource_struct_sizes[] = { + /* Small descriptors */ + + 0, + 0, + 0, + 0, + ACPI_RS_SIZE(struct acpi_resource_irq), + ACPI_RS_SIZE(struct acpi_resource_dma), + ACPI_RS_SIZE(struct acpi_resource_start_dependent), + ACPI_RS_SIZE_MIN, + ACPI_RS_SIZE(struct acpi_resource_io), + ACPI_RS_SIZE(struct acpi_resource_fixed_io), + 0, + 0, + 0, + 0, + ACPI_RS_SIZE(struct acpi_resource_vendor), + ACPI_RS_SIZE_MIN, + + /* Large descriptors */ + + 0, + ACPI_RS_SIZE(struct acpi_resource_memory24), + ACPI_RS_SIZE(struct acpi_resource_generic_register), + 0, + ACPI_RS_SIZE(struct acpi_resource_vendor), + ACPI_RS_SIZE(struct acpi_resource_memory32), + ACPI_RS_SIZE(struct acpi_resource_fixed_memory32), + ACPI_RS_SIZE(struct acpi_resource_address32), + ACPI_RS_SIZE(struct acpi_resource_address16), + ACPI_RS_SIZE(struct acpi_resource_extended_irq), + ACPI_RS_SIZE(struct acpi_resource_address64), + ACPI_RS_SIZE(struct acpi_resource_extended_address64) +}; diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c index d53bbe89e851..ea567167c4f2 100644 --- a/drivers/acpi/resources/rsio.c +++ b/drivers/acpi/resources/rsio.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,428 +49,206 @@ ACPI_MODULE_NAME("rsio") /******************************************************************************* * - * FUNCTION: acpi_rs_io_resource + * acpi_rs_convert_io * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned - * - * RETURN: Status + ******************************************************************************/ +struct acpi_rsconvert_info acpi_rs_convert_io[5] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IO, + ACPI_RS_SIZE(struct acpi_resource_io), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_io)}, + + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IO, + sizeof(struct aml_resource_io), + 0}, + + /* Decode flag */ + + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.io.io_decode), + AML_OFFSET(io.flags), + 0}, + /* + * These fields are contiguous in both the source and destination: + * Address Alignment + * Length + * Minimum Base Address + * Maximum Base Address + */ + {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.io.alignment), + AML_OFFSET(io.alignment), + 2}, + + {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.io.minimum), + AML_OFFSET(io.minimum), + 2} +}; + +/******************************************************************************* * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * acpi_rs_convert_fixed_io * ******************************************************************************/ -acpi_status -acpi_rs_io_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) -{ - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - acpi_size struct_size = ACPI_SIZEOF_RESOURCE(struct acpi_resource_io); - - ACPI_FUNCTION_TRACE("rs_io_resource"); - - /* The number of bytes consumed are Constant */ - - *bytes_consumed = 8; - - output_struct->id = ACPI_RSTYPE_IO; - - /* Check Decode */ - - buffer += 1; - temp8 = *buffer; - - output_struct->data.io.io_decode = temp8 & 0x01; - - /* Check min_base Address */ - - buffer += 1; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - output_struct->data.io.min_base_address = temp16; - - /* Check max_base Address */ - buffer += 2; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - output_struct->data.io.max_base_address = temp16; - - /* Check Base alignment */ - - buffer += 2; - temp8 = *buffer; - - output_struct->data.io.alignment = temp8; - - /* Check range_length */ - - buffer += 1; - temp8 = *buffer; - - output_struct->data.io.range_length = temp8; - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; - return_ACPI_STATUS(AE_OK); -} +struct acpi_rsconvert_info acpi_rs_convert_fixed_io[4] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_FIXED_IO, + ACPI_RS_SIZE(struct acpi_resource_fixed_io), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_fixed_io)}, + + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_FIXED_IO, + sizeof(struct aml_resource_fixed_io), + 0}, + /* + * These fields are contiguous in both the source and destination: + * Base Address + * Length + */ + {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.fixed_io.address_length), + AML_OFFSET(fixed_io.address_length), + 1}, + + {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.fixed_io.address), + AML_OFFSET(fixed_io.address), + 1} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_fixed_io_resource - * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * acpi_rs_convert_generic_reg * ******************************************************************************/ -acpi_status -acpi_rs_fixed_io_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) -{ - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_io); - - ACPI_FUNCTION_TRACE("rs_fixed_io_resource"); - - /* The number of bytes consumed are Constant */ - - *bytes_consumed = 4; - - output_struct->id = ACPI_RSTYPE_FIXED_IO; - - /* Check Range Base Address */ - - buffer += 1; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - output_struct->data.fixed_io.base_address = temp16; - - /* Check range_length */ - - buffer += 2; - temp8 = *buffer; - - output_struct->data.fixed_io.range_length = temp8; - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; - return_ACPI_STATUS(AE_OK); -} +struct acpi_rsconvert_info acpi_rs_convert_generic_reg[4] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_GENERIC_REGISTER, + ACPI_RS_SIZE(struct acpi_resource_generic_register), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_generic_reg)}, + + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_GENERIC_REGISTER, + sizeof(struct aml_resource_generic_register), + 0}, + /* + * These fields are contiguous in both the source and destination: + * Address Space ID + * Register Bit Width + * Register Bit Offset + * Access Size + */ + {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.generic_reg.space_id), + AML_OFFSET(generic_reg.address_space_id), + 4}, + + /* Get the Register Address */ + + {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.generic_reg.address), + AML_OFFSET(generic_reg.address), + 1} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_io_stream - * - * PARAMETERS: linked_list - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * acpi_rs_convert_end_dpf * ******************************************************************************/ -acpi_status -acpi_rs_io_stream(struct acpi_resource *linked_list, - u8 ** output_buffer, acpi_size * bytes_consumed) -{ - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - - ACPI_FUNCTION_TRACE("rs_io_stream"); - - /* The descriptor field is static */ - - *buffer = 0x47; - buffer += 1; - - /* Io Information Byte */ - - temp8 = (u8) (linked_list->data.io.io_decode & 0x01); - - *buffer = temp8; - buffer += 1; - - /* Set the Range minimum base address */ - - temp16 = (u16) linked_list->data.io.min_base_address; - - ACPI_MOVE_16_TO_16(buffer, &temp16); - buffer += 2; - - /* Set the Range maximum base address */ - - temp16 = (u16) linked_list->data.io.max_base_address; +struct acpi_rsconvert_info acpi_rs_convert_end_dpf[2] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_END_DEPENDENT, + ACPI_RS_SIZE_MIN, + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_end_dpf)}, - ACPI_MOVE_16_TO_16(buffer, &temp16); - buffer += 2; - - /* Set the base alignment */ - - temp8 = (u8) linked_list->data.io.alignment; - - *buffer = temp8; - buffer += 1; - - /* Set the range length */ - - temp8 = (u8) linked_list->data.io.range_length; - - *buffer = temp8; - buffer += 1; - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_END_DEPENDENT, + sizeof(struct aml_resource_end_dependent), + 0} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_fixed_io_stream - * - * PARAMETERS: linked_list - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * acpi_rs_convert_end_tag * ******************************************************************************/ -acpi_status -acpi_rs_fixed_io_stream(struct acpi_resource *linked_list, - u8 ** output_buffer, acpi_size * bytes_consumed) -{ - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - - ACPI_FUNCTION_TRACE("rs_fixed_io_stream"); - - /* The descriptor field is static */ - - *buffer = 0x4B; - - buffer += 1; - - /* Set the Range base address */ - - temp16 = (u16) linked_list->data.fixed_io.base_address; - - ACPI_MOVE_16_TO_16(buffer, &temp16); - buffer += 2; - - /* Set the range length */ - - temp8 = (u8) linked_list->data.fixed_io.range_length; - - *buffer = temp8; - buffer += 1; - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); - return_ACPI_STATUS(AE_OK); -} +struct acpi_rsconvert_info acpi_rs_convert_end_tag[2] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_END_TAG, + ACPI_RS_SIZE_MIN, + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_end_tag)}, + + /* + * Note: The checksum field is set to zero, meaning that the resource + * data is treated as if the checksum operation succeeded. + * (ACPI Spec 1.0b Section 6.4.2.8) + */ + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_END_TAG, + sizeof(struct aml_resource_end_tag), + 0} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_dma_resource - * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * acpi_rs_get_start_dpf * ******************************************************************************/ -acpi_status -acpi_rs_dma_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) -{ - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - u8 temp8 = 0; - u8 index; - u8 i; - acpi_size struct_size = ACPI_SIZEOF_RESOURCE(struct acpi_resource_dma); - - ACPI_FUNCTION_TRACE("rs_dma_resource"); - - /* The number of bytes consumed are Constant */ +struct acpi_rsconvert_info acpi_rs_get_start_dpf[5] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_START_DEPENDENT, + ACPI_RS_SIZE(struct acpi_resource_start_dependent), + ACPI_RSC_TABLE_SIZE(acpi_rs_get_start_dpf)}, - *bytes_consumed = 3; - output_struct->id = ACPI_RSTYPE_DMA; + /* Defaults for Compatibility and Performance priorities */ - /* Point to the 8-bits of Byte 1 */ + {ACPI_RSC_SET8, ACPI_RS_OFFSET(data.start_dpf.compatibility_priority), + ACPI_ACCEPTABLE_CONFIGURATION, + 2}, - buffer += 1; - temp8 = *buffer; + /* All done if there is no flag byte present in the descriptor */ - /* Decode the DMA channel bits */ + {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 1}, - for (i = 0, index = 0; index < 8; index++) { - if ((temp8 >> index) & 0x01) { - output_struct->data.dma.channels[i] = index; - i++; - } - } + /* Flag byte is present, get the flags */ - /* Zero DMA channels is valid */ + {ACPI_RSC_2BITFLAG, + ACPI_RS_OFFSET(data.start_dpf.compatibility_priority), + AML_OFFSET(start_dpf.flags), + 0}, - output_struct->data.dma.number_of_channels = i; - if (i > 0) { - /* Calculate the structure size based upon the number of interrupts */ - - struct_size += ((acpi_size) i - 1) * 4; - } - - /* Point to Byte 2 */ - - buffer += 1; - temp8 = *buffer; - - /* Check for transfer preference (Bits[1:0]) */ - - output_struct->data.dma.transfer = temp8 & 0x03; - - if (0x03 == output_struct->data.dma.transfer) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid DMA.Transfer preference (3)\n")); - return_ACPI_STATUS(AE_BAD_DATA); - } - - /* Get bus master preference (Bit[2]) */ - - output_struct->data.dma.bus_master = (temp8 >> 2) & 0x01; - - /* Get channel speed support (Bits[6:5]) */ - - output_struct->data.dma.type = (temp8 >> 5) & 0x03; - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_2BITFLAG, + ACPI_RS_OFFSET(data.start_dpf.performance_robustness), + AML_OFFSET(start_dpf.flags), + 2} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_dma_stream - * - * PARAMETERS: linked_list - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * acpi_rs_set_start_dpf * ******************************************************************************/ -acpi_status -acpi_rs_dma_stream(struct acpi_resource *linked_list, - u8 ** output_buffer, acpi_size * bytes_consumed) -{ - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - u8 index; - - ACPI_FUNCTION_TRACE("rs_dma_stream"); - - /* The descriptor field is static */ - - *buffer = 0x2A; - buffer += 1; - temp8 = 0; - - /* Loop through all of the Channels and set the mask bits */ - - for (index = 0; - index < linked_list->data.dma.number_of_channels; index++) { - temp16 = (u16) linked_list->data.dma.channels[index]; - temp8 |= 0x1 << temp16; - } - - *buffer = temp8; - buffer += 1; - - /* Set the DMA Info */ - - temp8 = (u8) ((linked_list->data.dma.type & 0x03) << 5); - temp8 |= ((linked_list->data.dma.bus_master & 0x01) << 2); - temp8 |= (linked_list->data.dma.transfer & 0x03); - - *buffer = temp8; - buffer += 1; - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); - return_ACPI_STATUS(AE_OK); -} +struct acpi_rsconvert_info acpi_rs_set_start_dpf[6] = { + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_START_DEPENDENT, + sizeof(struct aml_resource_start_dependent), + ACPI_RSC_TABLE_SIZE(acpi_rs_set_start_dpf)}, + + /* Set the default flag values */ + + {ACPI_RSC_2BITFLAG, + ACPI_RS_OFFSET(data.start_dpf.compatibility_priority), + AML_OFFSET(start_dpf.flags), + 0}, + + {ACPI_RSC_2BITFLAG, + ACPI_RS_OFFSET(data.start_dpf.performance_robustness), + AML_OFFSET(start_dpf.flags), + 2}, + /* + * All done if flags byte is necessary -- if either priority value + * is not ACPI_ACCEPTABLE_CONFIGURATION + */ + {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE, + ACPI_RS_OFFSET(data.start_dpf.compatibility_priority), + ACPI_ACCEPTABLE_CONFIGURATION}, + + {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE, + ACPI_RS_OFFSET(data.start_dpf.performance_robustness), + ACPI_ACCEPTABLE_CONFIGURATION}, + + /* Flag byte is not necessary */ + + {ACPI_RSC_LENGTH, 0, 0, + sizeof(struct aml_resource_start_dependent_noprio)} +}; diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c index 56043fee96cb..1fa63bc2e36f 100644 --- a/drivers/acpi/resources/rsirq.c +++ b/drivers/acpi/resources/rsirq.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,504 +49,182 @@ ACPI_MODULE_NAME("rsirq") /******************************************************************************* * - * FUNCTION: acpi_rs_irq_resource - * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * acpi_rs_get_irq * ******************************************************************************/ -acpi_status -acpi_rs_irq_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) -{ - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - u8 index; - u8 i; - acpi_size struct_size = ACPI_SIZEOF_RESOURCE(struct acpi_resource_irq); - - ACPI_FUNCTION_TRACE("rs_irq_resource"); - - /* - * The number of bytes consumed are contained in the descriptor - * (Bits:0-1) - */ - temp8 = *buffer; - *bytes_consumed = (temp8 & 0x03) + 1; - output_struct->id = ACPI_RSTYPE_IRQ; - - /* Point to the 16-bits of Bytes 1 and 2 */ - - buffer += 1; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - output_struct->data.irq.number_of_interrupts = 0; - - /* Decode the IRQ bits */ - - for (i = 0, index = 0; index < 16; index++) { - if ((temp16 >> index) & 0x01) { - output_struct->data.irq.interrupts[i] = index; - i++; - } - } +struct acpi_rsconvert_info acpi_rs_get_irq[7] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IRQ, + ACPI_RS_SIZE(struct acpi_resource_irq), + ACPI_RSC_TABLE_SIZE(acpi_rs_get_irq)}, - /* Zero interrupts is valid */ + /* Get the IRQ mask (bytes 1:2) */ - output_struct->data.irq.number_of_interrupts = i; - if (i > 0) { - /* Calculate the structure size based upon the number of interrupts */ + {ACPI_RSC_BITMASK16, ACPI_RS_OFFSET(data.irq.interrupts[0]), + AML_OFFSET(irq.irq_mask), + ACPI_RS_OFFSET(data.irq.interrupt_count)}, - struct_size += ((acpi_size) i - 1) * 4; - } + /* Set default flags (others are zero) */ - /* Point to Byte 3 if it is used */ + {ACPI_RSC_SET8, ACPI_RS_OFFSET(data.irq.triggering), + ACPI_EDGE_SENSITIVE, + 1}, - if (4 == *bytes_consumed) { - buffer += 2; - temp8 = *buffer; + /* All done if no flag byte present in descriptor */ - /* Check for HE, LL interrupts */ + {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 3}, - switch (temp8 & 0x09) { - case 0x01: /* HE */ - output_struct->data.irq.edge_level = - ACPI_EDGE_SENSITIVE; - output_struct->data.irq.active_high_low = - ACPI_ACTIVE_HIGH; - break; + /* Get flags: Triggering[0], Polarity[3], Sharing[4] */ - case 0x08: /* LL */ - output_struct->data.irq.edge_level = - ACPI_LEVEL_SENSITIVE; - output_struct->data.irq.active_high_low = - ACPI_ACTIVE_LOW; - break; + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering), + AML_OFFSET(irq.flags), + 0}, - default: - /* - * Only _LL and _HE polarity/trigger interrupts - * are allowed (ACPI spec, section "IRQ Format") - * so 0x00 and 0x09 are illegal. - */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid interrupt polarity/trigger in resource list, %X\n", - temp8)); - return_ACPI_STATUS(AE_BAD_DATA); - } + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.polarity), + AML_OFFSET(irq.flags), + 3}, - /* Check for sharable */ - - output_struct->data.irq.shared_exclusive = (temp8 >> 3) & 0x01; - } else { - /* - * Assume Edge Sensitive, Active High, Non-Sharable - * per ACPI Specification - */ - output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE; - output_struct->data.irq.active_high_low = ACPI_ACTIVE_HIGH; - output_struct->data.irq.shared_exclusive = ACPI_EXCLUSIVE; - } - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable), + AML_OFFSET(irq.flags), + 4} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_irq_stream - * - * PARAMETERS: linked_list - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * acpi_rs_set_irq * ******************************************************************************/ -acpi_status -acpi_rs_irq_stream(struct acpi_resource *linked_list, - u8 ** output_buffer, acpi_size * bytes_consumed) -{ - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - u8 index; - u8 IRqinfo_byte_needed; - - ACPI_FUNCTION_TRACE("rs_irq_stream"); - - /* - * The descriptor field is set based upon whether a third byte is - * needed to contain the IRQ Information. - */ - if (ACPI_EDGE_SENSITIVE == linked_list->data.irq.edge_level && - ACPI_ACTIVE_HIGH == linked_list->data.irq.active_high_low && - ACPI_EXCLUSIVE == linked_list->data.irq.shared_exclusive) { - *buffer = 0x22; - IRqinfo_byte_needed = FALSE; - } else { - *buffer = 0x23; - IRqinfo_byte_needed = TRUE; - } - - buffer += 1; - temp16 = 0; - - /* Loop through all of the interrupts and set the mask bits */ - - for (index = 0; - index < linked_list->data.irq.number_of_interrupts; index++) { - temp8 = (u8) linked_list->data.irq.interrupts[index]; - temp16 |= 0x1 << temp8; - } - - ACPI_MOVE_16_TO_16(buffer, &temp16); - buffer += 2; - - /* Set the IRQ Info byte if needed. */ - - if (IRqinfo_byte_needed) { - temp8 = 0; - temp8 = (u8) ((linked_list->data.irq.shared_exclusive & - 0x01) << 4); - - if (ACPI_LEVEL_SENSITIVE == linked_list->data.irq.edge_level && - ACPI_ACTIVE_LOW == linked_list->data.irq.active_high_low) { - temp8 |= 0x08; - } else { - temp8 |= 0x01; - } - - *buffer = temp8; - buffer += 1; - } - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_extended_irq_resource - * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. - * - ******************************************************************************/ - -acpi_status -acpi_rs_extended_irq_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) -{ - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - u8 *temp_ptr; - u8 index; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_ext_irq); - - ACPI_FUNCTION_TRACE("rs_extended_irq_resource"); - - /* Get the Descriptor Length field */ - - buffer += 1; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - /* Validate minimum descriptor length */ - - if (temp16 < 6) { - return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); - } - - *bytes_consumed = temp16 + 3; - output_struct->id = ACPI_RSTYPE_EXT_IRQ; - - /* Point to the Byte3 */ - - buffer += 2; - temp8 = *buffer; - - output_struct->data.extended_irq.producer_consumer = temp8 & 0x01; +struct acpi_rsconvert_info acpi_rs_set_irq[9] = { + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IRQ, + sizeof(struct aml_resource_irq), + ACPI_RSC_TABLE_SIZE(acpi_rs_set_irq)}, - /* - * Check for Interrupt Mode - * - * The definition of an Extended IRQ changed between ACPI spec v1.0b - * and ACPI spec 2.0 (section 6.4.3.6 in both). - * - * - Edge/Level are defined opposite in the table vs the headers - */ - output_struct->data.extended_irq.edge_level = - (temp8 & 0x2) ? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE; - - /* Check Interrupt Polarity */ - - output_struct->data.extended_irq.active_high_low = (temp8 >> 2) & 0x1; - - /* Check for sharable */ - - output_struct->data.extended_irq.shared_exclusive = (temp8 >> 3) & 0x01; + /* Convert interrupt list to 16-bit IRQ bitmask */ - /* Point to Byte4 (IRQ Table length) */ + {ACPI_RSC_BITMASK16, ACPI_RS_OFFSET(data.irq.interrupts[0]), + AML_OFFSET(irq.irq_mask), + ACPI_RS_OFFSET(data.irq.interrupt_count)}, - buffer += 1; - temp8 = *buffer; + /* Set the flags byte by default */ - /* Must have at least one IRQ */ + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering), + AML_OFFSET(irq.flags), + 0}, - if (temp8 < 1) { - return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); - } - - output_struct->data.extended_irq.number_of_interrupts = temp8; + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.polarity), + AML_OFFSET(irq.flags), + 3}, + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable), + AML_OFFSET(irq.flags), + 4}, /* - * Add any additional structure size to properly calculate - * the next pointer at the end of this function + * Check if the flags byte is necessary. Not needed if the flags are: + * ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH, ACPI_EXCLUSIVE */ - struct_size += (temp8 - 1) * 4; - - /* Point to Byte5 (First IRQ Number) */ - - buffer += 1; - - /* Cycle through every IRQ in the table */ - - for (index = 0; index < temp8; index++) { - ACPI_MOVE_32_TO_32(&output_struct->data.extended_irq. - interrupts[index], buffer); - - /* Point to the next IRQ */ - - buffer += 4; - } - - /* - * This will leave us pointing to the Resource Source Index - * If it is present, then save it off and calculate the - * pointer to where the null terminated string goes: - * Each Interrupt takes 32-bits + the 5 bytes of the - * stream that are default. - * - * Note: Some resource descriptors will have an additional null, so - * we add 1 to the length. - */ - if (*bytes_consumed > - ((acpi_size) output_struct->data.extended_irq.number_of_interrupts * - 4) + (5 + 1)) { - /* Dereference the Index */ - - temp8 = *buffer; - output_struct->data.extended_irq.resource_source.index = - (u32) temp8; - - /* Point to the String */ - - buffer += 1; - - /* Point the String pointer to the end of this structure. */ - - output_struct->data.extended_irq.resource_source.string_ptr = - (char *)((char *)output_struct + struct_size); + {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE, + ACPI_RS_OFFSET(data.irq.triggering), + ACPI_EDGE_SENSITIVE}, - temp_ptr = (u8 *) - output_struct->data.extended_irq.resource_source.string_ptr; + {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE, + ACPI_RS_OFFSET(data.irq.polarity), + ACPI_ACTIVE_HIGH}, - /* Copy the string into the buffer */ + {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE, + ACPI_RS_OFFSET(data.irq.sharable), + ACPI_EXCLUSIVE}, - index = 0; - while (*buffer) { - *temp_ptr = *buffer; + /* irq_no_flags() descriptor can be used */ - temp_ptr += 1; - buffer += 1; - index += 1; - } - - /* Add the terminating null */ - - *temp_ptr = 0; - output_struct->data.extended_irq.resource_source.string_length = - index + 1; - - /* - * In order for the struct_size to fall on a 32-bit boundary, - * calculate the length of the string and expand the - * struct_size to the next 32-bit boundary. - */ - temp8 = (u8) (index + 1); - struct_size += ACPI_ROUND_UP_to_32_bITS(temp8); - } else { - output_struct->data.extended_irq.resource_source.index = 0; - output_struct->data.extended_irq.resource_source.string_length = - 0; - output_struct->data.extended_irq.resource_source.string_ptr = - NULL; - } - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_extended_irq_stream - * - * PARAMETERS: linked_list - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * acpi_rs_convert_ext_irq * ******************************************************************************/ -acpi_status -acpi_rs_extended_irq_stream(struct acpi_resource *linked_list, - u8 ** output_buffer, acpi_size * bytes_consumed) -{ - u8 *buffer = *output_buffer; - u16 *length_field; - u8 temp8 = 0; - u8 index; +struct acpi_rsconvert_info acpi_rs_convert_ext_irq[9] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_IRQ, + ACPI_RS_SIZE(struct acpi_resource_extended_irq), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_irq)}, - ACPI_FUNCTION_TRACE("rs_extended_irq_stream"); + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_IRQ, + sizeof(struct aml_resource_extended_irq), + 0}, - /* Set the Descriptor Type field */ + /* Flag bits */ - *buffer = ACPI_RDESC_TYPE_EXTENDED_XRUPT; - buffer += 1; + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.producer_consumer), + AML_OFFSET(extended_irq.flags), + 0}, - /* Save a pointer to the Length field - to be filled in later */ + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.triggering), + AML_OFFSET(extended_irq.flags), + 1}, - length_field = ACPI_CAST_PTR(u16, buffer); - buffer += 2; + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.polarity), + AML_OFFSET(extended_irq.flags), + 2}, - /* Set the Interrupt vector flags */ + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.sharable), + AML_OFFSET(extended_irq.flags), + 3}, - temp8 = (u8) (linked_list->data.extended_irq.producer_consumer & 0x01); - temp8 |= - ((linked_list->data.extended_irq.shared_exclusive & 0x01) << 3); + /* IRQ Table length (Byte4) */ - /* - * Set the Interrupt Mode - * - * The definition of an Extended IRQ changed between ACPI spec v1.0b - * and ACPI spec 2.0 (section 6.4.3.6 in both). This code does not - * implement the more restrictive definition of 1.0b - * - * - Edge/Level are defined opposite in the table vs the headers - */ - if (ACPI_EDGE_SENSITIVE == linked_list->data.extended_irq.edge_level) { - temp8 |= 0x2; - } - - /* Set the Interrupt Polarity */ + {ACPI_RSC_COUNT, ACPI_RS_OFFSET(data.extended_irq.interrupt_count), + AML_OFFSET(extended_irq.interrupt_count), + sizeof(u32)} + , - temp8 |= ((linked_list->data.extended_irq.active_high_low & 0x1) << 2); + /* Copy every IRQ in the table, each is 32 bits */ - *buffer = temp8; - buffer += 1; + {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.extended_irq.interrupts[0]), + AML_OFFSET(extended_irq.interrupts[0]), + 0} + , - /* Set the Interrupt table length */ + /* Optional resource_source (Index and String) */ - temp8 = (u8) linked_list->data.extended_irq.number_of_interrupts; + {ACPI_RSC_SOURCEX, ACPI_RS_OFFSET(data.extended_irq.resource_source), + ACPI_RS_OFFSET(data.extended_irq.interrupts[0]), + sizeof(struct aml_resource_extended_irq)} +}; - *buffer = temp8; - buffer += 1; - - for (index = 0; - index < linked_list->data.extended_irq.number_of_interrupts; - index++) { - ACPI_MOVE_32_TO_32(buffer, - &linked_list->data.extended_irq. - interrupts[index]); - buffer += 4; - } +/******************************************************************************* + * + * acpi_rs_convert_dma + * + ******************************************************************************/ - /* Resource Source Index and Resource Source are optional */ +struct acpi_rsconvert_info acpi_rs_convert_dma[6] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_DMA, + ACPI_RS_SIZE(struct acpi_resource_dma), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_dma)}, - if (0 != linked_list->data.extended_irq.resource_source.string_length) { - *buffer = - (u8) linked_list->data.extended_irq.resource_source.index; - buffer += 1; + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_DMA, + sizeof(struct aml_resource_dma), + 0}, - /* Copy the string */ + /* Flags: transfer preference, bus mastering, channel speed */ - ACPI_STRCPY((char *)buffer, - linked_list->data.extended_irq.resource_source. - string_ptr); + {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.dma.transfer), + AML_OFFSET(dma.flags), + 0}, - /* - * Buffer needs to be set to the length of the string + one for the - * terminating null - */ - buffer += - (acpi_size) (ACPI_STRLEN - (linked_list->data.extended_irq. - resource_source.string_ptr) + 1); - } + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.dma.bus_master), + AML_OFFSET(dma.flags), + 2}, - /* Return the number of bytes consumed in this operation */ + {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.dma.type), + AML_OFFSET(dma.flags), + 5}, - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); + /* DMA channel mask bits */ - /* - * Set the length field to the number of bytes consumed - * minus the header size (3 bytes) - */ - *length_field = (u16) (*bytes_consumed - 3); - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_BITMASK, ACPI_RS_OFFSET(data.dma.channels[0]), + AML_OFFSET(dma.dma_channel_mask), + ACPI_RS_OFFSET(data.dma.channel_count)} +}; diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index 103eb31c284e..1434e786477e 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,52 +49,12 @@ ACPI_MODULE_NAME("rslist") /******************************************************************************* * - * FUNCTION: acpi_rs_get_resource_type + * FUNCTION: acpi_rs_convert_aml_to_resources * - * PARAMETERS: resource_start_byte - Byte 0 of a resource descriptor - * - * RETURN: The Resource Type with no extraneous bits - * - * DESCRIPTION: Extract the Resource Type/Name from the first byte of - * a resource descriptor. - * - ******************************************************************************/ -u8 acpi_rs_get_resource_type(u8 resource_start_byte) -{ - - ACPI_FUNCTION_ENTRY(); - - /* Determine if this is a small or large resource */ - - switch (resource_start_byte & ACPI_RDESC_TYPE_MASK) { - case ACPI_RDESC_TYPE_SMALL: - - /* Small Resource Type -- Only bits 6:3 are valid */ - - return ((u8) (resource_start_byte & ACPI_RDESC_SMALL_MASK)); - - case ACPI_RDESC_TYPE_LARGE: - - /* Large Resource Type -- All bits are valid */ - - return (resource_start_byte); - - default: - /* Invalid type */ - break; - } - - return (0xFF); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_byte_stream_to_list - * - * PARAMETERS: byte_stream_buffer - Pointer to the resource byte stream - * byte_stream_buffer_length - Length of byte_stream_buffer - * output_buffer - Pointer to the buffer that will - * contain the output structures + * PARAMETERS: Aml - Pointer to the resource byte stream + * aml_length - Length of Aml + * output_buffer - Pointer to the buffer that will + * contain the output structures * * RETURN: Status * @@ -102,241 +62,78 @@ u8 acpi_rs_get_resource_type(u8 resource_start_byte) * linked list of resources in the caller's output buffer * ******************************************************************************/ - acpi_status -acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer, - u32 byte_stream_buffer_length, u8 * output_buffer) +acpi_rs_convert_aml_to_resources(u8 * aml, u32 aml_length, u8 * output_buffer) { + struct acpi_resource *resource = (void *)output_buffer; acpi_status status; - acpi_size bytes_parsed = 0; - u8 resource_type = 0; - acpi_size bytes_consumed = 0; - u8 *buffer = output_buffer; - acpi_size structure_size = 0; - u8 end_tag_processed = FALSE; - struct acpi_resource *resource; - - ACPI_FUNCTION_TRACE("rs_byte_stream_to_list"); - - while (bytes_parsed < byte_stream_buffer_length && !end_tag_processed) { - /* The next byte in the stream is the resource type */ - - resource_type = acpi_rs_get_resource_type(*byte_stream_buffer); - - switch (resource_type) { - case ACPI_RDESC_TYPE_MEMORY_24: - /* - * 24-Bit Memory Resource - */ - status = acpi_rs_memory24_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_LARGE_VENDOR: - /* - * Vendor Defined Resource - */ - status = acpi_rs_vendor_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_MEMORY_32: - /* - * 32-Bit Memory Range Resource - */ - status = - acpi_rs_memory32_range_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_FIXED_MEMORY_32: - /* - * 32-Bit Fixed Memory Resource - */ - status = - acpi_rs_fixed_memory32_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE: - case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE: - /* - * 64-Bit Address Resource - */ - status = acpi_rs_address64_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE: - /* - * 32-Bit Address Resource - */ - status = acpi_rs_address32_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE: - /* - * 16-Bit Address Resource - */ - status = acpi_rs_address16_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_EXTENDED_XRUPT: - /* - * Extended IRQ - */ - status = - acpi_rs_extended_irq_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_IRQ_FORMAT: - /* - * IRQ Resource - */ - status = acpi_rs_irq_resource(byte_stream_buffer, - &bytes_consumed, &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_DMA_FORMAT: - /* - * DMA Resource - */ - status = acpi_rs_dma_resource(byte_stream_buffer, - &bytes_consumed, &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_START_DEPENDENT: - /* - * Start Dependent Functions Resource - */ - status = - acpi_rs_start_depend_fns_resource - (byte_stream_buffer, &bytes_consumed, &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_END_DEPENDENT: - /* - * End Dependent Functions Resource - */ - status = - acpi_rs_end_depend_fns_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_IO_PORT: - /* - * IO Port Resource - */ - status = acpi_rs_io_resource(byte_stream_buffer, - &bytes_consumed, &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_FIXED_IO_PORT: - /* - * Fixed IO Port Resource - */ - status = acpi_rs_fixed_io_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_SMALL_VENDOR: - /* - * Vendor Specific Resource - */ - status = acpi_rs_vendor_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_END_TAG: - /* - * End Tag - */ - end_tag_processed = TRUE; - status = acpi_rs_end_tag_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - default: - /* - * Invalid/Unknown resource type - */ - status = AE_AML_INVALID_RESOURCE_TYPE; - break; - } + u8 resource_index; + u8 *end_aml; + + ACPI_FUNCTION_TRACE("rs_convert_aml_to_resources"); + end_aml = aml + aml_length; + + /* Loop until end-of-buffer or an end_tag is found */ + + while (aml < end_aml) { + /* Validate the Resource Type and Resource Length */ + + status = acpi_ut_validate_resource(aml, &resource_index); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - /* Update the return value and counter */ + /* Convert the AML byte stream resource to a local resource struct */ - bytes_parsed += bytes_consumed; + status = + acpi_rs_convert_aml_to_resource(resource, + ACPI_CAST_PTR(union + aml_resource, + aml), + acpi_gbl_get_resource_dispatch + [resource_index]); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Could not convert AML resource (Type %X)", + *aml)); + return_ACPI_STATUS(status); + } - /* Set the byte stream to point to the next resource */ + /* Normal exit on completion of an end_tag resource descriptor */ - byte_stream_buffer += bytes_consumed; + if (acpi_ut_get_resource_type(aml) == + ACPI_RESOURCE_NAME_END_TAG) { + return_ACPI_STATUS(AE_OK); + } - /* Set the Buffer to the next structure */ + /* Point to the next input AML resource */ - resource = ACPI_CAST_PTR(struct acpi_resource, buffer); - resource->length = - (u32) ACPI_ALIGN_RESOURCE_SIZE(resource->length); - buffer += ACPI_ALIGN_RESOURCE_SIZE(structure_size); - } + aml += acpi_ut_get_descriptor_length(aml); - /* Check the reason for exiting the while loop */ + /* Point to the next structure in the output buffer */ - if (!end_tag_processed) { - return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); + resource = + ACPI_ADD_PTR(struct acpi_resource, resource, + resource->length); } - return_ACPI_STATUS(AE_OK); + /* Did not find an end_tag resource descriptor */ + + return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); } /******************************************************************************* * - * FUNCTION: acpi_rs_list_to_byte_stream + * FUNCTION: acpi_rs_convert_resources_to_aml * - * PARAMETERS: linked_list - Pointer to the resource linked list - * byte_steam_size_needed - Calculated size of the byte stream - * needed from calling - * acpi_rs_get_byte_stream_length() - * The size of the output_buffer is - * guaranteed to be >= - * byte_stream_size_needed - * output_buffer - Pointer to the buffer that will - * contain the byte stream + * PARAMETERS: Resource - Pointer to the resource linked list + * aml_size_needed - Calculated size of the byte stream + * needed from calling acpi_rs_get_aml_length() + * The size of the output_buffer is + * guaranteed to be >= aml_size_needed + * output_buffer - Pointer to the buffer that will + * contain the byte stream * * RETURN: Status * @@ -346,180 +143,73 @@ acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer, ******************************************************************************/ acpi_status -acpi_rs_list_to_byte_stream(struct acpi_resource *linked_list, - acpi_size byte_stream_size_needed, - u8 * output_buffer) +acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, + acpi_size aml_size_needed, u8 * output_buffer) { + u8 *aml = output_buffer; + u8 *end_aml = output_buffer + aml_size_needed; acpi_status status; - u8 *buffer = output_buffer; - acpi_size bytes_consumed = 0; - u8 done = FALSE; - - ACPI_FUNCTION_TRACE("rs_list_to_byte_stream"); - - while (!done) { - switch (linked_list->id) { - case ACPI_RSTYPE_IRQ: - /* - * IRQ Resource - */ - status = - acpi_rs_irq_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_DMA: - /* - * DMA Resource - */ - status = - acpi_rs_dma_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_START_DPF: - /* - * Start Dependent Functions Resource - */ - status = acpi_rs_start_depend_fns_stream(linked_list, - &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_END_DPF: - /* - * End Dependent Functions Resource - */ - status = acpi_rs_end_depend_fns_stream(linked_list, - &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_IO: - /* - * IO Port Resource - */ - status = - acpi_rs_io_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_FIXED_IO: - /* - * Fixed IO Port Resource - */ - status = - acpi_rs_fixed_io_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_VENDOR: - /* - * Vendor Defined Resource - */ - status = - acpi_rs_vendor_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_END_TAG: - /* - * End Tag - */ - status = - acpi_rs_end_tag_stream(linked_list, &buffer, - &bytes_consumed); - - /* An End Tag indicates the end of the Resource Template */ - - done = TRUE; - break; - - case ACPI_RSTYPE_MEM24: - /* - * 24-Bit Memory Resource - */ - status = - acpi_rs_memory24_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_MEM32: - /* - * 32-Bit Memory Range Resource - */ - status = - acpi_rs_memory32_range_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_FIXED_MEM32: - /* - * 32-Bit Fixed Memory Resource - */ - status = - acpi_rs_fixed_memory32_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_ADDRESS16: - /* - * 16-Bit Address Descriptor Resource - */ - status = acpi_rs_address16_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_ADDRESS32: - /* - * 32-Bit Address Descriptor Resource - */ - status = acpi_rs_address32_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_ADDRESS64: - /* - * 64-Bit Address Descriptor Resource - */ - status = acpi_rs_address64_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_EXT_IRQ: - /* - * Extended IRQ Resource - */ - status = - acpi_rs_extended_irq_stream(linked_list, &buffer, - &bytes_consumed); - break; - - default: - /* - * If we get here, everything is out of sync, - * so exit with an error - */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid descriptor type (%X) in resource list\n", - linked_list->id)); - status = AE_BAD_DATA; - break; + + ACPI_FUNCTION_TRACE("rs_convert_resources_to_aml"); + + /* Walk the resource descriptor list, convert each descriptor */ + + while (aml < end_aml) { + /* Validate the (internal) Resource Type */ + + if (resource->type > ACPI_RESOURCE_TYPE_MAX) { + ACPI_ERROR((AE_INFO, + "Invalid descriptor type (%X) in resource list", + resource->type)); + return_ACPI_STATUS(AE_BAD_DATA); } + /* Perform the conversion */ + + status = acpi_rs_convert_resource_to_aml(resource, + ACPI_CAST_PTR(union + aml_resource, + aml), + acpi_gbl_set_resource_dispatch + [resource->type]); if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Could not convert resource (type %X) to AML", + resource->type)); return_ACPI_STATUS(status); } - /* Set the Buffer to point to the open byte */ + /* Perform final sanity check on the new AML resource descriptor */ + + status = + acpi_ut_validate_resource(ACPI_CAST_PTR + (union aml_resource, aml), NULL); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } - buffer += bytes_consumed; + /* Check for end-of-list, normal exit */ - /* Point to the next object */ + if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { + /* An End Tag indicates the end of the input Resource Template */ - linked_list = ACPI_PTR_ADD(struct acpi_resource, - linked_list, linked_list->length); + return_ACPI_STATUS(AE_OK); + } + + /* + * Extract the total length of the new descriptor and set the + * Aml to point to the next (output) resource descriptor + */ + aml += acpi_ut_get_descriptor_length(aml); + + /* Point to the next input resource descriptor */ + + resource = + ACPI_ADD_PTR(struct acpi_resource, resource, + resource->length); } - return_ACPI_STATUS(AE_OK); + /* Completed buffer, but did not find an end_tag resource descriptor */ + + return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); } diff --git a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c index daba1a1ed46d..a5131936d690 100644 --- a/drivers/acpi/resources/rsmemory.c +++ b/drivers/acpi/resources/rsmemory.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,454 +49,187 @@ ACPI_MODULE_NAME("rsmemory") /******************************************************************************* * - * FUNCTION: acpi_rs_memory24_resource - * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * acpi_rs_convert_memory24 * ******************************************************************************/ -acpi_status -acpi_rs_memory24_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) -{ - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem24); - - ACPI_FUNCTION_TRACE("rs_memory24_resource"); - - /* Point past the Descriptor to get the number of bytes consumed */ - - buffer += 1; - - ACPI_MOVE_16_TO_16(&temp16, buffer); - buffer += 2; - *bytes_consumed = (acpi_size) temp16 + 3; - output_struct->id = ACPI_RSTYPE_MEM24; - - /* Check Byte 3 the Read/Write bit */ - - temp8 = *buffer; - buffer += 1; - output_struct->data.memory24.read_write_attribute = temp8 & 0x01; - - /* Get min_base_address (Bytes 4-5) */ - - ACPI_MOVE_16_TO_16(&temp16, buffer); - buffer += 2; - output_struct->data.memory24.min_base_address = temp16; - - /* Get max_base_address (Bytes 6-7) */ - - ACPI_MOVE_16_TO_16(&temp16, buffer); - buffer += 2; - output_struct->data.memory24.max_base_address = temp16; +struct acpi_rsconvert_info acpi_rs_convert_memory24[4] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_MEMORY24, + ACPI_RS_SIZE(struct acpi_resource_memory24), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_memory24)}, - /* Get Alignment (Bytes 8-9) */ + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_MEMORY24, + sizeof(struct aml_resource_memory24), + 0}, - ACPI_MOVE_16_TO_16(&temp16, buffer); - buffer += 2; - output_struct->data.memory24.alignment = temp16; + /* Read/Write bit */ - /* Get range_length (Bytes 10-11) */ - - ACPI_MOVE_16_TO_16(&temp16, buffer); - output_struct->data.memory24.range_length = temp16; - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.memory24.write_protect), + AML_OFFSET(memory24.flags), + 0}, + /* + * These fields are contiguous in both the source and destination: + * Minimum Base Address + * Maximum Base Address + * Address Base Alignment + * Range Length + */ + {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.memory24.minimum), + AML_OFFSET(memory24.minimum), + 4} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_memory24_stream - * - * PARAMETERS: linked_list - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * acpi_rs_convert_memory32 * ******************************************************************************/ -acpi_status -acpi_rs_memory24_stream(struct acpi_resource *linked_list, - u8 ** output_buffer, acpi_size * bytes_consumed) -{ - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - - ACPI_FUNCTION_TRACE("rs_memory24_stream"); - - /* The descriptor field is static */ - - *buffer = 0x81; - buffer += 1; +struct acpi_rsconvert_info acpi_rs_convert_memory32[4] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_MEMORY32, + ACPI_RS_SIZE(struct acpi_resource_memory32), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_memory32)}, - /* The length field is static */ + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_MEMORY32, + sizeof(struct aml_resource_memory32), + 0}, - temp16 = 0x09; - ACPI_MOVE_16_TO_16(buffer, &temp16); - buffer += 2; + /* Read/Write bit */ - /* Set the Information Byte */ - - temp8 = (u8) (linked_list->data.memory24.read_write_attribute & 0x01); - *buffer = temp8; - buffer += 1; - - /* Set the Range minimum base address */ - - ACPI_MOVE_32_TO_16(buffer, - &linked_list->data.memory24.min_base_address); - buffer += 2; - - /* Set the Range maximum base address */ - - ACPI_MOVE_32_TO_16(buffer, - &linked_list->data.memory24.max_base_address); - buffer += 2; - - /* Set the base alignment */ - - ACPI_MOVE_32_TO_16(buffer, &linked_list->data.memory24.alignment); - buffer += 2; - - /* Set the range length */ - - ACPI_MOVE_32_TO_16(buffer, &linked_list->data.memory24.range_length); - buffer += 2; - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.memory32.write_protect), + AML_OFFSET(memory32.flags), + 0}, + /* + * These fields are contiguous in both the source and destination: + * Minimum Base Address + * Maximum Base Address + * Address Base Alignment + * Range Length + */ + {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.memory32.minimum), + AML_OFFSET(memory32.minimum), + 4} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_memory32_range_resource - * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * acpi_rs_convert_fixed_memory32 * ******************************************************************************/ -acpi_status -acpi_rs_memory32_range_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) -{ - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem32); - - ACPI_FUNCTION_TRACE("rs_memory32_range_resource"); - - /* Point past the Descriptor to get the number of bytes consumed */ - - buffer += 1; +struct acpi_rsconvert_info acpi_rs_convert_fixed_memory32[4] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_FIXED_MEMORY32, + ACPI_RS_SIZE(struct acpi_resource_fixed_memory32), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_fixed_memory32)}, - ACPI_MOVE_16_TO_16(&temp16, buffer); - buffer += 2; - *bytes_consumed = (acpi_size) temp16 + 3; + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_FIXED_MEMORY32, + sizeof(struct aml_resource_fixed_memory32), + 0}, - output_struct->id = ACPI_RSTYPE_MEM32; + /* Read/Write bit */ + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.fixed_memory32.write_protect), + AML_OFFSET(fixed_memory32.flags), + 0}, /* - * Point to the place in the output buffer where the data portion will - * begin. - * 1. Set the RESOURCE_DATA * Data to point to its own address, then - * 2. Set the pointer to the next address. - * - * NOTE: output_struct->Data is cast to u8, otherwise, this addition adds - * 4 * sizeof(RESOURCE_DATA) instead of 4 * sizeof(u8) + * These fields are contiguous in both the source and destination: + * Base Address + * Range Length */ - - /* Check Byte 3 the Read/Write bit */ - - temp8 = *buffer; - buffer += 1; - - output_struct->data.memory32.read_write_attribute = temp8 & 0x01; - - /* Get min_base_address (Bytes 4-7) */ - - ACPI_MOVE_32_TO_32(&output_struct->data.memory32.min_base_address, - buffer); - buffer += 4; - - /* Get max_base_address (Bytes 8-11) */ - - ACPI_MOVE_32_TO_32(&output_struct->data.memory32.max_base_address, - buffer); - buffer += 4; - - /* Get Alignment (Bytes 12-15) */ - - ACPI_MOVE_32_TO_32(&output_struct->data.memory32.alignment, buffer); - buffer += 4; - - /* Get range_length (Bytes 16-19) */ - - ACPI_MOVE_32_TO_32(&output_struct->data.memory32.range_length, buffer); - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.fixed_memory32.address), + AML_OFFSET(fixed_memory32.address), + 2} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_fixed_memory32_resource - * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * acpi_rs_get_vendor_small * ******************************************************************************/ -acpi_status -acpi_rs_fixed_memory32_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) -{ - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_mem32); - - ACPI_FUNCTION_TRACE("rs_fixed_memory32_resource"); +struct acpi_rsconvert_info acpi_rs_get_vendor_small[3] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_VENDOR, + ACPI_RS_SIZE(struct acpi_resource_vendor), + ACPI_RSC_TABLE_SIZE(acpi_rs_get_vendor_small)}, - /* Point past the Descriptor to get the number of bytes consumed */ + /* Length of the vendor data (byte count) */ - buffer += 1; - ACPI_MOVE_16_TO_16(&temp16, buffer); + {ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length), + 0, + sizeof(u8)} + , - buffer += 2; - *bytes_consumed = (acpi_size) temp16 + 3; + /* Vendor data */ - output_struct->id = ACPI_RSTYPE_FIXED_MEM32; - - /* Check Byte 3 the Read/Write bit */ - - temp8 = *buffer; - buffer += 1; - output_struct->data.fixed_memory32.read_write_attribute = temp8 & 0x01; - - /* Get range_base_address (Bytes 4-7) */ - - ACPI_MOVE_32_TO_32(&output_struct->data.fixed_memory32. - range_base_address, buffer); - buffer += 4; - - /* Get range_length (Bytes 8-11) */ - - ACPI_MOVE_32_TO_32(&output_struct->data.fixed_memory32.range_length, - buffer); - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.vendor.byte_data[0]), + sizeof(struct aml_resource_small_header), + 0} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_memory32_range_stream - * - * PARAMETERS: linked_list - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * acpi_rs_get_vendor_large * ******************************************************************************/ -acpi_status -acpi_rs_memory32_range_stream(struct acpi_resource *linked_list, - u8 ** output_buffer, acpi_size * bytes_consumed) -{ - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - - ACPI_FUNCTION_TRACE("rs_memory32_range_stream"); - - /* The descriptor field is static */ - - *buffer = 0x85; - buffer += 1; - - /* The length field is static */ - - temp16 = 0x11; - - ACPI_MOVE_16_TO_16(buffer, &temp16); - buffer += 2; - - /* Set the Information Byte */ - - temp8 = (u8) (linked_list->data.memory32.read_write_attribute & 0x01); - *buffer = temp8; - buffer += 1; - - /* Set the Range minimum base address */ - - ACPI_MOVE_32_TO_32(buffer, - &linked_list->data.memory32.min_base_address); - buffer += 4; - - /* Set the Range maximum base address */ - - ACPI_MOVE_32_TO_32(buffer, - &linked_list->data.memory32.max_base_address); - buffer += 4; +struct acpi_rsconvert_info acpi_rs_get_vendor_large[3] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_VENDOR, + ACPI_RS_SIZE(struct acpi_resource_vendor), + ACPI_RSC_TABLE_SIZE(acpi_rs_get_vendor_large)}, - /* Set the base alignment */ + /* Length of the vendor data (byte count) */ - ACPI_MOVE_32_TO_32(buffer, &linked_list->data.memory32.alignment); - buffer += 4; + {ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length), + 0, + sizeof(u8)} + , - /* Set the range length */ + /* Vendor data */ - ACPI_MOVE_32_TO_32(buffer, &linked_list->data.memory32.range_length); - buffer += 4; - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.vendor.byte_data[0]), + sizeof(struct aml_resource_large_header), + 0} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_fixed_memory32_stream - * - * PARAMETERS: linked_list - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * acpi_rs_set_vendor * ******************************************************************************/ -acpi_status -acpi_rs_fixed_memory32_stream(struct acpi_resource *linked_list, - u8 ** output_buffer, acpi_size * bytes_consumed) -{ - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - - ACPI_FUNCTION_TRACE("rs_fixed_memory32_stream"); +struct acpi_rsconvert_info acpi_rs_set_vendor[7] = { + /* Default is a small vendor descriptor */ - /* The descriptor field is static */ + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_VENDOR_SMALL, + sizeof(struct aml_resource_small_header), + ACPI_RSC_TABLE_SIZE(acpi_rs_set_vendor)}, - *buffer = 0x86; - buffer += 1; + /* Get the length and copy the data */ - /* The length field is static */ + {ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length), + 0, + 0}, - temp16 = 0x09; + {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.vendor.byte_data[0]), + sizeof(struct aml_resource_small_header), + 0}, - ACPI_MOVE_16_TO_16(buffer, &temp16); - buffer += 2; - - /* Set the Information Byte */ - - temp8 = - (u8) (linked_list->data.fixed_memory32.read_write_attribute & 0x01); - *buffer = temp8; - buffer += 1; - - /* Set the Range base address */ - - ACPI_MOVE_32_TO_32(buffer, - &linked_list->data.fixed_memory32. - range_base_address); - buffer += 4; + /* + * All done if the Vendor byte length is 7 or less, meaning that it will + * fit within a small descriptor + */ + {ACPI_RSC_EXIT_LE, 0, 0, 7}, - /* Set the range length */ + /* Must create a large vendor descriptor */ - ACPI_MOVE_32_TO_32(buffer, - &linked_list->data.fixed_memory32.range_length); - buffer += 4; + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_VENDOR_LARGE, + sizeof(struct aml_resource_large_header), + 0}, - /* Return the number of bytes consumed in this operation */ + {ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length), + 0, + 0}, - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.vendor.byte_data[0]), + sizeof(struct aml_resource_large_header), + 0} +}; diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c index 7a8a34e757f5..ed866cf1c6d2 100644 --- a/drivers/acpi/resources/rsmisc.c +++ b/drivers/acpi/resources/rsmisc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,481 +47,501 @@ #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rsmisc") +#define INIT_RESOURCE_TYPE(i) i->resource_offset +#define INIT_RESOURCE_LENGTH(i) i->aml_offset +#define INIT_TABLE_LENGTH(i) i->value +#define COMPARE_OPCODE(i) i->resource_offset +#define COMPARE_TARGET(i) i->aml_offset +#define COMPARE_VALUE(i) i->value /******************************************************************************* * - * FUNCTION: acpi_rs_end_tag_resource + * FUNCTION: acpi_rs_convert_aml_to_resource * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned + * PARAMETERS: Resource - Pointer to the resource descriptor + * Aml - Where the AML descriptor is returned + * Info - Pointer to appropriate conversion table * * RETURN: Status * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * DESCRIPTION: Convert an external AML resource descriptor to the corresponding + * internal resource descriptor * ******************************************************************************/ acpi_status -acpi_rs_end_tag_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) +acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, + union aml_resource *aml, + struct acpi_rsconvert_info *info) { - struct acpi_resource *output_struct = (void *)*output_buffer; - acpi_size struct_size = ACPI_RESOURCE_LENGTH; - - ACPI_FUNCTION_TRACE("rs_end_tag_resource"); - - /* The number of bytes consumed is static */ - - *bytes_consumed = 2; - - /* Fill out the structure */ - - output_struct->id = ACPI_RSTYPE_END_TAG; - - /* Set the Length parameter */ - - output_struct->length = 0; - - /* Return the final size of the structure */ - - *structure_size = struct_size; - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_end_tag_stream - * - * PARAMETERS: linked_list - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream - * - ******************************************************************************/ - -acpi_status -acpi_rs_end_tag_stream(struct acpi_resource *linked_list, - u8 ** output_buffer, acpi_size * bytes_consumed) -{ - u8 *buffer = *output_buffer; - u8 temp8 = 0; - - ACPI_FUNCTION_TRACE("rs_end_tag_stream"); - - /* The descriptor field is static */ - - *buffer = 0x79; - buffer += 1; - - /* - * Set the Checksum - zero means that the resource data is treated as if - * the checksum operation succeeded (ACPI Spec 1.0b Section 6.4.2.8) - */ - temp8 = 0; - - *buffer = temp8; - buffer += 1; - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_vendor_resource - * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. - * - ******************************************************************************/ - -acpi_status -acpi_rs_vendor_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) -{ - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; + acpi_rs_length aml_resource_length; + void *source; + void *destination; + char *target; + u8 count; + u8 flags_mode = FALSE; + u16 item_count = 0; u16 temp16 = 0; - u8 temp8 = 0; - u8 index; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor); - - ACPI_FUNCTION_TRACE("rs_vendor_resource"); - - /* Dereference the Descriptor to find if this is a large or small item. */ - - temp8 = *buffer; - - if (temp8 & 0x80) { - /* Large Item, point to the length field */ - - buffer += 1; - /* Dereference */ + ACPI_FUNCTION_TRACE("rs_get_resource"); - ACPI_MOVE_16_TO_16(&temp16, buffer); + if (((acpi_native_uint) resource) & 0x3) { + /* Each internal resource struct is expected to be 32-bit aligned */ - /* Calculate bytes consumed */ - - *bytes_consumed = (acpi_size) temp16 + 3; - - /* Point to the first vendor byte */ - - buffer += 2; - } else { - /* Small Item, dereference the size */ - - temp16 = (u8) (*buffer & 0x07); - - /* Calculate bytes consumed */ - - *bytes_consumed = (acpi_size) temp16 + 1; - - /* Point to the first vendor byte */ - - buffer += 1; + ACPI_WARNING((AE_INFO, + "Misaligned resource pointer (get): %p Type %2.2X Len %X", + resource, resource->type, resource->length)); } - output_struct->id = ACPI_RSTYPE_VENDOR; - output_struct->data.vendor_specific.length = temp16; + /* Extract the resource Length field (does not include header length) */ - for (index = 0; index < temp16; index++) { - output_struct->data.vendor_specific.reserved[index] = *buffer; - buffer += 1; - } + aml_resource_length = acpi_ut_get_resource_length(aml); /* - * In order for the struct_size to fall on a 32-bit boundary, - * calculate the length of the vendor string and expand the - * struct_size to the next 32-bit boundary. + * First table entry must be ACPI_RSC_INITxxx and must contain the + * table length (# of table entries) */ - struct_size += ACPI_ROUND_UP_to_32_bITS(temp16); - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_vendor_stream - * - * PARAMETERS: linked_list - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream - * - ******************************************************************************/ - -acpi_status -acpi_rs_vendor_stream(struct acpi_resource *linked_list, - u8 ** output_buffer, acpi_size * bytes_consumed) -{ - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - u8 index; - - ACPI_FUNCTION_TRACE("rs_vendor_stream"); - - /* Dereference the length to find if this is a large or small item. */ - - if (linked_list->data.vendor_specific.length > 7) { - /* Large Item, Set the descriptor field and length bytes */ - - *buffer = 0x84; - buffer += 1; - - temp16 = (u16) linked_list->data.vendor_specific.length; - - ACPI_MOVE_16_TO_16(buffer, &temp16); - buffer += 2; - } else { - /* Small Item, Set the descriptor field */ - - temp8 = 0x70; - temp8 |= (u8) linked_list->data.vendor_specific.length; + count = INIT_TABLE_LENGTH(info); + + while (count) { + /* + * Source is the external AML byte stream buffer, + * destination is the internal resource descriptor + */ + source = ACPI_ADD_PTR(void, aml, info->aml_offset); + destination = + ACPI_ADD_PTR(void, resource, info->resource_offset); + + switch (info->opcode) { + case ACPI_RSC_INITGET: + /* + * Get the resource type and the initial (minimum) length + */ + ACPI_MEMSET(resource, 0, INIT_RESOURCE_LENGTH(info)); + resource->type = INIT_RESOURCE_TYPE(info); + resource->length = INIT_RESOURCE_LENGTH(info); + break; + + case ACPI_RSC_INITSET: + break; + + case ACPI_RSC_FLAGINIT: + + flags_mode = TRUE; + break; + + case ACPI_RSC_1BITFLAG: + /* + * Mask and shift the flag bit + */ + ACPI_SET8(destination) = (u8) + ((ACPI_GET8(source) >> info->value) & 0x01); + break; + + case ACPI_RSC_2BITFLAG: + /* + * Mask and shift the flag bits + */ + ACPI_SET8(destination) = (u8) + ((ACPI_GET8(source) >> info->value) & 0x03); + break; + + case ACPI_RSC_COUNT: + + item_count = ACPI_GET8(source); + ACPI_SET8(destination) = (u8) item_count; + + resource->length = resource->length + + (info->value * (item_count - 1)); + break; + + case ACPI_RSC_COUNT16: + + item_count = aml_resource_length; + ACPI_SET16(destination) = item_count; + + resource->length = resource->length + + (info->value * (item_count - 1)); + break; + + case ACPI_RSC_LENGTH: + + resource->length = resource->length + info->value; + break; + + case ACPI_RSC_MOVE8: + case ACPI_RSC_MOVE16: + case ACPI_RSC_MOVE32: + case ACPI_RSC_MOVE64: + /* + * Raw data move. Use the Info value field unless item_count has + * been previously initialized via a COUNT opcode + */ + if (info->value) { + item_count = info->value; + } + acpi_rs_move_data(destination, source, item_count, + info->opcode); + break; + + case ACPI_RSC_SET8: + + ACPI_MEMSET(destination, info->aml_offset, info->value); + break; + + case ACPI_RSC_DATA8: + + target = ACPI_ADD_PTR(char, resource, info->value); + ACPI_MEMCPY(destination, source, ACPI_GET16(target)); + break; + + case ACPI_RSC_ADDRESS: + /* + * Common handler for address descriptor flags + */ + if (!acpi_rs_get_address_common(resource, aml)) { + return_ACPI_STATUS + (AE_AML_INVALID_RESOURCE_TYPE); + } + break; + + case ACPI_RSC_SOURCE: + /* + * Optional resource_source (Index and String) + */ + resource->length += + acpi_rs_get_resource_source(aml_resource_length, + info->value, + destination, aml, NULL); + break; + + case ACPI_RSC_SOURCEX: + /* + * Optional resource_source (Index and String). This is the more + * complicated case used by the Interrupt() macro + */ + target = + ACPI_ADD_PTR(char, resource, + info->aml_offset + (item_count * 4)); + + resource->length += + acpi_rs_get_resource_source(aml_resource_length, + (acpi_rs_length) (((item_count - 1) * sizeof(u32)) + info->value), destination, aml, target); + break; + + case ACPI_RSC_BITMASK: + /* + * 8-bit encoded bitmask (DMA macro) + */ + item_count = + acpi_rs_decode_bitmask(ACPI_GET8(source), + destination); + if (item_count) { + resource->length += (item_count - 1); + } + + target = ACPI_ADD_PTR(char, resource, info->value); + ACPI_SET8(target) = (u8) item_count; + break; + + case ACPI_RSC_BITMASK16: + /* + * 16-bit encoded bitmask (IRQ macro) + */ + ACPI_MOVE_16_TO_16(&temp16, source); + + item_count = + acpi_rs_decode_bitmask(temp16, destination); + if (item_count) { + resource->length += (item_count - 1); + } + + target = ACPI_ADD_PTR(char, resource, info->value); + ACPI_SET8(target) = (u8) item_count; + break; + + case ACPI_RSC_EXIT_NE: + /* + * Control - Exit conversion if not equal + */ + switch (info->resource_offset) { + case ACPI_RSC_COMPARE_AML_LENGTH: + if (aml_resource_length != info->value) { + goto exit; + } + break; + + case ACPI_RSC_COMPARE_VALUE: + if (ACPI_GET8(source) != info->value) { + goto exit; + } + break; + + default: + + ACPI_ERROR((AE_INFO, + "Invalid conversion sub-opcode")); + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + break; + + default: + + ACPI_ERROR((AE_INFO, "Invalid conversion opcode")); + return_ACPI_STATUS(AE_BAD_PARAMETER); + } - *buffer = temp8; - buffer += 1; + count--; + info++; } - /* Loop through all of the Vendor Specific fields */ + exit: + if (!flags_mode) { + /* Round the resource struct length up to the next 32-bit boundary */ - for (index = 0; index < linked_list->data.vendor_specific.length; - index++) { - temp8 = linked_list->data.vendor_specific.reserved[index]; - - *buffer = temp8; - buffer += 1; + resource->length = ACPI_ROUND_UP_to_32_bITS(resource->length); } - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_rs_start_depend_fns_resource + * FUNCTION: acpi_rs_convert_resource_to_aml * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned + * PARAMETERS: Resource - Pointer to the resource descriptor + * Aml - Where the AML descriptor is returned + * Info - Pointer to appropriate conversion table * * RETURN: Status * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * DESCRIPTION: Convert an internal resource descriptor to the corresponding + * external AML resource descriptor. * ******************************************************************************/ acpi_status -acpi_rs_start_depend_fns_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, - acpi_size * structure_size) +acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, + union aml_resource *aml, + struct acpi_rsconvert_info *info) { - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - u8 temp8 = 0; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_start_dpf); - - ACPI_FUNCTION_TRACE("rs_start_depend_fns_resource"); - - /* The number of bytes consumed are found in the descriptor (Bits:0-1) */ - - temp8 = *buffer; - - *bytes_consumed = (temp8 & 0x01) + 1; - - output_struct->id = ACPI_RSTYPE_START_DPF; - - /* Point to Byte 1 if it is used */ - - if (2 == *bytes_consumed) { - buffer += 1; - temp8 = *buffer; - - /* Check Compatibility priority */ - - output_struct->data.start_dpf.compatibility_priority = - temp8 & 0x03; - - if (3 == output_struct->data.start_dpf.compatibility_priority) { - return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE); - } - - /* Check Performance/Robustness preference */ + void *source = NULL; + void *destination; + acpi_rsdesc_size aml_length = 0; + u8 count; + u16 temp16 = 0; + u16 item_count = 0; - output_struct->data.start_dpf.performance_robustness = - (temp8 >> 2) & 0x03; + ACPI_FUNCTION_TRACE("rs_convert_resource_to_aml"); - if (3 == output_struct->data.start_dpf.performance_robustness) { - return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE); + /* + * First table entry must be ACPI_RSC_INITxxx and must contain the + * table length (# of table entries) + */ + count = INIT_TABLE_LENGTH(info); + + while (count) { + /* + * Source is the internal resource descriptor, + * destination is the external AML byte stream buffer + */ + source = ACPI_ADD_PTR(void, resource, info->resource_offset); + destination = ACPI_ADD_PTR(void, aml, info->aml_offset); + + switch (info->opcode) { + case ACPI_RSC_INITSET: + + ACPI_MEMSET(aml, 0, INIT_RESOURCE_LENGTH(info)); + aml_length = INIT_RESOURCE_LENGTH(info); + acpi_rs_set_resource_header(INIT_RESOURCE_TYPE(info), + aml_length, aml); + break; + + case ACPI_RSC_INITGET: + break; + + case ACPI_RSC_FLAGINIT: + /* + * Clear the flag byte + */ + ACPI_SET8(destination) = 0; + break; + + case ACPI_RSC_1BITFLAG: + /* + * Mask and shift the flag bit + */ + ACPI_SET8(destination) |= (u8) + ((ACPI_GET8(source) & 0x01) << info->value); + break; + + case ACPI_RSC_2BITFLAG: + /* + * Mask and shift the flag bits + */ + ACPI_SET8(destination) |= (u8) + ((ACPI_GET8(source) & 0x03) << info->value); + break; + + case ACPI_RSC_COUNT: + + item_count = ACPI_GET8(source); + ACPI_SET8(destination) = (u8) item_count; + + aml_length = + (u16) (aml_length + + (info->value * (item_count - 1))); + break; + + case ACPI_RSC_COUNT16: + + item_count = ACPI_GET16(source); + aml_length = (u16) (aml_length + item_count); + acpi_rs_set_resource_length(aml_length, aml); + break; + + case ACPI_RSC_LENGTH: + + acpi_rs_set_resource_length(info->value, aml); + break; + + case ACPI_RSC_MOVE8: + case ACPI_RSC_MOVE16: + case ACPI_RSC_MOVE32: + case ACPI_RSC_MOVE64: + + if (info->value) { + item_count = info->value; + } + acpi_rs_move_data(destination, source, item_count, + info->opcode); + break; + + case ACPI_RSC_ADDRESS: + + /* Set the Resource Type, General Flags, and Type-Specific Flags */ + + acpi_rs_set_address_common(aml, resource); + break; + + case ACPI_RSC_SOURCEX: + /* + * Optional resource_source (Index and String) + */ + aml_length = + acpi_rs_set_resource_source(aml, + (acpi_rs_length) + aml_length, source); + acpi_rs_set_resource_length(aml_length, aml); + break; + + case ACPI_RSC_SOURCE: + /* + * Optional resource_source (Index and String). This is the more + * complicated case used by the Interrupt() macro + */ + aml_length = + acpi_rs_set_resource_source(aml, info->value, + source); + acpi_rs_set_resource_length(aml_length, aml); + break; + + case ACPI_RSC_BITMASK: + /* + * 8-bit encoded bitmask (DMA macro) + */ + ACPI_SET8(destination) = (u8) + acpi_rs_encode_bitmask(source, + *ACPI_ADD_PTR(u8, resource, + info->value)); + break; + + case ACPI_RSC_BITMASK16: + /* + * 16-bit encoded bitmask (IRQ macro) + */ + temp16 = acpi_rs_encode_bitmask(source, + *ACPI_ADD_PTR(u8, + resource, + info-> + value)); + ACPI_MOVE_16_TO_16(destination, &temp16); + break; + + case ACPI_RSC_EXIT_LE: + /* + * Control - Exit conversion if less than or equal + */ + if (item_count <= info->value) { + goto exit; + } + break; + + case ACPI_RSC_EXIT_NE: + /* + * Control - Exit conversion if not equal + */ + switch (COMPARE_OPCODE(info)) { + case ACPI_RSC_COMPARE_VALUE: + + if (*ACPI_ADD_PTR(u8, resource, + COMPARE_TARGET(info)) != + COMPARE_VALUE(info)) { + goto exit; + } + break; + + default: + + ACPI_ERROR((AE_INFO, + "Invalid conversion sub-opcode")); + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + break; + + default: + + ACPI_ERROR((AE_INFO, "Invalid conversion opcode")); + return_ACPI_STATUS(AE_BAD_PARAMETER); } - } else { - output_struct->data.start_dpf.compatibility_priority = - ACPI_ACCEPTABLE_CONFIGURATION; - output_struct->data.start_dpf.performance_robustness = - ACPI_ACCEPTABLE_CONFIGURATION; + count--; + info++; } - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; + exit: return_ACPI_STATUS(AE_OK); } -/******************************************************************************* - * - * FUNCTION: acpi_rs_end_depend_fns_resource - * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. - * - ******************************************************************************/ - -acpi_status -acpi_rs_end_depend_fns_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) -{ - struct acpi_resource *output_struct = (void *)*output_buffer; - acpi_size struct_size = ACPI_RESOURCE_LENGTH; - - ACPI_FUNCTION_TRACE("rs_end_depend_fns_resource"); - - /* The number of bytes consumed is static */ - - *bytes_consumed = 1; +#if 0 +/* Previous resource validations */ - /* Fill out the structure */ - - output_struct->id = ACPI_RSTYPE_END_DPF; - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; - return_ACPI_STATUS(AE_OK); +if (aml->ext_address64.revision_iD != AML_RESOURCE_EXTENDED_ADDRESS_REVISION) { + return_ACPI_STATUS(AE_SUPPORT); } -/******************************************************************************* - * - * FUNCTION: acpi_rs_start_depend_fns_stream - * - * PARAMETERS: linked_list - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - u32 pointer that is filled with - * the number of bytes of the - * output_buffer used - * - * RETURN: Status - * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream - * - ******************************************************************************/ - -acpi_status -acpi_rs_start_depend_fns_stream(struct acpi_resource *linked_list, - u8 ** output_buffer, acpi_size * bytes_consumed) -{ - u8 *buffer = *output_buffer; - u8 temp8 = 0; - - ACPI_FUNCTION_TRACE("rs_start_depend_fns_stream"); +if (resource->data.start_dpf.performance_robustness >= 3) { + return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE); +} +if (((aml->irq.flags & 0x09) == 0x00) || ((aml->irq.flags & 0x09) == 0x09)) { /* - * The descriptor field is set based upon whether a byte is needed - * to contain Priority data. + * Only [active_high, edge_sensitive] or [active_low, level_sensitive] + * polarity/trigger interrupts are allowed (ACPI spec, section + * "IRQ Format"), so 0x00 and 0x09 are illegal. */ - if (ACPI_ACCEPTABLE_CONFIGURATION == - linked_list->data.start_dpf.compatibility_priority && - ACPI_ACCEPTABLE_CONFIGURATION == - linked_list->data.start_dpf.performance_robustness) { - *buffer = 0x30; - } else { - *buffer = 0x31; - buffer += 1; - - /* Set the Priority Byte Definition */ - - temp8 = 0; - temp8 = - (u8) ((linked_list->data.start_dpf. - performance_robustness & 0x03) << 2); - temp8 |= - (linked_list->data.start_dpf.compatibility_priority & 0x03); - *buffer = temp8; - } - - buffer += 1; - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); - return_ACPI_STATUS(AE_OK); + ACPI_ERROR((AE_INFO, + "Invalid interrupt polarity/trigger in resource list, %X", + aml->irq.flags)); + return_ACPI_STATUS(AE_BAD_DATA); } -/******************************************************************************* - * - * FUNCTION: acpi_rs_end_depend_fns_stream - * - * PARAMETERS: linked_list - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream - * - ******************************************************************************/ - -acpi_status -acpi_rs_end_depend_fns_stream(struct acpi_resource *linked_list, - u8 ** output_buffer, acpi_size * bytes_consumed) -{ - u8 *buffer = *output_buffer; - - ACPI_FUNCTION_TRACE("rs_end_depend_fns_stream"); - - /* The descriptor field is static */ - - *buffer = 0x38; - buffer += 1; +resource->data.extended_irq.interrupt_count = temp8; +if (temp8 < 1) { + /* Must have at least one IRQ */ - /* Return the number of bytes consumed in this operation */ + return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); +} - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); - return_ACPI_STATUS(AE_OK); +if (resource->data.dma.transfer == 0x03) { + ACPI_ERROR((AE_INFO, "Invalid DMA.Transfer preference (3)")); + return_ACPI_STATUS(AE_BAD_DATA); } +#endif diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c index 4446778eaf79..25b5aedd6612 100644 --- a/drivers/acpi/resources/rsutils.c +++ b/drivers/acpi/resources/rsutils.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,6 +50,389 @@ ACPI_MODULE_NAME("rsutils") /******************************************************************************* * + * FUNCTION: acpi_rs_decode_bitmask + * + * PARAMETERS: Mask - Bitmask to decode + * List - Where the converted list is returned + * + * RETURN: Count of bits set (length of list) + * + * DESCRIPTION: Convert a bit mask into a list of values + * + ******************************************************************************/ +u8 acpi_rs_decode_bitmask(u16 mask, u8 * list) +{ + acpi_native_uint i; + u8 bit_count; + + ACPI_FUNCTION_ENTRY(); + + /* Decode the mask bits */ + + for (i = 0, bit_count = 0; mask; i++) { + if (mask & 0x0001) { + list[bit_count] = (u8) i; + bit_count++; + } + + mask >>= 1; + } + + return (bit_count); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_encode_bitmask + * + * PARAMETERS: List - List of values to encode + * Count - Length of list + * + * RETURN: Encoded bitmask + * + * DESCRIPTION: Convert a list of values to an encoded bitmask + * + ******************************************************************************/ + +u16 acpi_rs_encode_bitmask(u8 * list, u8 count) +{ + acpi_native_uint i; + u16 mask; + + ACPI_FUNCTION_ENTRY(); + + /* Encode the list into a single bitmask */ + + for (i = 0, mask = 0; i < count; i++) { + mask |= (0x0001 << list[i]); + } + + return (mask); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_move_data + * + * PARAMETERS: Destination - Pointer to the destination descriptor + * Source - Pointer to the source descriptor + * item_count - How many items to move + * move_type - Byte width + * + * RETURN: None + * + * DESCRIPTION: Move multiple data items from one descriptor to another. Handles + * alignment issues and endian issues if necessary, as configured + * via the ACPI_MOVE_* macros. (This is why a memcpy is not used) + * + ******************************************************************************/ + +void +acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) +{ + acpi_native_uint i; + + ACPI_FUNCTION_ENTRY(); + + /* One move per item */ + + for (i = 0; i < item_count; i++) { + switch (move_type) { + /* + * For the 8-bit case, we can perform the move all at once + * since there are no alignment or endian issues + */ + case ACPI_RSC_MOVE8: + ACPI_MEMCPY(destination, source, item_count); + return; + + /* + * 16-, 32-, and 64-bit cases must use the move macros that perform + * endian conversion and/or accomodate hardware that cannot perform + * misaligned memory transfers + */ + case ACPI_RSC_MOVE16: + ACPI_MOVE_16_TO_16(&ACPI_CAST_PTR(u16, destination)[i], + &ACPI_CAST_PTR(u16, source)[i]); + break; + + case ACPI_RSC_MOVE32: + ACPI_MOVE_32_TO_32(&ACPI_CAST_PTR(u32, destination)[i], + &ACPI_CAST_PTR(u32, source)[i]); + break; + + case ACPI_RSC_MOVE64: + ACPI_MOVE_64_TO_64(&ACPI_CAST_PTR(u64, destination)[i], + &ACPI_CAST_PTR(u64, source)[i]); + break; + + default: + return; + } + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_set_resource_length + * + * PARAMETERS: total_length - Length of the AML descriptor, including + * the header and length fields. + * Aml - Pointer to the raw AML descriptor + * + * RETURN: None + * + * DESCRIPTION: Set the resource_length field of an AML + * resource descriptor, both Large and Small descriptors are + * supported automatically. Note: Descriptor Type field must + * be valid. + * + ******************************************************************************/ + +void +acpi_rs_set_resource_length(acpi_rsdesc_size total_length, + union aml_resource *aml) +{ + acpi_rs_length resource_length; + + ACPI_FUNCTION_ENTRY(); + + /* Length is the total descriptor length minus the header length */ + + resource_length = (acpi_rs_length) + (total_length - acpi_ut_get_resource_header_length(aml)); + + /* Length is stored differently for large and small descriptors */ + + if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { + /* Large descriptor -- bytes 1-2 contain the 16-bit length */ + + ACPI_MOVE_16_TO_16(&aml->large_header.resource_length, + &resource_length); + } else { + /* Small descriptor -- bits 2:0 of byte 0 contain the length */ + + aml->small_header.descriptor_type = (u8) + + /* Clear any existing length, preserving descriptor type bits */ + ((aml->small_header. + descriptor_type & ~ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK) + + | resource_length); + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_set_resource_header + * + * PARAMETERS: descriptor_type - Byte to be inserted as the type + * total_length - Length of the AML descriptor, including + * the header and length fields. + * Aml - Pointer to the raw AML descriptor + * + * RETURN: None + * + * DESCRIPTION: Set the descriptor_type and resource_length fields of an AML + * resource descriptor, both Large and Small descriptors are + * supported automatically + * + ******************************************************************************/ + +void +acpi_rs_set_resource_header(u8 descriptor_type, + acpi_rsdesc_size total_length, + union aml_resource *aml) +{ + ACPI_FUNCTION_ENTRY(); + + /* Set the Resource Type */ + + aml->small_header.descriptor_type = descriptor_type; + + /* Set the Resource Length */ + + acpi_rs_set_resource_length(total_length, aml); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_strcpy + * + * PARAMETERS: Destination - Pointer to the destination string + * Source - Pointer to the source string + * + * RETURN: String length, including NULL terminator + * + * DESCRIPTION: Local string copy that returns the string length, saving a + * strcpy followed by a strlen. + * + ******************************************************************************/ + +static u16 acpi_rs_strcpy(char *destination, char *source) +{ + u16 i; + + ACPI_FUNCTION_ENTRY(); + + for (i = 0; source[i]; i++) { + destination[i] = source[i]; + } + + destination[i] = 0; + + /* Return string length including the NULL terminator */ + + return ((u16) (i + 1)); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_get_resource_source + * + * PARAMETERS: resource_length - Length field of the descriptor + * minimum_length - Minimum length of the descriptor (minus + * any optional fields) + * resource_source - Where the resource_source is returned + * Aml - Pointer to the raw AML descriptor + * string_ptr - (optional) where to store the actual + * resource_source string + * + * RETURN: Length of the string plus NULL terminator, rounded up to 32 bit + * + * DESCRIPTION: Copy the optional resource_source data from a raw AML descriptor + * to an internal resource descriptor + * + ******************************************************************************/ + +acpi_rs_length +acpi_rs_get_resource_source(acpi_rs_length resource_length, + acpi_rs_length minimum_length, + struct acpi_resource_source * resource_source, + union aml_resource * aml, char *string_ptr) +{ + acpi_rsdesc_size total_length; + u8 *aml_resource_source; + + ACPI_FUNCTION_ENTRY(); + + total_length = + resource_length + sizeof(struct aml_resource_large_header); + aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length); + + /* + * resource_source is present if the length of the descriptor is longer than + * the minimum length. + * + * Note: Some resource descriptors will have an additional null, so + * we add 1 to the minimum length. + */ + if (total_length > (acpi_rsdesc_size) (minimum_length + 1)) { + /* Get the resource_source_index */ + + resource_source->index = aml_resource_source[0]; + + resource_source->string_ptr = string_ptr; + if (!string_ptr) { + /* + * String destination pointer is not specified; Set the String + * pointer to the end of the current resource_source structure. + */ + resource_source->string_ptr = + ACPI_ADD_PTR(char, resource_source, + sizeof(struct acpi_resource_source)); + } + + /* + * In order for the struct_size to fall on a 32-bit boundary, calculate + * the length of the string (+1 for the NULL terminator) and expand the + * struct_size to the next 32-bit boundary. + * + * Zero the entire area of the buffer. + */ + total_length = + ACPI_ROUND_UP_to_32_bITS(ACPI_STRLEN + ((char *)&aml_resource_source[1]) + + 1); + ACPI_MEMSET(resource_source->string_ptr, 0, total_length); + + /* Copy the resource_source string to the destination */ + + resource_source->string_length = + acpi_rs_strcpy(resource_source->string_ptr, + (char *)&aml_resource_source[1]); + + return ((acpi_rs_length) total_length); + } + + /* resource_source is not present */ + + resource_source->index = 0; + resource_source->string_length = 0; + resource_source->string_ptr = NULL; + return (0); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_set_resource_source + * + * PARAMETERS: Aml - Pointer to the raw AML descriptor + * minimum_length - Minimum length of the descriptor (minus + * any optional fields) + * resource_source - Internal resource_source + + * + * RETURN: Total length of the AML descriptor + * + * DESCRIPTION: Convert an optional resource_source from internal format to a + * raw AML resource descriptor + * + ******************************************************************************/ + +acpi_rsdesc_size +acpi_rs_set_resource_source(union aml_resource * aml, + acpi_rs_length minimum_length, + struct acpi_resource_source * resource_source) +{ + u8 *aml_resource_source; + acpi_rsdesc_size descriptor_length; + + ACPI_FUNCTION_ENTRY(); + + descriptor_length = minimum_length; + + /* Non-zero string length indicates presence of a resource_source */ + + if (resource_source->string_length) { + /* Point to the end of the AML descriptor */ + + aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length); + + /* Copy the resource_source_index */ + + aml_resource_source[0] = (u8) resource_source->index; + + /* Copy the resource_source string */ + + ACPI_STRCPY((char *)&aml_resource_source[1], + resource_source->string_ptr); + + /* + * Add the length of the string (+ 1 for null terminator) to the + * final descriptor length + */ + descriptor_length += + ((acpi_rsdesc_size) resource_source->string_length + 1); + } + + /* Return the new total length of the AML descriptor */ + + return (descriptor_length); +} + +/******************************************************************************* + * * FUNCTION: acpi_rs_get_prt_method_data * * PARAMETERS: Handle - a handle to the containing object @@ -65,8 +448,9 @@ ACPI_MODULE_NAME("rsutils") * and the contents of the callers buffer is undefined. * ******************************************************************************/ + acpi_status -acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer) +acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer * ret_buffer) { union acpi_operand_object *obj_desc; acpi_status status; @@ -284,7 +668,7 @@ acpi_rs_set_srs_method_data(acpi_handle handle, struct acpi_buffer *in_buffer) * Convert the linked list into a byte stream */ buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; - status = acpi_rs_create_byte_stream(in_buffer->pointer, &buffer); + status = acpi_rs_create_aml_resources(in_buffer->pointer, &buffer); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c index ee5a5c509199..88b67077aeeb 100644 --- a/drivers/acpi/resources/rsxface.c +++ b/drivers/acpi/resources/rsxface.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -57,13 +57,17 @@ ACPI_MODULE_NAME("rsxface") ACPI_COPY_FIELD(out, in, decode); \ ACPI_COPY_FIELD(out, in, min_address_fixed); \ ACPI_COPY_FIELD(out, in, max_address_fixed); \ - ACPI_COPY_FIELD(out, in, attribute); \ + ACPI_COPY_FIELD(out, in, info); \ ACPI_COPY_FIELD(out, in, granularity); \ - ACPI_COPY_FIELD(out, in, min_address_range); \ - ACPI_COPY_FIELD(out, in, max_address_range); \ - ACPI_COPY_FIELD(out, in, address_translation_offset); \ + ACPI_COPY_FIELD(out, in, minimum); \ + ACPI_COPY_FIELD(out, in, maximum); \ + ACPI_COPY_FIELD(out, in, translation_offset); \ ACPI_COPY_FIELD(out, in, address_length); \ ACPI_COPY_FIELD(out, in, resource_source); +/* Local prototypes */ +static acpi_status +acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context); + /******************************************************************************* * * FUNCTION: acpi_get_irq_routing_table @@ -86,6 +90,7 @@ ACPI_MODULE_NAME("rsxface") * the object indicated by the passed device_handle. * ******************************************************************************/ + acpi_status acpi_get_irq_routing_table(acpi_handle device_handle, struct acpi_buffer *ret_buffer) @@ -222,12 +227,12 @@ EXPORT_SYMBOL(acpi_get_possible_resources); * * FUNCTION: acpi_walk_resources * - * PARAMETERS: device_handle - a handle to the device object for the + * PARAMETERS: device_handle - Handle to the device object for the * device we are querying - * Path - method name of the resources we want + * Name - Method name of the resources we want * (METHOD_NAME__CRS or METHOD_NAME__PRS) - * user_function - called for each resource - * Context - passed to user_function + * user_function - Called for each resource + * Context - Passed to user_function * * RETURN: Status * @@ -239,79 +244,74 @@ EXPORT_SYMBOL(acpi_get_possible_resources); acpi_status acpi_walk_resources(acpi_handle device_handle, - char *path, + char *name, ACPI_WALK_RESOURCE_CALLBACK user_function, void *context) { acpi_status status; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_buffer buffer; struct acpi_resource *resource; - struct acpi_resource *buffer_end; + struct acpi_resource *resource_end; ACPI_FUNCTION_TRACE("acpi_walk_resources"); - if (!device_handle || - (ACPI_STRNCMP(path, METHOD_NAME__CRS, sizeof(METHOD_NAME__CRS)) && - ACPI_STRNCMP(path, METHOD_NAME__PRS, sizeof(METHOD_NAME__PRS)))) { + /* Parameter validation */ + + if (!device_handle || !user_function || !name || + (ACPI_STRNCMP(name, METHOD_NAME__CRS, sizeof(METHOD_NAME__CRS)) && + ACPI_STRNCMP(name, METHOD_NAME__PRS, sizeof(METHOD_NAME__PRS)))) { return_ACPI_STATUS(AE_BAD_PARAMETER); } - status = acpi_rs_get_method_data(device_handle, path, &buffer); + /* Get the _CRS or _PRS resource list */ + + buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; + status = acpi_rs_get_method_data(device_handle, name, &buffer); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - /* Setup pointers */ + /* Buffer now contains the resource list */ - resource = (struct acpi_resource *)buffer.pointer; - buffer_end = ACPI_CAST_PTR(struct acpi_resource, - ((u8 *) buffer.pointer + buffer.length)); + resource = ACPI_CAST_PTR(struct acpi_resource, buffer.pointer); + resource_end = + ACPI_ADD_PTR(struct acpi_resource, buffer.pointer, buffer.length); - /* Walk the resource list */ + /* Walk the resource list until the end_tag is found (or buffer end) */ - for (;;) { - if (!resource || resource->id == ACPI_RSTYPE_END_TAG) { + while (resource < resource_end) { + /* Sanity check the resource */ + + if (resource->type > ACPI_RESOURCE_TYPE_MAX) { + status = AE_AML_INVALID_RESOURCE_TYPE; break; } - status = user_function(resource, context); - - switch (status) { - case AE_OK: - case AE_CTRL_DEPTH: + /* Invoke the user function, abort on any error returned */ - /* Just keep going */ + status = user_function(resource, context); + if (ACPI_FAILURE(status)) { + if (status == AE_CTRL_TERMINATE) { + /* This is an OK termination by the user function */ - status = AE_OK; + status = AE_OK; + } break; + } - case AE_CTRL_TERMINATE: - - /* Exit now, with OK stats */ - - status = AE_OK; - goto cleanup; - - default: - - /* All others are valid exceptions */ + /* end_tag indicates end-of-list */ - goto cleanup; + if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { + break; } /* Get the next resource descriptor */ - resource = ACPI_NEXT_RESOURCE(resource); - - /* Check for end-of-buffer */ - - if (resource >= buffer_end) { - goto cleanup; - } + resource = + ACPI_ADD_PTR(struct acpi_resource, resource, + resource->length); } - cleanup: - - acpi_os_free(buffer.pointer); + ACPI_MEM_FREE(buffer.pointer); return_ACPI_STATUS(status); } @@ -360,8 +360,8 @@ EXPORT_SYMBOL(acpi_set_current_resources); * * FUNCTION: acpi_resource_to_address64 * - * PARAMETERS: resource - Pointer to a resource - * out - Pointer to the users's return + * PARAMETERS: Resource - Pointer to a resource + * Out - Pointer to the users's return * buffer (a struct * struct acpi_resource_address64) * @@ -381,20 +381,26 @@ acpi_resource_to_address64(struct acpi_resource *resource, struct acpi_resource_address16 *address16; struct acpi_resource_address32 *address32; - switch (resource->id) { - case ACPI_RSTYPE_ADDRESS16: + if (!resource || !out) { + return (AE_BAD_PARAMETER); + } + + /* Convert 16 or 32 address descriptor to 64 */ + + switch (resource->type) { + case ACPI_RESOURCE_TYPE_ADDRESS16: address16 = (struct acpi_resource_address16 *)&resource->data; ACPI_COPY_ADDRESS(out, address16); break; - case ACPI_RSTYPE_ADDRESS32: + case ACPI_RESOURCE_TYPE_ADDRESS32: address32 = (struct acpi_resource_address32 *)&resource->data; ACPI_COPY_ADDRESS(out, address32); break; - case ACPI_RSTYPE_ADDRESS64: + case ACPI_RESOURCE_TYPE_ADDRESS64: /* Simple copy for 64 bit source */ @@ -410,3 +416,113 @@ acpi_resource_to_address64(struct acpi_resource *resource, } EXPORT_SYMBOL(acpi_resource_to_address64); + +/******************************************************************************* + * + * FUNCTION: acpi_get_vendor_resource + * + * PARAMETERS: device_handle - Handle for the parent device object + * Name - Method name for the parent resource + * (METHOD_NAME__CRS or METHOD_NAME__PRS) + * Uuid - Pointer to the UUID to be matched. + * includes both subtype and 16-byte UUID + * ret_buffer - Where the vendor resource is returned + * + * RETURN: Status + * + * DESCRIPTION: Walk a resource template for the specified evice to find a + * vendor-defined resource that matches the supplied UUID and + * UUID subtype. Returns a struct acpi_resource of type Vendor. + * + ******************************************************************************/ + +acpi_status +acpi_get_vendor_resource(acpi_handle device_handle, + char *name, + struct acpi_vendor_uuid * uuid, + struct acpi_buffer * ret_buffer) +{ + struct acpi_vendor_walk_info info; + acpi_status status; + + /* Other parameters are validated by acpi_walk_resources */ + + if (!uuid || !ret_buffer) { + return (AE_BAD_PARAMETER); + } + + info.uuid = uuid; + info.buffer = ret_buffer; + info.status = AE_NOT_EXIST; + + /* Walk the _CRS or _PRS resource list for this device */ + + status = + acpi_walk_resources(device_handle, name, + acpi_rs_match_vendor_resource, &info); + if (ACPI_FAILURE(status)) { + return (status); + } + + return (info.status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_match_vendor_resource + * + * PARAMETERS: ACPI_WALK_RESOURCE_CALLBACK + * + * RETURN: Status + * + * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID + * + ******************************************************************************/ + +static acpi_status +acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context) +{ + struct acpi_vendor_walk_info *info = context; + struct acpi_resource_vendor_typed *vendor; + struct acpi_buffer *buffer; + acpi_status status; + + /* Ignore all descriptors except Vendor */ + + if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) { + return (AE_OK); + } + + vendor = &resource->data.vendor_typed; + + /* + * For a valid match, these conditions must hold: + * + * 1) Length of descriptor data must be at least as long as a UUID struct + * 2) The UUID subtypes must match + * 3) The UUID data must match + */ + if ((vendor->byte_length < (ACPI_UUID_LENGTH + 1)) || + (vendor->uuid_subtype != info->uuid->subtype) || + (ACPI_MEMCMP(vendor->uuid, info->uuid->data, ACPI_UUID_LENGTH))) { + return (AE_OK); + } + + /* Validate/Allocate/Clear caller buffer */ + + buffer = info->buffer; + status = acpi_ut_initialize_buffer(buffer, resource->length); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* Found the correct resource, copy and return it */ + + ACPI_MEMCPY(buffer->pointer, resource, resource->length); + buffer->length = resource->length; + + /* Found the desired descriptor, terminate resource walk */ + + info->status = AE_OK; + return (AE_CTRL_TERMINATE); +} |