at v2.6.28 382 lines 10 kB view raw
1/****************************************************************************** 2 * 3 * Module Name: utalloc - local memory allocation routines 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 <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 (void)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_size input_buffer_length; 244 245 /* Parameter validation */ 246 247 if (!buffer || !required_length) { 248 return (AE_BAD_PARAMETER); 249 } 250 251 /* 252 * Buffer->Length is used as both an input and output parameter. Get the 253 * input actual length and set the output required buffer length. 254 */ 255 input_buffer_length = buffer->length; 256 buffer->length = required_length; 257 258 /* 259 * The input buffer length contains the actual buffer length, or the type 260 * of buffer to be allocated by this routine. 261 */ 262 switch (input_buffer_length) { 263 case ACPI_NO_BUFFER: 264 265 /* Return the exception (and the required buffer length) */ 266 267 return (AE_BUFFER_OVERFLOW); 268 269 case ACPI_ALLOCATE_BUFFER: 270 271 /* Allocate a new buffer */ 272 273 buffer->pointer = acpi_os_allocate(required_length); 274 break; 275 276 case ACPI_ALLOCATE_LOCAL_BUFFER: 277 278 /* Allocate a new buffer with local interface to allow tracking */ 279 280 buffer->pointer = ACPI_ALLOCATE(required_length); 281 break; 282 283 default: 284 285 /* Existing buffer: Validate the size of the buffer */ 286 287 if (input_buffer_length < required_length) { 288 return (AE_BUFFER_OVERFLOW); 289 } 290 break; 291 } 292 293 /* Validate allocation from above or input buffer pointer */ 294 295 if (!buffer->pointer) { 296 return (AE_NO_MEMORY); 297 } 298 299 /* Have a valid buffer, clear it */ 300 301 ACPI_MEMSET(buffer->pointer, 0, required_length); 302 return (AE_OK); 303} 304 305#ifdef NOT_USED_BY_LINUX 306/******************************************************************************* 307 * 308 * FUNCTION: acpi_ut_allocate 309 * 310 * PARAMETERS: Size - Size of the allocation 311 * Component - Component type of caller 312 * Module - Source file name of caller 313 * Line - Line number of caller 314 * 315 * RETURN: Address of the allocated memory on success, NULL on failure. 316 * 317 * DESCRIPTION: Subsystem equivalent of malloc. 318 * 319 ******************************************************************************/ 320 321void *acpi_ut_allocate(acpi_size size, 322 u32 component, const char *module, u32 line) 323{ 324 void *allocation; 325 326 ACPI_FUNCTION_TRACE_U32(ut_allocate, size); 327 328 /* Check for an inadvertent size of zero bytes */ 329 330 if (!size) { 331 ACPI_WARNING((module, line, 332 "Attempt to allocate zero bytes, allocating 1 byte")); 333 size = 1; 334 } 335 336 allocation = acpi_os_allocate(size); 337 if (!allocation) { 338 339 /* Report allocation error */ 340 341 ACPI_WARNING((module, line, 342 "Could not allocate size %X", (u32) size)); 343 344 return_PTR(NULL); 345 } 346 347 return_PTR(allocation); 348} 349 350/******************************************************************************* 351 * 352 * FUNCTION: acpi_ut_allocate_zeroed 353 * 354 * PARAMETERS: Size - Size of the allocation 355 * Component - Component type of caller 356 * Module - Source file name of caller 357 * Line - Line number of caller 358 * 359 * RETURN: Address of the allocated memory on success, NULL on failure. 360 * 361 * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory. 362 * 363 ******************************************************************************/ 364 365void *acpi_ut_allocate_zeroed(acpi_size size, 366 u32 component, const char *module, u32 line) 367{ 368 void *allocation; 369 370 ACPI_FUNCTION_ENTRY(); 371 372 allocation = acpi_ut_allocate(size, component, module, line); 373 if (allocation) { 374 375 /* Clear the memory block */ 376 377 ACPI_MEMSET(allocation, 0, size); 378 } 379 380 return (allocation); 381} 382#endif