1/******************************************************************************* 2 * 3 * Module Name: rslist - Linked list utilities 4 * 5 ******************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44#include <acpi/acpi.h> 45#include <acpi/acresrc.h> 46 47#define _COMPONENT ACPI_RESOURCES 48ACPI_MODULE_NAME("rslist") 49 50/******************************************************************************* 51 * 52 * FUNCTION: acpi_rs_convert_aml_to_resources 53 * 54 * PARAMETERS: acpi_walk_aml_callback 55 * resource_ptr - Pointer to the buffer that will 56 * contain the output structures 57 * 58 * RETURN: Status 59 * 60 * DESCRIPTION: Convert an AML resource to an internal representation of the 61 * resource that is aligned and easier to access. 62 * 63 ******************************************************************************/ 64acpi_status 65acpi_rs_convert_aml_to_resources(u8 * aml, 66 u32 length, 67 u32 offset, u8 resource_index, void **context) 68{ 69 struct acpi_resource **resource_ptr = 70 ACPI_CAST_INDIRECT_PTR(struct acpi_resource, context); 71 struct acpi_resource *resource; 72 acpi_status status; 73 74 ACPI_FUNCTION_TRACE(rs_convert_aml_to_resources); 75 76 /* 77 * Check that the input buffer and all subsequent pointers into it 78 * are aligned on a native word boundary. Most important on IA64 79 */ 80 resource = *resource_ptr; 81 if (ACPI_IS_MISALIGNED(resource)) { 82 ACPI_WARNING((AE_INFO, 83 "Misaligned resource pointer %p", resource)); 84 } 85 86 /* Convert the AML byte stream resource to a local resource struct */ 87 88 status = 89 acpi_rs_convert_aml_to_resource(resource, 90 ACPI_CAST_PTR(union aml_resource, 91 aml), 92 acpi_gbl_get_resource_dispatch 93 [resource_index]); 94 if (ACPI_FAILURE(status)) { 95 ACPI_EXCEPTION((AE_INFO, status, 96 "Could not convert AML resource (Type %X)", 97 *aml)); 98 return_ACPI_STATUS(status); 99 } 100 101 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, 102 "Type %.2X, AmlLength %.2X InternalLength %.2X\n", 103 acpi_ut_get_resource_type(aml), length, 104 resource->length)); 105 106 /* Point to the next structure in the output buffer */ 107 108 *resource_ptr = ACPI_ADD_PTR(void, resource, resource->length); 109 return_ACPI_STATUS(AE_OK); 110} 111 112/******************************************************************************* 113 * 114 * FUNCTION: acpi_rs_convert_resources_to_aml 115 * 116 * PARAMETERS: Resource - Pointer to the resource linked list 117 * aml_size_needed - Calculated size of the byte stream 118 * needed from calling acpi_rs_get_aml_length() 119 * The size of the output_buffer is 120 * guaranteed to be >= aml_size_needed 121 * output_buffer - Pointer to the buffer that will 122 * contain the byte stream 123 * 124 * RETURN: Status 125 * 126 * DESCRIPTION: Takes the resource linked list and parses it, creating a 127 * byte stream of resources in the caller's output buffer 128 * 129 ******************************************************************************/ 130 131acpi_status 132acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, 133 acpi_size aml_size_needed, u8 * output_buffer) 134{ 135 u8 *aml = output_buffer; 136 u8 *end_aml = output_buffer + aml_size_needed; 137 acpi_status status; 138 139 ACPI_FUNCTION_TRACE(rs_convert_resources_to_aml); 140 141 /* Walk the resource descriptor list, convert each descriptor */ 142 143 while (aml < end_aml) { 144 145 /* Validate the (internal) Resource Type */ 146 147 if (resource->type > ACPI_RESOURCE_TYPE_MAX) { 148 ACPI_ERROR((AE_INFO, 149 "Invalid descriptor type (%X) in resource list", 150 resource->type)); 151 return_ACPI_STATUS(AE_BAD_DATA); 152 } 153 154 /* Perform the conversion */ 155 156 status = acpi_rs_convert_resource_to_aml(resource, ACPI_CAST_PTR(union 157 aml_resource, 158 aml), 159 acpi_gbl_set_resource_dispatch 160 [resource->type]); 161 if (ACPI_FAILURE(status)) { 162 ACPI_EXCEPTION((AE_INFO, status, 163 "Could not convert resource (type %X) to AML", 164 resource->type)); 165 return_ACPI_STATUS(status); 166 } 167 168 /* Perform final sanity check on the new AML resource descriptor */ 169 170 status = 171 acpi_ut_validate_resource(ACPI_CAST_PTR 172 (union aml_resource, aml), NULL); 173 if (ACPI_FAILURE(status)) { 174 return_ACPI_STATUS(status); 175 } 176 177 /* Check for end-of-list, normal exit */ 178 179 if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { 180 181 /* An End Tag indicates the end of the input Resource Template */ 182 183 return_ACPI_STATUS(AE_OK); 184 } 185 186 /* 187 * Extract the total length of the new descriptor and set the 188 * Aml to point to the next (output) resource descriptor 189 */ 190 aml += acpi_ut_get_descriptor_length(aml); 191 192 /* Point to the next input resource descriptor */ 193 194 resource = 195 ACPI_ADD_PTR(struct acpi_resource, resource, 196 resource->length); 197 } 198 199 /* Completed buffer, but did not find an end_tag resource descriptor */ 200 201 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); 202} 203