ia64/linux-2.6.18-xen.hg

annotate drivers/acpi/utilities/utcache.c @ 912:dd42cdb0ab89

[IA64] Build blktap2 driver by default in x86 builds.

add CONFIG_XEN_BLKDEV_TAP2=y to buildconfigs/linux-defconfig_xen_ia64.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Isaku Yamahata <yamahata@valinux.co.jp>
date Mon Jun 29 12:09:16 2009 +0900 (2009-06-29)
parents 831230e53067
children
rev   line source
ian@0 1 /******************************************************************************
ian@0 2 *
ian@0 3 * Module Name: utcache - local cache allocation routines
ian@0 4 *
ian@0 5 *****************************************************************************/
ian@0 6
ian@0 7 /*
ian@0 8 * Copyright (C) 2000 - 2006, R. Byron Moore
ian@0 9 * All rights reserved.
ian@0 10 *
ian@0 11 * Redistribution and use in source and binary forms, with or without
ian@0 12 * modification, are permitted provided that the following conditions
ian@0 13 * are met:
ian@0 14 * 1. Redistributions of source code must retain the above copyright
ian@0 15 * notice, this list of conditions, and the following disclaimer,
ian@0 16 * without modification.
ian@0 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
ian@0 18 * substantially similar to the "NO WARRANTY" disclaimer below
ian@0 19 * ("Disclaimer") and any redistribution must be conditioned upon
ian@0 20 * including a substantially similar Disclaimer requirement for further
ian@0 21 * binary redistribution.
ian@0 22 * 3. Neither the names of the above-listed copyright holders nor the names
ian@0 23 * of any contributors may be used to endorse or promote products derived
ian@0 24 * from this software without specific prior written permission.
ian@0 25 *
ian@0 26 * Alternatively, this software may be distributed under the terms of the
ian@0 27 * GNU General Public License ("GPL") version 2 as published by the Free
ian@0 28 * Software Foundation.
ian@0 29 *
ian@0 30 * NO WARRANTY
ian@0 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
ian@0 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
ian@0 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
ian@0 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
ian@0 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ian@0 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
ian@0 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ian@0 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
ian@0 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
ian@0 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
ian@0 41 * POSSIBILITY OF SUCH DAMAGES.
ian@0 42 */
ian@0 43
ian@0 44 #include <acpi/acpi.h>
ian@0 45
ian@0 46 #define _COMPONENT ACPI_UTILITIES
ian@0 47 ACPI_MODULE_NAME("utcache")
ian@0 48
ian@0 49 #ifdef ACPI_USE_LOCAL_CACHE
ian@0 50 /*******************************************************************************
ian@0 51 *
ian@0 52 * FUNCTION: acpi_os_create_cache
ian@0 53 *
ian@0 54 * PARAMETERS: cache_name - Ascii name for the cache
ian@0 55 * object_size - Size of each cached object
ian@0 56 * max_depth - Maximum depth of the cache (in objects)
ian@0 57 * return_cache - Where the new cache object is returned
ian@0 58 *
ian@0 59 * RETURN: Status
ian@0 60 *
ian@0 61 * DESCRIPTION: Create a cache object
ian@0 62 *
ian@0 63 ******************************************************************************/
ian@0 64 acpi_status
ian@0 65 acpi_os_create_cache(char *cache_name,
ian@0 66 u16 object_size,
ian@0 67 u16 max_depth, struct acpi_memory_list **return_cache)
ian@0 68 {
ian@0 69 struct acpi_memory_list *cache;
ian@0 70
ian@0 71 ACPI_FUNCTION_ENTRY();
ian@0 72
ian@0 73 if (!cache_name || !return_cache || (object_size < 16)) {
ian@0 74 return (AE_BAD_PARAMETER);
ian@0 75 }
ian@0 76
ian@0 77 /* Create the cache object */
ian@0 78
ian@0 79 cache = acpi_os_allocate(sizeof(struct acpi_memory_list));
ian@0 80 if (!cache) {
ian@0 81 return (AE_NO_MEMORY);
ian@0 82 }
ian@0 83
ian@0 84 /* Populate the cache object and return it */
ian@0 85
ian@0 86 ACPI_MEMSET(cache, 0, sizeof(struct acpi_memory_list));
ian@0 87 cache->link_offset = 8;
ian@0 88 cache->list_name = cache_name;
ian@0 89 cache->object_size = object_size;
ian@0 90 cache->max_depth = max_depth;
ian@0 91
ian@0 92 *return_cache = cache;
ian@0 93 return (AE_OK);
ian@0 94 }
ian@0 95
ian@0 96 /*******************************************************************************
ian@0 97 *
ian@0 98 * FUNCTION: acpi_os_purge_cache
ian@0 99 *
ian@0 100 * PARAMETERS: Cache - Handle to cache object
ian@0 101 *
ian@0 102 * RETURN: Status
ian@0 103 *
ian@0 104 * DESCRIPTION: Free all objects within the requested cache.
ian@0 105 *
ian@0 106 ******************************************************************************/
ian@0 107
ian@0 108 acpi_status acpi_os_purge_cache(struct acpi_memory_list * cache)
ian@0 109 {
ian@0 110 char *next;
ian@0 111
ian@0 112 ACPI_FUNCTION_ENTRY();
ian@0 113
ian@0 114 if (!cache) {
ian@0 115 return (AE_BAD_PARAMETER);
ian@0 116 }
ian@0 117
ian@0 118 /* Walk the list of objects in this cache */
ian@0 119
ian@0 120 while (cache->list_head) {
ian@0 121
ian@0 122 /* Delete and unlink one cached state object */
ian@0 123
ian@0 124 next = *(ACPI_CAST_INDIRECT_PTR(char,
ian@0 125 &(((char *)cache->
ian@0 126 list_head)[cache->
ian@0 127 link_offset])));
ian@0 128 ACPI_FREE(cache->list_head);
ian@0 129
ian@0 130 cache->list_head = next;
ian@0 131 cache->current_depth--;
ian@0 132 }
ian@0 133
ian@0 134 return (AE_OK);
ian@0 135 }
ian@0 136
ian@0 137 /*******************************************************************************
ian@0 138 *
ian@0 139 * FUNCTION: acpi_os_delete_cache
ian@0 140 *
ian@0 141 * PARAMETERS: Cache - Handle to cache object
ian@0 142 *
ian@0 143 * RETURN: Status
ian@0 144 *
ian@0 145 * DESCRIPTION: Free all objects within the requested cache and delete the
ian@0 146 * cache object.
ian@0 147 *
ian@0 148 ******************************************************************************/
ian@0 149
ian@0 150 acpi_status acpi_os_delete_cache(struct acpi_memory_list * cache)
ian@0 151 {
ian@0 152 acpi_status status;
ian@0 153
ian@0 154 ACPI_FUNCTION_ENTRY();
ian@0 155
ian@0 156 /* Purge all objects in the cache */
ian@0 157
ian@0 158 status = acpi_os_purge_cache(cache);
ian@0 159 if (ACPI_FAILURE(status)) {
ian@0 160 return (status);
ian@0 161 }
ian@0 162
ian@0 163 /* Now we can delete the cache object */
ian@0 164
ian@0 165 ACPI_FREE(cache);
ian@0 166 return (AE_OK);
ian@0 167 }
ian@0 168
ian@0 169 /*******************************************************************************
ian@0 170 *
ian@0 171 * FUNCTION: acpi_os_release_object
ian@0 172 *
ian@0 173 * PARAMETERS: Cache - Handle to cache object
ian@0 174 * Object - The object to be released
ian@0 175 *
ian@0 176 * RETURN: None
ian@0 177 *
ian@0 178 * DESCRIPTION: Release an object to the specified cache. If cache is full,
ian@0 179 * the object is deleted.
ian@0 180 *
ian@0 181 ******************************************************************************/
ian@0 182
ian@0 183 acpi_status
ian@0 184 acpi_os_release_object(struct acpi_memory_list * cache, void *object)
ian@0 185 {
ian@0 186 acpi_status status;
ian@0 187
ian@0 188 ACPI_FUNCTION_ENTRY();
ian@0 189
ian@0 190 if (!cache || !object) {
ian@0 191 return (AE_BAD_PARAMETER);
ian@0 192 }
ian@0 193
ian@0 194 /* If cache is full, just free this object */
ian@0 195
ian@0 196 if (cache->current_depth >= cache->max_depth) {
ian@0 197 ACPI_FREE(object);
ian@0 198 ACPI_MEM_TRACKING(cache->total_freed++);
ian@0 199 }
ian@0 200
ian@0 201 /* Otherwise put this object back into the cache */
ian@0 202
ian@0 203 else {
ian@0 204 status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
ian@0 205 if (ACPI_FAILURE(status)) {
ian@0 206 return (status);
ian@0 207 }
ian@0 208
ian@0 209 /* Mark the object as cached */
ian@0 210
ian@0 211 ACPI_MEMSET(object, 0xCA, cache->object_size);
ian@0 212 ACPI_SET_DESCRIPTOR_TYPE(object, ACPI_DESC_TYPE_CACHED);
ian@0 213
ian@0 214 /* Put the object at the head of the cache list */
ian@0 215
ian@0 216 *(ACPI_CAST_INDIRECT_PTR(char,
ian@0 217 &(((char *)object)[cache->
ian@0 218 link_offset]))) =
ian@0 219 cache->list_head;
ian@0 220 cache->list_head = object;
ian@0 221 cache->current_depth++;
ian@0 222
ian@0 223 (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
ian@0 224 }
ian@0 225
ian@0 226 return (AE_OK);
ian@0 227 }
ian@0 228
ian@0 229 /*******************************************************************************
ian@0 230 *
ian@0 231 * FUNCTION: acpi_os_acquire_object
ian@0 232 *
ian@0 233 * PARAMETERS: Cache - Handle to cache object
ian@0 234 *
ian@0 235 * RETURN: the acquired object. NULL on error
ian@0 236 *
ian@0 237 * DESCRIPTION: Get an object from the specified cache. If cache is empty,
ian@0 238 * the object is allocated.
ian@0 239 *
ian@0 240 ******************************************************************************/
ian@0 241
ian@0 242 void *acpi_os_acquire_object(struct acpi_memory_list *cache)
ian@0 243 {
ian@0 244 acpi_status status;
ian@0 245 void *object;
ian@0 246
ian@0 247 ACPI_FUNCTION_NAME(os_acquire_object);
ian@0 248
ian@0 249 if (!cache) {
ian@0 250 return (NULL);
ian@0 251 }
ian@0 252
ian@0 253 status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
ian@0 254 if (ACPI_FAILURE(status)) {
ian@0 255 return (NULL);
ian@0 256 }
ian@0 257
ian@0 258 ACPI_MEM_TRACKING(cache->requests++);
ian@0 259
ian@0 260 /* Check the cache first */
ian@0 261
ian@0 262 if (cache->list_head) {
ian@0 263
ian@0 264 /* There is an object available, use it */
ian@0 265
ian@0 266 object = cache->list_head;
ian@0 267 cache->list_head = *(ACPI_CAST_INDIRECT_PTR(char,
ian@0 268 &(((char *)
ian@0 269 object)[cache->
ian@0 270 link_offset])));
ian@0 271
ian@0 272 cache->current_depth--;
ian@0 273
ian@0 274 ACPI_MEM_TRACKING(cache->hits++);
ian@0 275 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
ian@0 276 "Object %p from %s cache\n", object,
ian@0 277 cache->list_name));
ian@0 278
ian@0 279 status = acpi_ut_release_mutex(ACPI_MTX_CACHES);
ian@0 280 if (ACPI_FAILURE(status)) {
ian@0 281 return (NULL);
ian@0 282 }
ian@0 283
ian@0 284 /* Clear (zero) the previously used Object */
ian@0 285
ian@0 286 ACPI_MEMSET(object, 0, cache->object_size);
ian@0 287 } else {
ian@0 288 /* The cache is empty, create a new object */
ian@0 289
ian@0 290 ACPI_MEM_TRACKING(cache->total_allocated++);
ian@0 291
ian@0 292 /* Avoid deadlock with ACPI_ALLOCATE_ZEROED */
ian@0 293
ian@0 294 status = acpi_ut_release_mutex(ACPI_MTX_CACHES);
ian@0 295 if (ACPI_FAILURE(status)) {
ian@0 296 return (NULL);
ian@0 297 }
ian@0 298
ian@0 299 object = ACPI_ALLOCATE_ZEROED(cache->object_size);
ian@0 300 if (!object) {
ian@0 301 return (NULL);
ian@0 302 }
ian@0 303 }
ian@0 304
ian@0 305 return (object);
ian@0 306 }
ian@0 307 #endif /* ACPI_USE_LOCAL_CACHE */