utalloc.c 9.5 KB
Newer Older
L
Linus Torvalds 已提交
1 2
/******************************************************************************
 *
3
 * Module Name: utalloc - local memory allocation routines
L
Linus Torvalds 已提交
4 5 6 7
 *
 *****************************************************************************/

/*
B
Bob Moore 已提交
8
 * Copyright (C) 2000 - 2006, R. Byron Moore
L
Linus Torvalds 已提交
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    substantially similar to the "NO WARRANTY" disclaimer below
 *    ("Disclaimer") and any redistribution must be conditioned upon
 *    including a substantially similar Disclaimer requirement for further
 *    binary redistribution.
 * 3. Neither the names of the above-listed copyright holders nor the names
 *    of any contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 */

#include <acpi/acpi.h>

#define _COMPONENT          ACPI_UTILITIES
L
Len Brown 已提交
47
ACPI_MODULE_NAME("utalloc")
L
Linus Torvalds 已提交
48

R
Robert Moore 已提交
49
/*******************************************************************************
L
Linus Torvalds 已提交
50
 *
51
 * FUNCTION:    acpi_ut_create_caches
L
Linus Torvalds 已提交
52
 *
53
 * PARAMETERS:  None
L
Linus Torvalds 已提交
54
 *
55
 * RETURN:      Status
L
Linus Torvalds 已提交
56
 *
57
 * DESCRIPTION: Create all local caches
L
Linus Torvalds 已提交
58 59
 *
 ******************************************************************************/
L
Len Brown 已提交
60
acpi_status acpi_ut_create_caches(void)
L
Linus Torvalds 已提交
61
{
L
Len Brown 已提交
62
	acpi_status status;
L
Linus Torvalds 已提交
63

64
	/* Object Caches, for frequently used objects */
L
Linus Torvalds 已提交
65

L
Len Brown 已提交
66
	status =
B
Bob Moore 已提交
67 68 69 70 71 72 73 74 75 76
	    acpi_os_create_cache("Acpi-Namespace",
				 sizeof(struct acpi_namespace_node),
				 ACPI_MAX_NAMESPACE_CACHE_DEPTH,
				 &acpi_gbl_namespace_cache);
	if (ACPI_FAILURE(status)) {
		return (status);
	}

	status =
	    acpi_os_create_cache("Acpi-State", sizeof(union acpi_generic_state),
L
Len Brown 已提交
77 78 79
				 ACPI_MAX_STATE_CACHE_DEPTH,
				 &acpi_gbl_state_cache);
	if (ACPI_FAILURE(status)) {
80
		return (status);
L
Linus Torvalds 已提交
81 82
	}

L
Len Brown 已提交
83
	status =
B
Bob Moore 已提交
84
	    acpi_os_create_cache("Acpi-Parse",
L
Len Brown 已提交
85 86 87 88
				 sizeof(struct acpi_parse_obj_common),
				 ACPI_MAX_PARSE_CACHE_DEPTH,
				 &acpi_gbl_ps_node_cache);
	if (ACPI_FAILURE(status)) {
89
		return (status);
L
Linus Torvalds 已提交
90 91
	}

L
Len Brown 已提交
92
	status =
B
Bob Moore 已提交
93
	    acpi_os_create_cache("Acpi-ParseExt",
L
Len Brown 已提交
94 95 96 97
				 sizeof(struct acpi_parse_obj_named),
				 ACPI_MAX_EXTPARSE_CACHE_DEPTH,
				 &acpi_gbl_ps_node_ext_cache);
	if (ACPI_FAILURE(status)) {
98 99
		return (status);
	}
L
Linus Torvalds 已提交
100

L
Len Brown 已提交
101
	status =
B
Bob Moore 已提交
102
	    acpi_os_create_cache("Acpi-Operand",
L
Len Brown 已提交
103 104 105 106
				 sizeof(union acpi_operand_object),
				 ACPI_MAX_OBJECT_CACHE_DEPTH,
				 &acpi_gbl_operand_cache);
	if (ACPI_FAILURE(status)) {
107 108
		return (status);
	}
L
Linus Torvalds 已提交
109

B
Bob Moore 已提交
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
#ifdef ACPI_DBG_TRACK_ALLOCATIONS

	/* Memory allocation lists */

	status = acpi_ut_create_list("Acpi-Global", 0, &acpi_gbl_global_list);
	if (ACPI_FAILURE(status)) {
		return (status);
	}

	status =
	    acpi_ut_create_list("Acpi-Namespace",
				sizeof(struct acpi_namespace_node),
				&acpi_gbl_ns_node_list);
	if (ACPI_FAILURE(status)) {
		return (status);
	}
#endif

128
	return (AE_OK);
L
Linus Torvalds 已提交
129 130
}

R
Robert Moore 已提交
131
/*******************************************************************************
L
Linus Torvalds 已提交
132
 *
133
 * FUNCTION:    acpi_ut_delete_caches
L
Linus Torvalds 已提交
134
 *
135
 * PARAMETERS:  None
L
Linus Torvalds 已提交
136
 *
137
 * RETURN:      Status
L
Linus Torvalds 已提交
138
 *
139
 * DESCRIPTION: Purge and delete all local caches
L
Linus Torvalds 已提交
140 141 142
 *
 ******************************************************************************/

L
Len Brown 已提交
143
acpi_status acpi_ut_delete_caches(void)
L
Linus Torvalds 已提交
144 145
{

B
Bob Moore 已提交
146 147 148
	(void)acpi_os_delete_cache(acpi_gbl_namespace_cache);
	acpi_gbl_namespace_cache = NULL;

L
Len Brown 已提交
149
	(void)acpi_os_delete_cache(acpi_gbl_state_cache);
150
	acpi_gbl_state_cache = NULL;
L
Linus Torvalds 已提交
151

L
Len Brown 已提交
152
	(void)acpi_os_delete_cache(acpi_gbl_operand_cache);
153
	acpi_gbl_operand_cache = NULL;
L
Linus Torvalds 已提交
154

L
Len Brown 已提交
155
	(void)acpi_os_delete_cache(acpi_gbl_ps_node_cache);
156
	acpi_gbl_ps_node_cache = NULL;
L
Linus Torvalds 已提交
157

L
Len Brown 已提交
158
	(void)acpi_os_delete_cache(acpi_gbl_ps_node_ext_cache);
159
	acpi_gbl_ps_node_ext_cache = NULL;
L
Linus Torvalds 已提交
160

B
Bob Moore 已提交
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
#ifdef ACPI_DBG_TRACK_ALLOCATIONS

	/* Debug only - display leftover memory allocation, if any */

	acpi_ut_dump_allocations(ACPI_UINT32_MAX, NULL);

	/* Free memory lists */

	acpi_os_free(acpi_gbl_global_list);
	acpi_gbl_global_list = NULL;

	acpi_os_free(acpi_gbl_ns_node_list);
	acpi_gbl_ns_node_list = NULL;
#endif

176
	return (AE_OK);
L
Linus Torvalds 已提交
177 178 179 180 181 182 183 184 185 186 187 188 189 190
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_validate_buffer
 *
 * PARAMETERS:  Buffer              - Buffer descriptor to be validated
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Perform parameter validation checks on an struct acpi_buffer
 *
 ******************************************************************************/

L
Len Brown 已提交
191
acpi_status acpi_ut_validate_buffer(struct acpi_buffer * buffer)
L
Linus Torvalds 已提交
192 193 194 195 196 197 198 199 200 201
{

	/* Obviously, the structure pointer must be valid */

	if (!buffer) {
		return (AE_BAD_PARAMETER);
	}

	/* Special semantics for the length */

L
Len Brown 已提交
202 203 204
	if ((buffer->length == ACPI_NO_BUFFER) ||
	    (buffer->length == ACPI_ALLOCATE_BUFFER) ||
	    (buffer->length == ACPI_ALLOCATE_LOCAL_BUFFER)) {
L
Linus Torvalds 已提交
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
		return (AE_OK);
	}

	/* Length is valid, the buffer pointer must be also */

	if (!buffer->pointer) {
		return (AE_BAD_PARAMETER);
	}

	return (AE_OK);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_initialize_buffer
 *
 * PARAMETERS:  Buffer              - Buffer to be validated
 *              required_length     - Length needed
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Validate that the buffer is of the required length or
 *              allocate a new buffer.  Returned buffer is always zeroed.
 *
 ******************************************************************************/

acpi_status
L
Len Brown 已提交
232 233
acpi_ut_initialize_buffer(struct acpi_buffer * buffer,
			  acpi_size required_length)
L
Linus Torvalds 已提交
234
{
L
Len Brown 已提交
235
	acpi_status status = AE_OK;
L
Linus Torvalds 已提交
236 237 238 239 240 241 242 243 244 245 246 247 248

	switch (buffer->length) {
	case ACPI_NO_BUFFER:

		/* Set the exception and returned the required length */

		status = AE_BUFFER_OVERFLOW;
		break;

	case ACPI_ALLOCATE_BUFFER:

		/* Allocate a new buffer */

L
Len Brown 已提交
249
		buffer->pointer = acpi_os_allocate(required_length);
L
Linus Torvalds 已提交
250 251 252 253 254 255
		if (!buffer->pointer) {
			return (AE_NO_MEMORY);
		}

		/* Clear the buffer */

L
Len Brown 已提交
256
		ACPI_MEMSET(buffer->pointer, 0, required_length);
L
Linus Torvalds 已提交
257 258 259 260 261 262
		break;

	case ACPI_ALLOCATE_LOCAL_BUFFER:

		/* Allocate a new buffer with local interface to allow tracking */

B
Bob Moore 已提交
263
		buffer->pointer = ACPI_ALLOCATE_ZEROED(required_length);
L
Linus Torvalds 已提交
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
		if (!buffer->pointer) {
			return (AE_NO_MEMORY);
		}
		break;

	default:

		/* Existing buffer: Validate the size of the buffer */

		if (buffer->length < required_length) {
			status = AE_BUFFER_OVERFLOW;
			break;
		}

		/* Clear the buffer */

L
Len Brown 已提交
280
		ACPI_MEMSET(buffer->pointer, 0, required_length);
L
Linus Torvalds 已提交
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
		break;
	}

	buffer->length = required_length;
	return (status);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_allocate
 *
 * PARAMETERS:  Size                - Size of the allocation
 *              Component           - Component type of caller
 *              Module              - Source file name of caller
 *              Line                - Line number of caller
 *
 * RETURN:      Address of the allocated memory on success, NULL on failure.
 *
B
Bob Moore 已提交
299
 * DESCRIPTION: Subsystem equivalent of malloc.
L
Linus Torvalds 已提交
300 301 302
 *
 ******************************************************************************/

L
Len Brown 已提交
303
void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line)
L
Linus Torvalds 已提交
304
{
L
Len Brown 已提交
305
	void *allocation;
L
Linus Torvalds 已提交
306

B
Bob Moore 已提交
307
	ACPI_FUNCTION_TRACE_U32(ut_allocate, size);
L
Linus Torvalds 已提交
308 309 310 311

	/* Check for an inadvertent size of zero bytes */

	if (!size) {
B
Bob Moore 已提交
312 313
		ACPI_WARNING((module, line,
			      "Attempt to allocate zero bytes, allocating 1 byte"));
L
Linus Torvalds 已提交
314 315 316
		size = 1;
	}

L
Len Brown 已提交
317
	allocation = acpi_os_allocate(size);
L
Linus Torvalds 已提交
318
	if (!allocation) {
B
Bob Moore 已提交
319

L
Linus Torvalds 已提交
320 321
		/* Report allocation error */

B
Bob Moore 已提交
322 323
		ACPI_WARNING((module, line,
			      "Could not allocate size %X", (u32) size));
L
Linus Torvalds 已提交
324

L
Len Brown 已提交
325
		return_PTR(NULL);
L
Linus Torvalds 已提交
326 327
	}

L
Len Brown 已提交
328
	return_PTR(allocation);
L
Linus Torvalds 已提交
329 330 331 332
}

/*******************************************************************************
 *
B
Bob Moore 已提交
333
 * FUNCTION:    acpi_ut_allocate_zeroed
L
Linus Torvalds 已提交
334 335 336 337 338 339 340 341
 *
 * PARAMETERS:  Size                - Size of the allocation
 *              Component           - Component type of caller
 *              Module              - Source file name of caller
 *              Line                - Line number of caller
 *
 * RETURN:      Address of the allocated memory on success, NULL on failure.
 *
B
Bob Moore 已提交
342
 * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory.
L
Linus Torvalds 已提交
343 344 345
 *
 ******************************************************************************/

B
Bob Moore 已提交
346 347
void *acpi_ut_allocate_zeroed(acpi_size size,
			      u32 component, char *module, u32 line)
L
Linus Torvalds 已提交
348
{
L
Len Brown 已提交
349
	void *allocation;
L
Linus Torvalds 已提交
350

L
Len Brown 已提交
351
	ACPI_FUNCTION_ENTRY();
L
Linus Torvalds 已提交
352

B
Bob Moore 已提交
353 354
	allocation = acpi_ut_allocate(size, component, module, line);
	if (allocation) {
L
Linus Torvalds 已提交
355

B
Bob Moore 已提交
356
		/* Clear the memory block */
L
Linus Torvalds 已提交
357

B
Bob Moore 已提交
358
		ACPI_MEMSET(allocation, 0, size);
L
Linus Torvalds 已提交
359 360
	}

B
Bob Moore 已提交
361
	return (allocation);
L
Linus Torvalds 已提交
362
}