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