1 /******************************************************************************* 2 * 3 * Module Name: rslist - Linked list utilities 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2008, Intel Corp. 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 "accommon.h" 46 #include "acresrc.h" 47 48 #define _COMPONENT ACPI_RESOURCES 49 ACPI_MODULE_NAME("rslist") 50 51 /******************************************************************************* 52 * 53 * FUNCTION: acpi_rs_convert_aml_to_resources 54 * 55 * PARAMETERS: acpi_walk_aml_callback 56 * resource_ptr - Pointer to the buffer that will 57 * contain the output structures 58 * 59 * RETURN: Status 60 * 61 * DESCRIPTION: Convert an AML resource to an internal representation of the 62 * resource that is aligned and easier to access. 63 * 64 ******************************************************************************/ 65 acpi_status 66 acpi_rs_convert_aml_to_resources(u8 * aml, 67 u32 length, 68 u32 offset, u8 resource_index, void **context) 69 { 70 struct acpi_resource **resource_ptr = 71 ACPI_CAST_INDIRECT_PTR(struct acpi_resource, context); 72 struct acpi_resource *resource; 73 acpi_status status; 74 75 ACPI_FUNCTION_TRACE(rs_convert_aml_to_resources); 76 77 /* 78 * Check that the input buffer and all subsequent pointers into it 79 * are aligned on a native word boundary. Most important on IA64 80 */ 81 resource = *resource_ptr; 82 if (ACPI_IS_MISALIGNED(resource)) { 83 ACPI_WARNING((AE_INFO, 84 "Misaligned resource pointer %p", resource)); 85 } 86 87 /* Convert the AML byte stream resource to a local resource struct */ 88 89 status = 90 acpi_rs_convert_aml_to_resource(resource, 91 ACPI_CAST_PTR(union aml_resource, 92 aml), 93 acpi_gbl_get_resource_dispatch 94 [resource_index]); 95 if (ACPI_FAILURE(status)) { 96 ACPI_EXCEPTION((AE_INFO, status, 97 "Could not convert AML resource (Type %X)", 98 *aml)); 99 return_ACPI_STATUS(status); 100 } 101 102 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, 103 "Type %.2X, AmlLength %.2X InternalLength %.2X\n", 104 acpi_ut_get_resource_type(aml), length, 105 resource->length)); 106 107 /* Point to the next structure in the output buffer */ 108 109 *resource_ptr = ACPI_ADD_PTR(void, resource, resource->length); 110 return_ACPI_STATUS(AE_OK); 111 } 112 113 /******************************************************************************* 114 * 115 * FUNCTION: acpi_rs_convert_resources_to_aml 116 * 117 * PARAMETERS: Resource - Pointer to the resource linked list 118 * aml_size_needed - Calculated size of the byte stream 119 * needed from calling acpi_rs_get_aml_length() 120 * The size of the output_buffer is 121 * guaranteed to be >= aml_size_needed 122 * output_buffer - Pointer to the buffer that will 123 * contain the byte stream 124 * 125 * RETURN: Status 126 * 127 * DESCRIPTION: Takes the resource linked list and parses it, creating a 128 * byte stream of resources in the caller's output buffer 129 * 130 ******************************************************************************/ 131 132 acpi_status 133 acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, 134 acpi_size aml_size_needed, u8 * output_buffer) 135 { 136 u8 *aml = output_buffer; 137 u8 *end_aml = output_buffer + aml_size_needed; 138 acpi_status status; 139 140 ACPI_FUNCTION_TRACE(rs_convert_resources_to_aml); 141 142 /* Walk the resource descriptor list, convert each descriptor */ 143 144 while (aml < end_aml) { 145 146 /* Validate the (internal) Resource Type */ 147 148 if (resource->type > ACPI_RESOURCE_TYPE_MAX) { 149 ACPI_ERROR((AE_INFO, 150 "Invalid descriptor type (%X) in resource list", 151 resource->type)); 152 return_ACPI_STATUS(AE_BAD_DATA); 153 } 154 155 /* Perform the conversion */ 156 157 status = acpi_rs_convert_resource_to_aml(resource, ACPI_CAST_PTR(union 158 aml_resource, 159 aml), 160 acpi_gbl_set_resource_dispatch 161 [resource->type]); 162 if (ACPI_FAILURE(status)) { 163 ACPI_EXCEPTION((AE_INFO, status, 164 "Could not convert resource (type %X) to AML", 165 resource->type)); 166 return_ACPI_STATUS(status); 167 } 168 169 /* Perform final sanity check on the new AML resource descriptor */ 170 171 status = 172 acpi_ut_validate_resource(ACPI_CAST_PTR 173 (union aml_resource, aml), NULL); 174 if (ACPI_FAILURE(status)) { 175 return_ACPI_STATUS(status); 176 } 177 178 /* Check for end-of-list, normal exit */ 179 180 if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { 181 182 /* An End Tag indicates the end of the input Resource Template */ 183 184 return_ACPI_STATUS(AE_OK); 185 } 186 187 /* 188 * Extract the total length of the new descriptor and set the 189 * Aml to point to the next (output) resource descriptor 190 */ 191 aml += acpi_ut_get_descriptor_length(aml); 192 193 /* Point to the next input resource descriptor */ 194 195 resource = 196 ACPI_ADD_PTR(struct acpi_resource, resource, 197 resource->length); 198 } 199 200 /* Completed buffer, but did not find an end_tag resource descriptor */ 201 202 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); 203 } 204