utalloc.c revision 256281
1/****************************************************************************** 2 * 3 * Module Name: utalloc - local memory allocation routines 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2013, 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#define __UTALLOC_C__ 45 46#include <contrib/dev/acpica/include/acpi.h> 47#include <contrib/dev/acpica/include/accommon.h> 48#include <contrib/dev/acpica/include/acdebug.h> 49 50#define _COMPONENT ACPI_UTILITIES 51 ACPI_MODULE_NAME ("utalloc") 52 53 54/******************************************************************************* 55 * 56 * FUNCTION: AcpiUtCreateCaches 57 * 58 * PARAMETERS: None 59 * 60 * RETURN: Status 61 * 62 * DESCRIPTION: Create all local caches 63 * 64 ******************************************************************************/ 65 66ACPI_STATUS 67AcpiUtCreateCaches ( 68 void) 69{ 70 ACPI_STATUS Status; 71 72 73 /* Object Caches, for frequently used objects */ 74 75 Status = AcpiOsCreateCache ("Acpi-Namespace", sizeof (ACPI_NAMESPACE_NODE), 76 ACPI_MAX_NAMESPACE_CACHE_DEPTH, &AcpiGbl_NamespaceCache); 77 if (ACPI_FAILURE (Status)) 78 { 79 return (Status); 80 } 81 82 Status = AcpiOsCreateCache ("Acpi-State", sizeof (ACPI_GENERIC_STATE), 83 ACPI_MAX_STATE_CACHE_DEPTH, &AcpiGbl_StateCache); 84 if (ACPI_FAILURE (Status)) 85 { 86 return (Status); 87 } 88 89 Status = AcpiOsCreateCache ("Acpi-Parse", sizeof (ACPI_PARSE_OBJ_COMMON), 90 ACPI_MAX_PARSE_CACHE_DEPTH, &AcpiGbl_PsNodeCache); 91 if (ACPI_FAILURE (Status)) 92 { 93 return (Status); 94 } 95 96 Status = AcpiOsCreateCache ("Acpi-ParseExt", sizeof (ACPI_PARSE_OBJ_NAMED), 97 ACPI_MAX_EXTPARSE_CACHE_DEPTH, &AcpiGbl_PsNodeExtCache); 98 if (ACPI_FAILURE (Status)) 99 { 100 return (Status); 101 } 102 103 Status = AcpiOsCreateCache ("Acpi-Operand", sizeof (ACPI_OPERAND_OBJECT), 104 ACPI_MAX_OBJECT_CACHE_DEPTH, &AcpiGbl_OperandCache); 105 if (ACPI_FAILURE (Status)) 106 { 107 return (Status); 108 } 109 110 111#ifdef ACPI_DBG_TRACK_ALLOCATIONS 112 113 /* Memory allocation lists */ 114 115 Status = AcpiUtCreateList ("Acpi-Global", 0, 116 &AcpiGbl_GlobalList); 117 if (ACPI_FAILURE (Status)) 118 { 119 return (Status); 120 } 121 122 Status = AcpiUtCreateList ("Acpi-Namespace", sizeof (ACPI_NAMESPACE_NODE), 123 &AcpiGbl_NsNodeList); 124 if (ACPI_FAILURE (Status)) 125 { 126 return (Status); 127 } 128#endif 129 130 return (AE_OK); 131} 132 133 134/******************************************************************************* 135 * 136 * FUNCTION: AcpiUtDeleteCaches 137 * 138 * PARAMETERS: None 139 * 140 * RETURN: Status 141 * 142 * DESCRIPTION: Purge and delete all local caches 143 * 144 ******************************************************************************/ 145 146ACPI_STATUS 147AcpiUtDeleteCaches ( 148 void) 149{ 150#ifdef ACPI_DBG_TRACK_ALLOCATIONS 151 char Buffer[7]; 152 153 if (AcpiGbl_DisplayFinalMemStats) 154 { 155 ACPI_STRCPY (Buffer, "MEMORY"); 156 (void) AcpiDbDisplayStatistics (Buffer); 157 } 158#endif 159 160 (void) AcpiOsDeleteCache (AcpiGbl_NamespaceCache); 161 AcpiGbl_NamespaceCache = NULL; 162 163 (void) AcpiOsDeleteCache (AcpiGbl_StateCache); 164 AcpiGbl_StateCache = NULL; 165 166 (void) AcpiOsDeleteCache (AcpiGbl_OperandCache); 167 AcpiGbl_OperandCache = NULL; 168 169 (void) AcpiOsDeleteCache (AcpiGbl_PsNodeCache); 170 AcpiGbl_PsNodeCache = NULL; 171 172 (void) AcpiOsDeleteCache (AcpiGbl_PsNodeExtCache); 173 AcpiGbl_PsNodeExtCache = NULL; 174 175 176#ifdef ACPI_DBG_TRACK_ALLOCATIONS 177 178 /* Debug only - display leftover memory allocation, if any */ 179 180 AcpiUtDumpAllocations (ACPI_UINT32_MAX, NULL); 181 182 /* Free memory lists */ 183 184 AcpiOsFree (AcpiGbl_GlobalList); 185 AcpiGbl_GlobalList = NULL; 186 187 AcpiOsFree (AcpiGbl_NsNodeList); 188 AcpiGbl_NsNodeList = NULL; 189#endif 190 191 return (AE_OK); 192} 193 194 195/******************************************************************************* 196 * 197 * FUNCTION: AcpiUtValidateBuffer 198 * 199 * PARAMETERS: Buffer - Buffer descriptor to be validated 200 * 201 * RETURN: Status 202 * 203 * DESCRIPTION: Perform parameter validation checks on an ACPI_BUFFER 204 * 205 ******************************************************************************/ 206 207ACPI_STATUS 208AcpiUtValidateBuffer ( 209 ACPI_BUFFER *Buffer) 210{ 211 212 /* Obviously, the structure pointer must be valid */ 213 214 if (!Buffer) 215 { 216 return (AE_BAD_PARAMETER); 217 } 218 219 /* Special semantics for the length */ 220 221 if ((Buffer->Length == ACPI_NO_BUFFER) || 222 (Buffer->Length == ACPI_ALLOCATE_BUFFER) || 223 (Buffer->Length == ACPI_ALLOCATE_LOCAL_BUFFER)) 224 { 225 return (AE_OK); 226 } 227 228 /* Length is valid, the buffer pointer must be also */ 229 230 if (!Buffer->Pointer) 231 { 232 return (AE_BAD_PARAMETER); 233 } 234 235 return (AE_OK); 236} 237 238 239/******************************************************************************* 240 * 241 * FUNCTION: AcpiUtInitializeBuffer 242 * 243 * PARAMETERS: Buffer - Buffer to be validated 244 * RequiredLength - Length needed 245 * 246 * RETURN: Status 247 * 248 * DESCRIPTION: Validate that the buffer is of the required length or 249 * allocate a new buffer. Returned buffer is always zeroed. 250 * 251 ******************************************************************************/ 252 253ACPI_STATUS 254AcpiUtInitializeBuffer ( 255 ACPI_BUFFER *Buffer, 256 ACPI_SIZE RequiredLength) 257{ 258 ACPI_SIZE InputBufferLength; 259 260 261 /* Parameter validation */ 262 263 if (!Buffer || !RequiredLength) 264 { 265 return (AE_BAD_PARAMETER); 266 } 267 268 /* 269 * Buffer->Length is used as both an input and output parameter. Get the 270 * input actual length and set the output required buffer length. 271 */ 272 InputBufferLength = Buffer->Length; 273 Buffer->Length = RequiredLength; 274 275 /* 276 * The input buffer length contains the actual buffer length, or the type 277 * of buffer to be allocated by this routine. 278 */ 279 switch (InputBufferLength) 280 { 281 case ACPI_NO_BUFFER: 282 283 /* Return the exception (and the required buffer length) */ 284 285 return (AE_BUFFER_OVERFLOW); 286 287 case ACPI_ALLOCATE_BUFFER: 288 289 /* Allocate a new buffer */ 290 291 Buffer->Pointer = AcpiOsAllocate (RequiredLength); 292 break; 293 294 case ACPI_ALLOCATE_LOCAL_BUFFER: 295 296 /* Allocate a new buffer with local interface to allow tracking */ 297 298 Buffer->Pointer = ACPI_ALLOCATE (RequiredLength); 299 break; 300 301 default: 302 303 /* Existing buffer: Validate the size of the buffer */ 304 305 if (InputBufferLength < RequiredLength) 306 { 307 return (AE_BUFFER_OVERFLOW); 308 } 309 break; 310 } 311 312 /* Validate allocation from above or input buffer pointer */ 313 314 if (!Buffer->Pointer) 315 { 316 return (AE_NO_MEMORY); 317 } 318 319 /* Have a valid buffer, clear it */ 320 321 ACPI_MEMSET (Buffer->Pointer, 0, RequiredLength); 322 return (AE_OK); 323} 324 325 326/******************************************************************************* 327 * 328 * FUNCTION: AcpiUtAllocate 329 * 330 * PARAMETERS: Size - Size of the allocation 331 * Component - Component type of caller 332 * Module - Source file name of caller 333 * Line - Line number of caller 334 * 335 * RETURN: Address of the allocated memory on success, NULL on failure. 336 * 337 * DESCRIPTION: Subsystem equivalent of malloc. 338 * 339 ******************************************************************************/ 340 341void * 342AcpiUtAllocate ( 343 ACPI_SIZE Size, 344 UINT32 Component, 345 const char *Module, 346 UINT32 Line) 347{ 348 void *Allocation; 349 350 351 ACPI_FUNCTION_TRACE_U32 (UtAllocate, Size); 352 353 354 /* Check for an inadvertent size of zero bytes */ 355 356 if (!Size) 357 { 358 ACPI_WARNING ((Module, Line, 359 "Attempt to allocate zero bytes, allocating 1 byte")); 360 Size = 1; 361 } 362 363 Allocation = AcpiOsAllocate (Size); 364 if (!Allocation) 365 { 366 /* Report allocation error */ 367 368 ACPI_WARNING ((Module, Line, 369 "Could not allocate size %u", (UINT32) Size)); 370 371 return_PTR (NULL); 372 } 373 374 return_PTR (Allocation); 375} 376 377 378/******************************************************************************* 379 * 380 * FUNCTION: AcpiUtAllocateZeroed 381 * 382 * PARAMETERS: Size - Size of the allocation 383 * Component - Component type of caller 384 * Module - Source file name of caller 385 * Line - Line number of caller 386 * 387 * RETURN: Address of the allocated memory on success, NULL on failure. 388 * 389 * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory. 390 * 391 ******************************************************************************/ 392 393void * 394AcpiUtAllocateZeroed ( 395 ACPI_SIZE Size, 396 UINT32 Component, 397 const char *Module, 398 UINT32 Line) 399{ 400 void *Allocation; 401 402 403 ACPI_FUNCTION_ENTRY (); 404 405 406 Allocation = AcpiUtAllocate (Size, Component, Module, Line); 407 if (Allocation) 408 { 409 /* Clear the memory block */ 410 411 ACPI_MEMSET (Allocation, 0, Size); 412 } 413 414 return (Allocation); 415} 416