acpi_status acpi_rs_calculate_list_length ( u8 *byte_stream_buffer, u32 byte_stream_buffer_length, u32 *size_needed) { u32 buffer_size = 0; u32 bytes_parsed = 0; u8 number_of_interrupts = 0; u8 number_of_channels = 0; u8 resource_type; u32 structure_size; u32 bytes_consumed; u8 *buffer; u8 temp8; u16 temp16; u8 index; u8 additional_bytes; FUNCTION_TRACE ("Rs_calculate_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); switch (resource_type) { case RESOURCE_DESC_MEMORY_24: /* * 24-Bit Memory Resource */ bytes_consumed = 12; structure_size = SIZEOF_RESOURCE (acpi_resource_mem24); break; case RESOURCE_DESC_LARGE_VENDOR: /* * Vendor Defined Resource */ buffer = byte_stream_buffer; ++buffer; MOVE_UNALIGNED16_TO_16 (&temp16, buffer); bytes_consumed = temp16 + 3; /* * Ensure a 32-bit boundary for the structure */ temp16 = (u16) ROUND_UP_TO_32_bITS (temp16); structure_size = SIZEOF_RESOURCE (acpi_resource_vendor) + (temp16 * sizeof (u8)); break; case RESOURCE_DESC_MEMORY_32: /* * 32-Bit Memory Range Resource */ bytes_consumed = 20; structure_size = SIZEOF_RESOURCE (acpi_resource_mem32); break; case RESOURCE_DESC_FIXED_MEMORY_32: /* * 32-Bit Fixed Memory Resource */ bytes_consumed = 12; structure_size = SIZEOF_RESOURCE (acpi_resource_fixed_mem32); break; case RESOURCE_DESC_QWORD_ADDRESS_SPACE: /* * 64-Bit Address Resource */ buffer = byte_stream_buffer; ++buffer; MOVE_UNALIGNED16_TO_16 (&temp16, buffer); bytes_consumed = temp16 + 3; /* * 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 termininated 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 terminiated string. */ if (43 < temp16) { temp8 = (u8) (temp16 - 44); } else { temp8 = 0; } /* * Ensure a 64-bit boundary for the structure */ temp8 = (u8) ROUND_UP_TO_64_bITS (temp8); structure_size = SIZEOF_RESOURCE (acpi_resource_address64) + (temp8 * sizeof (u8)); break; case RESOURCE_DESC_DWORD_ADDRESS_SPACE: /* * 32-Bit Address Resource */ buffer = byte_stream_buffer; ++buffer; MOVE_UNALIGNED16_TO_16 (&temp16, buffer); bytes_consumed = temp16 + 3; /* * Resource Source Index and Resource Source are * optional elements. Check the length of the * Bytestream. If it is greater than 23, that * means that an Index exists and is followed by * a null termininated 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 terminiated string. */ if (23 < temp16) { temp8 = (u8) (temp16 - 24); } else { temp8 = 0; } /* * Ensure a 32-bit boundary for the structure */ temp8 = (u8) ROUND_UP_TO_32_bITS (temp8); structure_size = SIZEOF_RESOURCE (acpi_resource_address32) + (temp8 * sizeof (u8)); break; case RESOURCE_DESC_WORD_ADDRESS_SPACE: /* * 16-Bit Address Resource */ buffer = byte_stream_buffer; ++buffer; MOVE_UNALIGNED16_TO_16 (&temp16, buffer); bytes_consumed = temp16 + 3; /* * Resource Source Index and Resource Source are * optional elements. Check the length of the * Bytestream. If it is greater than 13, that * means that an Index exists and is followed by * a null termininated 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 terminiated string. */ if (13 < temp16) { temp8 = (u8) (temp16 - 14); } else { temp8 = 0; } /* * Ensure a 32-bit boundary for the structure */ temp8 = (u8) ROUND_UP_TO_32_bITS (temp8); structure_size = SIZEOF_RESOURCE (acpi_resource_address16) + (temp8 * sizeof (u8)); break; case RESOURCE_DESC_EXTENDED_XRUPT: /* * Extended IRQ */ buffer = byte_stream_buffer; ++buffer; MOVE_UNALIGNED16_TO_16 (&temp16, buffer); bytes_consumed = temp16 + 3; /* * Point past the length field and the * Interrupt vector flags to save off the * Interrupt table length to the Temp8 variable. */ buffer += 3; temp8 = *buffer; /* * To compensate for multiple interrupt numbers, add 4 bytes for * each additional interrupts greater than 1 */ additional_bytes = (u8) ((temp8 - 1) * 4); /* * Resource Source Index and Resource Source are * optional elements. Check the length of the * Bytestream. If it is greater than 9, that * means that an Index exists and is followed by * a null termininated 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 terminiated string. */ if (9 + additional_bytes < temp16) { temp8 = (u8) (temp16 - (9 + additional_bytes)); } else { temp8 = 0; } /* * Ensure a 32-bit boundary for the structure */ temp8 = (u8) ROUND_UP_TO_32_bITS (temp8); structure_size = SIZEOF_RESOURCE (acpi_resource_ext_irq) + (additional_bytes * sizeof (u8)) + (temp8 * sizeof (u8)); break; case RESOURCE_DESC_IRQ_FORMAT: /* * IRQ Resource. * Determine if it there are two or three trailing bytes */ buffer = byte_stream_buffer; temp8 = *buffer; if(temp8 & 0x01) { bytes_consumed = 4; } else { bytes_consumed = 3; } /* * Point past the descriptor */ ++buffer; /* * Look at the number of bits set */ MOVE_UNALIGNED16_TO_16 (&temp16, buffer); for (index = 0; index < 16; index++) { if (temp16 & 0x1) { ++number_of_interrupts; } temp16 >>= 1; } structure_size = SIZEOF_RESOURCE (acpi_resource_io) + (number_of_interrupts * sizeof (u32)); break; case RESOURCE_DESC_DMA_FORMAT: /* * DMA Resource */ buffer = byte_stream_buffer; bytes_consumed = 3; /* * Point past the descriptor */ ++buffer; /* * Look at the number of bits set */ temp8 = *buffer; for(index = 0; index < 8; index++) { if(temp8 & 0x1) { ++number_of_channels; } temp8 >>= 1; } structure_size = SIZEOF_RESOURCE (acpi_resource_dma) + (number_of_channels * sizeof (u32)); break; case RESOURCE_DESC_START_DEPENDENT: /* * Start Dependent Functions Resource * Determine if it there are two or three trailing bytes */ buffer = byte_stream_buffer; temp8 = *buffer; if(temp8 & 0x01) { bytes_consumed = 2; } else { bytes_consumed = 1; } structure_size = SIZEOF_RESOURCE (acpi_resource_start_dpf); break; case RESOURCE_DESC_END_DEPENDENT: /* * End Dependent Functions Resource */ bytes_consumed = 1; structure_size = ACPI_RESOURCE_LENGTH; break; case RESOURCE_DESC_IO_PORT: /* * IO Port Resource */ bytes_consumed = 8; structure_size = SIZEOF_RESOURCE (acpi_resource_io); break; case RESOURCE_DESC_FIXED_IO_PORT: /* * Fixed IO Port Resource */ bytes_consumed = 4; structure_size = SIZEOF_RESOURCE (acpi_resource_fixed_io); break; case RESOURCE_DESC_SMALL_VENDOR: /* * Vendor Specific Resource */ buffer = byte_stream_buffer; temp8 = *buffer; temp8 = (u8) (temp8 & 0x7); bytes_consumed = temp8 + 1; /* * Ensure a 32-bit boundary for the structure */ temp8 = (u8) ROUND_UP_TO_32_bITS (temp8); structure_size = SIZEOF_RESOURCE (acpi_resource_vendor) + (temp8 * sizeof (u8)); break; case RESOURCE_DESC_END_TAG: /* * End Tag */ bytes_consumed = 2; structure_size = ACPI_RESOURCE_LENGTH; byte_stream_buffer_length = bytes_parsed; break; default: /* * If we get here, everything is out of sync, * so exit with an error */ return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); break; } /* * Update the return value and counter */ buffer_size += structure_size; bytes_parsed += bytes_consumed; /* * Set the byte stream to point to the next resource */ byte_stream_buffer += bytes_consumed; } /* * This is the data the caller needs */ *size_needed = buffer_size; return_ACPI_STATUS (AE_OK); }
acpi_status acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer, u32 byte_stream_buffer_length, u8 * output_buffer) { acpi_status status; acpi_size bytes_parsed = 0; u8 resource_type = 0; acpi_size bytes_consumed = 0; u8 *buffer = output_buffer; acpi_size structure_size = 0; u8 end_tag_processed = FALSE; struct acpi_resource *resource; ACPI_FUNCTION_TRACE("rs_byte_stream_to_list"); while (bytes_parsed < byte_stream_buffer_length && !end_tag_processed) { /* The next byte in the stream is the resource type */ resource_type = acpi_rs_get_resource_type(*byte_stream_buffer); switch (resource_type) { case ACPI_RDESC_TYPE_MEMORY_24: /* * 24-Bit Memory Resource */ status = acpi_rs_memory24_resource(byte_stream_buffer, &bytes_consumed, &buffer, &structure_size); break; case ACPI_RDESC_TYPE_LARGE_VENDOR: /* * Vendor Defined Resource */ status = acpi_rs_vendor_resource(byte_stream_buffer, &bytes_consumed, &buffer, &structure_size); break; case ACPI_RDESC_TYPE_MEMORY_32: /* * 32-Bit Memory Range Resource */ status = acpi_rs_memory32_range_resource(byte_stream_buffer, &bytes_consumed, &buffer, &structure_size); break; case ACPI_RDESC_TYPE_FIXED_MEMORY_32: /* * 32-Bit Fixed Memory Resource */ status = acpi_rs_fixed_memory32_resource(byte_stream_buffer, &bytes_consumed, &buffer, &structure_size); break; case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE: case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE: /* * 64-Bit Address Resource */ status = acpi_rs_address64_resource(byte_stream_buffer, &bytes_consumed, &buffer, &structure_size); break; case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE: /* * 32-Bit Address Resource */ status = acpi_rs_address32_resource(byte_stream_buffer, &bytes_consumed, &buffer, &structure_size); break; case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE: /* * 16-Bit Address Resource */ status = acpi_rs_address16_resource(byte_stream_buffer, &bytes_consumed, &buffer, &structure_size); break; case ACPI_RDESC_TYPE_EXTENDED_XRUPT: /* * Extended IRQ */ status = acpi_rs_extended_irq_resource(byte_stream_buffer, &bytes_consumed, &buffer, &structure_size); break; case ACPI_RDESC_TYPE_IRQ_FORMAT: /* * IRQ Resource */ status = acpi_rs_irq_resource(byte_stream_buffer, &bytes_consumed, &buffer, &structure_size); break; case ACPI_RDESC_TYPE_DMA_FORMAT: /* * DMA Resource */ status = acpi_rs_dma_resource(byte_stream_buffer, &bytes_consumed, &buffer, &structure_size); break; case ACPI_RDESC_TYPE_START_DEPENDENT: /* * Start Dependent Functions Resource */ status = acpi_rs_start_depend_fns_resource (byte_stream_buffer, &bytes_consumed, &buffer, &structure_size); break; case ACPI_RDESC_TYPE_END_DEPENDENT: /* * End Dependent Functions Resource */ status = acpi_rs_end_depend_fns_resource(byte_stream_buffer, &bytes_consumed, &buffer, &structure_size); break; case ACPI_RDESC_TYPE_IO_PORT: /* * IO Port Resource */ status = acpi_rs_io_resource(byte_stream_buffer, &bytes_consumed, &buffer, &structure_size); break; case ACPI_RDESC_TYPE_FIXED_IO_PORT: /* * Fixed IO Port Resource */ status = acpi_rs_fixed_io_resource(byte_stream_buffer, &bytes_consumed, &buffer, &structure_size); break; case ACPI_RDESC_TYPE_SMALL_VENDOR: /* * Vendor Specific Resource */ status = acpi_rs_vendor_resource(byte_stream_buffer, &bytes_consumed, &buffer, &structure_size); break; case ACPI_RDESC_TYPE_END_TAG: /* * End Tag */ end_tag_processed = TRUE; status = acpi_rs_end_tag_resource(byte_stream_buffer, &bytes_consumed, &buffer, &structure_size); break; default: /* * Invalid/Unknown resource type */ status = AE_AML_INVALID_RESOURCE_TYPE; break; } if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* Update the return value and counter */ bytes_parsed += bytes_consumed; /* Set the byte stream to point to the next resource */ byte_stream_buffer += bytes_consumed; /* Set the Buffer to the next structure */ resource = ACPI_CAST_PTR(struct acpi_resource, buffer); resource->length = (u32) ACPI_ALIGN_RESOURCE_SIZE(resource->length); buffer += ACPI_ALIGN_RESOURCE_SIZE(structure_size); } /* Check the reason for exiting the while loop */ if (!end_tag_processed) { return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); } return_ACPI_STATUS(AE_OK); }