linux/drivers/acpi/acpica/utalloc.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Module Name: utalloc - local memory allocation routines
   4 *
   5 *****************************************************************************/
   6
   7/*
   8 * Copyright (C) 2000 - 2012, 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
  49ACPI_MODULE_NAME("utalloc")
  50
  51/*******************************************************************************
  52 *
  53 * FUNCTION:    acpi_ut_create_caches
  54 *
  55 * PARAMETERS:  None
  56 *
  57 * RETURN:      Status
  58 *
  59 * DESCRIPTION: Create all local caches
  60 *
  61 ******************************************************************************/
  62acpi_status acpi_ut_create_caches(void)
  63{
  64        acpi_status status;
  65
  66        /* Object Caches, for frequently used objects */
  67
  68        status =
  69            acpi_os_create_cache("Acpi-Namespace",
  70                                 sizeof(struct acpi_namespace_node),
  71                                 ACPI_MAX_NAMESPACE_CACHE_DEPTH,
  72                                 &acpi_gbl_namespace_cache);
  73        if (ACPI_FAILURE(status)) {
  74                return (status);
  75        }
  76
  77        status =
  78            acpi_os_create_cache("Acpi-State", sizeof(union acpi_generic_state),
  79                                 ACPI_MAX_STATE_CACHE_DEPTH,
  80                                 &acpi_gbl_state_cache);
  81        if (ACPI_FAILURE(status)) {
  82                return (status);
  83        }
  84
  85        status =
  86            acpi_os_create_cache("Acpi-Parse",
  87                                 sizeof(struct acpi_parse_obj_common),
  88                                 ACPI_MAX_PARSE_CACHE_DEPTH,
  89                                 &acpi_gbl_ps_node_cache);
  90        if (ACPI_FAILURE(status)) {
  91                return (status);
  92        }
  93
  94        status =
  95            acpi_os_create_cache("Acpi-ParseExt",
  96                                 sizeof(struct acpi_parse_obj_named),
  97                                 ACPI_MAX_EXTPARSE_CACHE_DEPTH,
  98                                 &acpi_gbl_ps_node_ext_cache);
  99        if (ACPI_FAILURE(status)) {
 100                return (status);
 101        }
 102
 103        status =
 104            acpi_os_create_cache("Acpi-Operand",
 105                                 sizeof(union acpi_operand_object),
 106                                 ACPI_MAX_OBJECT_CACHE_DEPTH,
 107                                 &acpi_gbl_operand_cache);
 108        if (ACPI_FAILURE(status)) {
 109                return (status);
 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                (void)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_size input_buffer_length;
 245
 246        /* Parameter validation */
 247
 248        if (!buffer || !required_length) {
 249                return (AE_BAD_PARAMETER);
 250        }
 251
 252        /*
 253         * Buffer->Length is used as both an input and output parameter. Get the
 254         * input actual length and set the output required buffer length.
 255         */
 256        input_buffer_length = buffer->length;
 257        buffer->length = required_length;
 258
 259        /*
 260         * The input buffer length contains the actual buffer length, or the type
 261         * of buffer to be allocated by this routine.
 262         */
 263        switch (input_buffer_length) {
 264        case ACPI_NO_BUFFER:
 265
 266                /* Return the exception (and the required buffer length) */
 267
 268                return (AE_BUFFER_OVERFLOW);
 269
 270        case ACPI_ALLOCATE_BUFFER:
 271
 272                /* Allocate a new buffer */
 273
 274                buffer->pointer = acpi_os_allocate(required_length);
 275                break;
 276
 277        case ACPI_ALLOCATE_LOCAL_BUFFER:
 278
 279                /* Allocate a new buffer with local interface to allow tracking */
 280
 281                buffer->pointer = ACPI_ALLOCATE(required_length);
 282                break;
 283
 284        default:
 285
 286                /* Existing buffer: Validate the size of the buffer */
 287
 288                if (input_buffer_length < required_length) {
 289                        return (AE_BUFFER_OVERFLOW);
 290                }
 291                break;
 292        }
 293
 294        /* Validate allocation from above or input buffer pointer */
 295
 296        if (!buffer->pointer) {
 297                return (AE_NO_MEMORY);
 298        }
 299
 300        /* Have a valid buffer, clear it */
 301
 302        ACPI_MEMSET(buffer->pointer, 0, required_length);
 303        return (AE_OK);
 304}
 305
 306#ifdef NOT_USED_BY_LINUX
 307/*******************************************************************************
 308 *
 309 * FUNCTION:    acpi_ut_allocate
 310 *
 311 * PARAMETERS:  Size                - Size of the allocation
 312 *              Component           - Component type of caller
 313 *              Module              - Source file name of caller
 314 *              Line                - Line number of caller
 315 *
 316 * RETURN:      Address of the allocated memory on success, NULL on failure.
 317 *
 318 * DESCRIPTION: Subsystem equivalent of malloc.
 319 *
 320 ******************************************************************************/
 321
 322void *acpi_ut_allocate(acpi_size size,
 323                       u32 component, const char *module, u32 line)
 324{
 325        void *allocation;
 326
 327        ACPI_FUNCTION_TRACE_U32(ut_allocate, size);
 328
 329        /* Check for an inadvertent size of zero bytes */
 330
 331        if (!size) {
 332                ACPI_WARNING((module, line,
 333                              "Attempt to allocate zero bytes, allocating 1 byte"));
 334                size = 1;
 335        }
 336
 337        allocation = acpi_os_allocate(size);
 338        if (!allocation) {
 339
 340                /* Report allocation error */
 341
 342                ACPI_WARNING((module, line,
 343                              "Could not allocate size %u", (u32) size));
 344
 345                return_PTR(NULL);
 346        }
 347
 348        return_PTR(allocation);
 349}
 350
 351/*******************************************************************************
 352 *
 353 * FUNCTION:    acpi_ut_allocate_zeroed
 354 *
 355 * PARAMETERS:  Size                - Size of the allocation
 356 *              Component           - Component type of caller
 357 *              Module              - Source file name of caller
 358 *              Line                - Line number of caller
 359 *
 360 * RETURN:      Address of the allocated memory on success, NULL on failure.
 361 *
 362 * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory.
 363 *
 364 ******************************************************************************/
 365
 366void *acpi_ut_allocate_zeroed(acpi_size size,
 367                              u32 component, const char *module, u32 line)
 368{
 369        void *allocation;
 370
 371        ACPI_FUNCTION_ENTRY();
 372
 373        allocation = acpi_ut_allocate(size, component, module, line);
 374        if (allocation) {
 375
 376                /* Clear the memory block */
 377
 378                ACPI_MEMSET(allocation, 0, size);
 379        }
 380
 381        return (allocation);
 382}
 383#endif
 384