^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Module Name: rscalc - Calculate stream and list lengths
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <acpi/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "accommon.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "acresrc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "acnamesp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #define _COMPONENT ACPI_RESOURCES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) ACPI_MODULE_NAME("rscalc")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /* Local prototypes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) static u8 acpi_rs_count_set_bits(u16 bit_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static acpi_rs_length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) acpi_rs_struct_option_length(struct acpi_resource_source *resource_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static u32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * FUNCTION: acpi_rs_count_set_bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * PARAMETERS: bit_field - Field in which to count bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * RETURN: Number of bits set within the field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * DESCRIPTION: Count the number of bits set in a resource field. Used for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * (Short descriptor) interrupt and DMA lists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static u8 acpi_rs_count_set_bits(u16 bit_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) u8 bits_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) ACPI_FUNCTION_ENTRY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) for (bits_set = 0; bit_field; bits_set++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* Zero the least significant bit that is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) bit_field &= (u16) (bit_field - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return (bits_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * FUNCTION: acpi_rs_struct_option_length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * PARAMETERS: resource_source - Pointer to optional descriptor field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * DESCRIPTION: Common code to handle optional resource_source_index and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * resource_source fields in some Large descriptors. Used during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * list-to-stream conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static acpi_rs_length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) acpi_rs_struct_option_length(struct acpi_resource_source *resource_source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) ACPI_FUNCTION_ENTRY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * If the resource_source string is valid, return the size of the string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * (string_length includes the NULL terminator) plus the size of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * resource_source_index (1).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (resource_source->string_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return ((acpi_rs_length)(resource_source->string_length + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * FUNCTION: acpi_rs_stream_option_length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * PARAMETERS: resource_length - Length from the resource header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * minimum_total_length - Minimum length of this resource, before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * any optional fields. Includes header size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * RETURN: Length of optional string (0 if no string present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * DESCRIPTION: Common code to handle optional resource_source_index and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * resource_source fields in some Large descriptors. Used during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * stream-to-list conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static u32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) acpi_rs_stream_option_length(u32 resource_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) u32 minimum_aml_resource_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) u32 string_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) ACPI_FUNCTION_ENTRY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * The resource_source_index and resource_source are optional elements of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * some Large-type resource descriptors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * If the length of the actual resource descriptor is greater than the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * ACPI spec-defined minimum length, it means that a resource_source_index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * exists and is followed by a (required) null terminated string. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * string length (including the null terminator) is the resource length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * minus the minimum length, minus one byte for the resource_source_index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (resource_length > minimum_aml_resource_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* Compute the length of the optional string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) string_length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) resource_length - minimum_aml_resource_length - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * Round the length up to a multiple of the native word in order to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * guarantee that the entire resource descriptor is native word aligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return ((u32) ACPI_ROUND_UP_TO_NATIVE_WORD(string_length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * FUNCTION: acpi_rs_get_aml_length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * PARAMETERS: resource - Pointer to the resource linked list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * resource_list_size - Size of the resource linked list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * size_needed - Where the required size is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * DESCRIPTION: Takes a linked list of internal resource descriptors and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * calculates the size buffer needed to hold the corresponding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * external resource byte stream.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) acpi_rs_get_aml_length(struct acpi_resource *resource,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) acpi_size resource_list_size, acpi_size *size_needed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) acpi_size aml_size_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct acpi_resource *resource_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) acpi_rs_length total_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ACPI_FUNCTION_TRACE(rs_get_aml_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* Traverse entire list of internal resource descriptors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) resource_end =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ACPI_ADD_PTR(struct acpi_resource, resource, resource_list_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) while (resource < resource_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /* Validate the descriptor type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* Sanity check the length. It must not be zero, or we loop forever */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (!resource->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /* Get the base size of the (external stream) resource descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) total_size = acpi_gbl_aml_resource_sizes[resource->type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * Augment the base size for descriptors with optional and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * variable-length fields
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) switch (resource->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) case ACPI_RESOURCE_TYPE_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /* Length can be 3 or 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (resource->data.irq.descriptor_length == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) total_size--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) case ACPI_RESOURCE_TYPE_START_DEPENDENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* Length can be 1 or 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (resource->data.irq.descriptor_length == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) total_size--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) case ACPI_RESOURCE_TYPE_VENDOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * Vendor Defined Resource:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * For a Vendor Specific resource, if the Length is between 1 and 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * it will be created as a Small Resource data type, otherwise it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * is a Large Resource data type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (resource->data.vendor.byte_length > 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* Base size of a Large resource descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) total_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) sizeof(struct aml_resource_large_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /* Add the size of the vendor-specific data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) total_size = (acpi_rs_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) (total_size + resource->data.vendor.byte_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) case ACPI_RESOURCE_TYPE_END_TAG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * End Tag:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * We are done -- return the accumulated total size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) *size_needed = aml_size_needed + total_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /* Normal exit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) case ACPI_RESOURCE_TYPE_ADDRESS16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * 16-Bit Address Resource:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * Add the size of the optional resource_source info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) total_size = (acpi_rs_length)(total_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) acpi_rs_struct_option_length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) (&resource->data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) address16.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) resource_source));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) case ACPI_RESOURCE_TYPE_ADDRESS32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * 32-Bit Address Resource:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * Add the size of the optional resource_source info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) total_size = (acpi_rs_length)(total_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) acpi_rs_struct_option_length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) (&resource->data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) address32.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) resource_source));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) case ACPI_RESOURCE_TYPE_ADDRESS64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * 64-Bit Address Resource:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * Add the size of the optional resource_source info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) total_size = (acpi_rs_length)(total_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) acpi_rs_struct_option_length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) (&resource->data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) address64.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) resource_source));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * Extended IRQ Resource:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * Add the size of each additional optional interrupt beyond the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * required 1 (4 bytes for each u32 interrupt number)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) total_size = (acpi_rs_length)(total_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) ((resource->data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) extended_irq.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) interrupt_count -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 1) * 4) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* Add the size of the optional resource_source info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) acpi_rs_struct_option_length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) (&resource->data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) extended_irq.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) resource_source));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) case ACPI_RESOURCE_TYPE_GPIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) total_size = (acpi_rs_length)(total_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) (resource->data.gpio.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) pin_table_length * 2) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) resource->data.gpio.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) resource_source.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) string_length +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) resource->data.gpio.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) vendor_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) case ACPI_RESOURCE_TYPE_PIN_FUNCTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) total_size = (acpi_rs_length)(total_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) (resource->data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) pin_function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) pin_table_length * 2) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) resource->data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) pin_function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) resource_source.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) string_length +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) resource->data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) pin_function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) vendor_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) case ACPI_RESOURCE_TYPE_SERIAL_BUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) total_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) acpi_gbl_aml_resource_serial_bus_sizes[resource->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) common_serial_bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) total_size = (acpi_rs_length)(total_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) resource->data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) i2c_serial_bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) resource_source.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) string_length +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) resource->data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) i2c_serial_bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) vendor_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) case ACPI_RESOURCE_TYPE_PIN_CONFIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) total_size = (acpi_rs_length)(total_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) (resource->data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) pin_config.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) pin_table_length * 2) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) resource->data.pin_config.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) resource_source.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) string_length +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) resource->data.pin_config.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) vendor_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) case ACPI_RESOURCE_TYPE_PIN_GROUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) total_size = (acpi_rs_length)(total_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) (resource->data.pin_group.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) pin_table_length * 2) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) resource->data.pin_group.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) resource_label.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) string_length +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) resource->data.pin_group.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) vendor_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) case ACPI_RESOURCE_TYPE_PIN_GROUP_FUNCTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) total_size = (acpi_rs_length)(total_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) resource->data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) pin_group_function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) resource_source.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) string_length +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) resource->data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) pin_group_function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) resource_source_label.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) string_length +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) resource->data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) pin_group_function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) vendor_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) case ACPI_RESOURCE_TYPE_PIN_GROUP_CONFIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) total_size = (acpi_rs_length)(total_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) resource->data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) pin_group_config.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) resource_source.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) string_length +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) resource->data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) pin_group_config.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) resource_source_label.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) string_length +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) resource->data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) pin_group_config.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) vendor_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /* Update the total */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) aml_size_needed += total_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /* Point to the next object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) resource =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ACPI_ADD_PTR(struct acpi_resource, resource,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) resource->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /* Did not find an end_tag resource descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) * FUNCTION: acpi_rs_get_list_length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * PARAMETERS: aml_buffer - Pointer to the resource byte stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * aml_buffer_length - Size of aml_buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * size_needed - Where the size needed is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * DESCRIPTION: Takes an external resource byte stream and calculates the size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * buffer needed to hold the corresponding internal resource
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * descriptor linked list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) acpi_rs_get_list_length(u8 *aml_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) u32 aml_buffer_length, acpi_size *size_needed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) u8 *end_aml;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) u8 *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) u32 buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) u16 temp16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) u16 resource_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) u32 extra_struct_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) u8 resource_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) u8 minimum_aml_resource_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) union aml_resource *aml_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) ACPI_FUNCTION_TRACE(rs_get_list_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) *size_needed = ACPI_RS_SIZE_MIN; /* Minimum size is one end_tag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) end_aml = aml_buffer + aml_buffer_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) /* Walk the list of AML resource descriptors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) while (aml_buffer < end_aml) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /* Validate the Resource Type and Resource Length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) acpi_ut_validate_resource(NULL, aml_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) &resource_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * Exit on failure. Cannot continue because the descriptor length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * may be bogus also.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) aml_resource = (void *)aml_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /* Get the resource length and base (minimum) AML size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) resource_length = acpi_ut_get_resource_length(aml_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) minimum_aml_resource_length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) acpi_gbl_resource_aml_sizes[resource_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * Augment the size for descriptors with optional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * and/or variable length fields
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) extra_struct_bytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) buffer =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) aml_buffer + acpi_ut_get_resource_header_length(aml_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) switch (acpi_ut_get_resource_type(aml_buffer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) case ACPI_RESOURCE_NAME_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) * IRQ Resource:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) * Get the number of bits set in the 16-bit IRQ mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) ACPI_MOVE_16_TO_16(&temp16, buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) extra_struct_bytes = acpi_rs_count_set_bits(temp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) case ACPI_RESOURCE_NAME_DMA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * DMA Resource:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * Get the number of bits set in the 8-bit DMA mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) extra_struct_bytes = acpi_rs_count_set_bits(*buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) case ACPI_RESOURCE_NAME_VENDOR_SMALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) case ACPI_RESOURCE_NAME_VENDOR_LARGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * Vendor Resource:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * Get the number of vendor data bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) extra_struct_bytes = resource_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * There is already one byte included in the minimum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) * descriptor size. If there are extra struct bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * subtract one from the count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (extra_struct_bytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) extra_struct_bytes--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) case ACPI_RESOURCE_NAME_END_TAG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * End Tag: This is the normal exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) case ACPI_RESOURCE_NAME_ADDRESS32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) case ACPI_RESOURCE_NAME_ADDRESS16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) case ACPI_RESOURCE_NAME_ADDRESS64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * Address Resource:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * Add the size of the optional resource_source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) extra_struct_bytes =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) acpi_rs_stream_option_length(resource_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) minimum_aml_resource_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) case ACPI_RESOURCE_NAME_EXTENDED_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * Extended IRQ Resource:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * Using the interrupt_table_length, add 4 bytes for each additional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * interrupt. Note: at least one interrupt is required and is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * included in the minimum descriptor size (reason for the -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) extra_struct_bytes = (buffer[1] - 1) * sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) /* Add the size of the optional resource_source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) extra_struct_bytes +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) acpi_rs_stream_option_length(resource_length -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) extra_struct_bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) minimum_aml_resource_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) case ACPI_RESOURCE_NAME_GPIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /* Vendor data is optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (aml_resource->gpio.vendor_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) extra_struct_bytes +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) aml_resource->gpio.vendor_offset -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) aml_resource->gpio.pin_table_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) aml_resource->gpio.vendor_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) extra_struct_bytes +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) aml_resource->large_header.resource_length +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) sizeof(struct aml_resource_large_header) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) aml_resource->gpio.pin_table_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) case ACPI_RESOURCE_NAME_PIN_FUNCTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) /* Vendor data is optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (aml_resource->pin_function.vendor_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) extra_struct_bytes +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) aml_resource->pin_function.vendor_offset -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) aml_resource->pin_function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) pin_table_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) aml_resource->pin_function.vendor_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) extra_struct_bytes +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) aml_resource->large_header.resource_length +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) sizeof(struct aml_resource_large_header) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) aml_resource->pin_function.pin_table_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) case ACPI_RESOURCE_NAME_SERIAL_BUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) minimum_aml_resource_length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) acpi_gbl_resource_aml_serial_bus_sizes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) [aml_resource->common_serial_bus.type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) extra_struct_bytes +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) aml_resource->common_serial_bus.resource_length -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) minimum_aml_resource_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) case ACPI_RESOURCE_NAME_PIN_CONFIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /* Vendor data is optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (aml_resource->pin_config.vendor_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) extra_struct_bytes +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) aml_resource->pin_config.vendor_offset -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) aml_resource->pin_config.pin_table_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) aml_resource->pin_config.vendor_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) extra_struct_bytes +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) aml_resource->large_header.resource_length +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) sizeof(struct aml_resource_large_header) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) aml_resource->pin_config.pin_table_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) case ACPI_RESOURCE_NAME_PIN_GROUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) extra_struct_bytes +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) aml_resource->pin_group.vendor_offset -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) aml_resource->pin_group.pin_table_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) aml_resource->pin_group.vendor_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) case ACPI_RESOURCE_NAME_PIN_GROUP_FUNCTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) extra_struct_bytes +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) aml_resource->pin_group_function.vendor_offset -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) aml_resource->pin_group_function.res_source_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) aml_resource->pin_group_function.vendor_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) case ACPI_RESOURCE_NAME_PIN_GROUP_CONFIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) extra_struct_bytes +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) aml_resource->pin_group_config.vendor_offset -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) aml_resource->pin_group_config.res_source_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) aml_resource->pin_group_config.vendor_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) * Update the required buffer size for the internal descriptor structs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * Important: Round the size up for the appropriate alignment. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * is a requirement on IA64.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (acpi_ut_get_resource_type(aml_buffer) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) ACPI_RESOURCE_NAME_SERIAL_BUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) buffer_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) acpi_gbl_resource_struct_serial_bus_sizes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) [aml_resource->common_serial_bus.type] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) extra_struct_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) buffer_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) acpi_gbl_resource_struct_sizes[resource_index] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) extra_struct_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) buffer_size = (u32)ACPI_ROUND_UP_TO_NATIVE_WORD(buffer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) *size_needed += buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) "Type %.2X, AmlLength %.2X InternalLength %.2X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) acpi_ut_get_resource_type(aml_buffer),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) acpi_ut_get_descriptor_length(aml_buffer),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) buffer_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * Point to the next resource within the AML stream using the length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * contained in the resource descriptor header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) aml_buffer += acpi_ut_get_descriptor_length(aml_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) /* Did not find an end_tag resource descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) * FUNCTION: acpi_rs_get_pci_routing_table_length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) * PARAMETERS: package_object - Pointer to the package object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) * buffer_size_needed - u32 pointer of the size buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) * needed to properly return the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * parsed data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) * DESCRIPTION: Given a package representing a PCI routing table, this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) * calculates the size of the corresponding linked list of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) * descriptions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) acpi_size *buffer_size_needed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) u32 number_of_elements;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) acpi_size temp_size_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) union acpi_operand_object **top_object_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) u32 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) union acpi_operand_object *package_element;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) union acpi_operand_object **sub_object_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) u8 name_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) u32 table_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) ACPI_FUNCTION_TRACE(rs_get_pci_routing_table_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) number_of_elements = package_object->package.count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) * Calculate the size of the return buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) * The base size is the number of elements * the sizes of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) * structures. Additional space for the strings is added below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * The minus one is to subtract the size of the u8 Source[1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) * member because it is added below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) * But each PRT_ENTRY structure has a pointer to a string and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * the size of that string must be found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) top_object_list = package_object->package.elements;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) for (index = 0; index < number_of_elements; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) /* Dereference the subpackage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) package_element = *top_object_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) /* We must have a valid Package object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (!package_element ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) (package_element->common.type != ACPI_TYPE_PACKAGE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * The sub_object_list will now point to an array of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) * four IRQ elements: Address, Pin, Source and source_index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) sub_object_list = package_element->package.elements;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /* Scan the irq_table_elements for the Source Name String */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) name_found = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) for (table_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) table_index < package_element->package.count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) && !name_found; table_index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (*sub_object_list && /* Null object allowed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) ((ACPI_TYPE_STRING ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) (*sub_object_list)->common.type) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) ((ACPI_TYPE_LOCAL_REFERENCE ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) (*sub_object_list)->common.type) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) ((*sub_object_list)->reference.class ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) ACPI_REFCLASS_NAME)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) name_found = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) /* Look at the next element */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) sub_object_list++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) temp_size_needed += (sizeof(struct acpi_pci_routing_table) - 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) /* Was a String type found? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (name_found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if ((*sub_object_list)->common.type == ACPI_TYPE_STRING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) * The length String.Length field does not include the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) * terminating NULL, add 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) temp_size_needed += ((acpi_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) (*sub_object_list)->string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) length + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) temp_size_needed += acpi_ns_get_pathname_length((*sub_object_list)->reference.node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) * If no name was found, then this is a NULL, which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) * translated as a u32 zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) temp_size_needed += sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) /* Round up the size since each element must be aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) temp_size_needed = ACPI_ROUND_UP_TO_64BIT(temp_size_needed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) /* Point to the next union acpi_operand_object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) top_object_list++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) * Add an extra element to the end of the list, essentially a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) * NULL terminator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) *buffer_size_needed =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) temp_size_needed + sizeof(struct acpi_pci_routing_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }