1 /****************************************************************************** 2 * 3 * Module Name: utalloc - local memory allocation routines 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, 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 "acdebug.h" 47 48 #define _COMPONENT ACPI_UTILITIES 49 ACPI_MODULE_NAME("utalloc") 50 51 #if !defined (USE_NATIVE_ALLOCATE_ZEROED) 52 /******************************************************************************* 53 * 54 * FUNCTION: acpi_os_allocate_zeroed 55 * 56 * PARAMETERS: size - Size of the allocation 57 * 58 * RETURN: Address of the allocated memory on success, NULL on failure. 59 * 60 * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory. 61 * This is the default implementation. Can be overridden via the 62 * USE_NATIVE_ALLOCATE_ZEROED flag. 63 * 64 ******************************************************************************/ 65 void *acpi_os_allocate_zeroed(acpi_size size) 66 { 67 void *allocation; 68 69 ACPI_FUNCTION_ENTRY(); 70 71 allocation = acpi_os_allocate(size); 72 if (allocation) { 73 74 /* Clear the memory block */ 75 76 ACPI_MEMSET(allocation, 0, size); 77 } 78 79 return (allocation); 80 } 81 82 #endif /* !USE_NATIVE_ALLOCATE_ZEROED */ 83 84 /******************************************************************************* 85 * 86 * FUNCTION: acpi_ut_create_caches 87 * 88 * PARAMETERS: None 89 * 90 * RETURN: Status 91 * 92 * DESCRIPTION: Create all local caches 93 * 94 ******************************************************************************/ 95 96 acpi_status acpi_ut_create_caches(void) 97 { 98 acpi_status status; 99 100 /* Object Caches, for frequently used objects */ 101 102 status = 103 acpi_os_create_cache("Acpi-Namespace", 104 sizeof(struct acpi_namespace_node), 105 ACPI_MAX_NAMESPACE_CACHE_DEPTH, 106 &acpi_gbl_namespace_cache); 107 if (ACPI_FAILURE(status)) { 108 return (status); 109 } 110 111 status = 112 acpi_os_create_cache("Acpi-State", sizeof(union acpi_generic_state), 113 ACPI_MAX_STATE_CACHE_DEPTH, 114 &acpi_gbl_state_cache); 115 if (ACPI_FAILURE(status)) { 116 return (status); 117 } 118 119 status = 120 acpi_os_create_cache("Acpi-Parse", 121 sizeof(struct acpi_parse_obj_common), 122 ACPI_MAX_PARSE_CACHE_DEPTH, 123 &acpi_gbl_ps_node_cache); 124 if (ACPI_FAILURE(status)) { 125 return (status); 126 } 127 128 status = 129 acpi_os_create_cache("Acpi-ParseExt", 130 sizeof(struct acpi_parse_obj_named), 131 ACPI_MAX_EXTPARSE_CACHE_DEPTH, 132 &acpi_gbl_ps_node_ext_cache); 133 if (ACPI_FAILURE(status)) { 134 return (status); 135 } 136 137 status = 138 acpi_os_create_cache("Acpi-Operand", 139 sizeof(union acpi_operand_object), 140 ACPI_MAX_OBJECT_CACHE_DEPTH, 141 &acpi_gbl_operand_cache); 142 if (ACPI_FAILURE(status)) { 143 return (status); 144 } 145 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 146 147 /* Memory allocation lists */ 148 149 status = acpi_ut_create_list("Acpi-Global", 0, &acpi_gbl_global_list); 150 if (ACPI_FAILURE(status)) { 151 return (status); 152 } 153 154 status = 155 acpi_ut_create_list("Acpi-Namespace", 156 sizeof(struct acpi_namespace_node), 157 &acpi_gbl_ns_node_list); 158 if (ACPI_FAILURE(status)) { 159 return (status); 160 } 161 #endif 162 163 return (AE_OK); 164 } 165 166 /******************************************************************************* 167 * 168 * FUNCTION: acpi_ut_delete_caches 169 * 170 * PARAMETERS: None 171 * 172 * RETURN: Status 173 * 174 * DESCRIPTION: Purge and delete all local caches 175 * 176 ******************************************************************************/ 177 178 acpi_status acpi_ut_delete_caches(void) 179 { 180 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 181 char buffer[7]; 182 183 if (acpi_gbl_display_final_mem_stats) { 184 ACPI_STRCPY(buffer, "MEMORY"); 185 (void)acpi_db_display_statistics(buffer); 186 } 187 #endif 188 189 (void)acpi_os_delete_cache(acpi_gbl_namespace_cache); 190 acpi_gbl_namespace_cache = NULL; 191 192 (void)acpi_os_delete_cache(acpi_gbl_state_cache); 193 acpi_gbl_state_cache = NULL; 194 195 (void)acpi_os_delete_cache(acpi_gbl_operand_cache); 196 acpi_gbl_operand_cache = NULL; 197 198 (void)acpi_os_delete_cache(acpi_gbl_ps_node_cache); 199 acpi_gbl_ps_node_cache = NULL; 200 201 (void)acpi_os_delete_cache(acpi_gbl_ps_node_ext_cache); 202 acpi_gbl_ps_node_ext_cache = NULL; 203 204 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 205 206 /* Debug only - display leftover memory allocation, if any */ 207 208 acpi_ut_dump_allocations(ACPI_UINT32_MAX, NULL); 209 210 /* Free memory lists */ 211 212 acpi_os_free(acpi_gbl_global_list); 213 acpi_gbl_global_list = NULL; 214 215 acpi_os_free(acpi_gbl_ns_node_list); 216 acpi_gbl_ns_node_list = NULL; 217 #endif 218 219 return (AE_OK); 220 } 221 222 /******************************************************************************* 223 * 224 * FUNCTION: acpi_ut_validate_buffer 225 * 226 * PARAMETERS: buffer - Buffer descriptor to be validated 227 * 228 * RETURN: Status 229 * 230 * DESCRIPTION: Perform parameter validation checks on an struct acpi_buffer 231 * 232 ******************************************************************************/ 233 234 acpi_status acpi_ut_validate_buffer(struct acpi_buffer * buffer) 235 { 236 237 /* Obviously, the structure pointer must be valid */ 238 239 if (!buffer) { 240 return (AE_BAD_PARAMETER); 241 } 242 243 /* Special semantics for the length */ 244 245 if ((buffer->length == ACPI_NO_BUFFER) || 246 (buffer->length == ACPI_ALLOCATE_BUFFER) || 247 (buffer->length == ACPI_ALLOCATE_LOCAL_BUFFER)) { 248 return (AE_OK); 249 } 250 251 /* Length is valid, the buffer pointer must be also */ 252 253 if (!buffer->pointer) { 254 return (AE_BAD_PARAMETER); 255 } 256 257 return (AE_OK); 258 } 259 260 /******************************************************************************* 261 * 262 * FUNCTION: acpi_ut_initialize_buffer 263 * 264 * PARAMETERS: buffer - Buffer to be validated 265 * required_length - Length needed 266 * 267 * RETURN: Status 268 * 269 * DESCRIPTION: Validate that the buffer is of the required length or 270 * allocate a new buffer. Returned buffer is always zeroed. 271 * 272 ******************************************************************************/ 273 274 acpi_status 275 acpi_ut_initialize_buffer(struct acpi_buffer * buffer, 276 acpi_size required_length) 277 { 278 acpi_size input_buffer_length; 279 280 /* Parameter validation */ 281 282 if (!buffer || !required_length) { 283 return (AE_BAD_PARAMETER); 284 } 285 286 /* 287 * Buffer->Length is used as both an input and output parameter. Get the 288 * input actual length and set the output required buffer length. 289 */ 290 input_buffer_length = buffer->length; 291 buffer->length = required_length; 292 293 /* 294 * The input buffer length contains the actual buffer length, or the type 295 * of buffer to be allocated by this routine. 296 */ 297 switch (input_buffer_length) { 298 case ACPI_NO_BUFFER: 299 300 /* Return the exception (and the required buffer length) */ 301 302 return (AE_BUFFER_OVERFLOW); 303 304 case ACPI_ALLOCATE_BUFFER: 305 /* 306 * Allocate a new buffer. We directectly call acpi_os_allocate here to 307 * purposefully bypass the (optionally enabled) internal allocation 308 * tracking mechanism since we only want to track internal 309 * allocations. Note: The caller should use acpi_os_free to free this 310 * buffer created via ACPI_ALLOCATE_BUFFER. 311 */ 312 buffer->pointer = acpi_os_allocate(required_length); 313 break; 314 315 case ACPI_ALLOCATE_LOCAL_BUFFER: 316 317 /* Allocate a new buffer with local interface to allow tracking */ 318 319 buffer->pointer = ACPI_ALLOCATE(required_length); 320 break; 321 322 default: 323 324 /* Existing buffer: Validate the size of the buffer */ 325 326 if (input_buffer_length < required_length) { 327 return (AE_BUFFER_OVERFLOW); 328 } 329 break; 330 } 331 332 /* Validate allocation from above or input buffer pointer */ 333 334 if (!buffer->pointer) { 335 return (AE_NO_MEMORY); 336 } 337 338 /* Have a valid buffer, clear it */ 339 340 ACPI_MEMSET(buffer->pointer, 0, required_length); 341 return (AE_OK); 342 } 343