aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorRobert Moore <Robert.Moore@intel.com>2005-09-16 16:51:15 -0400
committerLen Brown <len.brown@intel.com>2005-09-21 23:51:39 -0400
commitbda663d36b94c723153246a4231bbc0f1cd1836e (patch)
treecc9f75c1d010d1b99d29f13acd600b21eda5eec5 /drivers
parentefb0372bbaf5b829ff8c39db372779928af542a7 (diff)
[ACPI] ACPICA 20050916
Fixed a problem within the Resource Manager where support for the Generic Register descriptor was not fully implemented. This descriptor is now fully recognized, parsed, disassembled, and displayed. Restructured the Resource Manager code to utilize table-driven dispatch and lookup, eliminating many of the large switch() statements. This reduces overall subsystem code size and code complexity. Affects the resource parsing and construction, disassembly, and debug dump output. Cleaned up and restructured the debug dump output for all resource descriptors. Improved readability of the output and reduced code size. Fixed a problem where changes to internal data structures caused the optional ACPI_MUTEX_DEBUG code to fail compilation if specified. Signed-off-by: Robert Moore <Robert.Moore@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/resources/rsaddr.c99
-rw-r--r--drivers/acpi/resources/rscalc.c985
-rw-r--r--drivers/acpi/resources/rsdump.c1284
-rw-r--r--drivers/acpi/resources/rsio.c56
-rw-r--r--drivers/acpi/resources/rsirq.c57
-rw-r--r--drivers/acpi/resources/rslist.c533
-rw-r--r--drivers/acpi/resources/rsmemory.c68
-rw-r--r--drivers/acpi/resources/rsmisc.c234
-rw-r--r--drivers/acpi/resources/rsxface.c8
-rw-r--r--drivers/acpi/utilities/utmisc.c2
-rw-r--r--drivers/acpi/utilities/utmutex.c4
11 files changed, 1597 insertions, 1733 deletions
diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c
index 23b54baa0cb..798778261fb 100644
--- a/drivers/acpi/resources/rsaddr.c
+++ b/drivers/acpi/resources/rsaddr.c
@@ -270,7 +270,7 @@ acpi_rs_address16_resource(u8 * byte_stream_buffer,
}
*bytes_consumed = temp16 + 3;
- output_struct->id = ACPI_RSTYPE_ADDRESS16;
+ output_struct->type = ACPI_RSTYPE_ADDRESS16;
/* Get the Resource Type (Byte3) */
@@ -400,7 +400,7 @@ acpi_rs_address16_resource(u8 * byte_stream_buffer,
*
* FUNCTION: acpi_rs_address16_stream
*
- * PARAMETERS: linked_list - Pointer to the resource linked list
+ * PARAMETERS: Resource - 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
@@ -413,7 +413,7 @@ acpi_rs_address16_resource(u8 * byte_stream_buffer,
******************************************************************************/
acpi_status
-acpi_rs_address16_stream(struct acpi_resource *linked_list,
+acpi_rs_address16_stream(struct acpi_resource *resource,
u8 ** output_buffer, acpi_size * bytes_consumed)
{
u8 *buffer = *output_buffer;
@@ -434,59 +434,56 @@ acpi_rs_address16_stream(struct acpi_resource *linked_list,
/* Set the Resource Type (Memory, Io, bus_number) */
- *buffer = (u8) (linked_list->data.address16.resource_type & 0x03);
+ *buffer = (u8) (resource->data.address16.resource_type & 0x03);
buffer += 1;
/* Set the general flags */
- *buffer = acpi_rs_encode_general_flags(&linked_list->data);
+ *buffer = acpi_rs_encode_general_flags(&resource->data);
buffer += 1;
/* Set the type specific flags */
- *buffer = acpi_rs_encode_specific_flags(&linked_list->data);
+ *buffer = acpi_rs_encode_specific_flags(&resource->data);
buffer += 1;
/* Set the address space granularity */
- ACPI_MOVE_32_TO_16(buffer, &linked_list->data.address16.granularity);
+ ACPI_MOVE_32_TO_16(buffer, &resource->data.address16.granularity);
buffer += 2;
/* Set the address range minimum */
- ACPI_MOVE_32_TO_16(buffer,
- &linked_list->data.address16.min_address_range);
+ ACPI_MOVE_32_TO_16(buffer, &resource->data.address16.min_address_range);
buffer += 2;
/* Set the address range maximum */
- ACPI_MOVE_32_TO_16(buffer,
- &linked_list->data.address16.max_address_range);
+ ACPI_MOVE_32_TO_16(buffer, &resource->data.address16.max_address_range);
buffer += 2;
/* Set the address translation offset */
ACPI_MOVE_32_TO_16(buffer,
- &linked_list->data.address16.
+ &resource->data.address16.
address_translation_offset);
buffer += 2;
/* Set the address length */
- ACPI_MOVE_32_TO_16(buffer, &linked_list->data.address16.address_length);
+ ACPI_MOVE_32_TO_16(buffer, &resource->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;
+ if (resource->data.address16.resource_source.string_length) {
+ *buffer = (u8) resource->data.address16.resource_source.index;
buffer += 1;
/* Copy the resource_source string */
ACPI_STRCPY((char *)buffer,
- linked_list->data.address16.resource_source.
+ resource->data.address16.resource_source.
string_ptr);
/*
@@ -495,7 +492,7 @@ acpi_rs_address16_stream(struct acpi_resource *linked_list,
*/
buffer +=
(acpi_size) (ACPI_STRLEN
- (linked_list->data.address16.resource_source.
+ (resource->data.address16.resource_source.
string_ptr) + 1);
}
@@ -562,7 +559,7 @@ acpi_rs_address32_resource(u8 * byte_stream_buffer,
}
*bytes_consumed = temp16 + 3;
- output_struct->id = ACPI_RSTYPE_ADDRESS32;
+ output_struct->type = ACPI_RSTYPE_ADDRESS32;
/* Get the Resource Type (Byte3) */
@@ -690,7 +687,7 @@ acpi_rs_address32_resource(u8 * byte_stream_buffer,
*
* FUNCTION: acpi_rs_address32_stream
*
- * PARAMETERS: linked_list - Pointer to the resource linked list
+ * PARAMETERS: Resource - 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
@@ -703,7 +700,7 @@ acpi_rs_address32_resource(u8 * byte_stream_buffer,
******************************************************************************/
acpi_status
-acpi_rs_address32_stream(struct acpi_resource *linked_list,
+acpi_rs_address32_stream(struct acpi_resource *resource,
u8 ** output_buffer, acpi_size * bytes_consumed)
{
u8 *buffer;
@@ -725,59 +722,56 @@ acpi_rs_address32_stream(struct acpi_resource *linked_list,
/* Set the Resource Type (Memory, Io, bus_number) */
- *buffer = (u8) (linked_list->data.address32.resource_type & 0x03);
+ *buffer = (u8) (resource->data.address32.resource_type & 0x03);
buffer += 1;
/* Set the general flags */
- *buffer = acpi_rs_encode_general_flags(&linked_list->data);
+ *buffer = acpi_rs_encode_general_flags(&resource->data);
buffer += 1;
/* Set the type specific flags */
- *buffer = acpi_rs_encode_specific_flags(&linked_list->data);
+ *buffer = acpi_rs_encode_specific_flags(&resource->data);
buffer += 1;
/* Set the address space granularity */
- ACPI_MOVE_32_TO_32(buffer, &linked_list->data.address32.granularity);
+ ACPI_MOVE_32_TO_32(buffer, &resource->data.address32.granularity);
buffer += 4;
/* Set the address range minimum */
- ACPI_MOVE_32_TO_32(buffer,
- &linked_list->data.address32.min_address_range);
+ ACPI_MOVE_32_TO_32(buffer, &resource->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);
+ ACPI_MOVE_32_TO_32(buffer, &resource->data.address32.max_address_range);
buffer += 4;
/* Set the address translation offset */
ACPI_MOVE_32_TO_32(buffer,
- &linked_list->data.address32.
+ &resource->data.address32.
address_translation_offset);
buffer += 4;
/* Set the address length */
- ACPI_MOVE_32_TO_32(buffer, &linked_list->data.address32.address_length);
+ ACPI_MOVE_32_TO_32(buffer, &resource->data.address32.address_length);
buffer += 4;
/* Resource Source Index and Resource Source are optional */
- if (linked_list->data.address32.resource_source.string_length) {
- *buffer =
- (u8) linked_list->data.address32.resource_source.index;
+ if (resource->data.address32.resource_source.string_length) {
+ *buffer = (u8) resource->data.address32.resource_source.index;
buffer += 1;
/* Copy the resource_source string */
ACPI_STRCPY((char *)buffer,
- linked_list->data.address32.resource_source.
+ resource->data.address32.resource_source.
string_ptr);
/*
@@ -786,7 +780,7 @@ acpi_rs_address32_stream(struct acpi_resource *linked_list,
*/
buffer +=
(acpi_size) (ACPI_STRLEN
- (linked_list->data.address32.resource_source.
+ (resource->data.address32.resource_source.
string_ptr) + 1);
}
@@ -856,7 +850,7 @@ acpi_rs_address64_resource(u8 * byte_stream_buffer,
}
*bytes_consumed = temp16 + 3;
- output_struct->id = ACPI_RSTYPE_ADDRESS64;
+ output_struct->type = ACPI_RSTYPE_ADDRESS64;
/* Get the Resource Type (Byte3) */
@@ -1005,7 +999,7 @@ acpi_rs_address64_resource(u8 * byte_stream_buffer,
*
* FUNCTION: acpi_rs_address64_stream
*
- * PARAMETERS: linked_list - Pointer to the resource linked list
+ * PARAMETERS: Resource - 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
@@ -1018,7 +1012,7 @@ acpi_rs_address64_resource(u8 * byte_stream_buffer,
******************************************************************************/
acpi_status
-acpi_rs_address64_stream(struct acpi_resource *linked_list,
+acpi_rs_address64_stream(struct acpi_resource *resource,
u8 ** output_buffer, acpi_size * bytes_consumed)
{
u8 *buffer;
@@ -1040,59 +1034,56 @@ acpi_rs_address64_stream(struct acpi_resource *linked_list,
/* Set the Resource Type (Memory, Io, bus_number) */
- *buffer = (u8) (linked_list->data.address64.resource_type & 0x03);
+ *buffer = (u8) (resource->data.address64.resource_type & 0x03);
buffer += 1;
/* Set the general flags */
- *buffer = acpi_rs_encode_general_flags(&linked_list->data);
+ *buffer = acpi_rs_encode_general_flags(&resource->data);
buffer += 1;
/* Set the type specific flags */
- *buffer = acpi_rs_encode_specific_flags(&linked_list->data);
+ *buffer = acpi_rs_encode_specific_flags(&resource->data);
buffer += 1;
/* Set the address space granularity */
- ACPI_MOVE_64_TO_64(buffer, &linked_list->data.address64.granularity);
+ ACPI_MOVE_64_TO_64(buffer, &resource->data.address64.granularity);
buffer += 8;
/* Set the address range minimum */
- ACPI_MOVE_64_TO_64(buffer,
- &linked_list->data.address64.min_address_range);
+ ACPI_MOVE_64_TO_64(buffer, &resource->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);
+ ACPI_MOVE_64_TO_64(buffer, &resource->data.address64.max_address_range);
buffer += 8;
/* Set the address translation offset */
ACPI_MOVE_64_TO_64(buffer,
- &linked_list->data.address64.
+ &resource->data.address64.
address_translation_offset);
buffer += 8;
/* Set the address length */
- ACPI_MOVE_64_TO_64(buffer, &linked_list->data.address64.address_length);
+ ACPI_MOVE_64_TO_64(buffer, &resource->data.address64.address_length);
buffer += 8;
/* Resource Source Index and Resource Source are optional */
- if (linked_list->data.address64.resource_source.string_length) {
- *buffer =
- (u8) linked_list->data.address64.resource_source.index;
+ if (resource->data.address64.resource_source.string_length) {
+ *buffer = (u8) resource->data.address64.resource_source.index;
buffer += 1;
/* Copy the resource_source string */
ACPI_STRCPY((char *)buffer,
- linked_list->data.address64.resource_source.
+ resource->data.address64.resource_source.
string_ptr);
/*
@@ -1101,7 +1092,7 @@ acpi_rs_address64_stream(struct acpi_resource *linked_list,
*/
buffer +=
(acpi_size) (ACPI_STRLEN
- (linked_list->data.address64.resource_source.
+ (resource->data.address64.resource_source.
string_ptr) + 1);
}
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
index 378f58390fc..cd051c97bf5 100644
--- a/drivers/acpi/resources/rscalc.c
+++ b/drivers/acpi/resources/rscalc.c
@@ -44,651 +44,620 @@
#include <acpi/acpi.h>
#include <acpi/acresrc.h>
#include <acpi/amlcode.h>
+#include <acpi/amlresrc.h>
#include <acpi/acnamesp.h>
#define _COMPONENT ACPI_RESOURCES
ACPI_MODULE_NAME("rscalc")
+/*
+ * Base sizes for external resource descriptors, indexed by internal type.
+ * Includes size of the descriptor header (1 byte for small descriptors,
+ * 3 bytes for large descriptors)
+ */
+static u8 acpi_gbl_stream_sizes[] = {
+ 4, /* ACPI_RSTYPE_IRQ (Byte 3 is optional, but always created) */
+ 3, /* ACPI_RSTYPE_DMA */
+ 2, /* ACPI_RSTYPE_START_DPF (Byte 1 is optional, but always created) */
+ 1, /* ACPI_RSTYPE_END_DPF */
+ 8, /* ACPI_RSTYPE_IO */
+ 4, /* ACPI_RSTYPE_FIXED_IO */
+ 1, /* ACPI_RSTYPE_VENDOR */
+ 2, /* ACPI_RSTYPE_END_TAG */
+ 12, /* ACPI_RSTYPE_MEM24 */
+ 20, /* ACPI_RSTYPE_MEM32 */
+ 12, /* ACPI_RSTYPE_FIXED_MEM32 */
+ 16, /* ACPI_RSTYPE_ADDRESS16 */
+ 26, /* ACPI_RSTYPE_ADDRESS32 */
+ 46, /* ACPI_RSTYPE_ADDRESS64 */
+ 9, /* ACPI_RSTYPE_EXT_IRQ */
+ 15 /* ACPI_RSTYPE_GENERIC_REG */
+};
+
+/*
+ * Base sizes of resource descriptors, both the actual AML stream length and
+ * size of the internal struct representation.
+ */
+typedef struct acpi_resource_sizes {
+ u8 minimum_stream_size;
+ u8 minimum_struct_size;
+
+} ACPI_RESOURCE_SIZES;
+
+static ACPI_RESOURCE_SIZES acpi_gbl_sm_resource_sizes[] = {
+ 0, 0, /* 0x00, Reserved */
+ 0, 0, /* 0x01, Reserved */
+ 0, 0, /* 0x02, Reserved */
+ 0, 0, /* 0x03, Reserved */
+ 3, ACPI_SIZEOF_RESOURCE(struct acpi_resource_irq), /* ACPI_RDESC_TYPE_IRQ_FORMAT */
+ 3, ACPI_SIZEOF_RESOURCE(struct acpi_resource_dma), /* ACPI_RDESC_TYPE_DMA_FORMAT */
+ 1, ACPI_SIZEOF_RESOURCE(struct acpi_resource_start_dpf), /* ACPI_RDESC_TYPE_START_DEPENDENT */
+ 1, ACPI_RESOURCE_LENGTH, /* ACPI_RDESC_TYPE_END_DEPENDENT */
+ 8, ACPI_SIZEOF_RESOURCE(struct acpi_resource_io), /* ACPI_RDESC_TYPE_IO_PORT */
+ 4, ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_io), /* ACPI_RDESC_TYPE_FIXED_IO_PORT */
+ 0, 0, /* 0x0A, Reserved */
+ 0, 0, /* 0x0B, Reserved */
+ 0, 0, /* 0x0C, Reserved */
+ 0, 0, /* 0x0D, Reserved */
+ 1, ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor), /* ACPI_RDESC_TYPE_SMALL_VENDOR */
+ 2, ACPI_RESOURCE_LENGTH, /* ACPI_RDESC_TYPE_END_TAG */
+};
+
+static ACPI_RESOURCE_SIZES acpi_gbl_lg_resource_sizes[] = {
+ 0, 0, /* 0x00, Reserved */
+ 12, ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem24), /* ACPI_RDESC_TYPE_MEMORY_24 */
+ 15, ACPI_SIZEOF_RESOURCE(struct acpi_resource_generic_reg), /* ACPI_RDESC_TYPE_GENERIC_REGISTER */
+ 0, 0, /* 0x03, Reserved */
+ 3, ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor), /* ACPI_RDESC_TYPE_LARGE_VENDOR */
+ 20, ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem32), /* ACPI_RDESC_TYPE_MEMORY_32 */
+ 12, ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_mem32), /* ACPI_RDESC_TYPE_FIXED_MEMORY_32 */
+ 26, ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32), /* ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE */
+ 16, ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16), /* ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE */
+ 9, ACPI_SIZEOF_RESOURCE(struct acpi_resource_ext_irq), /* ACPI_RDESC_TYPE_EXTENDED_XRUPT */
+ 46, ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64), /* ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE */
+ 56, ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64), /* ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE */
+};
+
+/* Local prototypes */
+
+static u8 acpi_rs_count_set_bits(u16 bit_field);
+
+static ACPI_RESOURCE_SIZES *acpi_rs_get_resource_sizes(u8 resource_type);
+
+static u16 acpi_rs_get_resource_length(u8 * resource);
+
+static acpi_size
+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. */
+static u8 acpi_rs_count_set_bits(u16 bit_field)
+{
+ u8 bits_set;
- segment_size = 0;
+ ACPI_FUNCTION_ENTRY();
- 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;
+ for (bits_set = 0; bit_field; bits_set++) {
+ /* Zero the least significant bit that is set */
- 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;
+ bit_field &= (bit_field - 1);
+ }
- case ACPI_RSTYPE_END_DPF:
- /*
- * End Dependent Functions Resource
- * For this resource the size is static
- */
- segment_size = 1;
- break;
+ return (bits_set);
+}
- case ACPI_RSTYPE_IO:
- /*
- * IO Port Resource
- * For this resource the size is static
- */
- segment_size = 8;
- break;
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_rs_get_resource_sizes
+ *
+ * PARAMETERS: resource_type - Byte 0 of a resource descriptor
+ *
+ * RETURN: Pointer to the resource conversion handler
+ *
+ * DESCRIPTION: Extract the Resource Type/Name from the first byte of
+ * a resource descriptor.
+ *
+ ******************************************************************************/
- case ACPI_RSTYPE_FIXED_IO:
- /*
- * Fixed IO Port Resource
- * For this resource the size is static
- */
- segment_size = 4;
- break;
+static ACPI_RESOURCE_SIZES *acpi_rs_get_resource_sizes(u8 resource_type)
+{
+ ACPI_RESOURCE_SIZES *size_info;
- 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;
+ ACPI_FUNCTION_ENTRY();
- case ACPI_RSTYPE_END_TAG:
- /*
- * End Tag
- * For this resource the size is static
- */
- segment_size = 2;
- done = TRUE;
- break;
+ /* Determine if this is a small or large resource */
- case ACPI_RSTYPE_MEM24:
- /*
- * 24-Bit Memory Resource
- * For this resource the size is static
- */
- segment_size = 12;
- break;
+ if (resource_type & ACPI_RDESC_TYPE_LARGE) {
+ /* Large Resource Type -- bits 6:0 contain the name */
- case ACPI_RSTYPE_MEM32:
- /*
- * 32-Bit Memory Range Resource
- * For this resource the size is static
- */
- segment_size = 20;
- break;
+ if (resource_type > ACPI_RDESC_LARGE_MAX) {
+ return (NULL);
+ }
- case ACPI_RSTYPE_FIXED_MEM32:
- /*
- * 32-Bit Fixed Memory Resource
- * For this resource the size is static
- */
- segment_size = 12;
- break;
+ size_info = &acpi_gbl_lg_resource_sizes[(resource_type &
+ ACPI_RDESC_LARGE_MASK)];
+ } else {
+ /* Small Resource Type -- bits 6:3 contain the name */
- 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;
+ size_info = &acpi_gbl_sm_resource_sizes[((resource_type &
+ ACPI_RDESC_SMALL_MASK)
+ >> 3)];
+ }
- 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;
+ /* Zero entry indicates an invalid resource type */
- 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;
+ if (!size_info->minimum_stream_size) {
+ return (NULL);
+ }
- 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;
+ return (size_info);
+}
- default:
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_rs_get_resource_length
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ *
+ * RETURN: Byte length of the (AML byte stream) descriptor. By definition,
+ * this does not include the size of the descriptor header and the
+ * length field itself.
+ *
+ * DESCRIPTION: Extract the length of a resource descriptor.
+ *
+ ******************************************************************************/
- /* If we get here, everything is out of sync, exit with error */
+static u16 acpi_rs_get_resource_length(u8 * resource)
+{
+ u16 resource_length;
- return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
+ ACPI_FUNCTION_ENTRY();
- } /* switch (linked_list->Id) */
+ /* Determine if this is a small or large resource */
- /* Update the total */
+ if (*resource & ACPI_RDESC_TYPE_LARGE) {
+ /* Large Resource type -- length is in bytes 1-2 */
- byte_stream_size_needed += segment_size;
+ ACPI_MOVE_16_TO_16(&resource_length, (resource + 1));
- /* Point to the next object */
+ } else {
+ /* Small Resource Type -- bits 2:0 of byte 0 contain the length */
- linked_list = ACPI_PTR_ADD(struct acpi_resource,
- linked_list, linked_list->length);
+ resource_length =
+ (u16) (*resource & ACPI_RDESC_SMALL_LENGTH_MASK);
}
- /* This is the data the caller needs */
-
- *size_needed = byte_stream_size_needed;
- return_ACPI_STATUS(AE_OK);
+ return (resource_length);
}
/*******************************************************************************
*
- * FUNCTION: acpi_rs_get_list_length
+ * FUNCTION: acpi_rs_struct_option_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_source - Pointer to optional descriptor field
*
* 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: Common code to handle optional resource_source_index and
+ * resource_source fields in some Large descriptors. Used during
+ * list-to-stream conversion
*
******************************************************************************/
-acpi_status
-acpi_rs_get_list_length(u8 * byte_stream_buffer,
- u32 byte_stream_buffer_length, acpi_size * size_needed)
+static acpi_size
+acpi_rs_struct_option_length(struct acpi_resource_source *resource_source)
{
- 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");
-
- while (bytes_parsed < byte_stream_buffer_length) {
- /* The next byte in the stream is the resource type */
-
- resource_type = acpi_rs_get_resource_type(*byte_stream_buffer);
+ ACPI_FUNCTION_ENTRY();
- 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;
+ /*
+ * 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_size) resource_source->string_length + 1);
+ }
- case ACPI_RDESC_TYPE_LARGE_VENDOR:
- /*
- * Vendor Defined Resource
- */
- buffer = byte_stream_buffer;
- ++buffer;
+ return (0);
+}
- ACPI_MOVE_16_TO_16(&temp16, buffer);
- bytes_consumed = temp16 + 3;
+/*******************************************************************************
+ *
+ * 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
+ *
+ ******************************************************************************/
- /* Ensure a 32-bit boundary for the structure */
+static u32
+acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length)
+{
+ u32 string_length = 0;
+ u32 minimum_resource_length;
- temp16 = (u16) ACPI_ROUND_UP_to_32_bITS(temp16);
+ ACPI_FUNCTION_ENTRY();
- structure_size =
- ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor) +
- (temp16 * sizeof(u8));
- break;
+ /*
+ * The resource_source_index and resource_source are optional elements of some
+ * Large-type resource descriptors.
+ */
- case ACPI_RDESC_TYPE_MEMORY_32:
- /*
- * 32-Bit Memory Range Resource
- */
- bytes_consumed = 20;
+ /* Compute minimum size of the data part of the resource descriptor */
- structure_size =
- ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem32);
- break;
+ minimum_resource_length =
+ minimum_total_length - sizeof(struct asl_large_header);
- case ACPI_RDESC_TYPE_FIXED_MEMORY_32:
- /*
- * 32-Bit Fixed Memory Resource
- */
- bytes_consumed = 12;
+ /*
+ * 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_resource_length) {
+ /* Compute the length of the optional string */
- structure_size =
- ACPI_SIZEOF_RESOURCE(struct
- acpi_resource_fixed_mem32);
- break;
+ string_length = resource_length - minimum_resource_length - 1;
+ }
- case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE:
- /*
- * 64-Bit Address Resource
- */
- buffer = byte_stream_buffer;
+ /* Round up length to 32 bits for internal structure alignment */
- ++buffer;
- ACPI_MOVE_16_TO_16(&temp16, buffer);
+ return (ACPI_ROUND_UP_to_32_bITS(string_length));
+}
- bytes_consumed = temp16 + 3;
- structure_size =
- ACPI_SIZEOF_RESOURCE(struct
- acpi_resource_address64);
- break;
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_rs_get_byte_stream_length
+ *
+ * PARAMETERS: Resource - Pointer to the resource linked list
+ * size_needed - Where the required size is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Takes a linked list of internal resource descriptors and
+ * calculates the size buffer needed to hold the corresponding
+ * external resource byte stream.
+ *
+ ******************************************************************************/
- case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE:
- /*
- * 64-Bit Address Resource
- */
- buffer = byte_stream_buffer;
+acpi_status
+acpi_rs_get_byte_stream_length(struct acpi_resource * resource,
+ acpi_size * size_needed)
+{
+ acpi_size byte_stream_size_needed = 0;
+ acpi_size segment_size;
- ++buffer;
- ACPI_MOVE_16_TO_16(&temp16, buffer);
+ ACPI_FUNCTION_TRACE("rs_get_byte_stream_length");
- bytes_consumed = temp16 + 3;
+ /* Traverse entire list of internal resource descriptors */
- /*
- * 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.
- */
- if (43 < temp16) {
- temp8 = (u8) (temp16 - 44);
- } else {
- temp8 = 0;
- }
+ while (resource) {
+ /* Validate the descriptor type */
- /* Ensure a 64-bit boundary for the structure */
+ if (resource->type > ACPI_RSTYPE_MAX) {
+ return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
+ }
- temp8 = (u8) ACPI_ROUND_UP_to_64_bITS(temp8);
+ /* Get the base size of the (external stream) resource descriptor */
- structure_size =
- ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64)
- + (temp8 * sizeof(u8));
- break;
+ segment_size = acpi_gbl_stream_sizes[resource->type];
- case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE:
+ /*
+ * Augment the base size for descriptors with optional and/or
+ * variable-length fields
+ */
+ switch (resource->type) {
+ case ACPI_RSTYPE_VENDOR:
/*
- * 32-Bit Address Resource
+ * Vendor Defined Res