summaryrefslogtreecommitdiff
path: root/drivers/acpi/resources/rsutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/resources/rsutils.c')
-rw-r--r--drivers/acpi/resources/rsutils.c269
1 files changed, 133 insertions, 136 deletions
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
index 9d503de1a349..7613033f5dcf 100644
--- a/drivers/acpi/resources/rsutils.c
+++ b/drivers/acpi/resources/rsutils.c
@@ -50,6 +50,64 @@ 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;
+
+ /* 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;
+
+ /* 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
@@ -64,6 +122,7 @@ ACPI_MODULE_NAME("rsutils")
* 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)
{
@@ -73,22 +132,30 @@ acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type)
for (i = 0; i < item_count; i++) {
switch (move_type) {
- case ACPI_MOVE_TYPE_16_TO_32:
- ACPI_MOVE_16_TO_32(&((u32 *) destination)[i],
- &((u16 *) source)[i]);
- break;
+ /*
+ * 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;
- case ACPI_MOVE_TYPE_32_TO_16:
- ACPI_MOVE_32_TO_16(&((u16 *) destination)[i],
- &((u32 *) source)[i]);
+ /*
+ * 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(&((u16 *) destination)[i],
+ &((u16 *) source)[i]);
break;
- case ACPI_MOVE_TYPE_32_TO_32:
+ case ACPI_RSC_MOVE32:
ACPI_MOVE_32_TO_32(&((u32 *) destination)[i],
&((u32 *) source)[i]);
break;
- case ACPI_MOVE_TYPE_64_TO_64:
+ case ACPI_RSC_MOVE64:
ACPI_MOVE_64_TO_64(&((u64 *) destination)[i],
&((u64 *) source)[i]);
break;
@@ -148,80 +215,57 @@ struct acpi_resource_info *acpi_rs_get_resource_info(u8 resource_type)
/*******************************************************************************
*
- * FUNCTION: acpi_rs_get_resource_length
+ * FUNCTION: acpi_rs_set_resource_length
*
- * PARAMETERS: Aml - Pointer to the raw AML resource descriptor
+ * PARAMETERS: total_length - Length of the AML descriptor, including
+ * the header and length fields.
+ * Aml - Pointer to the raw AML descriptor
*
- * RETURN: Byte Length
+ * RETURN: None
*
- * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By
- * definition, this does not include the size of the descriptor
- * header or the length field itself.
+ * 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.
*
******************************************************************************/
-u16 acpi_rs_get_resource_length(union aml_resource * aml)
+void
+acpi_rs_set_resource_length(acpi_rsdesc_size total_length,
+ union aml_resource *aml)
{
- u16 resource_length;
+ acpi_rs_length resource_length;
ACPI_FUNCTION_ENTRY();
/* Determine if this is a small or large resource */
- if (aml->large_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) {
+ if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) {
/* Large Resource type -- bytes 1-2 contain the 16-bit length */
- ACPI_MOVE_16_TO_16(&resource_length,
- &aml->large_header.resource_length);
+ resource_length = (acpi_rs_length)
+ (total_length - sizeof(struct aml_resource_large_header));
+
+ /* Insert length into the Large descriptor length field */
+ ACPI_MOVE_16_TO_16(&aml->large_header.resource_length,
+ &resource_length);
} else {
/* Small Resource type -- bits 2:0 of byte 0 contain the length */
- resource_length = (u16) (aml->small_header.descriptor_type &
- ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK);
- }
-
- return (resource_length);
-}
+ resource_length = (acpi_rs_length)
+ (total_length - sizeof(struct aml_resource_small_header));
-/*******************************************************************************
- *
- * FUNCTION: acpi_rs_get_descriptor_length
- *
- * PARAMETERS: Aml - Pointer to the raw AML resource descriptor
- *
- * RETURN: Byte length
- *
- * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the
- * length of the descriptor header and the length field itself.
- * Used to walk descriptor lists.
- *
- ******************************************************************************/
-
-u32 acpi_rs_get_descriptor_length(union aml_resource * aml)
-{
- u32 descriptor_length;
-
- ACPI_FUNCTION_ENTRY();
-
- /* Determine if this is a small or large resource */
-
- if (aml->large_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) {
- /* Large Resource type -- bytes 1-2 contain the 16-bit length */
+ /* Insert length into the descriptor type byte */
- ACPI_MOVE_16_TO_32(&descriptor_length,
- &aml->large_header.resource_length);
- descriptor_length += sizeof(struct aml_resource_large_header);
+ aml->small_header.descriptor_type = (u8)
- } else {
- /* Small Resource type -- bits 2:0 of byte 0 contain the length */
+ /* Clear any existing length, preserving descriptor type bits */
+ ((aml->small_header.
+ descriptor_type & ~ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK)
- descriptor_length = (u32) (aml->small_header.descriptor_type &
- ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK);
- descriptor_length += sizeof(struct aml_resource_small_header);
+ | resource_length);
}
-
- return (descriptor_length);
}
/*******************************************************************************
@@ -243,71 +287,18 @@ u32 acpi_rs_get_descriptor_length(union aml_resource * aml)
void
acpi_rs_set_resource_header(u8 descriptor_type,
- acpi_size total_length, union aml_resource *aml)
+ acpi_rsdesc_size total_length,
+ union aml_resource *aml)
{
- u16 resource_length;
-
ACPI_FUNCTION_ENTRY();
- /* Set the descriptor type */
+ /* Set the Descriptor Type */
aml->small_header.descriptor_type = descriptor_type;
- /* Determine if this is a small or large resource */
-
- if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) {
- /* Large Resource type -- bytes 1-2 contain the 16-bit length */
-
- resource_length =
- (u16) (total_length -
- sizeof(struct aml_resource_large_header));
-
- /* Insert length into the Large descriptor length field */
-
- ACPI_MOVE_16_TO_16(&aml->large_header.resource_length,
- &resource_length);
- } else {
- /* Small Resource type -- bits 2:0 of byte 0 contain the length */
-
- resource_length =
- (u16) (total_length -
- sizeof(struct aml_resource_small_header));
-
- /* Insert length into the descriptor type byte */
-
- aml->small_header.descriptor_type |= (u8) resource_length;
- }
-}
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_rs_get_resource_type
- *
- * PARAMETERS: resource_type - Byte 0 of a resource descriptor
- *
- * RETURN: The Resource Type with no extraneous bits (except the
- * Large/Small descriptor bit -- this is left alone)
- *
- * DESCRIPTION: Extract the Resource Type/Name from the first byte of
- * a resource descriptor.
- *
- ******************************************************************************/
-
-u8 acpi_rs_get_resource_type(u8 resource_type)
-{
- ACPI_FUNCTION_ENTRY();
+ /* Set the Resource Length */
- /* Determine if this is a small or large resource */
-
- if (resource_type & ACPI_RESOURCE_NAME_LARGE) {
- /* Large Resource Type -- bits 6:0 contain the name */
-
- return (resource_type);
- } else {
- /* Small Resource Type -- bits 6:3 contain the name */
-
- return ((u8) (resource_type & ACPI_RESOURCE_NAME_SMALL_MASK));
- }
+ acpi_rs_set_resource_length(total_length, aml);
}
/*******************************************************************************
@@ -360,13 +351,13 @@ static u16 acpi_rs_strcpy(char *destination, char *source)
*
******************************************************************************/
-u16
-acpi_rs_get_resource_source(u16 resource_length,
- acpi_size minimum_length,
+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_size total_length;
+ acpi_rsdesc_size total_length;
u8 *aml_resource_source;
ACPI_FUNCTION_ENTRY();
@@ -382,7 +373,7 @@ acpi_rs_get_resource_source(u16 resource_length,
* Note: Some resource descriptors will have an additional null, so
* we add 1 to the minimum length.
*/
- if (total_length > (minimum_length + 1)) {
+ if (total_length > (acpi_rsdesc_size) (minimum_length + 1)) {
/* Get the resource_source_index */
resource_source->index = aml_resource_source[0];
@@ -398,20 +389,26 @@ acpi_rs_get_resource_source(u16 resource_length,
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]);
- /*
- * 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.
- */
- return ((u16)
- ACPI_ROUND_UP_to_32_bITS(resource_source->
- string_length));
+ return ((acpi_rs_length) total_length);
} else {
/* resource_source is not present */
@@ -434,18 +431,18 @@ acpi_rs_get_resource_source(u16 resource_length,
*
* RETURN: Total length of the AML descriptor
*
- * DESCRIPTION: Convert an optoinal resource_source from internal format to a
+ * DESCRIPTION: Convert an optional resource_source from internal format to a
* raw AML resource descriptor
*
******************************************************************************/
-acpi_size
+acpi_rsdesc_size
acpi_rs_set_resource_source(union aml_resource * aml,
- acpi_size minimum_length,
+ acpi_rs_length minimum_length,
struct acpi_resource_source * resource_source)
{
u8 *aml_resource_source;
- acpi_size descriptor_length;
+ acpi_rsdesc_size descriptor_length;
ACPI_FUNCTION_ENTRY();
@@ -472,7 +469,7 @@ acpi_rs_set_resource_source(union aml_resource * aml,
* final descriptor length
*/
descriptor_length +=
- ((acpi_size) resource_source->string_length + 1);
+ ((acpi_rsdesc_size) resource_source->string_length + 1);
}
/* Return the new total length of the AML descriptor */