1/****************************************************************************** 2 * 3 * Module Name: utalloc - local memory allocation routines 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/acdebug.h> 46 47#define _COMPONENT ACPI_UTILITIES 48ACPI_MODULE_NAME("utalloc") 49 50/******************************************************************************* 51 * 52 * FUNCTION: acpi_ut_create_caches 53 * 54 * PARAMETERS: None 55 * 56 * RETURN: Status 57 * 58 * DESCRIPTION: Create all local caches 59 * 60 ******************************************************************************/ 61acpi_status acpi_ut_create_caches(void) 62{ 63 acpi_status status; 64 65 /* Object Caches, for frequently used objects */ 66 67 status = 68 acpi_os_create_cache("Acpi-Namespace", 69 sizeof(struct acpi_namespace_node), 70 ACPI_MAX_NAMESPACE_CACHE_DEPTH, 71 &acpi_gbl_namespace_cache); 72 if (ACPI_FAILURE(status)) { 73 return (status); 74 } 75 76 status = 77 acpi_os_create_cache("Acpi-State", sizeof(union acpi_generic_state), 78 ACPI_MAX_STATE_CACHE_DEPTH, 79 &acpi_gbl_state_cache); 80 if (ACPI_FAILURE(status)) { 81 return (status); 82 } 83 84 status = 85 acpi_os_create_cache("Acpi-Parse", 86 sizeof(struct acpi_parse_obj_common), 87 ACPI_MAX_PARSE_CACHE_DEPTH, 88 &acpi_gbl_ps_node_cache); 89 if (ACPI_FAILURE(status)) { 90 return (status); 91 } 92 93 status = 94 acpi_os_create_cache("Acpi-ParseExt", 95 sizeof(struct acpi_parse_obj_named), 96 ACPI_MAX_EXTPARSE_CACHE_DEPTH, 97 &acpi_gbl_ps_node_ext_cache); 98 if (ACPI_FAILURE(status)) { 99 return (status); 100 } 101 102 status = 103 acpi_os_create_cache("Acpi-Operand", 104 sizeof(union acpi_operand_object), 105 ACPI_MAX_OBJECT_CACHE_DEPTH, 106 &acpi_gbl_operand_cache); 107 if (ACPI_FAILURE(status)) { 108 return (status); 109 } 110#ifdef ACPI_DBG_TRACK_ALLOCATIONS 111 112 /* Memory allocation lists */ 113 114 status = acpi_ut_create_list("Acpi-Global", 0, &acpi_gbl_global_list); 115 if (ACPI_FAILURE(status)) { 116 return (status); 117 } 118 119 status = 120 acpi_ut_create_list("Acpi-Namespace", 121 sizeof(struct acpi_namespace_node), 122 &acpi_gbl_ns_node_list); 123 if (ACPI_FAILURE(status)) { 124 return (status); 125 } 126#endif 127 128 return (AE_OK); 129} 130 131/******************************************************************************* 132 * 133 * FUNCTION: acpi_ut_delete_caches 134 * 135 * PARAMETERS: None 136 * 137 * RETURN: Status 138 * 139 * DESCRIPTION: Purge and delete all local caches 140 * 141 ******************************************************************************/ 142 143acpi_status acpi_ut_delete_caches(void) 144{ 145#ifdef ACPI_DBG_TRACK_ALLOCATIONS 146 char buffer[7]; 147 148 if (acpi_gbl_display_final_mem_stats) { 149 ACPI_STRCPY(buffer, "MEMORY"); 150 acpi_db_display_statistics(buffer); 151 } 152#endif 153 154 (void)acpi_os_delete_cache(acpi_gbl_namespace_cache); 155 acpi_gbl_namespace_cache = NULL; 156 157 (void)acpi_os_delete_cache(acpi_gbl_state_cache); 158 acpi_gbl_state_cache = NULL; 159 160 (void)acpi_os_delete_cache(acpi_gbl_operand_cache); 161 acpi_gbl_operand_cache = NULL; 162 163 (void)acpi_os_delete_cache(acpi_gbl_ps_node_cache); 164 acpi_gbl_ps_node_cache = NULL; 165 166 (void)acpi_os_delete_cache(acpi_gbl_ps_node_ext_cache); 167 acpi_gbl_ps_node_ext_cache = NULL; 168 169#ifdef ACPI_DBG_TRACK_ALLOCATIONS 170 171 /* Debug only - display leftover memory allocation, if any */ 172 173 acpi_ut_dump_allocations(ACPI_UINT32_MAX, NULL); 174 175 /* Free memory lists */ 176 177 ACPI_FREE(acpi_gbl_global_list); 178 acpi_gbl_global_list = NULL; 179 180 ACPI_FREE(acpi_gbl_ns_node_list); 181 acpi_gbl_ns_node_list = NULL; 182#endif 183 184 return (AE_OK); 185} 186 187/******************************************************************************* 188 * 189 * FUNCTION: acpi_ut_validate_buffer 190 * 191 * PARAMETERS: Buffer - Buffer descriptor to be validated 192 * 193 * RETURN: Status 194 * 195 * DESCRIPTION: Perform parameter validation checks on an struct acpi_buffer 196 * 197 ******************************************************************************/ 198 199acpi_status acpi_ut_validate_buffer(struct acpi_buffer * buffer) 200{ 201 202 /* Obviously, the structure pointer must be valid */ 203 204 if (!buffer) { 205 return (AE_BAD_PARAMETER); 206 } 207 208 /* Special semantics for the length */ 209 210 if ((buffer->length == ACPI_NO_BUFFER) || 211 (buffer->length == ACPI_ALLOCATE_BUFFER) || 212 (buffer->length == ACPI_ALLOCATE_LOCAL_BUFFER)) { 213 return (AE_OK); 214 } 215 216 /* Length is valid, the buffer pointer must be also */ 217 218 if (!buffer->pointer) { 219 return (AE_BAD_PARAMETER); 220 } 221 222 return (AE_OK); 223} 224 225/******************************************************************************* 226 * 227 * FUNCTION: acpi_ut_initialize_buffer 228 * 229 * PARAMETERS: Buffer - Buffer to be validated 230 * required_length - Length needed 231 * 232 * RETURN: Status 233 * 234 * DESCRIPTION: Validate that the buffer is of the required length or 235 * allocate a new buffer. Returned buffer is always zeroed. 236 * 237 ******************************************************************************/ 238 239acpi_status 240acpi_ut_initialize_buffer(struct acpi_buffer * buffer, 241 acpi_size required_length) 242{ 243 acpi_status status = AE_OK; 244 245 switch (buffer->length) { 246 case ACPI_NO_BUFFER: 247 248 /* Set the exception and returned the required length */ 249 250 status = AE_BUFFER_OVERFLOW; 251 break; 252 253 case ACPI_ALLOCATE_BUFFER: 254 255 /* Allocate a new buffer */ 256 257 buffer->pointer = acpi_os_allocate(required_length); 258 if (!buffer->pointer) { 259 return (AE_NO_MEMORY); 260 } 261 262 /* Clear the buffer */ 263 264 ACPI_MEMSET(buffer->pointer, 0, required_length); 265 break; 266 267 case ACPI_ALLOCATE_LOCAL_BUFFER: 268 269 /* Allocate a new buffer with local interface to allow tracking */ 270 271 buffer->pointer = ACPI_ALLOCATE_ZEROED(required_length); 272 if (!buffer->pointer) { 273 return (AE_NO_MEMORY); 274 } 275 break; 276 277 default: 278 279 /* Existing buffer: Validate the size of the buffer */ 280 281 if (buffer->length < required_length) { 282 status = AE_BUFFER_OVERFLOW; 283 break; 284 } 285 286 /* Clear the buffer */ 287 288 ACPI_MEMSET(buffer->pointer, 0, required_length); 289 break; 290 } 291 292 buffer->length = required_length; 293 return (status); 294} 295 296#ifdef NOT_USED_BY_LINUX 297/******************************************************************************* 298 * 299 * FUNCTION: acpi_ut_allocate 300 * 301 * PARAMETERS: Size - Size of the allocation 302 * Component - Component type of caller 303 * Module - Source file name of caller 304 * Line - Line number of caller 305 * 306 * RETURN: Address of the allocated memory on success, NULL on failure. 307 * 308 * DESCRIPTION: Subsystem equivalent of malloc. 309 * 310 ******************************************************************************/ 311 312void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line) 313{ 314 void *allocation; 315 316 ACPI_FUNCTION_TRACE_U32(ut_allocate, size); 317 318 /* Check for an inadvertent size of zero bytes */ 319 320 if (!size) { 321 ACPI_WARNING((module, line, 322 "Attempt to allocate zero bytes, allocating 1 byte")); 323 size = 1; 324 } 325 326 allocation = acpi_os_allocate(size); 327 if (!allocation) { 328 329 /* Report allocation error */ 330 331 ACPI_WARNING((module, line, 332 "Could not allocate size %X", (u32) size)); 333 334 return_PTR(NULL); 335 } 336 337 return_PTR(allocation); 338} 339 340/******************************************************************************* 341 * 342 * FUNCTION: acpi_ut_allocate_zeroed 343 * 344 * PARAMETERS: Size - Size of the allocation 345 * Component - Component type of caller 346 * Module - Source file name of caller 347 * Line - Line number of caller 348 * 349 * RETURN: Address of the allocated memory on success, NULL on failure. 350 * 351 * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory. 352 * 353 ******************************************************************************/ 354 355void *acpi_ut_allocate_zeroed(acpi_size size, 356 u32 component, char *module, u32 line) 357{ 358 void *allocation; 359 360 ACPI_FUNCTION_ENTRY(); 361 362 allocation = acpi_ut_allocate(size, component, module, line); 363 if (allocation) { 364 365 /* Clear the memory block */ 366 367 ACPI_MEMSET(allocation, 0, size); 368 } 369 370 return (allocation); 371} 372#endif 373