diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/acpi/utilities |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/acpi/utilities')
-rw-r--r-- | drivers/acpi/utilities/Makefile | 8 | ||||
-rw-r--r-- | drivers/acpi/utilities/utalloc.c | 988 | ||||
-rw-r--r-- | drivers/acpi/utilities/utcopy.c | 930 | ||||
-rw-r--r-- | drivers/acpi/utilities/utdebug.c | 624 | ||||
-rw-r--r-- | drivers/acpi/utilities/utdelete.c | 700 | ||||
-rw-r--r-- | drivers/acpi/utilities/uteval.c | 696 | ||||
-rw-r--r-- | drivers/acpi/utilities/utglobal.c | 935 | ||||
-rw-r--r-- | drivers/acpi/utilities/utinit.c | 266 | ||||
-rw-r--r-- | drivers/acpi/utilities/utmath.c | 333 | ||||
-rw-r--r-- | drivers/acpi/utilities/utmisc.c | 1516 | ||||
-rw-r--r-- | drivers/acpi/utilities/utobject.c | 671 | ||||
-rw-r--r-- | drivers/acpi/utilities/utxface.c | 525 |
12 files changed, 8192 insertions, 0 deletions
diff --git a/drivers/acpi/utilities/Makefile b/drivers/acpi/utilities/Makefile new file mode 100644 index 000000000000..939c447dd52a --- /dev/null +++ b/drivers/acpi/utilities/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | # | ||
2 | # Makefile for all Linux ACPI interpreter subdirectories | ||
3 | # | ||
4 | |||
5 | obj-y := utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ | ||
6 | utcopy.o utdelete.o utglobal.o utmath.o utobject.o | ||
7 | |||
8 | EXTRA_CFLAGS += $(ACPI_CFLAGS) | ||
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c new file mode 100644 index 000000000000..3313439c4bc7 --- /dev/null +++ b/drivers/acpi/utilities/utalloc.c | |||
@@ -0,0 +1,988 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: utalloc - local cache and memory allocation routines | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
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 | |||
45 | #include <acpi/acpi.h> | ||
46 | |||
47 | #define _COMPONENT ACPI_UTILITIES | ||
48 | ACPI_MODULE_NAME ("utalloc") | ||
49 | |||
50 | |||
51 | /****************************************************************************** | ||
52 | * | ||
53 | * FUNCTION: acpi_ut_release_to_cache | ||
54 | * | ||
55 | * PARAMETERS: list_id - Memory list/cache ID | ||
56 | * Object - The object to be released | ||
57 | * | ||
58 | * RETURN: None | ||
59 | * | ||
60 | * DESCRIPTION: Release an object to the specified cache. If cache is full, | ||
61 | * the object is deleted. | ||
62 | * | ||
63 | ******************************************************************************/ | ||
64 | |||
65 | void | ||
66 | acpi_ut_release_to_cache ( | ||
67 | u32 list_id, | ||
68 | void *object) | ||
69 | { | ||
70 | struct acpi_memory_list *cache_info; | ||
71 | |||
72 | |||
73 | ACPI_FUNCTION_ENTRY (); | ||
74 | |||
75 | |||
76 | cache_info = &acpi_gbl_memory_lists[list_id]; | ||
77 | |||
78 | #ifdef ACPI_ENABLE_OBJECT_CACHE | ||
79 | |||
80 | /* If walk cache is full, just free this wallkstate object */ | ||
81 | |||
82 | if (cache_info->cache_depth >= cache_info->max_cache_depth) { | ||
83 | ACPI_MEM_FREE (object); | ||
84 | ACPI_MEM_TRACKING (cache_info->total_freed++); | ||
85 | } | ||
86 | |||
87 | /* Otherwise put this object back into the cache */ | ||
88 | |||
89 | else { | ||
90 | if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) { | ||
91 | return; | ||
92 | } | ||
93 | |||
94 | /* Mark the object as cached */ | ||
95 | |||
96 | ACPI_MEMSET (object, 0xCA, cache_info->object_size); | ||
97 | ACPI_SET_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_CACHED); | ||
98 | |||
99 | /* Put the object at the head of the cache list */ | ||
100 | |||
101 | * (ACPI_CAST_INDIRECT_PTR (char, &(((char *) object)[cache_info->link_offset]))) = cache_info->list_head; | ||
102 | cache_info->list_head = object; | ||
103 | cache_info->cache_depth++; | ||
104 | |||
105 | (void) acpi_ut_release_mutex (ACPI_MTX_CACHES); | ||
106 | } | ||
107 | |||
108 | #else | ||
109 | |||
110 | /* Object cache is disabled; just free the object */ | ||
111 | |||
112 | ACPI_MEM_FREE (object); | ||
113 | ACPI_MEM_TRACKING (cache_info->total_freed++); | ||
114 | #endif | ||
115 | } | ||
116 | |||
117 | |||
118 | /****************************************************************************** | ||
119 | * | ||
120 | * FUNCTION: acpi_ut_acquire_from_cache | ||
121 | * | ||
122 | * PARAMETERS: list_id - Memory list ID | ||
123 | * | ||
124 | * RETURN: A requested object. NULL if the object could not be | ||
125 | * allocated. | ||
126 | * | ||
127 | * DESCRIPTION: Get an object from the specified cache. If cache is empty, | ||
128 | * the object is allocated. | ||
129 | * | ||
130 | ******************************************************************************/ | ||
131 | |||
132 | void * | ||
133 | acpi_ut_acquire_from_cache ( | ||
134 | u32 list_id) | ||
135 | { | ||
136 | struct acpi_memory_list *cache_info; | ||
137 | void *object; | ||
138 | |||
139 | |||
140 | ACPI_FUNCTION_NAME ("ut_acquire_from_cache"); | ||
141 | |||
142 | |||
143 | cache_info = &acpi_gbl_memory_lists[list_id]; | ||
144 | |||
145 | #ifdef ACPI_ENABLE_OBJECT_CACHE | ||
146 | |||
147 | if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) { | ||
148 | return (NULL); | ||
149 | } | ||
150 | |||
151 | ACPI_MEM_TRACKING (cache_info->cache_requests++); | ||
152 | |||
153 | /* Check the cache first */ | ||
154 | |||
155 | if (cache_info->list_head) { | ||
156 | /* There is an object available, use it */ | ||
157 | |||
158 | object = cache_info->list_head; | ||
159 | cache_info->list_head = *(ACPI_CAST_INDIRECT_PTR (char, &(((char *) object)[cache_info->link_offset]))); | ||
160 | |||
161 | ACPI_MEM_TRACKING (cache_info->cache_hits++); | ||
162 | cache_info->cache_depth--; | ||
163 | |||
164 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
165 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p from %s\n", | ||
166 | object, acpi_gbl_memory_lists[list_id].list_name)); | ||
167 | #endif | ||
168 | |||
169 | if (ACPI_FAILURE (acpi_ut_release_mutex (ACPI_MTX_CACHES))) { | ||
170 | return (NULL); | ||
171 | } | ||
172 | |||
173 | /* Clear (zero) the previously used Object */ | ||
174 | |||
175 | ACPI_MEMSET (object, 0, cache_info->object_size); | ||
176 | } | ||
177 | |||
178 | else { | ||
179 | /* The cache is empty, create a new object */ | ||
180 | |||
181 | /* Avoid deadlock with ACPI_MEM_CALLOCATE */ | ||
182 | |||
183 | if (ACPI_FAILURE (acpi_ut_release_mutex (ACPI_MTX_CACHES))) { | ||
184 | return (NULL); | ||
185 | } | ||
186 | |||
187 | object = ACPI_MEM_CALLOCATE (cache_info->object_size); | ||
188 | ACPI_MEM_TRACKING (cache_info->total_allocated++); | ||
189 | } | ||
190 | |||
191 | #else | ||
192 | |||
193 | /* Object cache is disabled; just allocate the object */ | ||
194 | |||
195 | object = ACPI_MEM_CALLOCATE (cache_info->object_size); | ||
196 | ACPI_MEM_TRACKING (cache_info->total_allocated++); | ||
197 | #endif | ||
198 | |||
199 | return (object); | ||
200 | } | ||
201 | |||
202 | |||
203 | #ifdef ACPI_ENABLE_OBJECT_CACHE | ||
204 | /****************************************************************************** | ||
205 | * | ||
206 | * FUNCTION: acpi_ut_delete_generic_cache | ||
207 | * | ||
208 | * PARAMETERS: list_id - Memory list ID | ||
209 | * | ||
210 | * RETURN: None | ||
211 | * | ||
212 | * DESCRIPTION: Free all objects within the requested cache. | ||
213 | * | ||
214 | ******************************************************************************/ | ||
215 | |||
216 | void | ||
217 | acpi_ut_delete_generic_cache ( | ||
218 | u32 list_id) | ||
219 | { | ||
220 | struct acpi_memory_list *cache_info; | ||
221 | char *next; | ||
222 | |||
223 | |||
224 | ACPI_FUNCTION_ENTRY (); | ||
225 | |||
226 | |||
227 | cache_info = &acpi_gbl_memory_lists[list_id]; | ||
228 | while (cache_info->list_head) { | ||
229 | /* Delete one cached state object */ | ||
230 | |||
231 | next = *(ACPI_CAST_INDIRECT_PTR (char, &(((char *) cache_info->list_head)[cache_info->link_offset]))); | ||
232 | ACPI_MEM_FREE (cache_info->list_head); | ||
233 | |||
234 | cache_info->list_head = next; | ||
235 | cache_info->cache_depth--; | ||
236 | } | ||
237 | } | ||
238 | #endif | ||
239 | |||
240 | |||
241 | /******************************************************************************* | ||
242 | * | ||
243 | * FUNCTION: acpi_ut_validate_buffer | ||
244 | * | ||
245 | * PARAMETERS: Buffer - Buffer descriptor to be validated | ||
246 | * | ||
247 | * RETURN: Status | ||
248 | * | ||
249 | * DESCRIPTION: Perform parameter validation checks on an struct acpi_buffer | ||
250 | * | ||
251 | ******************************************************************************/ | ||
252 | |||
253 | acpi_status | ||
254 | acpi_ut_validate_buffer ( | ||
255 | struct acpi_buffer *buffer) | ||
256 | { | ||
257 | |||
258 | /* Obviously, the structure pointer must be valid */ | ||
259 | |||
260 | if (!buffer) { | ||
261 | return (AE_BAD_PARAMETER); | ||
262 | } | ||
263 | |||
264 | /* Special semantics for the length */ | ||
265 | |||
266 | if ((buffer->length == ACPI_NO_BUFFER) || | ||
267 | (buffer->length == ACPI_ALLOCATE_BUFFER) || | ||
268 | (buffer->length == ACPI_ALLOCATE_LOCAL_BUFFER)) { | ||
269 | return (AE_OK); | ||
270 | } | ||
271 | |||
272 | /* Length is valid, the buffer pointer must be also */ | ||
273 | |||
274 | if (!buffer->pointer) { | ||
275 | return (AE_BAD_PARAMETER); | ||
276 | } | ||
277 | |||
278 | return (AE_OK); | ||
279 | } | ||
280 | |||
281 | |||
282 | /******************************************************************************* | ||
283 | * | ||
284 | * FUNCTION: acpi_ut_initialize_buffer | ||
285 | * | ||
286 | * PARAMETERS: Buffer - Buffer to be validated | ||
287 | * required_length - Length needed | ||
288 | * | ||
289 | * RETURN: Status | ||
290 | * | ||
291 | * DESCRIPTION: Validate that the buffer is of the required length or | ||
292 | * allocate a new buffer. Returned buffer is always zeroed. | ||
293 | * | ||
294 | ******************************************************************************/ | ||
295 | |||
296 | acpi_status | ||
297 | acpi_ut_initialize_buffer ( | ||
298 | struct acpi_buffer *buffer, | ||
299 | acpi_size required_length) | ||
300 | { | ||
301 | acpi_status status = AE_OK; | ||
302 | |||
303 | |||
304 | switch (buffer->length) { | ||
305 | case ACPI_NO_BUFFER: | ||
306 | |||
307 | /* Set the exception and returned the required length */ | ||
308 | |||
309 | status = AE_BUFFER_OVERFLOW; | ||
310 | break; | ||
311 | |||
312 | |||
313 | case ACPI_ALLOCATE_BUFFER: | ||
314 | |||
315 | /* Allocate a new buffer */ | ||
316 | |||
317 | buffer->pointer = acpi_os_allocate (required_length); | ||
318 | if (!buffer->pointer) { | ||
319 | return (AE_NO_MEMORY); | ||
320 | } | ||
321 | |||
322 | /* Clear the buffer */ | ||
323 | |||
324 | ACPI_MEMSET (buffer->pointer, 0, required_length); | ||
325 | break; | ||
326 | |||
327 | |||
328 | case ACPI_ALLOCATE_LOCAL_BUFFER: | ||
329 | |||
330 | /* Allocate a new buffer with local interface to allow tracking */ | ||
331 | |||
332 | buffer->pointer = ACPI_MEM_CALLOCATE (required_length); | ||
333 | if (!buffer->pointer) { | ||
334 | return (AE_NO_MEMORY); | ||
335 | } | ||
336 | break; | ||
337 | |||
338 | |||
339 | default: | ||
340 | |||
341 | /* Existing buffer: Validate the size of the buffer */ | ||
342 | |||
343 | if (buffer->length < required_length) { | ||
344 | status = AE_BUFFER_OVERFLOW; | ||
345 | break; | ||
346 | } | ||
347 | |||
348 | /* Clear the buffer */ | ||
349 | |||
350 | ACPI_MEMSET (buffer->pointer, 0, required_length); | ||
351 | break; | ||
352 | } | ||
353 | |||
354 | buffer->length = required_length; | ||
355 | return (status); | ||
356 | } | ||
357 | |||
358 | |||
359 | /******************************************************************************* | ||
360 | * | ||
361 | * FUNCTION: acpi_ut_allocate | ||
362 | * | ||
363 | * PARAMETERS: Size - Size of the allocation | ||
364 | * Component - Component type of caller | ||
365 | * Module - Source file name of caller | ||
366 | * Line - Line number of caller | ||
367 | * | ||
368 | * RETURN: Address of the allocated memory on success, NULL on failure. | ||
369 | * | ||
370 | * DESCRIPTION: The subsystem's equivalent of malloc. | ||
371 | * | ||
372 | ******************************************************************************/ | ||
373 | |||
374 | void * | ||
375 | acpi_ut_allocate ( | ||
376 | acpi_size size, | ||
377 | u32 component, | ||
378 | char *module, | ||
379 | u32 line) | ||
380 | { | ||
381 | void *allocation; | ||
382 | |||
383 | |||
384 | ACPI_FUNCTION_TRACE_U32 ("ut_allocate", size); | ||
385 | |||
386 | |||
387 | /* Check for an inadvertent size of zero bytes */ | ||
388 | |||
389 | if (!size) { | ||
390 | _ACPI_REPORT_ERROR (module, line, component, | ||
391 | ("ut_allocate: Attempt to allocate zero bytes\n")); | ||
392 | size = 1; | ||
393 | } | ||
394 | |||
395 | allocation = acpi_os_allocate (size); | ||
396 | if (!allocation) { | ||
397 | /* Report allocation error */ | ||
398 | |||
399 | _ACPI_REPORT_ERROR (module, line, component, | ||
400 | ("ut_allocate: Could not allocate size %X\n", (u32) size)); | ||
401 | |||
402 | return_PTR (NULL); | ||
403 | } | ||
404 | |||
405 | return_PTR (allocation); | ||
406 | } | ||
407 | |||
408 | |||
409 | /******************************************************************************* | ||
410 | * | ||
411 | * FUNCTION: acpi_ut_callocate | ||
412 | * | ||
413 | * PARAMETERS: Size - Size of the allocation | ||
414 | * Component - Component type of caller | ||
415 | * Module - Source file name of caller | ||
416 | * Line - Line number of caller | ||
417 | * | ||
418 | * RETURN: Address of the allocated memory on success, NULL on failure. | ||
419 | * | ||
420 | * DESCRIPTION: Subsystem equivalent of calloc. | ||
421 | * | ||
422 | ******************************************************************************/ | ||
423 | |||
424 | void * | ||
425 | acpi_ut_callocate ( | ||
426 | acpi_size size, | ||
427 | u32 component, | ||
428 | char *module, | ||
429 | u32 line) | ||
430 | { | ||
431 | void *allocation; | ||
432 | |||
433 | |||
434 | ACPI_FUNCTION_TRACE_U32 ("ut_callocate", size); | ||
435 | |||
436 | |||
437 | /* Check for an inadvertent size of zero bytes */ | ||
438 | |||
439 | if (!size) { | ||
440 | _ACPI_REPORT_ERROR (module, line, component, | ||
441 | ("ut_callocate: Attempt to allocate zero bytes\n")); | ||
442 | return_PTR (NULL); | ||
443 | } | ||
444 | |||
445 | allocation = acpi_os_allocate (size); | ||
446 | if (!allocation) { | ||
447 | /* Report allocation error */ | ||
448 | |||
449 | _ACPI_REPORT_ERROR (module, line, component, | ||
450 | ("ut_callocate: Could not allocate size %X\n", (u32) size)); | ||
451 | return_PTR (NULL); | ||
452 | } | ||
453 | |||
454 | /* Clear the memory block */ | ||
455 | |||
456 | ACPI_MEMSET (allocation, 0, size); | ||
457 | return_PTR (allocation); | ||
458 | } | ||
459 | |||
460 | |||
461 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
462 | /* | ||
463 | * These procedures are used for tracking memory leaks in the subsystem, and | ||
464 | * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set. | ||
465 | * | ||
466 | * Each memory allocation is tracked via a doubly linked list. Each | ||
467 | * element contains the caller's component, module name, function name, and | ||
468 | * line number. acpi_ut_allocate and acpi_ut_callocate call | ||
469 | * acpi_ut_track_allocation to add an element to the list; deletion | ||
470 | * occurs in the body of acpi_ut_free. | ||
471 | */ | ||
472 | |||
473 | |||
474 | /******************************************************************************* | ||
475 | * | ||
476 | * FUNCTION: acpi_ut_allocate_and_track | ||
477 | * | ||
478 | * PARAMETERS: Size - Size of the allocation | ||
479 | * Component - Component type of caller | ||
480 | * Module - Source file name of caller | ||
481 | * Line - Line number of caller | ||
482 | * | ||
483 | * RETURN: Address of the allocated memory on success, NULL on failure. | ||
484 | * | ||
485 | * DESCRIPTION: The subsystem's equivalent of malloc. | ||
486 | * | ||
487 | ******************************************************************************/ | ||
488 | |||
489 | void * | ||
490 | acpi_ut_allocate_and_track ( | ||
491 | acpi_size size, | ||
492 | u32 component, | ||
493 | char *module, | ||
494 | u32 line) | ||
495 | { | ||
496 | struct acpi_debug_mem_block *allocation; | ||
497 | acpi_status status; | ||
498 | |||
499 | |||
500 | allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_header), component, | ||
501 | module, line); | ||
502 | if (!allocation) { | ||
503 | return (NULL); | ||
504 | } | ||
505 | |||
506 | status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, allocation, size, | ||
507 | ACPI_MEM_MALLOC, component, module, line); | ||
508 | if (ACPI_FAILURE (status)) { | ||
509 | acpi_os_free (allocation); | ||
510 | return (NULL); | ||
511 | } | ||
512 | |||
513 | acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++; | ||
514 | acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += (u32) size; | ||
515 | |||
516 | return ((void *) &allocation->user_space); | ||
517 | } | ||
518 | |||
519 | |||
520 | /******************************************************************************* | ||
521 | * | ||
522 | * FUNCTION: acpi_ut_callocate_and_track | ||
523 | * | ||
524 | * PARAMETERS: Size - Size of the allocation | ||
525 | * Component - Component type of caller | ||
526 | * Module - Source file name of caller | ||
527 | * Line - Line number of caller | ||
528 | * | ||
529 | * RETURN: Address of the allocated memory on success, NULL on failure. | ||
530 | * | ||
531 | * DESCRIPTION: Subsystem equivalent of calloc. | ||
532 | * | ||
533 | ******************************************************************************/ | ||
534 | |||
535 | void * | ||
536 | acpi_ut_callocate_and_track ( | ||
537 | acpi_size size, | ||
538 | u32 component, | ||
539 | char *module, | ||
540 | u32 line) | ||
541 | { | ||
542 | struct acpi_debug_mem_block *allocation; | ||
543 | acpi_status status; | ||
544 | |||
545 | |||
546 | allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_header), component, | ||
547 | module, line); | ||
548 | if (!allocation) { | ||
549 | /* Report allocation error */ | ||
550 | |||
551 | _ACPI_REPORT_ERROR (module, line, component, | ||
552 | ("ut_callocate: Could not allocate size %X\n", (u32) size)); | ||
553 | return (NULL); | ||
554 | } | ||
555 | |||
556 | status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, allocation, size, | ||
557 | ACPI_MEM_CALLOC, component, module, line); | ||
558 | if (ACPI_FAILURE (status)) { | ||
559 | acpi_os_free (allocation); | ||
560 | return (NULL); | ||
561 | } | ||
562 | |||
563 | acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++; | ||
564 | acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += (u32) size; | ||
565 | |||
566 | return ((void *) &allocation->user_space); | ||
567 | } | ||
568 | |||
569 | |||
570 | /******************************************************************************* | ||
571 | * | ||
572 | * FUNCTION: acpi_ut_free_and_track | ||
573 | * | ||
574 | * PARAMETERS: Allocation - Address of the memory to deallocate | ||
575 | * Component - Component type of caller | ||
576 | * Module - Source file name of caller | ||
577 | * Line - Line number of caller | ||
578 | * | ||
579 | * RETURN: None | ||
580 | * | ||
581 | * DESCRIPTION: Frees the memory at Allocation | ||
582 | * | ||
583 | ******************************************************************************/ | ||
584 | |||
585 | void | ||
586 | acpi_ut_free_and_track ( | ||
587 | void *allocation, | ||
588 | u32 component, | ||
589 | char *module, | ||
590 | u32 line) | ||
591 | { | ||
592 | struct acpi_debug_mem_block *debug_block; | ||
593 | acpi_status status; | ||
594 | |||
595 | |||
596 | ACPI_FUNCTION_TRACE_PTR ("ut_free", allocation); | ||
597 | |||
598 | |||
599 | if (NULL == allocation) { | ||
600 | _ACPI_REPORT_ERROR (module, line, component, | ||
601 | ("acpi_ut_free: Attempt to delete a NULL address\n")); | ||
602 | |||
603 | return_VOID; | ||
604 | } | ||
605 | |||
606 | debug_block = ACPI_CAST_PTR (struct acpi_debug_mem_block, | ||
607 | (((char *) allocation) - sizeof (struct acpi_debug_mem_header))); | ||
608 | |||
609 | acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_freed++; | ||
610 | acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size -= debug_block->size; | ||
611 | |||
612 | status = acpi_ut_remove_allocation (ACPI_MEM_LIST_GLOBAL, debug_block, | ||
613 | component, module, line); | ||
614 | if (ACPI_FAILURE (status)) { | ||
615 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not free memory, %s\n", | ||
616 | acpi_format_exception (status))); | ||
617 | } | ||
618 | |||
619 | acpi_os_free (debug_block); | ||
620 | |||
621 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation)); | ||
622 | |||
623 | return_VOID; | ||
624 | } | ||
625 | |||
626 | |||
627 | /******************************************************************************* | ||
628 | * | ||
629 | * FUNCTION: acpi_ut_find_allocation | ||
630 | * | ||
631 | * PARAMETERS: list_id - Memory list to search | ||
632 | * Allocation - Address of allocated memory | ||
633 | * | ||
634 | * RETURN: A list element if found; NULL otherwise. | ||
635 | * | ||
636 | * DESCRIPTION: Searches for an element in the global allocation tracking list. | ||
637 | * | ||
638 | ******************************************************************************/ | ||
639 | |||
640 | struct acpi_debug_mem_block * | ||
641 | acpi_ut_find_allocation ( | ||
642 | u32 list_id, | ||
643 | void *allocation) | ||
644 | { | ||
645 | struct acpi_debug_mem_block *element; | ||
646 | |||
647 | |||
648 | ACPI_FUNCTION_ENTRY (); | ||
649 | |||
650 | |||
651 | if (list_id > ACPI_MEM_LIST_MAX) { | ||
652 | return (NULL); | ||
653 | } | ||
654 | |||
655 | element = acpi_gbl_memory_lists[list_id].list_head; | ||
656 | |||
657 | /* Search for the address. */ | ||
658 | |||
659 | while (element) { | ||
660 | if (element == allocation) { | ||
661 | return (element); | ||
662 | } | ||
663 | |||
664 | element = element->next; | ||
665 | } | ||
666 | |||
667 | return (NULL); | ||
668 | } | ||
669 | |||
670 | |||
671 | /******************************************************************************* | ||
672 | * | ||
673 | * FUNCTION: acpi_ut_track_allocation | ||
674 | * | ||
675 | * PARAMETERS: list_id - Memory list to search | ||
676 | * Allocation - Address of allocated memory | ||
677 | * Size - Size of the allocation | ||
678 | * alloc_type - MEM_MALLOC or MEM_CALLOC | ||
679 | * Component - Component type of caller | ||
680 | * Module - Source file name of caller | ||
681 | * Line - Line number of caller | ||
682 | * | ||
683 | * RETURN: None. | ||
684 | * | ||
685 | * DESCRIPTION: Inserts an element into the global allocation tracking list. | ||
686 | * | ||
687 | ******************************************************************************/ | ||
688 | |||
689 | acpi_status | ||
690 | acpi_ut_track_allocation ( | ||
691 | u32 list_id, | ||
692 | struct acpi_debug_mem_block *allocation, | ||
693 | acpi_size size, | ||
694 | u8 alloc_type, | ||
695 | u32 component, | ||
696 | char *module, | ||
697 | u32 line) | ||
698 | { | ||
699 | struct acpi_memory_list *mem_list; | ||
700 | struct acpi_debug_mem_block *element; | ||
701 | acpi_status status = AE_OK; | ||
702 | |||
703 | |||
704 | ACPI_FUNCTION_TRACE_PTR ("ut_track_allocation", allocation); | ||
705 | |||
706 | |||
707 | if (list_id > ACPI_MEM_LIST_MAX) { | ||
708 | return_ACPI_STATUS (AE_BAD_PARAMETER); | ||
709 | } | ||
710 | |||
711 | mem_list = &acpi_gbl_memory_lists[list_id]; | ||
712 | status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY); | ||
713 | if (ACPI_FAILURE (status)) { | ||
714 | return_ACPI_STATUS (status); | ||
715 | } | ||
716 | |||
717 | /* | ||
718 | * Search list for this address to make sure it is not already on the list. | ||
719 | * This will catch several kinds of problems. | ||
720 | */ | ||
721 | |||
722 | element = acpi_ut_find_allocation (list_id, allocation); | ||
723 | if (element) { | ||
724 | ACPI_REPORT_ERROR (("ut_track_allocation: Allocation already present in list! (%p)\n", | ||
725 | allocation)); | ||
726 | |||
727 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n", element, allocation)); | ||
728 | |||
729 | goto unlock_and_exit; | ||
730 | } | ||
731 | |||
732 | /* Fill in the instance data. */ | ||
733 | |||
734 | allocation->size = (u32) size; | ||
735 | allocation->alloc_type = alloc_type; | ||
736 | allocation->component = component; | ||
737 | allocation->line = line; | ||
738 | |||
739 | ACPI_STRNCPY (allocation->module, module, ACPI_MAX_MODULE_NAME); | ||
740 | allocation->module[ACPI_MAX_MODULE_NAME-1] = 0; | ||
741 | |||
742 | /* Insert at list head */ | ||
743 | |||
744 | if (mem_list->list_head) { | ||
745 | ((struct acpi_debug_mem_block *)(mem_list->list_head))->previous = allocation; | ||
746 | } | ||
747 | |||
748 | allocation->next = mem_list->list_head; | ||
749 | allocation->previous = NULL; | ||
750 | |||
751 | mem_list->list_head = allocation; | ||
752 | |||
753 | |||
754 | unlock_and_exit: | ||
755 | status = acpi_ut_release_mutex (ACPI_MTX_MEMORY); | ||
756 | return_ACPI_STATUS (status); | ||
757 | } | ||
758 | |||
759 | |||
760 | /******************************************************************************* | ||
761 | * | ||
762 | * FUNCTION: acpi_ut_remove_allocation | ||
763 | * | ||
764 | * PARAMETERS: list_id - Memory list to search | ||
765 | * Allocation - Address of allocated memory | ||
766 | * Component - Component type of caller | ||
767 | * Module - Source file name of caller | ||
768 | * Line - Line number of caller | ||
769 | * | ||
770 | * RETURN: | ||
771 | * | ||
772 | * DESCRIPTION: Deletes an element from the global allocation tracking list. | ||
773 | * | ||
774 | ******************************************************************************/ | ||
775 | |||
776 | acpi_status | ||
777 | acpi_ut_remove_allocation ( | ||
778 | u32 list_id, | ||
779 | struct acpi_debug_mem_block *allocation, | ||
780 | u32 component, | ||
781 | char *module, | ||
782 | u32 line) | ||
783 | { | ||
784 | struct acpi_memory_list *mem_list; | ||
785 | acpi_status status; | ||
786 | |||
787 | |||
788 | ACPI_FUNCTION_TRACE ("ut_remove_allocation"); | ||
789 | |||
790 | |||
791 | if (list_id > ACPI_MEM_LIST_MAX) { | ||
792 | return_ACPI_STATUS (AE_BAD_PARAMETER); | ||
793 | } | ||
794 | |||
795 | mem_list = &acpi_gbl_memory_lists[list_id]; | ||
796 | if (NULL == mem_list->list_head) { | ||
797 | /* No allocations! */ | ||
798 | |||
799 | _ACPI_REPORT_ERROR (module, line, component, | ||
800 | ("ut_remove_allocation: Empty allocation list, nothing to free!\n")); | ||
801 | |||
802 | return_ACPI_STATUS (AE_OK); | ||
803 | } | ||
804 | |||
805 | status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY); | ||
806 | if (ACPI_FAILURE (status)) { | ||
807 | return_ACPI_STATUS (status); | ||
808 | } | ||
809 | |||
810 | /* Unlink */ | ||
811 | |||
812 | if (allocation->previous) { | ||
813 | (allocation->previous)->next = allocation->next; | ||
814 | } | ||
815 | else { | ||
816 | mem_list->list_head = allocation->next; | ||
817 | } | ||
818 | |||
819 | if (allocation->next) { | ||
820 | (allocation->next)->previous = allocation->previous; | ||
821 | } | ||
822 | |||
823 | /* Mark the segment as deleted */ | ||
824 | |||
825 | ACPI_MEMSET (&allocation->user_space, 0xEA, allocation->size); | ||
826 | |||
827 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n", allocation->size)); | ||
828 | |||
829 | status = acpi_ut_release_mutex (ACPI_MTX_MEMORY); | ||
830 | return_ACPI_STATUS (status); | ||
831 | } | ||
832 | |||
833 | |||
834 | /******************************************************************************* | ||
835 | * | ||
836 | * FUNCTION: acpi_ut_dump_allocation_info | ||
837 | * | ||
838 | * PARAMETERS: | ||
839 | * | ||
840 | * RETURN: None | ||
841 | * | ||
842 | * DESCRIPTION: Print some info about the outstanding allocations. | ||
843 | * | ||
844 | ******************************************************************************/ | ||
845 | #ifdef ACPI_FUTURE_USAGE | ||
846 | void | ||
847 | acpi_ut_dump_allocation_info ( | ||
848 | void) | ||
849 | { | ||
850 | /* | ||
851 | struct acpi_memory_list *mem_list; | ||
852 | */ | ||
853 | |||
854 | ACPI_FUNCTION_TRACE ("ut_dump_allocation_info"); | ||
855 | |||
856 | /* | ||
857 | ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, | ||
858 | ("%30s: %4d (%3d Kb)\n", "Current allocations", | ||
859 | mem_list->current_count, | ||
860 | ROUND_UP_TO_1K (mem_list->current_size))); | ||
861 | |||
862 | ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, | ||
863 | ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations", | ||
864 | mem_list->max_concurrent_count, | ||
865 | ROUND_UP_TO_1K (mem_list->max_concurrent_size))); | ||
866 | |||
867 | |||
868 | ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, | ||
869 | ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects", | ||
870 | running_object_count, | ||
871 | ROUND_UP_TO_1K (running_object_size))); | ||
872 | |||
873 | ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, | ||
874 | ("%30s: %4d (%3d Kb)\n", "Total (all) allocations", | ||
875 | running_alloc_count, | ||
876 | ROUND_UP_TO_1K (running_alloc_size))); | ||
877 | |||
878 | |||
879 | ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, | ||
880 | ("%30s: %4d (%3d Kb)\n", "Current Nodes", | ||
881 | acpi_gbl_current_node_count, | ||
882 | ROUND_UP_TO_1K (acpi_gbl_current_node_size))); | ||
883 | |||
884 | ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, | ||
885 | ("%30s: %4d (%3d Kb)\n", "Max Nodes", | ||
886 | acpi_gbl_max_concurrent_node_count, | ||
887 | ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count * sizeof (struct acpi_namespace_node))))); | ||
888 | */ | ||
889 | return_VOID; | ||
890 | } | ||
891 | #endif /* ACPI_FUTURE_USAGE */ | ||
892 | |||
893 | |||
894 | /******************************************************************************* | ||
895 | * | ||
896 | * FUNCTION: acpi_ut_dump_allocations | ||
897 | * | ||
898 | * PARAMETERS: Component - Component(s) to dump info for. | ||
899 | * Module - Module to dump info for. NULL means all. | ||
900 | * | ||
901 | * RETURN: None | ||
902 | * | ||
903 | * DESCRIPTION: Print a list of all outstanding allocations. | ||
904 | * | ||
905 | ******************************************************************************/ | ||
906 | |||
907 | void | ||
908 | acpi_ut_dump_allocations ( | ||
909 | u32 component, | ||
910 | char *module) | ||
911 | { | ||
912 | struct acpi_debug_mem_block *element; | ||
913 | union acpi_descriptor *descriptor; | ||
914 | u32 num_outstanding = 0; | ||
915 | |||
916 | |||
917 | ACPI_FUNCTION_TRACE ("ut_dump_allocations"); | ||
918 | |||
919 | |||
920 | /* | ||
921 | * Walk the allocation list. | ||
922 | */ | ||
923 | if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_MEMORY))) { | ||
924 | return; | ||
925 | } | ||
926 | |||
927 | element = acpi_gbl_memory_lists[0].list_head; | ||
928 | while (element) { | ||
929 | if ((element->component & component) && | ||
930 | ((module == NULL) || (0 == ACPI_STRCMP (module, element->module)))) { | ||
931 | /* Ignore allocated objects that are in a cache */ | ||
932 | |||
933 | descriptor = ACPI_CAST_PTR (union acpi_descriptor, &element->user_space); | ||
934 | if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) { | ||
935 | acpi_os_printf ("%p Len %04X %9.9s-%d [%s] ", | ||
936 | descriptor, element->size, element->module, | ||
937 | element->line, acpi_ut_get_descriptor_name (descriptor)); | ||
938 | |||
939 | /* Most of the elements will be Operand objects. */ | ||
940 | |||
941 | switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor)) { | ||
942 | case ACPI_DESC_TYPE_OPERAND: | ||
943 | acpi_os_printf ("%12.12s R%hd", | ||
944 | acpi_ut_get_type_name (descriptor->object.common.type), | ||
945 | descriptor->object.common.reference_count); | ||
946 | break; | ||
947 | |||
948 | case ACPI_DESC_TYPE_PARSER: | ||
949 | acpi_os_printf ("aml_opcode %04hX", | ||
950 | descriptor->op.asl.aml_opcode); | ||
951 | break; | ||
952 | |||
953 | case ACPI_DESC_TYPE_NAMED: | ||
954 | acpi_os_printf ("%4.4s", | ||
955 | acpi_ut_get_node_name (&descriptor->node)); | ||
956 | break; | ||
957 | |||
958 | default: | ||
959 | break; | ||
960 | } | ||
961 | |||
962 | acpi_os_printf ( "\n"); | ||
963 | num_outstanding++; | ||
964 | } | ||
965 | } | ||
966 | element = element->next; | ||
967 | } | ||
968 | |||
969 | (void) acpi_ut_release_mutex (ACPI_MTX_MEMORY); | ||
970 | |||
971 | /* Print summary */ | ||
972 | |||
973 | if (!num_outstanding) { | ||
974 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
975 | "No outstanding allocations.\n")); | ||
976 | } | ||
977 | else { | ||
978 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
979 | "%d(%X) Outstanding allocations\n", | ||
980 | num_outstanding, num_outstanding)); | ||
981 | } | ||
982 | |||
983 | return_VOID; | ||
984 | } | ||
985 | |||
986 | |||
987 | #endif /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */ | ||
988 | |||
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c new file mode 100644 index 000000000000..0fcd98bde0d1 --- /dev/null +++ b/drivers/acpi/utilities/utcopy.c | |||
@@ -0,0 +1,930 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: utcopy - Internal to external object translation utilities | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
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 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/amlcode.h> | ||
47 | |||
48 | |||
49 | #define _COMPONENT ACPI_UTILITIES | ||
50 | ACPI_MODULE_NAME ("utcopy") | ||
51 | |||
52 | |||
53 | /******************************************************************************* | ||
54 | * | ||
55 | * FUNCTION: acpi_ut_copy_isimple_to_esimple | ||
56 | * | ||
57 | * PARAMETERS: *internal_object - Pointer to the object we are examining | ||
58 | * *Buffer - Where the object is returned | ||
59 | * *space_used - Where the data length is returned | ||
60 | * | ||
61 | * RETURN: Status | ||
62 | * | ||
63 | * DESCRIPTION: This function is called to place a simple object in a user | ||
64 | * buffer. | ||
65 | * | ||
66 | * The buffer is assumed to have sufficient space for the object. | ||
67 | * | ||
68 | ******************************************************************************/ | ||
69 | |||
70 | static acpi_status | ||
71 | acpi_ut_copy_isimple_to_esimple ( | ||
72 | union acpi_operand_object *internal_object, | ||
73 | union acpi_object *external_object, | ||
74 | u8 *data_space, | ||
75 | acpi_size *buffer_space_used) | ||
76 | { | ||
77 | acpi_status status = AE_OK; | ||
78 | |||
79 | |||
80 | ACPI_FUNCTION_TRACE ("ut_copy_isimple_to_esimple"); | ||
81 | |||
82 | |||
83 | *buffer_space_used = 0; | ||
84 | |||
85 | /* | ||
86 | * Check for NULL object case (could be an uninitialized | ||
87 | * package element) | ||
88 | */ | ||
89 | if (!internal_object) { | ||
90 | return_ACPI_STATUS (AE_OK); | ||
91 | } | ||
92 | |||
93 | /* Always clear the external object */ | ||
94 | |||
95 | ACPI_MEMSET (external_object, 0, sizeof (union acpi_object)); | ||
96 | |||
97 | /* | ||
98 | * In general, the external object will be the same type as | ||
99 | * the internal object | ||
100 | */ | ||
101 | external_object->type = ACPI_GET_OBJECT_TYPE (internal_object); | ||
102 | |||
103 | /* However, only a limited number of external types are supported */ | ||
104 | |||
105 | switch (ACPI_GET_OBJECT_TYPE (internal_object)) { | ||
106 | case ACPI_TYPE_STRING: | ||
107 | |||
108 | external_object->string.pointer = (char *) data_space; | ||
109 | external_object->string.length = internal_object->string.length; | ||
110 | *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD ((acpi_size) internal_object->string.length + 1); | ||
111 | |||
112 | ACPI_MEMCPY ((void *) data_space, (void *) internal_object->string.pointer, | ||
113 | (acpi_size) internal_object->string.length + 1); | ||
114 | break; | ||
115 | |||
116 | |||
117 | case ACPI_TYPE_BUFFER: | ||
118 | |||
119 | external_object->buffer.pointer = data_space; | ||
120 | external_object->buffer.length = internal_object->buffer.length; | ||
121 | *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD (internal_object->string.length); | ||
122 | |||
123 | ACPI_MEMCPY ((void *) data_space, (void *) internal_object->buffer.pointer, | ||
124 | internal_object->buffer.length); | ||
125 | break; | ||
126 | |||
127 | |||
128 | case ACPI_TYPE_INTEGER: | ||
129 | |||
130 | external_object->integer.value = internal_object->integer.value; | ||
131 | break; | ||
132 | |||
133 | |||
134 | case ACPI_TYPE_LOCAL_REFERENCE: | ||
135 | |||
136 | /* | ||
137 | * This is an object reference. Attempt to dereference it. | ||
138 | */ | ||
139 | switch (internal_object->reference.opcode) { | ||
140 | case AML_INT_NAMEPATH_OP: | ||
141 | |||
142 | /* For namepath, return the object handle ("reference") */ | ||
143 | |||
144 | default: | ||
145 | /* | ||
146 | * Use the object type of "Any" to indicate a reference | ||
147 | * to object containing a handle to an ACPI named object. | ||
148 | */ | ||
149 | external_object->type = ACPI_TYPE_ANY; | ||
150 | external_object->reference.handle = internal_object->reference.node; | ||
151 | break; | ||
152 | } | ||
153 | break; | ||
154 | |||
155 | |||
156 | case ACPI_TYPE_PROCESSOR: | ||
157 | |||
158 | external_object->processor.proc_id = internal_object->processor.proc_id; | ||
159 | external_object->processor.pblk_address = internal_object->processor.address; | ||
160 | external_object->processor.pblk_length = internal_object->processor.length; | ||
161 | break; | ||
162 | |||
163 | |||
164 | case ACPI_TYPE_POWER: | ||
165 | |||
166 | external_object->power_resource.system_level = | ||
167 | internal_object->power_resource.system_level; | ||
168 | |||
169 | external_object->power_resource.resource_order = | ||
170 | internal_object->power_resource.resource_order; | ||
171 | break; | ||
172 | |||
173 | |||
174 | default: | ||
175 | /* | ||
176 | * There is no corresponding external object type | ||
177 | */ | ||
178 | return_ACPI_STATUS (AE_SUPPORT); | ||
179 | } | ||
180 | |||
181 | return_ACPI_STATUS (status); | ||
182 | } | ||
183 | |||
184 | |||
185 | /******************************************************************************* | ||
186 | * | ||
187 | * FUNCTION: acpi_ut_copy_ielement_to_eelement | ||
188 | * | ||
189 | * PARAMETERS: acpi_pkg_callback | ||
190 | * | ||
191 | * RETURN: Status | ||
192 | * | ||
193 | * DESCRIPTION: Copy one package element to another package element | ||
194 | * | ||
195 | ******************************************************************************/ | ||
196 | |||
197 | acpi_status | ||
198 | acpi_ut_copy_ielement_to_eelement ( | ||
199 | u8 object_type, | ||
200 | union acpi_operand_object *source_object, | ||
201 | union acpi_generic_state *state, | ||
202 | void *context) | ||
203 | { | ||
204 | acpi_status status = AE_OK; | ||
205 | struct acpi_pkg_info *info = (struct acpi_pkg_info *) context; | ||
206 | acpi_size object_space; | ||
207 | u32 this_index; | ||
208 | union acpi_object *target_object; | ||
209 | |||
210 | |||
211 | ACPI_FUNCTION_ENTRY (); | ||
212 | |||
213 | |||
214 | this_index = state->pkg.index; | ||
215 | target_object = (union acpi_object *) | ||
216 | &((union acpi_object *)(state->pkg.dest_object))->package.elements[this_index]; | ||
217 | |||
218 | switch (object_type) { | ||
219 | case ACPI_COPY_TYPE_SIMPLE: | ||
220 | |||
221 | /* | ||
222 | * This is a simple or null object | ||
223 | */ | ||
224 | status = acpi_ut_copy_isimple_to_esimple (source_object, | ||
225 | target_object, info->free_space, &object_space); | ||
226 | if (ACPI_FAILURE (status)) { | ||
227 | return (status); | ||
228 | } | ||
229 | break; | ||
230 | |||
231 | |||
232 | case ACPI_COPY_TYPE_PACKAGE: | ||
233 | |||
234 | /* | ||
235 | * Build the package object | ||
236 | */ | ||
237 | target_object->type = ACPI_TYPE_PACKAGE; | ||
238 | target_object->package.count = source_object->package.count; | ||
239 | target_object->package.elements = ACPI_CAST_PTR (union acpi_object, info->free_space); | ||
240 | |||
241 | /* | ||
242 | * Pass the new package object back to the package walk routine | ||
243 | */ | ||
244 | state->pkg.this_target_obj = target_object; | ||
245 | |||
246 | /* | ||
247 | * Save space for the array of objects (Package elements) | ||
248 | * update the buffer length counter | ||
249 | */ | ||
250 | object_space = ACPI_ROUND_UP_TO_NATIVE_WORD ( | ||
251 | (acpi_size) target_object->package.count * sizeof (union acpi_object)); | ||
252 | break; | ||
253 | |||
254 | |||
255 | default: | ||
256 | return (AE_BAD_PARAMETER); | ||
257 | } | ||
258 | |||
259 | info->free_space += object_space; | ||
260 | info->length += object_space; | ||
261 | return (status); | ||
262 | } | ||
263 | |||
264 | |||
265 | /******************************************************************************* | ||
266 | * | ||
267 | * FUNCTION: acpi_ut_copy_ipackage_to_epackage | ||
268 | * | ||
269 | * PARAMETERS: *internal_object - Pointer to the object we are returning | ||
270 | * *Buffer - Where the object is returned | ||
271 | * *space_used - Where the object length is returned | ||
272 | * | ||
273 | * RETURN: Status | ||
274 | * | ||
275 | * DESCRIPTION: This function is called to place a package object in a user | ||
276 | * buffer. A package object by definition contains other objects. | ||
277 | * | ||
278 | * The buffer is assumed to have sufficient space for the object. | ||
279 | * The caller must have verified the buffer length needed using the | ||
280 | * acpi_ut_get_object_size function before calling this function. | ||
281 | * | ||
282 | ******************************************************************************/ | ||
283 | |||
284 | static acpi_status | ||
285 | acpi_ut_copy_ipackage_to_epackage ( | ||
286 | union acpi_operand_object *internal_object, | ||
287 | u8 *buffer, | ||
288 | acpi_size *space_used) | ||
289 | { | ||
290 | union acpi_object *external_object; | ||
291 | acpi_status status; | ||
292 | struct acpi_pkg_info info; | ||
293 | |||
294 | |||
295 | ACPI_FUNCTION_TRACE ("ut_copy_ipackage_to_epackage"); | ||
296 | |||
297 | |||
298 | /* | ||
299 | * First package at head of the buffer | ||
300 | */ | ||
301 | external_object = ACPI_CAST_PTR (union acpi_object, buffer); | ||
302 | |||
303 | /* | ||
304 | * Free space begins right after the first package | ||
305 | */ | ||
306 | info.length = ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object)); | ||
307 | info.free_space = buffer + ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object)); | ||
308 | info.object_space = 0; | ||
309 | info.num_packages = 1; | ||
310 | |||
311 | external_object->type = ACPI_GET_OBJECT_TYPE (internal_object); | ||
312 | external_object->package.count = internal_object->package.count; | ||
313 | external_object->package.elements = ACPI_CAST_PTR (union acpi_object, info.free_space); | ||
314 | |||
315 | /* | ||
316 | * Leave room for an array of ACPI_OBJECTS in the buffer | ||
317 | * and move the free space past it | ||
318 | */ | ||
319 | info.length += (acpi_size) external_object->package.count * | ||
320 | ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object)); | ||
321 | info.free_space += external_object->package.count * | ||
322 | ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object)); | ||
323 | |||
324 | status = acpi_ut_walk_package_tree (internal_object, external_object, | ||
325 | acpi_ut_copy_ielement_to_eelement, &info); | ||
326 | |||
327 | *space_used = info.length; | ||
328 | return_ACPI_STATUS (status); | ||
329 | } | ||
330 | |||
331 | |||
332 | /******************************************************************************* | ||
333 | * | ||
334 | * FUNCTION: acpi_ut_copy_iobject_to_eobject | ||
335 | * | ||
336 | * PARAMETERS: *internal_object - The internal object to be converted | ||
337 | * *buffer_ptr - Where the object is returned | ||
338 | * | ||
339 | * RETURN: Status | ||
340 | * | ||
341 | * DESCRIPTION: This function is called to build an API object to be returned to | ||
342 | * the caller. | ||
343 | * | ||
344 | ******************************************************************************/ | ||
345 | |||
346 | acpi_status | ||
347 | acpi_ut_copy_iobject_to_eobject ( | ||
348 | union acpi_operand_object *internal_object, | ||
349 | struct acpi_buffer *ret_buffer) | ||
350 | { | ||
351 | acpi_status status; | ||
352 | |||
353 | |||
354 | ACPI_FUNCTION_TRACE ("ut_copy_iobject_to_eobject"); | ||
355 | |||
356 | |||
357 | if (ACPI_GET_OBJECT_TYPE (internal_object) == ACPI_TYPE_PACKAGE) { | ||
358 | /* | ||
359 | * Package object: Copy all subobjects (including | ||
360 | * nested packages) | ||
361 | */ | ||
362 | status = acpi_ut_copy_ipackage_to_epackage (internal_object, | ||
363 | ret_buffer->pointer, &ret_buffer->length); | ||
364 | } | ||
365 | else { | ||
366 | /* | ||
367 | * Build a simple object (no nested objects) | ||
368 | */ | ||
369 | status = acpi_ut_copy_isimple_to_esimple (internal_object, | ||
370 | (union acpi_object *) ret_buffer->pointer, | ||
371 | ((u8 *) ret_buffer->pointer + | ||
372 | ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object))), | ||
373 | &ret_buffer->length); | ||
374 | /* | ||
375 | * build simple does not include the object size in the length | ||
376 | * so we add it in here | ||
377 | */ | ||
378 | ret_buffer->length += sizeof (union acpi_object); | ||
379 | } | ||
380 | |||
381 | return_ACPI_STATUS (status); | ||
382 | } | ||
383 | |||
384 | |||
385 | /******************************************************************************* | ||
386 | * | ||
387 | * FUNCTION: acpi_ut_copy_esimple_to_isimple | ||
388 | * | ||
389 | * PARAMETERS: *external_object - The external object to be converted | ||
390 | * *internal_object - Where the internal object is returned | ||
391 | * | ||
392 | * RETURN: Status | ||
393 | * | ||
394 | * DESCRIPTION: This function copies an external object to an internal one. | ||
395 | * NOTE: Pointers can be copied, we don't need to copy data. | ||
396 | * (The pointers have to be valid in our address space no matter | ||
397 | * what we do with them!) | ||
398 | * | ||
399 | ******************************************************************************/ | ||
400 | |||
401 | acpi_status | ||
402 | acpi_ut_copy_esimple_to_isimple ( | ||
403 | union acpi_object *external_object, | ||
404 | union acpi_operand_object **ret_internal_object) | ||
405 | { | ||
406 | union acpi_operand_object *internal_object; | ||
407 | |||
408 | |||
409 | ACPI_FUNCTION_TRACE ("ut_copy_esimple_to_isimple"); | ||
410 | |||
411 | |||
412 | /* | ||
413 | * Simple types supported are: String, Buffer, Integer | ||
414 | */ | ||
415 | switch (external_object->type) { | ||
416 | case ACPI_TYPE_STRING: | ||
417 | case ACPI_TYPE_BUFFER: | ||
418 | case ACPI_TYPE_INTEGER: | ||
419 | |||
420 | internal_object = acpi_ut_create_internal_object ((u8) external_object->type); | ||
421 | if (!internal_object) { | ||
422 | return_ACPI_STATUS (AE_NO_MEMORY); | ||
423 | } | ||
424 | break; | ||
425 | |||
426 | default: | ||
427 | /* All other types are not supported */ | ||
428 | |||
429 | return_ACPI_STATUS (AE_SUPPORT); | ||
430 | } | ||
431 | |||
432 | |||
433 | /* Must COPY string and buffer contents */ | ||
434 | |||
435 | switch (external_object->type) { | ||
436 | case ACPI_TYPE_STRING: | ||
437 | |||
438 | internal_object->string.pointer = | ||
439 | ACPI_MEM_CALLOCATE ((acpi_size) external_object->string.length + 1); | ||
440 | if (!internal_object->string.pointer) { | ||
441 | goto error_exit; | ||
442 | } | ||
443 | |||
444 | ACPI_MEMCPY (internal_object->string.pointer, | ||
445 | external_object->string.pointer, | ||
446 | external_object->string.length); | ||
447 | |||
448 | internal_object->string.length = external_object->string.length; | ||
449 | break; | ||
450 | |||
451 | |||
452 | case ACPI_TYPE_BUFFER: | ||
453 | |||
454 | internal_object->buffer.pointer = | ||
455 | ACPI_MEM_CALLOCATE (external_object->buffer.length); | ||
456 | if (!internal_object->buffer.pointer) { | ||
457 | goto error_exit; | ||
458 | } | ||
459 | |||
460 | ACPI_MEMCPY (internal_object->buffer.pointer, | ||
461 | external_object->buffer.pointer, | ||
462 | external_object->buffer.length); | ||
463 | |||
464 | internal_object->buffer.length = external_object->buffer.length; | ||
465 | break; | ||
466 | |||
467 | |||
468 | case ACPI_TYPE_INTEGER: | ||
469 | |||
470 | internal_object->integer.value = external_object->integer.value; | ||
471 | break; | ||
472 | |||
473 | default: | ||
474 | /* Other types can't get here */ | ||
475 | break; | ||
476 | } | ||
477 | |||
478 | *ret_internal_object = internal_object; | ||
479 | return_ACPI_STATUS (AE_OK); | ||
480 | |||
481 | |||
482 | error_exit: | ||
483 | acpi_ut_remove_reference (internal_object); | ||
484 | return_ACPI_STATUS (AE_NO_MEMORY); | ||
485 | } | ||
486 | |||
487 | |||
488 | #ifdef ACPI_FUTURE_IMPLEMENTATION | ||
489 | |||
490 | /* Code to convert packages that are parameters to control methods */ | ||
491 | |||
492 | /******************************************************************************* | ||
493 | * | ||
494 | * FUNCTION: acpi_ut_copy_epackage_to_ipackage | ||
495 | * | ||
496 | * PARAMETERS: *internal_object - Pointer to the object we are returning | ||
497 | * *Buffer - Where the object is returned | ||
498 | * *space_used - Where the length of the object is returned | ||
499 | * | ||
500 | * RETURN: Status | ||
501 | * | ||
502 | * DESCRIPTION: This function is called to place a package object in a user | ||
503 | * buffer. A package object by definition contains other objects. | ||
504 | * | ||
505 | * The buffer is assumed to have sufficient space for the object. | ||
506 | * The caller must have verified the buffer length needed using the | ||
507 | * acpi_ut_get_object_size function before calling this function. | ||
508 | * | ||
509 | ******************************************************************************/ | ||
510 | |||
511 | static acpi_status | ||
512 | acpi_ut_copy_epackage_to_ipackage ( | ||
513 | union acpi_operand_object *internal_object, | ||
514 | u8 *buffer, | ||
515 | u32 *space_used) | ||
516 | { | ||
517 | u8 *free_space; | ||
518 | union acpi_object *external_object; | ||
519 | u32 length = 0; | ||
520 | u32 this_index; | ||
521 | u32 object_space = 0; | ||
522 | union acpi_operand_object *this_internal_obj; | ||
523 | union acpi_object *this_external_obj; | ||
524 | |||
525 | |||
526 | ACPI_FUNCTION_TRACE ("ut_copy_epackage_to_ipackage"); | ||
527 | |||
528 | |||
529 | /* | ||
530 | * First package at head of the buffer | ||
531 | */ | ||
532 | external_object = (union acpi_object *)buffer; | ||
533 | |||
534 | /* | ||
535 | * Free space begins right after the first package | ||
536 | */ | ||
537 | free_space = buffer + sizeof(union acpi_object); | ||
538 | |||
539 | |||
540 | external_object->type = ACPI_GET_OBJECT_TYPE (internal_object); | ||
541 | external_object->package.count = internal_object->package.count; | ||
542 | external_object->package.elements = (union acpi_object *)free_space; | ||
543 | |||
544 | /* | ||
545 | * Build an array of ACPI_OBJECTS in the buffer | ||
546 | * and move the free space past it | ||
547 | */ | ||
548 | free_space += external_object->package.count * sizeof(union acpi_object); | ||
549 | |||
550 | |||
551 | /* Call walk_package */ | ||
552 | |||
553 | } | ||
554 | |||
555 | #endif /* Future implementation */ | ||
556 | |||
557 | |||
558 | /******************************************************************************* | ||
559 | * | ||
560 | * FUNCTION: acpi_ut_copy_eobject_to_iobject | ||
561 | * | ||
562 | * PARAMETERS: *internal_object - The external object to be converted | ||
563 | * *buffer_ptr - Where the internal object is returned | ||
564 | * | ||
565 | * RETURN: Status - the status of the call | ||
566 | * | ||
567 | * DESCRIPTION: Converts an external object to an internal object. | ||
568 | * | ||
569 | ******************************************************************************/ | ||
570 | |||
571 | acpi_status | ||
572 | acpi_ut_copy_eobject_to_iobject ( | ||
573 | union acpi_object *external_object, | ||
574 | union acpi_operand_object **internal_object) | ||
575 | { | ||
576 | acpi_status status; | ||
577 | |||
578 | |||
579 | ACPI_FUNCTION_TRACE ("ut_copy_eobject_to_iobject"); | ||
580 | |||
581 | |||
582 | if (external_object->type == ACPI_TYPE_PACKAGE) { | ||
583 | /* | ||
584 | * Packages as external input to control methods are not supported, | ||
585 | */ | ||
586 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
587 | "Packages as parameters not implemented!\n")); | ||
588 | |||
589 | return_ACPI_STATUS (AE_NOT_IMPLEMENTED); | ||
590 | } | ||
591 | |||
592 | else { | ||
593 | /* | ||
594 | * Build a simple object (no nested objects) | ||
595 | */ | ||
596 | status = acpi_ut_copy_esimple_to_isimple (external_object, internal_object); | ||
597 | } | ||
598 | |||
599 | return_ACPI_STATUS (status); | ||
600 | } | ||
601 | |||
602 | |||
603 | /******************************************************************************* | ||
604 | * | ||
605 | * FUNCTION: acpi_ut_copy_simple_object | ||
606 | * | ||
607 | * PARAMETERS: source_desc - The internal object to be copied | ||
608 | * dest_desc - New target object | ||
609 | * | ||
610 | * RETURN: Status | ||
611 | * | ||
612 | * DESCRIPTION: Simple copy of one internal object to another. Reference count | ||
613 | * of the destination object is preserved. | ||
614 | * | ||
615 | ******************************************************************************/ | ||
616 | |||
617 | acpi_status | ||
618 | acpi_ut_copy_simple_object ( | ||
619 | union acpi_operand_object *source_desc, | ||
620 | union acpi_operand_object *dest_desc) | ||
621 | { | ||
622 | u16 reference_count; | ||
623 | union acpi_operand_object *next_object; | ||
624 | |||
625 | |||
626 | /* Save fields from destination that we don't want to overwrite */ | ||
627 | |||
628 | reference_count = dest_desc->common.reference_count; | ||
629 | next_object = dest_desc->common.next_object; | ||
630 | |||
631 | /* Copy the entire source object over the destination object*/ | ||
632 | |||
633 | ACPI_MEMCPY ((char *) dest_desc, (char *) source_desc, | ||
634 | sizeof (union acpi_operand_object)); | ||
635 | |||
636 | /* Restore the saved fields */ | ||
637 | |||
638 | dest_desc->common.reference_count = reference_count; | ||
639 | dest_desc->common.next_object = next_object; | ||
640 | |||
641 | /* Handle the objects with extra data */ | ||
642 | |||
643 | switch (ACPI_GET_OBJECT_TYPE (dest_desc)) { | ||
644 | case ACPI_TYPE_BUFFER: | ||
645 | |||
646 | dest_desc->buffer.node = NULL; | ||
647 | dest_desc->common.flags = source_desc->common.flags; | ||
648 | |||
649 | /* | ||
650 | * Allocate and copy the actual buffer if and only if: | ||
651 | * 1) There is a valid buffer pointer | ||
652 | * 2) The buffer is not static (not in an ACPI table) (in this case, | ||
653 | * the actual pointer was already copied above) | ||
654 | */ | ||
655 | if ((source_desc->buffer.pointer) && | ||
656 | (!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) { | ||
657 | dest_desc->buffer.pointer = NULL; | ||
658 | |||
659 | /* Create an actual buffer only if length > 0 */ | ||
660 | |||
661 | if (source_desc->buffer.length) { | ||
662 | dest_desc->buffer.pointer = | ||
663 | ACPI_MEM_ALLOCATE (source_desc->buffer.length); | ||
664 | if (!dest_desc->buffer.pointer) { | ||
665 | return (AE_NO_MEMORY); | ||
666 | } | ||
667 | |||
668 | /* Copy the actual buffer data */ | ||
669 | |||
670 | ACPI_MEMCPY (dest_desc->buffer.pointer, | ||
671 | source_desc->buffer.pointer, | ||
672 | source_desc->buffer.length); | ||
673 | } | ||
674 | } | ||
675 | break; | ||
676 | |||
677 | case ACPI_TYPE_STRING: | ||
678 | |||
679 | /* | ||
680 | * Allocate and copy the actual string if and only if: | ||
681 | * 1) There is a valid string pointer | ||
682 | * 2) The string is not static (not in an ACPI table) (in this case, | ||
683 | * the actual pointer was already copied above) | ||
684 | */ | ||
685 | if ((source_desc->string.pointer) && | ||
686 | (!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) { | ||
687 | dest_desc->string.pointer = | ||
688 | ACPI_MEM_ALLOCATE ((acpi_size) source_desc->string.length + 1); | ||
689 | if (!dest_desc->string.pointer) { | ||
690 | return (AE_NO_MEMORY); | ||
691 | } | ||
692 | |||
693 | ACPI_MEMCPY (dest_desc->string.pointer, source_desc->string.pointer, | ||
694 | (acpi_size) source_desc->string.length + 1); | ||
695 | } | ||
696 | break; | ||
697 | |||
698 | case ACPI_TYPE_LOCAL_REFERENCE: | ||
699 | /* | ||
700 | * We copied the reference object, so we now must add a reference | ||
701 | * to the object pointed to by the reference | ||
702 | */ | ||
703 | acpi_ut_add_reference (source_desc->reference.object); | ||
704 | break; | ||
705 | |||
706 | default: | ||
707 | /* Nothing to do for other simple objects */ | ||
708 | break; | ||
709 | } | ||
710 | |||
711 | return (AE_OK); | ||
712 | } | ||
713 | |||
714 | |||
715 | /******************************************************************************* | ||
716 | * | ||
717 | * FUNCTION: acpi_ut_copy_ielement_to_ielement | ||
718 | * | ||
719 | * PARAMETERS: acpi_pkg_callback | ||
720 | * | ||
721 | * RETURN: Status | ||
722 | * | ||
723 | * DESCRIPTION: Copy one package element to another package element | ||
724 | * | ||
725 | ******************************************************************************/ | ||
726 | |||
727 | acpi_status | ||
728 | acpi_ut_copy_ielement_to_ielement ( | ||
729 | u8 object_type, | ||
730 | union acpi_operand_object *source_object, | ||
731 | union acpi_generic_state *state, | ||
732 | void *context) | ||
733 | { | ||
734 | acpi_status status = AE_OK; | ||
735 | u32 this_index; | ||
736 | union acpi_operand_object **this_target_ptr; | ||
737 | union acpi_operand_object *target_object; | ||
738 | |||
739 | |||
740 | ACPI_FUNCTION_ENTRY (); | ||
741 | |||
742 | |||
743 | this_index = state->pkg.index; | ||
744 | this_target_ptr = (union acpi_operand_object **) | ||
745 | &state->pkg.dest_object->package.elements[this_index]; | ||
746 | |||
747 | switch (object_type) { | ||
748 | case ACPI_COPY_TYPE_SIMPLE: | ||
749 | |||
750 | /* A null source object indicates a (legal) null package element */ | ||
751 | |||
752 | if (source_object) { | ||
753 | /* | ||
754 | * This is a simple object, just copy it | ||
755 | */ | ||
756 | target_object = acpi_ut_create_internal_object ( | ||
757 | ACPI_GET_OBJECT_TYPE (source_object)); | ||
758 | if (!target_object) { | ||
759 | return (AE_NO_MEMORY); | ||
760 | } | ||
761 | |||
762 | status = acpi_ut_copy_simple_object (source_object, target_object); | ||
763 | if (ACPI_FAILURE (status)) { | ||
764 | goto error_exit; | ||
765 | } | ||
766 | |||
767 | *this_target_ptr = target_object; | ||
768 | } | ||
769 | else { | ||
770 | /* Pass through a null element */ | ||
771 | |||
772 | *this_target_ptr = NULL; | ||
773 | } | ||
774 | break; | ||
775 | |||
776 | |||
777 | case ACPI_COPY_TYPE_PACKAGE: | ||
778 | |||
779 | /* | ||
780 | * This object is a package - go down another nesting level | ||
781 | * Create and build the package object | ||
782 | */ | ||
783 | target_object = acpi_ut_create_internal_object (ACPI_TYPE_PACKAGE); | ||
784 | if (!target_object) { | ||
785 | return (AE_NO_MEMORY); | ||
786 | } | ||
787 | |||
788 | target_object->package.count = source_object->package.count; | ||
789 | target_object->common.flags = source_object->common.flags; | ||
790 | |||
791 | /* | ||
792 | * Create the object array | ||
793 | */ | ||
794 | target_object->package.elements = | ||
795 | ACPI_MEM_CALLOCATE (((acpi_size) source_object->package.count + 1) * | ||
796 | sizeof (void *)); | ||
797 | if (!target_object->package.elements) { | ||
798 | status = AE_NO_MEMORY; | ||
799 | goto error_exit; | ||
800 | } | ||
801 | |||
802 | /* | ||
803 | * Pass the new package object back to the package walk routine | ||
804 | */ | ||
805 | state->pkg.this_target_obj = target_object; | ||
806 | |||
807 | /* | ||
808 | * Store the object pointer in the parent package object | ||
809 | */ | ||
810 | *this_target_ptr = target_object; | ||
811 | break; | ||
812 | |||
813 | |||
814 | default: | ||
815 | return (AE_BAD_PARAMETER); | ||
816 | } | ||
817 | |||
818 | return (status); | ||
819 | |||
820 | error_exit: | ||
821 | acpi_ut_remove_reference (target_object); | ||
822 | return (status); | ||
823 | } | ||
824 | |||
825 | |||
826 | /******************************************************************************* | ||
827 | * | ||
828 | * FUNCTION: acpi_ut_copy_ipackage_to_ipackage | ||
829 | * | ||
830 | * PARAMETERS: *source_obj - Pointer to the source package object | ||
831 | * *dest_obj - Where the internal object is returned | ||
832 | * | ||
833 | * RETURN: Status - the status of the call | ||
834 | * | ||
835 | * DESCRIPTION: This function is called to copy an internal package object | ||
836 | * into another internal package object. | ||
837 | * | ||
838 | ******************************************************************************/ | ||
839 | |||
840 | acpi_status | ||
841 | acpi_ut_copy_ipackage_to_ipackage ( | ||
842 | union acpi_operand_object *source_obj, | ||
843 | union acpi_operand_object *dest_obj, | ||
844 | struct acpi_walk_state *walk_state) | ||
845 | { | ||
846 | acpi_status status = AE_OK; | ||
847 | |||
848 | |||
849 | ACPI_FUNCTION_TRACE ("ut_copy_ipackage_to_ipackage"); | ||
850 | |||
851 | |||
852 | dest_obj->common.type = ACPI_GET_OBJECT_TYPE (source_obj); | ||
853 | dest_obj->common.flags = source_obj->common.flags; | ||
854 | dest_obj->package.count = source_obj->package.count; | ||
855 | |||
856 | /* | ||
857 | * Create the object array and walk the source package tree | ||
858 | */ | ||
859 | dest_obj->package.elements = ACPI_MEM_CALLOCATE ( | ||
860 | ((acpi_size) source_obj->package.count + 1) * | ||
861 | sizeof (void *)); | ||
862 | if (!dest_obj->package.elements) { | ||
863 | ACPI_REPORT_ERROR ( | ||
864 | ("aml_build_copy_internal_package_object: Package allocation failure\n")); | ||
865 | return_ACPI_STATUS (AE_NO_MEMORY); | ||
866 | } | ||
867 | |||
868 | /* | ||
869 | * Copy the package element-by-element by walking the package "tree". | ||
870 | * This handles nested packages of arbitrary depth. | ||
871 | */ | ||
872 | status = acpi_ut_walk_package_tree (source_obj, dest_obj, | ||
873 | acpi_ut_copy_ielement_to_ielement, walk_state); | ||
874 | if (ACPI_FAILURE (status)) { | ||
875 | /* On failure, delete the destination package object */ | ||
876 | |||
877 | acpi_ut_remove_reference (dest_obj); | ||
878 | } | ||
879 | |||
880 | return_ACPI_STATUS (status); | ||
881 | } | ||
882 | |||
883 | |||
884 | /******************************************************************************* | ||
885 | * | ||
886 | * FUNCTION: acpi_ut_copy_iobject_to_iobject | ||
887 | * | ||
888 | * PARAMETERS: walk_state - Current walk state | ||
889 | * source_desc - The internal object to be copied | ||
890 | * dest_desc - Where the copied object is returned | ||
891 | * | ||
892 | * RETURN: Status | ||
893 | * | ||
894 | * DESCRIPTION: Copy an internal object to a new internal object | ||
895 | * | ||
896 | ******************************************************************************/ | ||
897 | |||
898 | acpi_status | ||
899 | acpi_ut_copy_iobject_to_iobject ( | ||
900 | union acpi_operand_object *source_desc, | ||
901 | union acpi_operand_object **dest_desc, | ||
902 | struct acpi_walk_state *walk_state) | ||
903 | { | ||
904 | acpi_status status = AE_OK; | ||
905 | |||
906 | |||
907 | ACPI_FUNCTION_TRACE ("ut_copy_iobject_to_iobject"); | ||
908 | |||
909 | |||
910 | /* Create the top level object */ | ||
911 | |||
912 | *dest_desc = acpi_ut_create_internal_object (ACPI_GET_OBJECT_TYPE (source_desc)); | ||
913 | if (!*dest_desc) { | ||
914 | return_ACPI_STATUS (AE_NO_MEMORY); | ||
915 | } | ||
916 | |||
917 | /* Copy the object and possible subobjects */ | ||
918 | |||
919 | if (ACPI_GET_OBJECT_TYPE (source_desc) == ACPI_TYPE_PACKAGE) { | ||
920 | status = acpi_ut_copy_ipackage_to_ipackage (source_desc, *dest_desc, | ||
921 | walk_state); | ||
922 | } | ||
923 | else { | ||
924 | status = acpi_ut_copy_simple_object (source_desc, *dest_desc); | ||
925 | } | ||
926 | |||
927 | return_ACPI_STATUS (status); | ||
928 | } | ||
929 | |||
930 | |||
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c new file mode 100644 index 000000000000..985c5d045b78 --- /dev/null +++ b/drivers/acpi/utilities/utdebug.c | |||
@@ -0,0 +1,624 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: utdebug - Debug print routines | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
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 <linux/module.h> | ||
45 | |||
46 | #include <acpi/acpi.h> | ||
47 | |||
48 | #define _COMPONENT ACPI_UTILITIES | ||
49 | ACPI_MODULE_NAME ("utdebug") | ||
50 | |||
51 | |||
52 | #ifdef ACPI_DEBUG_OUTPUT | ||
53 | |||
54 | static u32 acpi_gbl_prev_thread_id = 0xFFFFFFFF; | ||
55 | static char *acpi_gbl_fn_entry_str = "----Entry"; | ||
56 | static char *acpi_gbl_fn_exit_str = "----Exit-"; | ||
57 | |||
58 | |||
59 | /***************************************************************************** | ||
60 | * | ||
61 | * FUNCTION: acpi_ut_init_stack_ptr_trace | ||
62 | * | ||
63 | * PARAMETERS: None | ||
64 | * | ||
65 | * RETURN: None | ||
66 | * | ||
67 | * DESCRIPTION: Save the current stack pointer | ||
68 | * | ||
69 | ****************************************************************************/ | ||
70 | |||
71 | void | ||
72 | acpi_ut_init_stack_ptr_trace ( | ||
73 | void) | ||
74 | { | ||
75 | u32 current_sp; | ||
76 | |||
77 | |||
78 | acpi_gbl_entry_stack_pointer = ACPI_PTR_DIFF (¤t_sp, NULL); | ||
79 | } | ||
80 | |||
81 | |||
82 | /***************************************************************************** | ||
83 | * | ||
84 | * FUNCTION: acpi_ut_track_stack_ptr | ||
85 | * | ||
86 | * PARAMETERS: None | ||
87 | * | ||
88 | * RETURN: None | ||
89 | * | ||
90 | * DESCRIPTION: Save the current stack pointer | ||
91 | * | ||
92 | ****************************************************************************/ | ||
93 | |||
94 | void | ||
95 | acpi_ut_track_stack_ptr ( | ||
96 | void) | ||
97 | { | ||
98 | acpi_size current_sp; | ||
99 | |||
100 | |||
101 | current_sp = ACPI_PTR_DIFF (¤t_sp, NULL); | ||
102 | |||
103 | if (current_sp < acpi_gbl_lowest_stack_pointer) { | ||
104 | acpi_gbl_lowest_stack_pointer = current_sp; | ||
105 | } | ||
106 | |||
107 | if (acpi_gbl_nesting_level > acpi_gbl_deepest_nesting) { | ||
108 | acpi_gbl_deepest_nesting = acpi_gbl_nesting_level; | ||
109 | } | ||
110 | } | ||
111 | |||
112 | |||
113 | /***************************************************************************** | ||
114 | * | ||
115 | * FUNCTION: acpi_ut_debug_print | ||
116 | * | ||
117 | * PARAMETERS: debug_level - Requested debug print level | ||
118 | * proc_name - Caller's procedure name | ||
119 | * module_name - Caller's module name (for error output) | ||
120 | * line_number - Caller's line number (for error output) | ||
121 | * component_id - Caller's component ID (for error output) | ||
122 | * | ||
123 | * Format - Printf format field | ||
124 | * ... - Optional printf arguments | ||
125 | * | ||
126 | * RETURN: None | ||
127 | * | ||
128 | * DESCRIPTION: Print error message with prefix consisting of the module name, | ||
129 | * line number, and component ID. | ||
130 | * | ||
131 | ****************************************************************************/ | ||
132 | |||
133 | void ACPI_INTERNAL_VAR_XFACE | ||
134 | acpi_ut_debug_print ( | ||
135 | u32 requested_debug_level, | ||
136 | u32 line_number, | ||
137 | struct acpi_debug_print_info *dbg_info, | ||
138 | char *format, | ||
139 | ...) | ||
140 | { | ||
141 | u32 thread_id; | ||
142 | va_list args; | ||
143 | |||
144 | |||
145 | /* | ||
146 | * Stay silent if the debug level or component ID is disabled | ||
147 | */ | ||
148 | if (!(requested_debug_level & acpi_dbg_level) || | ||
149 | !(dbg_info->component_id & acpi_dbg_layer)) { | ||
150 | return; | ||
151 | } | ||
152 | |||
153 | /* | ||
154 | * Thread tracking and context switch notification | ||
155 | */ | ||
156 | thread_id = acpi_os_get_thread_id (); | ||
157 | |||
158 | if (thread_id != acpi_gbl_prev_thread_id) { | ||
159 | if (ACPI_LV_THREADS & acpi_dbg_level) { | ||
160 | acpi_os_printf ("\n**** Context Switch from TID %X to TID %X ****\n\n", | ||
161 | acpi_gbl_prev_thread_id, thread_id); | ||
162 | } | ||
163 | |||
164 | acpi_gbl_prev_thread_id = thread_id; | ||
165 | } | ||
166 | |||
167 | /* | ||
168 | * Display the module name, current line number, thread ID (if requested), | ||
169 | * current procedure nesting level, and the current procedure name | ||
170 | */ | ||
171 | acpi_os_printf ("%8s-%04ld ", dbg_info->module_name, line_number); | ||
172 | |||
173 | if (ACPI_LV_THREADS & acpi_dbg_level) { | ||
174 | acpi_os_printf ("[%04lX] ", thread_id); | ||
175 | } | ||
176 | |||
177 | acpi_os_printf ("[%02ld] %-22.22s: ", acpi_gbl_nesting_level, dbg_info->proc_name); | ||
178 | |||
179 | va_start (args, format); | ||
180 | acpi_os_vprintf (format, args); | ||
181 | } | ||
182 | EXPORT_SYMBOL(acpi_ut_debug_print); | ||
183 | |||
184 | |||
185 | /***************************************************************************** | ||
186 | * | ||
187 | * FUNCTION: acpi_ut_debug_print_raw | ||
188 | * | ||
189 | * PARAMETERS: requested_debug_level - Requested debug print level | ||
190 | * line_number - Caller's line number | ||
191 | * dbg_info - Contains: | ||
192 | * proc_name - Caller's procedure name | ||
193 | * module_name - Caller's module name | ||
194 | * component_id - Caller's component ID | ||
195 | * Format - Printf format field | ||
196 | * ... - Optional printf arguments | ||
197 | * | ||
198 | * RETURN: None | ||
199 | * | ||
200 | * DESCRIPTION: Print message with no headers. Has same interface as | ||
201 | * debug_print so that the same macros can be used. | ||
202 | * | ||
203 | ****************************************************************************/ | ||
204 | |||
205 | void ACPI_INTERNAL_VAR_XFACE | ||
206 | acpi_ut_debug_print_raw ( | ||
207 | u32 requested_debug_level, | ||
208 | u32 line_number, | ||
209 | struct acpi_debug_print_info *dbg_info, | ||
210 | char *format, | ||
211 | ...) | ||
212 | { | ||
213 | va_list args; | ||
214 | |||
215 | |||
216 | if (!(requested_debug_level & acpi_dbg_level) || | ||
217 | !(dbg_info->component_id & acpi_dbg_layer)) { | ||
218 | return; | ||
219 | } | ||
220 | |||
221 | va_start (args, format); | ||
222 | acpi_os_vprintf (format, args); | ||
223 | } | ||
224 | EXPORT_SYMBOL(acpi_ut_debug_print_raw); | ||
225 | |||
226 | |||
227 | /***************************************************************************** | ||
228 | * | ||
229 | * FUNCTION: acpi_ut_trace | ||
230 | * | ||
231 | * PARAMETERS: line_number - Caller's line number | ||
232 | * dbg_info - Contains: | ||
233 | * proc_name - Caller's procedure name | ||
234 | * module_name - Caller's module name | ||
235 | * component_id - Caller's component ID | ||
236 | * | ||
237 | * RETURN: None | ||
238 | * | ||
239 | * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is | ||
240 | * set in debug_level | ||
241 | * | ||
242 | ****************************************************************************/ | ||
243 | |||
244 | void | ||
245 | acpi_ut_trace ( | ||
246 | u32 line_number, | ||
247 | struct acpi_debug_print_info *dbg_info) | ||
248 | { | ||
249 | |||
250 | acpi_gbl_nesting_level++; | ||
251 | acpi_ut_track_stack_ptr (); | ||
252 | |||
253 | acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info, | ||
254 | "%s\n", acpi_gbl_fn_entry_str); | ||
255 | } | ||
256 | EXPORT_SYMBOL(acpi_ut_trace); | ||
257 | |||
258 | |||
259 | /***************************************************************************** | ||
260 | * | ||
261 | * FUNCTION: acpi_ut_trace_ptr | ||
262 | * | ||
263 | * PARAMETERS: line_number - Caller's line number | ||
264 | * dbg_info - Contains: | ||
265 | * proc_name - Caller's procedure name | ||
266 | * module_name - Caller's module name | ||
267 | * component_id - Caller's component ID | ||
268 | * Pointer - Pointer to display | ||
269 | * | ||
270 | * RETURN: None | ||
271 | * | ||
272 | * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is | ||
273 | * set in debug_level | ||
274 | * | ||
275 | ****************************************************************************/ | ||
276 | |||
277 | void | ||
278 | acpi_ut_trace_ptr ( | ||
279 | u32 line_number, | ||
280 | struct acpi_debug_print_info *dbg_info, | ||
281 | void *pointer) | ||
282 | { | ||
283 | acpi_gbl_nesting_level++; | ||
284 | acpi_ut_track_stack_ptr (); | ||
285 | |||
286 | acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info, | ||
287 | "%s %p\n", acpi_gbl_fn_entry_str, pointer); | ||
288 | } | ||
289 | |||
290 | |||
291 | /***************************************************************************** | ||
292 | * | ||
293 | * FUNCTION: acpi_ut_trace_str | ||
294 | * | ||
295 | * PARAMETERS: line_number - Caller's line number | ||
296 | * dbg_info - Contains: | ||
297 | * proc_name - Caller's procedure name | ||
298 | * module_name - Caller's module name | ||
299 | * component_id - Caller's component ID | ||
300 | * String - Additional string to display | ||
301 | * | ||
302 | * RETURN: None | ||
303 | * | ||
304 | * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is | ||
305 | * set in debug_level | ||
306 | * | ||
307 | ****************************************************************************/ | ||
308 | |||
309 | void | ||
310 | acpi_ut_trace_str ( | ||
311 | u32 line_number, | ||
312 | struct acpi_debug_print_info *dbg_info, | ||
313 | char *string) | ||
314 | { | ||
315 | |||
316 | acpi_gbl_nesting_level++; | ||
317 | acpi_ut_track_stack_ptr (); | ||
318 | |||
319 | acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info, | ||
320 | "%s %s\n", acpi_gbl_fn_entry_str, string); | ||
321 | } | ||
322 | |||
323 | |||
324 | /***************************************************************************** | ||
325 | * | ||
326 | * FUNCTION: acpi_ut_trace_u32 | ||
327 | * | ||
328 | * PARAMETERS: line_number - Caller's line number | ||
329 | * dbg_info - Contains: | ||
330 | * proc_name - Caller's procedure name | ||
331 | * module_name - Caller's module name | ||
332 | * component_id - Caller's component ID | ||
333 | * Integer - Integer to display | ||
334 | * | ||
335 | * RETURN: None | ||
336 | * | ||
337 | * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is | ||
338 | * set in debug_level | ||
339 | * | ||
340 | ****************************************************************************/ | ||
341 | |||
342 | void | ||
343 | acpi_ut_trace_u32 ( | ||
344 | u32 line_number, | ||
345 | struct acpi_debug_print_info *dbg_info, | ||
346 | u32 integer) | ||
347 | { | ||
348 | |||
349 | acpi_gbl_nesting_level++; | ||
350 | acpi_ut_track_stack_ptr (); | ||
351 | |||
352 | acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info, | ||
353 | "%s %08X\n", acpi_gbl_fn_entry_str, integer); | ||
354 | } | ||
355 | |||
356 | |||
357 | /***************************************************************************** | ||
358 | * | ||
359 | * FUNCTION: acpi_ut_exit | ||
360 | * | ||
361 | * PARAMETERS: line_number - Caller's line number | ||
362 | * dbg_info - Contains: | ||
363 | * proc_name - Caller's procedure name | ||
364 | * module_name - Caller's module name | ||
365 | * component_id - Caller's component ID | ||
366 | * | ||
367 | * RETURN: None | ||
368 | * | ||
369 | * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is | ||
370 | * set in debug_level | ||
371 | * | ||
372 | ****************************************************************************/ | ||
373 | |||
374 | void | ||
375 | acpi_ut_exit ( | ||
376 | u32 line_number, | ||
377 | struct acpi_debug_print_info *dbg_info) | ||
378 | { | ||
379 | |||
380 | acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info, | ||
381 | "%s\n", acpi_gbl_fn_exit_str); | ||
382 | |||
383 | acpi_gbl_nesting_level--; | ||
384 | } | ||
385 | EXPORT_SYMBOL(acpi_ut_exit); | ||
386 | |||
387 | |||
388 | /***************************************************************************** | ||
389 | * | ||
390 | * FUNCTION: acpi_ut_status_exit | ||
391 | * | ||
392 | * PARAMETERS: line_number - Caller's line number | ||
393 | * dbg_info - Contains: | ||
394 | * proc_name - Caller's procedure name | ||
395 | * module_name - Caller's module name | ||
396 | * component_id - Caller's component ID | ||
397 | * Status - Exit status code | ||
398 | * | ||
399 | * RETURN: None | ||
400 | * | ||
401 | * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is | ||
402 | * set in debug_level. Prints exit status also. | ||
403 | * | ||
404 | ****************************************************************************/ | ||
405 | |||
406 | void | ||
407 | acpi_ut_status_exit ( | ||
408 | u32 line_number, | ||
409 | struct acpi_debug_print_info *dbg_info, | ||
410 | acpi_status status) | ||
411 | { | ||
412 | |||
413 | if (ACPI_SUCCESS (status)) { | ||
414 | acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info, | ||
415 | "%s %s\n", acpi_gbl_fn_exit_str, | ||
416 | acpi_format_exception (status)); | ||
417 | } | ||
418 | else { | ||
419 | acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info, | ||
420 | "%s ****Exception****: %s\n", acpi_gbl_fn_exit_str, | ||
421 | acpi_format_exception (status)); | ||
422 | } | ||
423 | |||
424 | acpi_gbl_nesting_level--; | ||
425 | } | ||
426 | EXPORT_SYMBOL(acpi_ut_status_exit); | ||
427 | |||
428 | |||
429 | /***************************************************************************** | ||
430 | * | ||
431 | * FUNCTION: acpi_ut_value_exit | ||
432 | * | ||
433 | * PARAMETERS: line_number - Caller's line number | ||
434 | * dbg_info - Contains: | ||
435 | * proc_name - Caller's procedure name | ||
436 | * module_name - Caller's module name | ||
437 | * component_id - Caller's component ID | ||
438 | * Value - Value to be printed with exit msg | ||
439 | * | ||
440 | * RETURN: None | ||
441 | * | ||
442 | * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is | ||
443 | * set in debug_level. Prints exit value also. | ||
444 | * | ||
445 | ****************************************************************************/ | ||
446 | |||
447 | void | ||
448 | acpi_ut_value_exit ( | ||
449 | u32 line_number, | ||
450 | struct acpi_debug_print_info *dbg_info, | ||
451 | acpi_integer value) | ||
452 | { | ||
453 | |||
454 | acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info, | ||
455 | "%s %8.8X%8.8X\n", acpi_gbl_fn_exit_str, | ||
456 | ACPI_FORMAT_UINT64 (value)); | ||
457 | |||
458 | acpi_gbl_nesting_level--; | ||
459 | } | ||
460 | EXPORT_SYMBOL(acpi_ut_value_exit); | ||
461 | |||
462 | |||
463 | /***************************************************************************** | ||
464 | * | ||
465 | * FUNCTION: acpi_ut_ptr_exit | ||
466 | * | ||
467 | * PARAMETERS: line_number - Caller's line number | ||
468 | * dbg_info - Contains: | ||
469 | * proc_name - Caller's procedure name | ||
470 | * module_name - Caller's module name | ||
471 | * component_id - Caller's component ID | ||
472 | * Value - Value to be printed with exit msg | ||
473 | * | ||
474 | * RETURN: None | ||
475 | * | ||
476 | * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is | ||
477 | * set in debug_level. Prints exit value also. | ||
478 | * | ||
479 | ****************************************************************************/ | ||
480 | |||
481 | void | ||
482 | acpi_ut_ptr_exit ( | ||
483 | u32 line_number, | ||
484 | struct acpi_debug_print_info *dbg_info, | ||
485 | u8 *ptr) | ||
486 | { | ||
487 | |||
488 | acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info, | ||
489 | "%s %p\n", acpi_gbl_fn_exit_str, ptr); | ||
490 | |||
491 | acpi_gbl_nesting_level--; | ||
492 | } | ||
493 | |||
494 | #endif | ||
495 | |||
496 | |||
497 | /***************************************************************************** | ||
498 | * | ||
499 | * FUNCTION: acpi_ut_dump_buffer | ||
500 | * | ||
501 | * PARAMETERS: Buffer - Buffer to dump | ||
502 | * Count - Amount to dump, in bytes | ||
503 | * Display - BYTE, WORD, DWORD, or QWORD display | ||
504 | * component_iD - Caller's component ID | ||
505 | * | ||
506 | * RETURN: None | ||
507 | * | ||
508 | * DESCRIPTION: Generic dump buffer in both hex and ascii. | ||
509 | * | ||
510 | ****************************************************************************/ | ||
511 | |||
512 | void | ||
513 | acpi_ut_dump_buffer ( | ||
514 | u8 *buffer, | ||
515 | u32 count, | ||
516 | u32 display, | ||
517 | u32 component_id) | ||
518 | { | ||
519 | acpi_native_uint i = 0; | ||
520 | acpi_native_uint j; | ||
521 | u32 temp32; | ||
522 | u8 buf_char; | ||
523 | |||
524 | |||
525 | /* Only dump the buffer if tracing is enabled */ | ||
526 | |||
527 | if (!((ACPI_LV_TABLES & acpi_dbg_level) && | ||
528 | (component_id & acpi_dbg_layer))) { | ||
529 | return; | ||
530 | } | ||
531 | |||
532 | if ((count < 4) || (count & 0x01)) { | ||
533 | display = DB_BYTE_DISPLAY; | ||
534 | } | ||
535 | |||
536 | acpi_os_printf ("\nOffset Value\n"); | ||
537 | |||
538 | /* | ||
539 | * Nasty little dump buffer routine! | ||
540 | */ | ||
541 | while (i < count) { | ||
542 | /* Print current offset */ | ||
543 | |||
544 | acpi_os_printf ("%05X ", (u32) i); | ||
545 | |||
546 | /* Print 16 hex chars */ | ||
547 | |||
548 | for (j = 0; j < 16;) { | ||
549 | if (i + j >= count) { | ||
550 | acpi_os_printf ("\n"); | ||
551 | return; | ||
552 | } | ||
553 | |||
554 | /* Make sure that the s8 doesn't get sign-extended! */ | ||
555 | |||
556 | switch (display) { | ||
557 | /* Default is BYTE display */ | ||
558 | |||
559 | default: | ||
560 | |||
561 | acpi_os_printf ("%02X ", | ||
562 | *((u8 *) &buffer[i + j])); | ||
563 | j += 1; | ||
564 | break; | ||
565 | |||
566 | |||
567 | case DB_WORD_DISPLAY: | ||
568 | |||
569 | ACPI_MOVE_16_TO_32 (&temp32, &buffer[i + j]); | ||
570 | acpi_os_printf ("%04X ", temp32); | ||
571 | j += 2; | ||
572 | break; | ||
573 | |||
574 | |||
575 | case DB_DWORD_DISPLAY: | ||
576 | |||
577 | ACPI_MOVE_32_TO_32 (&temp32, &buffer[i + j]); | ||
578 | acpi_os_printf ("%08X ", temp32); | ||
579 | j += 4; | ||
580 | break; | ||
581 | |||
582 | |||
583 | case DB_QWORD_DISPLAY: | ||
584 | |||
585 | ACPI_MOVE_32_TO_32 (&temp32, &buffer[i + j]); | ||
586 | acpi_os_printf ("%08X", temp32); | ||
587 | |||
588 | ACPI_MOVE_32_TO_32 (&temp32, &buffer[i + j + 4]); | ||
589 | acpi_os_printf ("%08X ", temp32); | ||
590 | j += 8; | ||
591 | break; | ||
592 | } | ||
593 | } | ||
594 | |||
595 | /* | ||
596 | * Print the ASCII equivalent characters | ||
597 | * But watch out for the bad unprintable ones... | ||
598 | */ | ||
599 | for (j = 0; j < 16; j++) { | ||
600 | if (i + j >= count) { | ||
601 | acpi_os_printf ("\n"); | ||
602 | return; | ||
603 | } | ||
604 | |||
605 | buf_char = buffer[i + j]; | ||
606 | if ((buf_char > 0x1F && buf_char < 0x2E) || | ||
607 | (buf_char > 0x2F && buf_char < 0x61) || | ||
608 | (buf_char > 0x60 && buf_char < 0x7F)) { | ||
609 | acpi_os_printf ("%c", buf_char); | ||
610 | } | ||
611 | else { | ||
612 | acpi_os_printf ("."); | ||
613 | } | ||
614 | } | ||
615 | |||
616 | /* Done with that line. */ | ||
617 | |||
618 | acpi_os_printf ("\n"); | ||
619 | i += 16; | ||
620 | } | ||
621 | |||
622 | return; | ||
623 | } | ||
624 | |||
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c new file mode 100644 index 000000000000..9a52ad52a23a --- /dev/null +++ b/drivers/acpi/utilities/utdelete.c | |||
@@ -0,0 +1,700 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: utdelete - object deletion and reference count utilities | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
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 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/acinterp.h> | ||
47 | #include <acpi/acnamesp.h> | ||
48 | #include <acpi/acevents.h> | ||
49 | #include <acpi/amlcode.h> | ||
50 | |||
51 | #define _COMPONENT ACPI_UTILITIES | ||
52 | ACPI_MODULE_NAME ("utdelete") | ||
53 | |||
54 | |||
55 | /******************************************************************************* | ||
56 | * | ||
57 | * FUNCTION: acpi_ut_delete_internal_obj | ||
58 | * | ||
59 | * PARAMETERS: *Object - Pointer to the list to be deleted | ||
60 | * | ||
61 | * RETURN: None | ||
62 | * | ||
63 | * DESCRIPTION: Low level object deletion, after reference counts have been | ||
64 | * updated (All reference counts, including sub-objects!) | ||
65 | * | ||
66 | ******************************************************************************/ | ||
67 | |||
68 | void | ||
69 | acpi_ut_delete_internal_obj ( | ||
70 | union acpi_operand_object *object) | ||
71 | { | ||
72 | void *obj_pointer = NULL; | ||
73 | union acpi_operand_object *handler_desc; | ||
74 | union acpi_operand_object *second_desc; | ||
75 | union acpi_operand_object *next_desc; | ||
76 | |||
77 | |||
78 | ACPI_FUNCTION_TRACE_PTR ("ut_delete_internal_obj", object); | ||
79 | |||
80 | |||
81 | if (!object) { | ||
82 | return_VOID; | ||
83 | } | ||
84 | |||
85 | /* | ||
86 | * Must delete or free any pointers within the object that are not | ||
87 | * actual ACPI objects (for example, a raw buffer pointer). | ||
88 | */ | ||
89 | switch (ACPI_GET_OBJECT_TYPE (object)) { | ||
90 | case ACPI_TYPE_STRING: | ||
91 | |||
92 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** String %p, ptr %p\n", | ||
93 | object, object->string.pointer)); | ||
94 | |||
95 | /* Free the actual string buffer */ | ||
96 | |||
97 | if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) { | ||
98 | /* But only if it is NOT a pointer into an ACPI table */ | ||
99 | |||
100 | obj_pointer = object->string.pointer; | ||
101 | } | ||
102 | break; | ||
103 | |||
104 | |||
105 | case ACPI_TYPE_BUFFER: | ||
106 | |||
107 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** Buffer %p, ptr %p\n", | ||
108 | object, object->buffer.pointer)); | ||
109 | |||
110 | /* Free the actual buffer */ | ||
111 | |||
112 | if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) { | ||
113 | /* But only if it is NOT a pointer into an ACPI table */ | ||
114 | |||
115 | obj_pointer = object->buffer.pointer; | ||
116 | } | ||
117 | break; | ||
118 | |||
119 | |||
120 | case ACPI_TYPE_PACKAGE: | ||
121 | |||
122 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, " **** Package of count %X\n", | ||
123 | object->package.count)); | ||
124 | |||
125 | /* | ||
126 | * Elements of the package are not handled here, they are deleted | ||
127 | * separately | ||
128 | */ | ||
129 | |||
130 | /* Free the (variable length) element pointer array */ | ||
131 | |||
132 | obj_pointer = object->package.elements; | ||
133 | break; | ||
134 | |||
135 | |||
136 | case ACPI_TYPE_DEVICE: | ||
137 | |||
138 | if (object->device.gpe_block) { | ||
139 | (void) acpi_ev_delete_gpe_block (object->device.gpe_block); | ||
140 | } | ||
141 | |||
142 | /* Walk the handler list for this device */ | ||
143 | |||
144 | handler_desc = object->device.handler; | ||
145 | while (handler_desc) { | ||
146 | next_desc = handler_desc->address_space.next; | ||
147 | acpi_ut_remove_reference (handler_desc); | ||
148 | handler_desc = next_desc; | ||
149 | } | ||
150 | break; | ||
151 | |||
152 | |||
153 | case ACPI_TYPE_MUTEX: | ||
154 | |||
155 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Mutex %p, Semaphore %p\n", | ||
156 | object, object->mutex.semaphore)); | ||
157 | |||
158 | acpi_ex_unlink_mutex (object); | ||
159 | (void) acpi_os_delete_semaphore (object->mutex.semaphore); | ||
160 | break; | ||
161 | |||
162 | |||
163 | case ACPI_TYPE_EVENT: | ||
164 | |||
165 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Event %p, Semaphore %p\n", | ||
166 | object, object->event.semaphore)); | ||
167 | |||
168 | (void) acpi_os_delete_semaphore (object->event.semaphore); | ||
169 | object->event.semaphore = NULL; | ||
170 | break; | ||
171 | |||
172 | |||
173 | case ACPI_TYPE_METHOD: | ||
174 | |||
175 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Method %p\n", object)); | ||
176 | |||
177 | /* Delete the method semaphore if it exists */ | ||
178 | |||
179 | if (object->method.semaphore) { | ||
180 | (void) acpi_os_delete_semaphore (object->method.semaphore); | ||
181 | object->method.semaphore = NULL; | ||
182 | } | ||
183 | break; | ||
184 | |||
185 | |||
186 | case ACPI_TYPE_REGION: | ||
187 | |||
188 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Region %p\n", object)); | ||
189 | |||
190 | second_desc = acpi_ns_get_secondary_object (object); | ||
191 | if (second_desc) { | ||
192 | /* | ||
193 | * Free the region_context if and only if the handler is one of the | ||
194 | * default handlers -- and therefore, we created the context object | ||
195 | * locally, it was not created by an external caller. | ||
196 | */ | ||
197 | handler_desc = object->region.handler; | ||
198 | if (handler_desc) { | ||
199 | if (handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) { | ||
200 | obj_pointer = second_desc->extra.region_context; | ||
201 | } | ||
202 | |||
203 | acpi_ut_remove_reference (handler_desc); | ||
204 | } | ||
205 | |||
206 | /* Now we can free the Extra object */ | ||
207 | |||
208 | acpi_ut_delete_object_desc (second_desc); | ||
209 | } | ||
210 | break; | ||
211 | |||
212 | |||
213 | case ACPI_TYPE_BUFFER_FIELD: | ||
214 | |||
215 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Buffer Field %p\n", object)); | ||
216 | |||
217 | second_desc = acpi_ns_get_secondary_object (object); | ||
218 | if (second_desc) { | ||
219 | acpi_ut_delete_object_desc (second_desc); | ||
220 | } | ||
221 | break; | ||
222 | |||
223 | |||
224 | default: | ||
225 | break; | ||
226 | } | ||
227 | |||
228 | /* Free any allocated memory (pointer within the object) found above */ | ||
229 | |||
230 | if (obj_pointer) { | ||
231 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object Subptr %p\n", | ||
232 | obj_pointer)); | ||
233 | ACPI_MEM_FREE (obj_pointer); | ||
234 | } | ||
235 | |||
236 | /* Now the object can be safely deleted */ | ||
237 | |||
238 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n", | ||
239 | object, acpi_ut_get_object_type_name (object))); | ||
240 | |||
241 | acpi_ut_delete_object_desc (object); | ||
242 | return_VOID; | ||
243 | } | ||
244 | |||
245 | |||
246 | /******************************************************************************* | ||
247 | * | ||
248 | * FUNCTION: acpi_ut_delete_internal_object_list | ||
249 | * | ||
250 | * PARAMETERS: *obj_list - Pointer to the list to be deleted | ||
251 | * | ||
252 | * RETURN: None | ||
253 | * | ||
254 | * DESCRIPTION: This function deletes an internal object list, including both | ||
255 | * simple objects and package objects | ||
256 | * | ||
257 | ******************************************************************************/ | ||
258 | |||
259 | void | ||
260 | acpi_ut_delete_internal_object_list ( | ||
261 | union acpi_operand_object **obj_list) | ||
262 | { | ||
263 | union acpi_operand_object **internal_obj; | ||
264 | |||
265 | |||
266 | ACPI_FUNCTION_TRACE ("ut_delete_internal_object_list"); | ||
267 | |||
268 | |||
269 | /* Walk the null-terminated internal list */ | ||
270 | |||
271 | for (internal_obj = obj_list; *internal_obj; internal_obj++) { | ||
272 | acpi_ut_remove_reference (*internal_obj); | ||
273 | } | ||
274 | |||
275 | /* Free the combined parameter pointer list and object array */ | ||
276 | |||
277 | ACPI_MEM_FREE (obj_list); | ||
278 | return_VOID; | ||
279 | } | ||
280 | |||
281 | |||
282 | /******************************************************************************* | ||
283 | * | ||
284 | * FUNCTION: acpi_ut_update_ref_count | ||
285 | * | ||
286 | * PARAMETERS: *Object - Object whose ref count is to be updated | ||
287 | * Action - What to do | ||
288 | * | ||
289 | * RETURN: New ref count | ||
290 | * | ||
291 | * DESCRIPTION: Modify the ref count and return it. | ||
292 | * | ||
293 | ******************************************************************************/ | ||
294 | |||
295 | static void | ||
296 | acpi_ut_update_ref_count ( | ||
297 | union acpi_operand_object *object, | ||
298 | u32 action) | ||
299 | { | ||
300 | u16 count; | ||
301 | u16 new_count; | ||
302 | |||
303 | |||
304 | ACPI_FUNCTION_NAME ("ut_update_ref_count"); | ||
305 | |||
306 | |||
307 | if (!object) { | ||
308 | return; | ||
309 | } | ||
310 | |||
311 | count = object->common.reference_count; | ||
312 | new_count = count; | ||
313 | |||
314 | /* | ||
315 | * Perform the reference count action (increment, decrement, or force delete) | ||
316 | */ | ||
317 | switch (action) { | ||
318 | |||
319 | case REF_INCREMENT: | ||
320 | |||
321 | new_count++; | ||
322 | object->common.reference_count = new_count; | ||
323 | |||
324 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, [Incremented]\n", | ||
325 | object, new_count)); | ||
326 | break; | ||
327 | |||
328 | |||
329 | case REF_DECREMENT: | ||
330 | |||
331 | if (count < 1) { | ||
332 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, can't decrement! (Set to 0)\n", | ||
333 | object, new_count)); | ||
334 | |||
335 | new_count = 0; | ||
336 | } | ||
337 | else { | ||
338 | new_count--; | ||
339 | |||
340 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, [Decremented]\n", | ||
341 | object, new_count)); | ||
342 | } | ||
343 | |||
344 | if (ACPI_GET_OBJECT_TYPE (object) == ACPI_TYPE_METHOD) { | ||
345 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Method Obj %p Refs=%X, [Decremented]\n", | ||
346 | object, new_count)); | ||
347 | } | ||
348 | |||
349 | object->common.reference_count = new_count; | ||
350 | if (new_count == 0) { | ||
351 | acpi_ut_delete_internal_obj (object); | ||
352 | } | ||
353 | |||
354 | break; | ||
355 | |||
356 | |||
357 | case REF_FORCE_DELETE: | ||
358 | |||
359 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, Force delete! (Set to 0)\n", | ||
360 | object, count)); | ||
361 | |||
362 | new_count = 0; | ||
363 | object->common.reference_count = new_count; | ||
364 | acpi_ut_delete_internal_obj (object); | ||
365 | break; | ||
366 | |||
367 | |||
368 | default: | ||
369 | |||
370 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown action (%X)\n", action)); | ||
371 | break; | ||
372 | } | ||
373 | |||
374 | /* | ||
375 | * Sanity check the reference count, for debug purposes only. | ||
376 | * (A deleted object will have a huge reference count) | ||
377 | */ | ||
378 | if (count > ACPI_MAX_REFERENCE_COUNT) { | ||
379 | |||
380 | ACPI_DEBUG_PRINT ((ACPI_DB_WARN, | ||
381 | "**** Warning **** Large Reference Count (%X) in object %p\n\n", | ||
382 | count, object)); | ||
383 | } | ||
384 | |||
385 | return; | ||
386 | } | ||
387 | |||
388 | |||
389 | /******************************************************************************* | ||
390 | * | ||
391 | * FUNCTION: acpi_ut_update_object_reference | ||
392 | * | ||
393 | * PARAMETERS: *Object - Increment ref count for this object | ||
394 | * and all sub-objects | ||
395 | * Action - Either REF_INCREMENT or REF_DECREMENT or | ||
396 | * REF_FORCE_DELETE | ||
397 | * | ||
398 | * RETURN: Status | ||
399 | * | ||
400 | * DESCRIPTION: Increment the object reference count | ||
401 | * | ||
402 | * Object references are incremented when: | ||
403 | * 1) An object is attached to a Node (namespace object) | ||
404 | * 2) An object is copied (all subobjects must be incremented) | ||
405 | * | ||
406 | * Object references are decremented when: | ||
407 | * 1) An object is detached from an Node | ||
408 | * | ||
409 | ******************************************************************************/ | ||
410 | |||
411 | acpi_status | ||
412 | acpi_ut_update_object_reference ( | ||
413 | union acpi_operand_object *object, | ||
414 | u16 action) | ||
415 | { | ||
416 | acpi_status status; | ||
417 | u32 i; | ||
418 | union acpi_generic_state *state_list = NULL; | ||
419 | union acpi_generic_state *state; | ||
420 | union acpi_operand_object *tmp; | ||
421 | |||
422 | ACPI_FUNCTION_TRACE_PTR ("ut_update_object_reference", object); | ||
423 | |||
424 | |||
425 | /* Ignore a null object ptr */ | ||
426 | |||
427 | if (!object) { | ||
428 | return_ACPI_STATUS (AE_OK); | ||
429 | } | ||
430 | |||
431 | /* Make sure that this isn't a namespace handle */ | ||
432 | |||
433 | if (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED) { | ||
434 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p is NS handle\n", object)); | ||
435 | return_ACPI_STATUS (AE_OK); | ||
436 | } | ||
437 | |||
438 | state = acpi_ut_create_update_state (object, action); | ||
439 | |||
440 | while (state) { | ||
441 | object = state->update.object; | ||
442 | action = state->update.value; | ||
443 | acpi_ut_delete_generic_state (state); | ||
444 | |||
445 | /* | ||
446 | * All sub-objects must have their reference count incremented also. | ||
447 | * Different object types have different subobjects. | ||
448 | */ | ||
449 | switch (ACPI_GET_OBJECT_TYPE (object)) { | ||
450 | case ACPI_TYPE_DEVICE: | ||
451 | |||
452 | tmp = object->device.system_notify; | ||
453 | if (tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT) | ||
454 | object->device.system_notify = NULL; | ||
455 | acpi_ut_update_ref_count (tmp, action); | ||
456 | |||
457 | tmp = object->device.device_notify; | ||
458 | if (tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT) | ||
459 | object->device.device_notify = NULL; | ||
460 | acpi_ut_update_ref_count (tmp, action); | ||
461 | |||
462 | break; | ||
463 | |||
464 | |||
465 | case ACPI_TYPE_PACKAGE: | ||
466 | |||
467 | /* | ||
468 | * We must update all the sub-objects of the package | ||
469 | * (Each of whom may have their own sub-objects, etc. | ||
470 | */ | ||
471 | for (i = 0; i < object->package.count; i++) { | ||
472 | /* | ||
473 | * Push each element onto the stack for later processing. | ||
474 | * Note: There can be null elements within the package, | ||
475 | * these are simply ignored | ||
476 | */ | ||
477 | status = acpi_ut_create_update_state_and_push ( | ||
478 | object->package.elements[i], action, &state_list); | ||
479 | if (ACPI_FAILURE (status)) { | ||
480 | goto error_exit; | ||
481 | } | ||
482 | |||
483 | tmp = object->package.elements[i]; | ||
484 | if (tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT) | ||
485 | object->package.elements[i] = NULL; | ||
486 | } | ||
487 | break; | ||
488 | |||
489 | |||
490 | case ACPI_TYPE_BUFFER_FIELD: | ||
491 | |||
492 | status = acpi_ut_create_update_state_and_push ( | ||
493 | object->buffer_field.buffer_obj, action, &state_list); | ||
494 | if (ACPI_FAILURE (status)) { | ||
495 | goto error_exit; | ||
496 | } | ||
497 | |||
498 | tmp = object->buffer_field.buffer_obj; | ||
499 | if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT) | ||
500 | object->buffer_field.buffer_obj = NULL; | ||
501 | break; | ||
502 | |||
503 | |||
504 | case ACPI_TYPE_LOCAL_REGION_FIELD: | ||
505 | |||
506 | status = acpi_ut_create_update_state_and_push ( | ||
507 | object->field.region_obj, action, &state_list); | ||
508 | if (ACPI_FAILURE (status)) { | ||
509 | goto error_exit; | ||
510 | } | ||
511 | |||
512 | tmp = object->field.region_obj; | ||
513 | if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT) | ||
514 | object->field.region_obj = NULL; | ||
515 | break; | ||
516 | |||
517 | |||
518 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
519 | |||
520 | status = acpi_ut_create_update_state_and_push ( | ||
521 | object->bank_field.bank_obj, action, &state_list); | ||
522 | if (ACPI_FAILURE (status)) { | ||
523 | goto error_exit; | ||
524 | } | ||
525 | |||
526 | tmp = object->bank_field.bank_obj; | ||
527 | if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT) | ||
528 | object->bank_field.bank_obj = NULL; | ||
529 | |||
530 | status = acpi_ut_create_update_state_and_push ( | ||
531 | object->bank_field.region_obj, action, &state_list); | ||
532 | if (ACPI_FAILURE (status)) { | ||
533 | goto error_exit; | ||
534 | } | ||
535 | |||
536 | tmp = object->bank_field.region_obj; | ||
537 | if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT) | ||
538 | object->bank_field.region_obj = NULL; | ||
539 | break; | ||
540 | |||
541 | |||
542 | case ACPI_TYPE_LOCAL_INDEX_FIELD: | ||
543 | |||
544 | status = acpi_ut_create_update_state_and_push ( | ||
545 | object->index_field.index_obj, action, &state_list); | ||
546 | if (ACPI_FAILURE (status)) { | ||
547 | goto error_exit; | ||
548 | } | ||
549 | |||
550 | tmp = object->index_field.index_obj; | ||
551 | if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT) | ||
552 | object->index_field.index_obj = NULL; | ||
553 | |||
554 | status = acpi_ut_create_update_state_and_push ( | ||
555 | object->index_field.data_obj, action, &state_list); | ||
556 | if (ACPI_FAILURE (status)) { | ||
557 | goto error_exit; | ||
558 | } | ||
559 | |||
560 | tmp = object->index_field.data_obj; | ||
561 | if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT) | ||
562 | object->index_field.data_obj = NULL; | ||
563 | break; | ||
564 | |||
565 | |||
566 | case ACPI_TYPE_LOCAL_REFERENCE: | ||
567 | |||
568 | /* | ||
569 | * The target of an Index (a package, string, or buffer) must track | ||
570 | * changes to the ref count of the index. | ||
571 | */ | ||
572 | if (object->reference.opcode == AML_INDEX_OP) { | ||
573 | status = acpi_ut_create_update_state_and_push ( | ||
574 | object->reference.object, action, &state_list); | ||
575 | if (ACPI_FAILURE (status)) { | ||
576 | goto error_exit; | ||
577 | } | ||
578 | } | ||
579 | break; | ||
580 | |||
581 | |||
582 | case ACPI_TYPE_REGION: | ||
583 | default: | ||
584 | |||
585 | /* No subobjects */ | ||
586 | break; | ||
587 | } | ||
588 | |||
589 | /* | ||
590 | * Now we can update the count in the main object. This can only | ||
591 | * happen after we update the sub-objects in case this causes the | ||
592 | * main object to be deleted. | ||
593 | */ | ||
594 | acpi_ut_update_ref_count (object, action); | ||
595 | |||
596 | /* Move on to the next object to be updated */ | ||
597 | |||
598 | state = acpi_ut_pop_generic_state (&state_list); | ||
599 | } | ||
600 | |||
601 | return_ACPI_STATUS (AE_OK); | ||
602 | |||
603 | |||
604 | error_exit: | ||
605 | |||
606 | ACPI_REPORT_ERROR (("Could not update object reference count, %s\n", | ||
607 | acpi_format_exception (status))); | ||
608 | |||
609 | return_ACPI_STATUS (status); | ||
610 | } | ||
611 | |||
612 | |||
613 | /******************************************************************************* | ||
614 | * | ||
615 | * FUNCTION: acpi_ut_add_reference | ||
616 | * | ||
617 | * PARAMETERS: *Object - Object whose reference count is to be | ||
618 | * incremented | ||
619 | * | ||
620 | * RETURN: None | ||
621 | * | ||
622 | * DESCRIPTION: Add one reference to an ACPI object | ||
623 | * | ||
624 | ******************************************************************************/ | ||
625 | |||
626 | void | ||
627 | acpi_ut_add_reference ( | ||
628 | union acpi_operand_object *object) | ||
629 | { | ||
630 | |||
631 | ACPI_FUNCTION_TRACE_PTR ("ut_add_reference", object); | ||
632 | |||
633 | |||
634 | /* Ensure that we have a valid object */ | ||
635 | |||
636 | if (!acpi_ut_valid_internal_object (object)) { | ||
637 | return_VOID; | ||
638 | } | ||
639 | |||
640 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, | ||
641 | "Obj %p Current Refs=%X [To Be Incremented]\n", | ||
642 | object, object->common.reference_count)); | ||
643 | |||
644 | /* Increment the reference count */ | ||
645 | |||
646 | (void) acpi_ut_update_object_reference (object, REF_INCREMENT); | ||
647 | return_VOID; | ||
648 | } | ||
649 | |||
650 | |||
651 | /******************************************************************************* | ||
652 | * | ||
653 | * FUNCTION: acpi_ut_remove_reference | ||
654 | * | ||
655 | * PARAMETERS: *Object - Object whose ref count will be decremented | ||
656 | * | ||
657 | * RETURN: None | ||
658 | * | ||
659 | * DESCRIPTION: Decrement the reference count of an ACPI internal object | ||
660 | * | ||
661 | ******************************************************************************/ | ||
662 | |||
663 | void | ||
664 | acpi_ut_remove_reference ( | ||
665 | union acpi_operand_object *object) | ||
666 | { | ||
667 | |||
668 | ACPI_FUNCTION_TRACE_PTR ("ut_remove_reference", object); | ||
669 | |||
670 | |||
671 | /* | ||
672 | * Allow a NULL pointer to be passed in, just ignore it. This saves | ||
673 | * each caller from having to check. Also, ignore NS nodes. | ||
674 | * | ||
675 | */ | ||
676 | if (!object || | ||
677 | (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED)) { | ||
678 | return_VOID; | ||
679 | } | ||
680 | |||
681 | /* Ensure that we have a valid object */ | ||
682 | |||
683 | if (!acpi_ut_valid_internal_object (object)) { | ||
684 | return_VOID; | ||
685 | } | ||
686 | |||
687 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, | ||
688 | "Obj %p Current Refs=%X [To Be Decremented]\n", | ||
689 | object, object->common.reference_count)); | ||
690 | |||
691 | /* | ||
692 | * Decrement the reference count, and only actually delete the object | ||
693 | * if the reference count becomes 0. (Must also decrement the ref count | ||
694 | * of all subobjects!) | ||
695 | */ | ||
696 | (void) acpi_ut_update_object_reference (object, REF_DECREMENT); | ||
697 | return_VOID; | ||
698 | } | ||
699 | |||
700 | |||
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c new file mode 100644 index 000000000000..ead27d2c4d18 --- /dev/null +++ b/drivers/acpi/utilities/uteval.c | |||
@@ -0,0 +1,696 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: uteval - Object evaluation | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
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 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/acnamesp.h> | ||
47 | #include <acpi/acinterp.h> | ||
48 | |||
49 | |||
50 | #define _COMPONENT ACPI_UTILITIES | ||
51 | ACPI_MODULE_NAME ("uteval") | ||
52 | |||
53 | |||
54 | /******************************************************************************* | ||
55 | * | ||
56 | * FUNCTION: acpi_ut_osi_implementation | ||
57 | * | ||
58 | * PARAMETERS: walk_state - Current walk state | ||
59 | * | ||
60 | * RETURN: Status | ||
61 | * | ||
62 | * DESCRIPTION: Implementation of _OSI predefined control method | ||
63 | * Supported = _OSI (String) | ||
64 | * | ||
65 | ******************************************************************************/ | ||
66 | |||
67 | acpi_status | ||
68 | acpi_ut_osi_implementation ( | ||
69 | struct acpi_walk_state *walk_state) | ||
70 | { | ||
71 | union acpi_operand_object *string_desc; | ||
72 | union acpi_operand_object *return_desc; | ||
73 | acpi_native_uint i; | ||
74 | |||
75 | |||
76 | ACPI_FUNCTION_TRACE ("ut_osi_implementation"); | ||
77 | |||
78 | |||
79 | /* Validate the string input argument */ | ||
80 | |||
81 | string_desc = walk_state->arguments[0].object; | ||
82 | if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) { | ||
83 | return_ACPI_STATUS (AE_TYPE); | ||
84 | } | ||
85 | |||
86 | /* Create a return object (Default value = 0) */ | ||
87 | |||
88 | return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); | ||
89 | if (!return_desc) { | ||
90 | return_ACPI_STATUS (AE_NO_MEMORY); | ||
91 | } | ||
92 | |||
93 | /* Compare input string to table of supported strings */ | ||
94 | |||
95 | for (i = 0; i < ACPI_NUM_OSI_STRINGS; i++) { | ||
96 | if (!ACPI_STRCMP (string_desc->string.pointer, | ||
97 | (char *) acpi_gbl_valid_osi_strings[i])) { | ||
98 | /* This string is supported */ | ||
99 | |||
100 | return_desc->integer.value = 0xFFFFFFFF; | ||
101 | break; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | walk_state->return_desc = return_desc; | ||
106 | return_ACPI_STATUS (AE_CTRL_TERMINATE); | ||
107 | } | ||
108 | |||
109 | |||
110 | /******************************************************************************* | ||
111 | * | ||
112 | * FUNCTION: acpi_ut_evaluate_object | ||
113 | * | ||
114 | * PARAMETERS: prefix_node - Starting node | ||
115 | * Path - Path to object from starting node | ||
116 | * expected_return_types - Bitmap of allowed return types | ||
117 | * return_desc - Where a return value is stored | ||
118 | * | ||
119 | * RETURN: Status | ||
120 | * | ||
121 | * DESCRIPTION: Evaluates a namespace object and verifies the type of the | ||
122 | * return object. Common code that simplifies accessing objects | ||
123 | * that have required return objects of fixed types. | ||
124 | * | ||
125 | * NOTE: Internal function, no parameter validation | ||
126 | * | ||
127 | ******************************************************************************/ | ||
128 | |||
129 | acpi_status | ||
130 | acpi_ut_evaluate_object ( | ||
131 | struct acpi_namespace_node *prefix_node, | ||
132 | char *path, | ||
133 | u32 expected_return_btypes, | ||
134 | union acpi_operand_object **return_desc) | ||
135 | { | ||
136 | struct acpi_parameter_info info; | ||
137 | acpi_status status; | ||
138 | u32 return_btype; | ||
139 | |||
140 | |||
141 | ACPI_FUNCTION_TRACE ("ut_evaluate_object"); | ||
142 | |||
143 | |||
144 | info.node = prefix_node; | ||
145 | info.parameters = NULL; | ||
146 | info.parameter_type = ACPI_PARAM_ARGS; | ||
147 | |||
148 | /* Evaluate the object/method */ | ||
149 | |||
150 | status = acpi_ns_evaluate_relative (path, &info); | ||
151 | if (ACPI_FAILURE (status)) { | ||
152 | if (status == AE_NOT_FOUND) { | ||
153 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n", | ||
154 | acpi_ut_get_node_name (prefix_node), path)); | ||
155 | } | ||
156 | else { | ||
157 | ACPI_REPORT_METHOD_ERROR ("Method execution failed", | ||
158 | prefix_node, path, status); | ||
159 | } | ||
160 | |||
161 | return_ACPI_STATUS (status); | ||
162 | } | ||
163 | |||
164 | /* Did we get a return object? */ | ||
165 | |||
166 | if (!info.return_object) { | ||
167 | if (expected_return_btypes) { | ||
168 | ACPI_REPORT_METHOD_ERROR ("No object was returned from", | ||
169 | prefix_node, path, AE_NOT_EXIST); | ||
170 | |||
171 | return_ACPI_STATUS (AE_NOT_EXIST); | ||
172 | } | ||
173 | |||
174 | return_ACPI_STATUS (AE_OK); | ||
175 | } | ||
176 | |||
177 | /* Map the return object type to the bitmapped type */ | ||
178 | |||
179 | switch (ACPI_GET_OBJECT_TYPE (info.return_object)) { | ||
180 | case ACPI_TYPE_INTEGER: | ||
181 | return_btype = ACPI_BTYPE_INTEGER; | ||
182 | break; | ||
183 | |||
184 | case ACPI_TYPE_BUFFER: | ||
185 | return_btype = ACPI_BTYPE_BUFFER; | ||
186 | break; | ||
187 | |||
188 | case ACPI_TYPE_STRING: | ||
189 | return_btype = ACPI_BTYPE_STRING; | ||
190 | break; | ||
191 | |||
192 | case ACPI_TYPE_PACKAGE: | ||
193 | return_btype = ACPI_BTYPE_PACKAGE; | ||
194 | break; | ||
195 | |||
196 | default: | ||
197 | return_btype = 0; | ||
198 | break; | ||
199 | } | ||
200 | |||
201 | if ((acpi_gbl_enable_interpreter_slack) && | ||
202 | (!expected_return_btypes)) { | ||
203 | /* | ||
204 | * We received a return object, but one was not expected. This can | ||
205 | * happen frequently if the "implicit return" feature is enabled. | ||
206 | * Just delete the return object and return AE_OK. | ||
207 | */ | ||
208 | acpi_ut_remove_reference (info.return_object); | ||
209 | return_ACPI_STATUS (AE_OK); | ||
210 | } | ||
211 | |||
212 | /* Is the return object one of the expected types? */ | ||
213 | |||
214 | if (!(expected_return_btypes & return_btype)) { | ||
215 | ACPI_REPORT_METHOD_ERROR ("Return object type is incorrect", | ||
216 | prefix_node, path, AE_TYPE); | ||
217 | |||
218 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
219 | "Type returned from %s was incorrect: %s, expected Btypes: %X\n", | ||
220 | path, acpi_ut_get_object_type_name (info.return_object), | ||
221 | expected_return_btypes)); | ||
222 | |||
223 | /* On error exit, we must delete the return object */ | ||
224 | |||
225 | acpi_ut_remove_reference (info.return_object); | ||
226 | return_ACPI_STATUS (AE_TYPE); | ||
227 | } | ||
228 | |||
229 | /* Object type is OK, return it */ | ||
230 | |||
231 | *return_desc = info.return_object; | ||
232 | return_ACPI_STATUS (AE_OK); | ||
233 | } | ||
234 | |||
235 | |||
236 | /******************************************************************************* | ||
237 | * | ||
238 | * FUNCTION: acpi_ut_evaluate_numeric_object | ||
239 | * | ||
240 | * PARAMETERS: *object_name - Object name to be evaluated | ||
241 | * device_node - Node for the device | ||
242 | * *Address - Where the value is returned | ||
243 | * | ||
244 | * RETURN: Status | ||
245 | * | ||
246 | * DESCRIPTION: Evaluates a numeric namespace object for a selected device | ||
247 | * and stores result in *Address. | ||
248 | * | ||
249 | * NOTE: Internal function, no parameter validation | ||
250 | * | ||
251 | ******************************************************************************/ | ||
252 | |||
253 | acpi_status | ||
254 | acpi_ut_evaluate_numeric_object ( | ||
255 | char *object_name, | ||
256 | struct acpi_namespace_node *device_node, | ||
257 | acpi_integer *address) | ||
258 | { | ||
259 | union acpi_operand_object *obj_desc; | ||
260 | acpi_status status; | ||
261 | |||
262 | |||
263 | ACPI_FUNCTION_TRACE ("ut_evaluate_numeric_object"); | ||
264 | |||
265 | |||
266 | status = acpi_ut_evaluate_object (device_node, object_name, | ||
267 | ACPI_BTYPE_INTEGER, &obj_desc); | ||
268 | if (ACPI_FAILURE (status)) { | ||
269 | return_ACPI_STATUS (status); | ||
270 | } | ||
271 | |||
272 | /* Get the returned Integer */ | ||
273 | |||
274 | *address = obj_desc->integer.value; | ||
275 | |||
276 | /* On exit, we must delete the return object */ | ||
277 | |||
278 | acpi_ut_remove_reference (obj_desc); | ||
279 | return_ACPI_STATUS (status); | ||
280 | } | ||
281 | |||
282 | |||
283 | /******************************************************************************* | ||
284 | * | ||
285 | * FUNCTION: acpi_ut_copy_id_string | ||
286 | * | ||
287 | * PARAMETERS: Destination - Where to copy the string | ||
288 | * Source - Source string | ||
289 | * max_length - Length of the destination buffer | ||
290 | * | ||
291 | * RETURN: None | ||
292 | * | ||
293 | * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods. | ||
294 | * Performs removal of a leading asterisk if present -- workaround | ||
295 | * for a known issue on a bunch of machines. | ||
296 | * | ||
297 | ******************************************************************************/ | ||
298 | |||
299 | static void | ||
300 | acpi_ut_copy_id_string ( | ||
301 | char *destination, | ||
302 | char *source, | ||
303 | acpi_size max_length) | ||
304 | { | ||
305 | |||
306 | |||
307 | /* | ||
308 | * Workaround for ID strings that have a leading asterisk. This construct | ||
309 | * is not allowed by the ACPI specification (ID strings must be | ||
310 | * alphanumeric), but enough existing machines have this embedded in their | ||
311 | * ID strings that the following code is useful. | ||
312 | */ | ||
313 | if (*source == '*') { | ||
314 | source++; | ||
315 | } | ||
316 | |||
317 | /* Do the actual copy */ | ||
318 | |||
319 | ACPI_STRNCPY (destination, source, max_length); | ||
320 | } | ||
321 | |||
322 | |||
323 | /******************************************************************************* | ||
324 | * | ||
325 | * FUNCTION: acpi_ut_execute_HID | ||
326 | * | ||
327 | * PARAMETERS: device_node - Node for the device | ||
328 | * *Hid - Where the HID is returned | ||
329 | * | ||
330 | * RETURN: Status | ||
331 | * | ||
332 | * DESCRIPTION: Executes the _HID control method that returns the hardware | ||
333 | * ID of the device. | ||
334 | * | ||
335 | * NOTE: Internal function, no parameter validation | ||
336 | * | ||
337 | ******************************************************************************/ | ||
338 | |||
339 | acpi_status | ||
340 | acpi_ut_execute_HID ( | ||
341 | struct acpi_namespace_node *device_node, | ||
342 | struct acpi_device_id *hid) | ||
343 | { | ||
344 | union acpi_operand_object *obj_desc; | ||
345 | acpi_status status; | ||
346 | |||
347 | |||
348 | ACPI_FUNCTION_TRACE ("ut_execute_HID"); | ||
349 | |||
350 | |||
351 | status = acpi_ut_evaluate_object (device_node, METHOD_NAME__HID, | ||
352 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &obj_desc); | ||
353 | if (ACPI_FAILURE (status)) { | ||
354 | return_ACPI_STATUS (status); | ||
355 | } | ||
356 | |||
357 | if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) { | ||
358 | /* Convert the Numeric HID to string */ | ||
359 | |||
360 | acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, hid->value); | ||
361 | } | ||
362 | else { | ||
363 | /* Copy the String HID from the returned object */ | ||
364 | |||
365 | acpi_ut_copy_id_string (hid->value, obj_desc->string.pointer, | ||
366 | sizeof (hid->value)); | ||
367 | } | ||
368 | |||
369 | /* On exit, we must delete the return object */ | ||
370 | |||
371 | acpi_ut_remove_reference (obj_desc); | ||
372 | return_ACPI_STATUS (status); | ||
373 | } | ||
374 | |||
375 | |||
376 | /******************************************************************************* | ||
377 | * | ||
378 | * FUNCTION: acpi_ut_translate_one_cid | ||
379 | * | ||
380 | * PARAMETERS: obj_desc - _CID object, must be integer or string | ||
381 | * one_cid - Where the CID string is returned | ||
382 | * | ||
383 | * RETURN: Status | ||
384 | * | ||
385 | * DESCRIPTION: Return a numeric or string _CID value as a string. | ||
386 | * (Compatible ID) | ||
387 | * | ||
388 | * NOTE: Assumes a maximum _CID string length of | ||
389 | * ACPI_MAX_CID_LENGTH. | ||
390 | * | ||
391 | ******************************************************************************/ | ||
392 | |||
393 | static acpi_status | ||
394 | acpi_ut_translate_one_cid ( | ||
395 | union acpi_operand_object *obj_desc, | ||
396 | struct acpi_compatible_id *one_cid) | ||
397 | { | ||
398 | |||
399 | |||
400 | switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { | ||
401 | case ACPI_TYPE_INTEGER: | ||
402 | |||
403 | /* Convert the Numeric CID to string */ | ||
404 | |||
405 | acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, one_cid->value); | ||
406 | return (AE_OK); | ||
407 | |||
408 | case ACPI_TYPE_STRING: | ||
409 | |||
410 | if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) { | ||
411 | return (AE_AML_STRING_LIMIT); | ||
412 | } | ||
413 | |||
414 | /* Copy the String CID from the returned object */ | ||
415 | |||
416 | acpi_ut_copy_id_string (one_cid->value, obj_desc->string.pointer, | ||
417 | ACPI_MAX_CID_LENGTH); | ||
418 | return (AE_OK); | ||
419 | |||
420 | default: | ||
421 | |||
422 | return (AE_TYPE); | ||
423 | } | ||
424 | } | ||
425 | |||
426 | |||
427 | /******************************************************************************* | ||
428 | * | ||
429 | * FUNCTION: acpi_ut_execute_CID | ||
430 | * | ||
431 | * PARAMETERS: device_node - Node for the device | ||
432 | * *Cid - Where the CID is returned | ||
433 | * | ||
434 | * RETURN: Status | ||
435 | * | ||
436 | * DESCRIPTION: Executes the _CID control method that returns one or more | ||
437 | * compatible hardware IDs for the device. | ||
438 | * | ||
439 | * NOTE: Internal function, no parameter validation | ||
440 | * | ||
441 | ******************************************************************************/ | ||
442 | |||
443 | acpi_status | ||
444 | acpi_ut_execute_CID ( | ||
445 | struct acpi_namespace_node *device_node, | ||
446 | struct acpi_compatible_id_list **return_cid_list) | ||
447 | { | ||
448 | union acpi_operand_object *obj_desc; | ||
449 | acpi_status status; | ||
450 | u32 count; | ||
451 | u32 size; | ||
452 | struct acpi_compatible_id_list *cid_list; | ||
453 | acpi_native_uint i; | ||
454 | |||
455 | |||
456 | ACPI_FUNCTION_TRACE ("ut_execute_CID"); | ||
457 | |||
458 | |||
459 | /* Evaluate the _CID method for this device */ | ||
460 | |||
461 | status = acpi_ut_evaluate_object (device_node, METHOD_NAME__CID, | ||
462 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE, | ||
463 | &obj_desc); | ||
464 | if (ACPI_FAILURE (status)) { | ||
465 | return_ACPI_STATUS (status); | ||
466 | } | ||
467 | |||
468 | /* Get the number of _CIDs returned */ | ||
469 | |||
470 | count = 1; | ||
471 | if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) { | ||
472 | count = obj_desc->package.count; | ||
473 | } | ||
474 | |||
475 | /* Allocate a worst-case buffer for the _CIDs */ | ||
476 | |||
477 | size = (((count - 1) * sizeof (struct acpi_compatible_id)) + | ||
478 | sizeof (struct acpi_compatible_id_list)); | ||
479 | |||
480 | cid_list = ACPI_MEM_CALLOCATE ((acpi_size) size); | ||
481 | if (!cid_list) { | ||
482 | return_ACPI_STATUS (AE_NO_MEMORY); | ||
483 | } | ||
484 | |||
485 | /* Init CID list */ | ||
486 | |||
487 | cid_list->count = count; | ||
488 | cid_list->size = size; | ||
489 | |||
490 | /* | ||
491 | * A _CID can return either a single compatible ID or a package of compatible | ||
492 | * IDs. Each compatible ID can be one of the following: | ||
493 | * -- Number (32 bit compressed EISA ID) or | ||
494 | * -- String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss"). | ||
495 | */ | ||
496 | |||
497 | /* The _CID object can be either a single CID or a package (list) of CIDs */ | ||
498 | |||
499 | if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) { | ||
500 | /* Translate each package element */ | ||
501 | |||
502 | for (i = 0; i < count; i++) { | ||
503 | status = acpi_ut_translate_one_cid (obj_desc->package.elements[i], | ||
504 | &cid_list->id[i]); | ||
505 | if (ACPI_FAILURE (status)) { | ||
506 | break; | ||
507 | } | ||
508 | } | ||
509 | } | ||
510 | else { | ||
511 | /* Only one CID, translate to a string */ | ||
512 | |||
513 | status = acpi_ut_translate_one_cid (obj_desc, cid_list->id); | ||
514 | } | ||
515 | |||
516 | /* Cleanup on error */ | ||
517 | |||
518 | if (ACPI_FAILURE (status)) { | ||
519 | ACPI_MEM_FREE (cid_list); | ||
520 | } | ||
521 | else { | ||
522 | *return_cid_list = cid_list; | ||
523 | } | ||
524 | |||
525 | /* On exit, we must delete the _CID return object */ | ||
526 | |||
527 | acpi_ut_remove_reference (obj_desc); | ||
528 | return_ACPI_STATUS (status); | ||
529 | } | ||
530 | |||
531 | |||
532 | /******************************************************************************* | ||
533 | * | ||
534 | * FUNCTION: acpi_ut_execute_UID | ||
535 | * | ||
536 | * PARAMETERS: device_node - Node for the device | ||
537 | * *Uid - Where the UID is returned | ||
538 | * | ||
539 | * RETURN: Status | ||
540 | * | ||
541 | * DESCRIPTION: Executes the _UID control method that returns the hardware | ||
542 | * ID of the device. | ||
543 | * | ||
544 | * NOTE: Internal function, no parameter validation | ||
545 | * | ||
546 | ******************************************************************************/ | ||
547 | |||
548 | acpi_status | ||
549 | acpi_ut_execute_UID ( | ||
550 | struct acpi_namespace_node *device_node, | ||
551 | struct acpi_device_id *uid) | ||
552 | { | ||
553 | union acpi_operand_object *obj_desc; | ||
554 | acpi_status status; | ||
555 | |||
556 | |||
557 | ACPI_FUNCTION_TRACE ("ut_execute_UID"); | ||
558 | |||
559 | |||
560 | status = acpi_ut_evaluate_object (device_node, METHOD_NAME__UID, | ||
561 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &obj_desc); | ||
562 | if (ACPI_FAILURE (status)) { | ||
563 | return_ACPI_STATUS (status); | ||
564 | } | ||
565 | |||
566 | if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) { | ||
567 | /* Convert the Numeric UID to string */ | ||
568 | |||
569 | acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->value); | ||
570 | } | ||
571 | else { | ||
572 | /* Copy the String UID from the returned object */ | ||
573 | |||
574 | acpi_ut_copy_id_string (uid->value, obj_desc->string.pointer, | ||
575 | sizeof (uid->value)); | ||
576 | } | ||
577 | |||
578 | /* On exit, we must delete the return object */ | ||
579 | |||
580 | acpi_ut_remove_reference (obj_desc); | ||
581 | return_ACPI_STATUS (status); | ||
582 | } | ||
583 | |||
584 | |||
585 | /******************************************************************************* | ||
586 | * | ||
587 | * FUNCTION: acpi_ut_execute_STA | ||
588 | * | ||
589 | * PARAMETERS: device_node - Node for the device | ||
590 | * *Flags - Where the status flags are returned | ||
591 | * | ||
592 | * RETURN: Status | ||
593 | * | ||
594 | * DESCRIPTION: Executes _STA for selected device and stores results in | ||
595 | * *Flags. | ||
596 | * | ||
597 | * NOTE: Internal function, no parameter validation | ||
598 | * | ||
599 | ******************************************************************************/ | ||
600 | |||
601 | acpi_status | ||
602 | acpi_ut_execute_STA ( | ||
603 | struct acpi_namespace_node *device_node, | ||
604 | u32 *flags) | ||
605 | { | ||
606 | union acpi_operand_object *obj_desc; | ||
607 | acpi_status status; | ||
608 | |||
609 | |||
610 | ACPI_FUNCTION_TRACE ("ut_execute_STA"); | ||
611 | |||
612 | |||
613 | status = acpi_ut_evaluate_object (device_node, METHOD_NAME__STA, | ||
614 | ACPI_BTYPE_INTEGER, &obj_desc); | ||
615 | if (ACPI_FAILURE (status)) { | ||
616 | if (AE_NOT_FOUND == status) { | ||
617 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, | ||
618 | "_STA on %4.4s was not found, assuming device is present\n", | ||
619 | acpi_ut_get_node_name (device_node))); | ||
620 | |||
621 | *flags = 0x0F; | ||
622 | status = AE_OK; | ||
623 | } | ||
624 | |||
625 | return_ACPI_STATUS (status); | ||
626 | } | ||
627 | |||
628 | /* Extract the status flags */ | ||
629 | |||
630 | *flags = (u32) obj_desc->integer.value; | ||
631 | |||
632 | /* On exit, we must delete the return object */ | ||
633 | |||
634 | acpi_ut_remove_reference (obj_desc); | ||
635 | return_ACPI_STATUS (status); | ||
636 | } | ||
637 | |||
638 | |||
639 | /******************************************************************************* | ||
640 | * | ||
641 | * FUNCTION: acpi_ut_execute_Sxds | ||
642 | * | ||
643 | * PARAMETERS: device_node - Node for the device | ||
644 | * *Flags - Where the status flags are returned | ||
645 | * | ||
646 | * RETURN: Status | ||
647 | * | ||
648 | * DESCRIPTION: Executes _STA for selected device and stores results in | ||
649 | * *Flags. | ||
650 | * | ||
651 | * NOTE: Internal function, no parameter validation | ||
652 | * | ||
653 | ******************************************************************************/ | ||
654 | |||
655 | acpi_status | ||
656 | acpi_ut_execute_sxds ( | ||
657 | struct acpi_namespace_node *device_node, | ||
658 | u8 *highest) | ||
659 | { | ||
660 | union acpi_operand_object *obj_desc; | ||
661 | acpi_status status; | ||
662 | u32 i; | ||
663 | |||
664 | |||
665 | ACPI_FUNCTION_TRACE ("ut_execute_Sxds"); | ||
666 | |||
667 | |||
668 | for (i = 0; i < 4; i++) { | ||
669 | highest[i] = 0xFF; | ||
670 | status = acpi_ut_evaluate_object (device_node, | ||
671 | (char *) acpi_gbl_highest_dstate_names[i], | ||
672 | ACPI_BTYPE_INTEGER, &obj_desc); | ||
673 | if (ACPI_FAILURE (status)) { | ||
674 | if (status != AE_NOT_FOUND) { | ||
675 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, | ||
676 | "%s on Device %4.4s, %s\n", | ||
677 | (char *) acpi_gbl_highest_dstate_names[i], | ||
678 | acpi_ut_get_node_name (device_node), | ||
679 | acpi_format_exception (status))); | ||
680 | |||
681 | return_ACPI_STATUS (status); | ||
682 | } | ||
683 | } | ||
684 | else { | ||
685 | /* Extract the Dstate value */ | ||
686 | |||
687 | highest[i] = (u8) obj_desc->integer.value; | ||
688 | |||
689 | /* Delete the return object */ | ||
690 | |||
691 | acpi_ut_remove_reference (obj_desc); | ||
692 | } | ||
693 | } | ||
694 | |||
695 | return_ACPI_STATUS (AE_OK); | ||
696 | } | ||
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c new file mode 100644 index 000000000000..25b0f8ae1bc6 --- /dev/null +++ b/drivers/acpi/utilities/utglobal.c | |||
@@ -0,0 +1,935 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: utglobal - Global variables for the ACPI subsystem | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
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 DEFINE_ACPI_GLOBALS | ||
45 | |||
46 | #include <linux/module.h> | ||
47 | |||
48 | #include <acpi/acpi.h> | ||
49 | #include <acpi/acnamesp.h> | ||
50 | |||
51 | #define _COMPONENT ACPI_UTILITIES | ||
52 | ACPI_MODULE_NAME ("utglobal") | ||
53 | |||
54 | |||
55 | /****************************************************************************** | ||
56 | * | ||
57 | * FUNCTION: acpi_format_exception | ||
58 | * | ||
59 | * PARAMETERS: Status - The acpi_status code to be formatted | ||
60 | * | ||
61 | * RETURN: A string containing the exception text | ||
62 | * | ||
63 | * DESCRIPTION: This function translates an ACPI exception into an ASCII string. | ||
64 | * | ||
65 | ******************************************************************************/ | ||
66 | |||
67 | const char * | ||
68 | acpi_format_exception ( | ||
69 | acpi_status status) | ||
70 | { | ||
71 | const char *exception = "UNKNOWN_STATUS_CODE"; | ||
72 | acpi_status sub_status; | ||
73 | |||
74 | |||
75 | ACPI_FUNCTION_NAME ("format_exception"); | ||
76 | |||
77 | |||
78 | sub_status = (status & ~AE_CODE_MASK); | ||
79 | |||
80 | switch (status & AE_CODE_MASK) { | ||
81 | case AE_CODE_ENVIRONMENTAL: | ||
82 | |||
83 | if (sub_status <= AE_CODE_ENV_MAX) { | ||
84 | exception = acpi_gbl_exception_names_env [sub_status]; | ||
85 | break; | ||
86 | } | ||
87 | goto unknown; | ||
88 | |||
89 | case AE_CODE_PROGRAMMER: | ||
90 | |||
91 | if (sub_status <= AE_CODE_PGM_MAX) { | ||
92 | exception = acpi_gbl_exception_names_pgm [sub_status -1]; | ||
93 | break; | ||
94 | } | ||
95 | goto unknown; | ||
96 | |||
97 | case AE_CODE_ACPI_TABLES: | ||
98 | |||
99 | if (sub_status <= AE_CODE_TBL_MAX) { | ||
100 | exception = acpi_gbl_exception_names_tbl [sub_status -1]; | ||
101 | break; | ||
102 | } | ||
103 | goto unknown; | ||
104 | |||
105 | case AE_CODE_AML: | ||
106 | |||
107 | if (sub_status <= AE_CODE_AML_MAX) { | ||
108 | exception = acpi_gbl_exception_names_aml [sub_status -1]; | ||
109 | break; | ||
110 | } | ||
111 | goto unknown; | ||
112 | |||
113 | case AE_CODE_CONTROL: | ||
114 | |||
115 | if (sub_status <= AE_CODE_CTRL_MAX) { | ||
116 | exception = acpi_gbl_exception_names_ctrl [sub_status -1]; | ||
117 | break; | ||
118 | } | ||
119 | goto unknown; | ||
120 | |||
121 | default: | ||
122 | goto unknown; | ||
123 | } | ||
124 | |||
125 | |||
126 | return ((const char *) exception); | ||
127 | |||
128 | unknown: | ||
129 | |||
130 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown exception code: 0x%8.8X\n", status)); | ||
131 | return ((const char *) exception); | ||
132 | } | ||
133 | |||
134 | |||
135 | /****************************************************************************** | ||
136 | * | ||
137 | * Static global variable initialization. | ||
138 | * | ||
139 | ******************************************************************************/ | ||
140 | |||
141 | /* | ||
142 | * We want the debug switches statically initialized so they | ||
143 | * are already set when the debugger is entered. | ||
144 | */ | ||
145 | |||
146 | /* Debug switch - level and trace mask */ | ||
147 | u32 acpi_dbg_level = ACPI_DEBUG_DEFAULT; | ||
148 | EXPORT_SYMBOL(acpi_dbg_level); | ||
149 | |||
150 | /* Debug switch - layer (component) mask */ | ||
151 | |||
152 | u32 acpi_dbg_layer = ACPI_COMPONENT_DEFAULT | ACPI_ALL_DRIVERS; | ||
153 | EXPORT_SYMBOL(acpi_dbg_layer); | ||
154 | u32 acpi_gbl_nesting_level = 0; | ||
155 | |||
156 | |||
157 | /* Debugger globals */ | ||
158 | |||
159 | u8 acpi_gbl_db_terminate_threads = FALSE; | ||
160 | u8 acpi_gbl_abort_method = FALSE; | ||
161 | u8 acpi_gbl_method_executing = FALSE; | ||
162 | |||
163 | /* System flags */ | ||
164 | |||
165 | u32 acpi_gbl_startup_flags = 0; | ||
166 | |||
167 | /* System starts uninitialized */ | ||
168 | |||
169 | u8 acpi_gbl_shutdown = TRUE; | ||
170 | |||
171 | const u8 acpi_gbl_decode_to8bit [8] = {1,2,4,8,16,32,64,128}; | ||
172 | |||
173 | const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = | ||
174 | { | ||
175 | "\\_S0_", | ||
176 | "\\_S1_", | ||
177 | "\\_S2_", | ||
178 | "\\_S3_", | ||
179 | "\\_S4_", | ||
180 | "\\_S5_" | ||
181 | }; | ||
182 | |||
183 | const char *acpi_gbl_highest_dstate_names[4] = | ||
184 | { | ||
185 | "_S1D", | ||
186 | "_S2D", | ||
187 | "_S3D", | ||
188 | "_S4D" | ||
189 | }; | ||
190 | |||
191 | /* | ||
192 | * Strings supported by the _OSI predefined (internal) method. | ||
193 | * When adding strings, be sure to update ACPI_NUM_OSI_STRINGS. | ||
194 | */ | ||
195 | const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] = | ||
196 | { | ||
197 | /* Operating System Vendor Strings */ | ||
198 | |||
199 | "Linux", | ||
200 | "Windows 2000", | ||
201 | "Windows 2001", | ||
202 | "Windows 2001.1", | ||
203 | "Windows 2001 SP0", | ||
204 | "Windows 2001 SP1", | ||
205 | "Windows 2001 SP2", | ||
206 | "Windows 2001 SP3", | ||
207 | "Windows 2001 SP4", | ||
208 | |||
209 | /* Feature Group Strings */ | ||
210 | |||
211 | "Extended Address Space Descriptor" | ||
212 | }; | ||
213 | |||
214 | |||
215 | /****************************************************************************** | ||
216 | * | ||
217 | * Namespace globals | ||
218 | * | ||
219 | ******************************************************************************/ | ||
220 | |||
221 | |||
222 | /* | ||
223 | * Predefined ACPI Names (Built-in to the Interpreter) | ||
224 | * | ||
225 | * NOTES: | ||
226 | * 1) _SB_ is defined to be a device to allow \_SB_._INI to be run | ||
227 | * during the initialization sequence. | ||
228 | * 2) _TZ_ is defined to be a thermal zone in order to allow ASL code to | ||
229 | * perform a Notify() operation on it. | ||
230 | */ | ||
231 | const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = | ||
232 | { {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL}, | ||
233 | {"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL}, | ||
234 | {"_SB_", ACPI_TYPE_DEVICE, NULL}, | ||
235 | {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL}, | ||
236 | {"_TZ_", ACPI_TYPE_THERMAL, NULL}, | ||
237 | {"_REV", ACPI_TYPE_INTEGER, (char *) ACPI_CA_SUPPORT_LEVEL}, | ||
238 | {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, | ||
239 | {"_GL_", ACPI_TYPE_MUTEX, (char *) 1}, | ||
240 | |||
241 | #if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) | ||
242 | {"_OSI", ACPI_TYPE_METHOD, (char *) 1}, | ||
243 | #endif | ||
244 | {NULL, ACPI_TYPE_ANY, NULL} /* Table terminator */ | ||
245 | }; | ||
246 | |||
247 | |||
248 | /* | ||
249 | * Properties of the ACPI Object Types, both internal and external. | ||
250 | * The table is indexed by values of acpi_object_type | ||
251 | */ | ||
252 | const u8 acpi_gbl_ns_properties[] = | ||
253 | { | ||
254 | ACPI_NS_NORMAL, /* 00 Any */ | ||
255 | ACPI_NS_NORMAL, /* 01 Number */ | ||
256 | ACPI_NS_NORMAL, /* 02 String */ | ||
257 | ACPI_NS_NORMAL, /* 03 Buffer */ | ||
258 | ACPI_NS_NORMAL, /* 04 Package */ | ||
259 | ACPI_NS_NORMAL, /* 05 field_unit */ | ||
260 | ACPI_NS_NEWSCOPE, /* 06 Device */ | ||
261 | ACPI_NS_NORMAL, /* 07 Event */ | ||
262 | ACPI_NS_NEWSCOPE, /* 08 Method */ | ||
263 | ACPI_NS_NORMAL, /* 09 Mutex */ | ||
264 | ACPI_NS_NORMAL, /* 10 Region */ | ||
265 | ACPI_NS_NEWSCOPE, /* 11 Power */ | ||
266 | ACPI_NS_NEWSCOPE, /* 12 Processor */ | ||
267 | ACPI_NS_NEWSCOPE, /* 13 Thermal */ | ||
268 | ACPI_NS_NORMAL, /* 14 buffer_field */ | ||
269 | ACPI_NS_NORMAL, /* 15 ddb_handle */ | ||
270 | ACPI_NS_NORMAL, /* 16 Debug Object */ | ||
271 | ACPI_NS_NORMAL, /* 17 def_field */ | ||
272 | ACPI_NS_NORMAL, /* 18 bank_field */ | ||
273 | ACPI_NS_NORMAL, /* 19 index_field */ | ||
274 | ACPI_NS_NORMAL, /* 20 Reference */ | ||
275 | ACPI_NS_NORMAL, /* 21 Alias */ | ||
276 | ACPI_NS_NORMAL, /* 22 method_alias */ | ||
277 | ACPI_NS_NORMAL, /* 23 Notify */ | ||
278 | ACPI_NS_NORMAL, /* 24 Address Handler */ | ||
279 | ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 25 Resource Desc */ | ||
280 | ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 26 Resource Field */ | ||
281 | ACPI_NS_NEWSCOPE, /* 27 Scope */ | ||
282 | ACPI_NS_NORMAL, /* 28 Extra */ | ||
283 | ACPI_NS_NORMAL, /* 29 Data */ | ||
284 | ACPI_NS_NORMAL /* 30 Invalid */ | ||
285 | }; | ||
286 | |||
287 | |||
288 | /* Hex to ASCII conversion table */ | ||
289 | |||
290 | static const char acpi_gbl_hex_to_ascii[] = | ||
291 | {'0','1','2','3','4','5','6','7', | ||
292 | '8','9','A','B','C','D','E','F'}; | ||
293 | |||
294 | /***************************************************************************** | ||
295 | * | ||
296 | * FUNCTION: acpi_ut_hex_to_ascii_char | ||
297 | * | ||
298 | * PARAMETERS: Integer - Contains the hex digit | ||
299 | * Position - bit position of the digit within the | ||
300 | * integer | ||
301 | * | ||
302 | * RETURN: Ascii character | ||
303 | * | ||
304 | * DESCRIPTION: Convert a hex digit to an ascii character | ||
305 | * | ||
306 | ****************************************************************************/ | ||
307 | |||
308 | char | ||
309 | acpi_ut_hex_to_ascii_char ( | ||
310 | acpi_integer integer, | ||
311 | u32 position) | ||
312 | { | ||
313 | |||
314 | return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]); | ||
315 | } | ||
316 | |||
317 | |||
318 | /****************************************************************************** | ||
319 | * | ||
320 | * Table name globals | ||
321 | * | ||
322 | * NOTE: This table includes ONLY the ACPI tables that the subsystem consumes. | ||
323 | * it is NOT an exhaustive list of all possible ACPI tables. All ACPI tables | ||
324 | * that are not used by the subsystem are simply ignored. | ||
325 | * | ||
326 | * Do NOT add any table to this list that is not consumed directly by this | ||
327 | * subsystem. | ||
328 | * | ||
329 | ******************************************************************************/ | ||
330 | |||
331 | struct acpi_table_list acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES]; | ||
332 | |||
333 | struct acpi_table_support acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES] = | ||
334 | { | ||
335 | /*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Contains valid AML? */ | ||
336 | |||
337 | /* RSDP 0 */ {RSDP_NAME, RSDP_SIG, NULL, sizeof (RSDP_SIG)-1, ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE}, | ||
338 | /* DSDT 1 */ {DSDT_SIG, DSDT_SIG, (void *) &acpi_gbl_DSDT, sizeof (DSDT_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE | ACPI_TABLE_EXECUTABLE}, | ||
339 | /* FADT 2 */ {FADT_SIG, FADT_SIG, (void *) &acpi_gbl_FADT, sizeof (FADT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_SINGLE}, | ||
340 | /* FACS 3 */ {FACS_SIG, FACS_SIG, (void *) &acpi_gbl_FACS, sizeof (FACS_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE}, | ||
341 | /* PSDT 4 */ {PSDT_SIG, PSDT_SIG, NULL, sizeof (PSDT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE}, | ||
342 | /* SSDT 5 */ {SSDT_SIG, SSDT_SIG, NULL, sizeof (SSDT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE}, | ||
343 | /* XSDT 6 */ {XSDT_SIG, XSDT_SIG, NULL, sizeof (RSDT_SIG)-1, ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE}, | ||
344 | }; | ||
345 | |||
346 | |||
347 | /****************************************************************************** | ||
348 | * | ||
349 | * Event and Hardware globals | ||
350 | * | ||
351 | ******************************************************************************/ | ||
352 | |||
353 | struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG] = | ||
354 | { | ||
355 | /* Name Parent Register Register Bit Position Register Bit Mask */ | ||
356 | |||
357 | /* ACPI_BITREG_TIMER_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_TIMER_STATUS, ACPI_BITMASK_TIMER_STATUS}, | ||
358 | /* ACPI_BITREG_BUS_MASTER_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_BUS_MASTER_STATUS, ACPI_BITMASK_BUS_MASTER_STATUS}, | ||
359 | /* ACPI_BITREG_GLOBAL_LOCK_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_GLOBAL_LOCK_STATUS, ACPI_BITMASK_GLOBAL_LOCK_STATUS}, | ||
360 | /* ACPI_BITREG_POWER_BUTTON_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_POWER_BUTTON_STATUS, ACPI_BITMASK_POWER_BUTTON_STATUS}, | ||
361 | /* ACPI_BITREG_SLEEP_BUTTON_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_SLEEP_BUTTON_STATUS, ACPI_BITMASK_SLEEP_BUTTON_STATUS}, | ||
362 | /* ACPI_BITREG_RT_CLOCK_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_RT_CLOCK_STATUS, ACPI_BITMASK_RT_CLOCK_STATUS}, | ||
363 | /* ACPI_BITREG_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_WAKE_STATUS, ACPI_BITMASK_WAKE_STATUS}, | ||
364 | /* ACPI_BITREG_PCIEXP_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_PCIEXP_WAKE_STATUS, ACPI_BITMASK_PCIEXP_WAKE_STATUS}, | ||
365 | |||
366 | /* ACPI_BITREG_TIMER_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_TIMER_ENABLE, ACPI_BITMASK_TIMER_ENABLE}, | ||
367 | /* ACPI_BITREG_GLOBAL_LOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_GLOBAL_LOCK_ENABLE, ACPI_BITMASK_GLOBAL_LOCK_ENABLE}, | ||
368 | /* ACPI_BITREG_POWER_BUTTON_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_POWER_BUTTON_ENABLE, ACPI_BITMASK_POWER_BUTTON_ENABLE}, | ||
369 | /* ACPI_BITREG_SLEEP_BUTTON_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE, ACPI_BITMASK_SLEEP_BUTTON_ENABLE}, | ||
370 | /* ACPI_BITREG_RT_CLOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_RT_CLOCK_ENABLE, ACPI_BITMASK_RT_CLOCK_ENABLE}, | ||
371 | /* ACPI_BITREG_WAKE_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, 0, 0}, | ||
372 | /* ACPI_BITREG_PCIEXP_WAKE_DISABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE, ACPI_BITMASK_PCIEXP_WAKE_DISABLE}, | ||
373 | |||
374 | /* ACPI_BITREG_SCI_ENABLE */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SCI_ENABLE, ACPI_BITMASK_SCI_ENABLE}, | ||
375 | /* ACPI_BITREG_BUS_MASTER_RLD */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_BUS_MASTER_RLD, ACPI_BITMASK_BUS_MASTER_RLD}, | ||
376 | /* ACPI_BITREG_GLOBAL_LOCK_RELEASE */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE, ACPI_BITMASK_GLOBAL_LOCK_RELEASE}, | ||
377 | /* ACPI_BITREG_SLEEP_TYPE_A */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SLEEP_TYPE_X, ACPI_BITMASK_SLEEP_TYPE_X}, | ||
378 | /* ACPI_BITREG_SLEEP_TYPE_B */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SLEEP_TYPE_X, ACPI_BITMASK_SLEEP_TYPE_X}, | ||
379 | /* ACPI_BITREG_SLEEP_ENABLE */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SLEEP_ENABLE, ACPI_BITMASK_SLEEP_ENABLE}, | ||
380 | |||
381 | /* ACPI_BITREG_ARB_DIS */ {ACPI_REGISTER_PM2_CONTROL, ACPI_BITPOSITION_ARB_DISABLE, ACPI_BITMASK_ARB_DISABLE} | ||
382 | }; | ||
383 | |||
384 | |||
385 | struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] = | ||
386 | { | ||
387 | /* ACPI_EVENT_PMTIMER */ {ACPI_BITREG_TIMER_STATUS, ACPI_BITREG_TIMER_ENABLE, ACPI_BITMASK_TIMER_STATUS, ACPI_BITMASK_TIMER_ENABLE}, | ||
388 | /* ACPI_EVENT_GLOBAL */ {ACPI_BITREG_GLOBAL_LOCK_STATUS, ACPI_BITREG_GLOBAL_LOCK_ENABLE, ACPI_BITMASK_GLOBAL_LOCK_STATUS, ACPI_BITMASK_GLOBAL_LOCK_ENABLE}, | ||
389 | /* ACPI_EVENT_POWER_BUTTON */ {ACPI_BITREG_POWER_BUTTON_STATUS, ACPI_BITREG_POWER_BUTTON_ENABLE, ACPI_BITMASK_POWER_BUTTON_STATUS, ACPI_BITMASK_POWER_BUTTON_ENABLE}, | ||
390 | /* ACPI_EVENT_SLEEP_BUTTON */ {ACPI_BITREG_SLEEP_BUTTON_STATUS, ACPI_BITREG_SLEEP_BUTTON_ENABLE, ACPI_BITMASK_SLEEP_BUTTON_STATUS, ACPI_BITMASK_SLEEP_BUTTON_ENABLE}, | ||
391 | /* ACPI_EVENT_RTC */ {ACPI_BITREG_RT_CLOCK_STATUS, ACPI_BITREG_RT_CLOCK_ENABLE, ACPI_BITMASK_RT_CLOCK_STATUS, ACPI_BITMASK_RT_CLOCK_ENABLE}, | ||
392 | }; | ||
393 | |||
394 | /***************************************************************************** | ||
395 | * | ||
396 | * FUNCTION: acpi_ut_get_region_name | ||
397 | * | ||
398 | * PARAMETERS: None. | ||
399 | * | ||
400 | * RETURN: Status | ||
401 | * | ||
402 | * DESCRIPTION: Translate a Space ID into a name string (Debug only) | ||
403 | * | ||
404 | ****************************************************************************/ | ||
405 | |||
406 | /* Region type decoding */ | ||
407 | |||
408 | const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = | ||
409 | { | ||
410 | /*! [Begin] no source code translation (keep these ASL Keywords as-is) */ | ||
411 | "SystemMemory", | ||
412 | "SystemIO", | ||
413 | "PCI_Config", | ||
414 | "EmbeddedControl", | ||
415 | "SMBus", | ||
416 | "CMOS", | ||
417 | "PCIBARTarget", | ||
418 | "DataTable" | ||
419 | /*! [End] no source code translation !*/ | ||
420 | }; | ||
421 | |||
422 | |||
423 | char * | ||
424 | acpi_ut_get_region_name ( | ||
425 | u8 space_id) | ||
426 | { | ||
427 | |||
428 | if (space_id >= ACPI_USER_REGION_BEGIN) | ||
429 | { | ||
430 | return ("user_defined_region"); | ||
431 | } | ||
432 | |||
433 | else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS) | ||
434 | { | ||
435 | return ("invalid_space_id"); | ||
436 | } | ||
437 | |||
438 | return ((char *) acpi_gbl_region_types[space_id]); | ||
439 | } | ||
440 | |||
441 | |||
442 | /***************************************************************************** | ||
443 | * | ||
444 | * FUNCTION: acpi_ut_get_event_name | ||
445 | * | ||
446 | * PARAMETERS: None. | ||
447 | * | ||
448 | * RETURN: Status | ||
449 | * | ||
450 | * DESCRIPTION: Translate a Event ID into a name string (Debug only) | ||
451 | * | ||
452 | ****************************************************************************/ | ||
453 | |||
454 | /* Event type decoding */ | ||
455 | |||
456 | static const char *acpi_gbl_event_types[ACPI_NUM_FIXED_EVENTS] = | ||
457 | { | ||
458 | "PM_Timer", | ||
459 | "global_lock", | ||
460 | "power_button", | ||
461 | "sleep_button", | ||
462 | "real_time_clock", | ||
463 | }; | ||
464 | |||
465 | |||
466 | char * | ||
467 | acpi_ut_get_event_name ( | ||
468 | u32 event_id) | ||
469 | { | ||
470 | |||
471 | if (event_id > ACPI_EVENT_MAX) | ||
472 | { | ||
473 | return ("invalid_event_iD"); | ||
474 | } | ||
475 | |||
476 | return ((char *) acpi_gbl_event_types[event_id]); | ||
477 | } | ||
478 | |||
479 | |||
480 | /***************************************************************************** | ||
481 | * | ||
482 | * FUNCTION: acpi_ut_get_type_name | ||
483 | * | ||
484 | * PARAMETERS: None. | ||
485 | * | ||
486 | * RETURN: Status | ||
487 | * | ||
488 | * DESCRIPTION: Translate a Type ID into a name string (Debug only) | ||
489 | * | ||
490 | ****************************************************************************/ | ||
491 | |||
492 | /* | ||
493 | * Elements of acpi_gbl_ns_type_names below must match | ||
494 | * one-to-one with values of acpi_object_type | ||
495 | * | ||
496 | * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching; when | ||
497 | * stored in a table it really means that we have thus far seen no evidence to | ||
498 | * indicate what type is actually going to be stored for this entry. | ||
499 | */ | ||
500 | static const char acpi_gbl_bad_type[] = "UNDEFINED"; | ||
501 | #define TYPE_NAME_LENGTH 12 /* Maximum length of each string */ | ||
502 | |||
503 | static const char *acpi_gbl_ns_type_names[] = /* printable names of ACPI types */ | ||
504 | { | ||
505 | /* 00 */ "Untyped", | ||
506 | /* 01 */ "Integer", | ||
507 | /* 02 */ "String", | ||
508 | /* 03 */ "Buffer", | ||
509 | /* 04 */ "Package", | ||
510 | /* 05 */ "field_unit", | ||
511 | /* 06 */ "Device", | ||
512 | /* 07 */ "Event", | ||
513 | /* 08 */ "Method", | ||
514 | /* 09 */ "Mutex", | ||
515 | /* 10 */ "Region", | ||
516 | /* 11 */ "Power", | ||
517 | /* 12 */ "Processor", | ||
518 | /* 13 */ "Thermal", | ||
519 | /* 14 */ "buffer_field", | ||
520 | /* 15 */ "ddb_handle", | ||
521 | /* 16 */ "debug_object", | ||
522 | /* 17 */ "region_field", | ||
523 | /* 18 */ "bank_field", | ||
524 | /* 19 */ "index_field", | ||
525 | /* 20 */ "Reference", | ||
526 | /* 21 */ "Alias", | ||
527 | /* 22 */ "method_alias", | ||
528 | /* 23 */ "Notify", | ||
529 | /* 24 */ "addr_handler", | ||
530 | /* 25 */ "resource_desc", | ||
531 | /* 26 */ "resource_fld", | ||
532 | /* 27 */ "Scope", | ||
533 | /* 28 */ "Extra", | ||
534 | /* 29 */ "Data", | ||
535 | /* 30 */ "Invalid" | ||
536 | }; | ||
537 | |||
538 | |||
539 | char * | ||
540 | acpi_ut_get_type_name ( | ||
541 | acpi_object_type type) | ||
542 | { | ||
543 | |||
544 | if (type > ACPI_TYPE_INVALID) | ||
545 | { | ||
546 | return ((char *) acpi_gbl_bad_type); | ||
547 | } | ||
548 | |||
549 | return ((char *) acpi_gbl_ns_type_names[type]); | ||
550 | } | ||
551 | |||
552 | |||
553 | char * | ||
554 | acpi_ut_get_object_type_name ( | ||
555 | union acpi_operand_object *obj_desc) | ||
556 | { | ||
557 | |||
558 | if (!obj_desc) | ||
559 | { | ||
560 | return ("[NULL Object Descriptor]"); | ||
561 | } | ||
562 | |||
563 | return (acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (obj_desc))); | ||
564 | } | ||
565 | |||
566 | |||
567 | /***************************************************************************** | ||
568 | * | ||
569 | * FUNCTION: acpi_ut_get_node_name | ||
570 | * | ||
571 | * PARAMETERS: Object - A namespace node | ||
572 | * | ||
573 | * RETURN: Pointer to a string | ||
574 | * | ||
575 | * DESCRIPTION: Validate the node and return the node's ACPI name. | ||
576 | * | ||
577 | ****************************************************************************/ | ||
578 | |||
579 | char * | ||
580 | acpi_ut_get_node_name ( | ||
581 | void *object) | ||
582 | { | ||
583 | struct acpi_namespace_node *node = (struct acpi_namespace_node *) object; | ||
584 | |||
585 | |||
586 | /* Must return a string of exactly 4 characters == ACPI_NAME_SIZE */ | ||
587 | |||
588 | if (!object) | ||
589 | { | ||
590 | return ("NULL"); | ||
591 | } | ||
592 | |||
593 | /* Check for Root node */ | ||
594 | |||
595 | if ((object == ACPI_ROOT_OBJECT) || | ||
596 | (object == acpi_gbl_root_node)) | ||
597 | { | ||
598 | return ("\"\\\" "); | ||
599 | } | ||
600 | |||
601 | /* Descriptor must be a namespace node */ | ||
602 | |||
603 | if (node->descriptor != ACPI_DESC_TYPE_NAMED) | ||
604 | { | ||
605 | return ("####"); | ||
606 | } | ||
607 | |||
608 | /* Name must be a valid ACPI name */ | ||
609 | |||
610 | if (!acpi_ut_valid_acpi_name (* (u32 *) node->name.ascii)) | ||
611 | { | ||
612 | return ("????"); | ||
613 | } | ||
614 | |||
615 | /* Return the name */ | ||
616 | |||
617 | return (node->name.ascii); | ||
618 | } | ||
619 | |||
620 | |||
621 | /***************************************************************************** | ||
622 | * | ||
623 | * FUNCTION: acpi_ut_get_descriptor_name | ||
624 | * | ||
625 | * PARAMETERS: Object - An ACPI object | ||
626 | * | ||
627 | * RETURN: Pointer to a string | ||
628 | * | ||
629 | * DESCRIPTION: Validate object and return the descriptor type | ||
630 | * | ||
631 | ****************************************************************************/ | ||
632 | |||
633 | static const char *acpi_gbl_desc_type_names[] = /* printable names of descriptor types */ | ||
634 | { | ||
635 | /* 00 */ "Invalid", | ||
636 | /* 01 */ "Cached", | ||
637 | /* 02 */ "State-Generic", | ||
638 | /* 03 */ "State-Update", | ||
639 | /* 04 */ "State-Package", | ||
640 | /* 05 */ "State-Control", | ||
641 | /* 06 */ "State-root_parse_scope", | ||
642 | /* 07 */ "State-parse_scope", | ||
643 | /* 08 */ "State-walk_scope", | ||
644 | /* 09 */ "State-Result", | ||
645 | /* 10 */ "State-Notify", | ||
646 | /* 11 */ "State-Thread", | ||
647 | /* 12 */ "Walk", | ||
648 | /* 13 */ "Parser", | ||
649 | /* 14 */ "Operand", | ||
650 | /* 15 */ "Node" | ||
651 | }; | ||
652 | |||
653 | |||
654 | char * | ||
655 | acpi_ut_get_descriptor_name ( | ||
656 | void *object) | ||
657 | { | ||
658 | |||
659 | if (!object) | ||
660 | { | ||
661 | return ("NULL OBJECT"); | ||
662 | } | ||
663 | |||
664 | if (ACPI_GET_DESCRIPTOR_TYPE (object) > ACPI_DESC_TYPE_MAX) | ||
665 | { | ||
666 | return ((char *) acpi_gbl_bad_type); | ||
667 | } | ||
668 | |||
669 | return ((char *) acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE (object)]); | ||
670 | |||
671 | } | ||
672 | |||
673 | |||
674 | #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) | ||
675 | /* | ||
676 | * Strings and procedures used for debug only | ||
677 | */ | ||
678 | |||
679 | /***************************************************************************** | ||
680 | * | ||
681 | * FUNCTION: acpi_ut_get_mutex_name | ||
682 | * | ||
683 | * PARAMETERS: None. | ||
684 | * | ||
685 | * RETURN: Status | ||
686 | * | ||
687 | * DESCRIPTION: Translate a mutex ID into a name string (Debug only) | ||
688 | * | ||
689 | ****************************************************************************/ | ||
690 | |||
691 | char * | ||
692 | acpi_ut_get_mutex_name ( | ||
693 | u32 mutex_id) | ||
694 | { | ||
695 | |||
696 | if (mutex_id > MAX_MUTEX) | ||
697 | { | ||
698 | return ("Invalid Mutex ID"); | ||
699 | } | ||
700 | |||
701 | return (acpi_gbl_mutex_names[mutex_id]); | ||
702 | } | ||
703 | |||
704 | #endif | ||
705 | |||
706 | |||
707 | /***************************************************************************** | ||
708 | * | ||
709 | * FUNCTION: acpi_ut_valid_object_type | ||
710 | * | ||
711 | * PARAMETERS: Type - Object type to be validated | ||
712 | * | ||
713 | * RETURN: TRUE if valid object type | ||
714 | * | ||
715 | * DESCRIPTION: Validate an object type | ||
716 | * | ||
717 | ****************************************************************************/ | ||
718 | |||
719 | u8 | ||
720 | acpi_ut_valid_object_type ( | ||
721 | acpi_object_type type) | ||
722 | { | ||
723 | |||
724 | if (type > ACPI_TYPE_LOCAL_MAX) | ||
725 | { | ||
726 | /* Note: Assumes all TYPEs are contiguous (external/local) */ | ||
727 | |||
728 | return (FALSE); | ||
729 | } | ||
730 | |||
731 | return (TRUE); | ||
732 | } | ||
733 | |||
734 | |||
735 | /**************************************************************************** | ||
736 | * | ||
737 | * FUNCTION: acpi_ut_allocate_owner_id | ||
738 | * | ||
739 | * PARAMETERS: id_type - Type of ID (method or table) | ||
740 | * | ||
741 | * DESCRIPTION: Allocate a table or method owner id | ||
742 | * | ||
743 | ***************************************************************************/ | ||
744 | |||
745 | acpi_owner_id | ||
746 | acpi_ut_allocate_owner_id ( | ||
747 | u32 id_type) | ||
748 | { | ||
749 | acpi_owner_id owner_id = 0xFFFF; | ||
750 | |||
751 | |||
752 | ACPI_FUNCTION_TRACE ("ut_allocate_owner_id"); | ||
753 | |||
754 | |||
755 | if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) | ||
756 | { | ||
757 | return (0); | ||
758 | } | ||
759 | |||
760 | switch (id_type) | ||
761 | { | ||
762 | case ACPI_OWNER_TYPE_TABLE: | ||
763 | |||
764 | owner_id = acpi_gbl_next_table_owner_id; | ||
765 | acpi_gbl_next_table_owner_id++; | ||
766 | |||
767 | /* Check for wraparound */ | ||
768 | |||
769 | if (acpi_gbl_next_table_owner_id == ACPI_FIRST_METHOD_ID) | ||
770 | { | ||
771 | acpi_gbl_next_table_owner_id = ACPI_FIRST_TABLE_ID; | ||
772 | ACPI_REPORT_WARNING (("Table owner ID wraparound\n")); | ||
773 | } | ||
774 | break; | ||
775 | |||
776 | |||
777 | case ACPI_OWNER_TYPE_METHOD: | ||
778 | |||
779 | owner_id = acpi_gbl_next_method_owner_id; | ||
780 | acpi_gbl_next_method_owner_id++; | ||
781 | |||
782 | if (acpi_gbl_next_method_owner_id == ACPI_FIRST_TABLE_ID) | ||
783 | { | ||
784 | /* Check for wraparound */ | ||
785 | |||
786 | acpi_gbl_next_method_owner_id = ACPI_FIRST_METHOD_ID; | ||
787 | } | ||
788 | break; | ||
789 | |||
790 | default: | ||
791 | break; | ||
792 | } | ||
793 | |||
794 | (void) acpi_ut_release_mutex (ACPI_MTX_CACHES); | ||
795 | return_VALUE (owner_id); | ||
796 | } | ||
797 | |||
798 | |||
799 | /**************************************************************************** | ||
800 | * | ||
801 | * FUNCTION: acpi_ut_init_globals | ||
802 | * | ||
803 | * PARAMETERS: none | ||
804 | * | ||
805 | * DESCRIPTION: Init library globals. All globals that require specific | ||
806 | * initialization should be initialized here! | ||
807 | * | ||
808 | ***************************************************************************/ | ||
809 | |||
810 | void | ||
811 | acpi_ut_init_globals ( | ||
812 | void) | ||
813 | { | ||
814 | u32 i; | ||
815 | |||
816 | |||
817 | ACPI_FUNCTION_TRACE ("ut_init_globals"); | ||
818 | |||
819 | |||
820 | /* Memory allocation and cache lists */ | ||
821 | |||
822 | ACPI_MEMSET (acpi_gbl_memory_lists, 0, sizeof (struct acpi_memory_list) * ACPI_NUM_MEM_LISTS); | ||
823 | |||
824 | acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_generic_state *) NULL)->common.next), NULL); | ||
825 | acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_parse_object *) NULL)->common.next), NULL); | ||
826 | acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_parse_object *) NULL)->common.next), NULL); | ||
827 | acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_operand_object *) NULL)->cache.next), NULL); | ||
828 | acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].link_offset = (u16) ACPI_PTR_DIFF (&(((struct acpi_walk_state *) NULL)->next), NULL); | ||
829 | |||
830 | acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].object_size = sizeof (struct acpi_namespace_node); | ||
831 | acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].object_size = sizeof (union acpi_generic_state); | ||
832 | acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].object_size = sizeof (struct acpi_parse_obj_common); | ||
833 | acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].object_size = sizeof (struct acpi_parse_obj_named); | ||
834 | acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].object_size = sizeof (union acpi_operand_object); | ||
835 | acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].object_size = sizeof (struct acpi_walk_state); | ||
836 | |||
837 | acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].max_cache_depth = ACPI_MAX_STATE_CACHE_DEPTH; | ||
838 | acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].max_cache_depth = ACPI_MAX_PARSE_CACHE_DEPTH; | ||
839 | acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].max_cache_depth = ACPI_MAX_EXTPARSE_CACHE_DEPTH; | ||
840 | acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].max_cache_depth = ACPI_MAX_OBJECT_CACHE_DEPTH; | ||
841 | acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].max_cache_depth = ACPI_MAX_WALK_CACHE_DEPTH; | ||
842 | |||
843 | ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].list_name = "Global Memory Allocation"); | ||
844 | ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].list_name = "Namespace Nodes"); | ||
845 | ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].list_name = "State Object Cache"); | ||
846 | ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].list_name = "Parse Node Cache"); | ||
847 | ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].list_name = "Extended Parse Node Cache"); | ||
848 | ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].list_name = "Operand Object Cache"); | ||
849 | ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].list_name = "Tree Walk Node Cache"); | ||
850 | |||
851 | /* ACPI table structure */ | ||
852 | |||
853 | for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) | ||
854 | { | ||
855 | acpi_gbl_table_lists[i].next = NULL; | ||
856 | acpi_gbl_table_lists[i].count = 0; | ||
857 | } | ||
858 | |||
859 | /* Mutex locked flags */ | ||
860 | |||
861 | for (i = 0; i < NUM_MUTEX; i++) | ||
862 | { | ||
863 | acpi_gbl_mutex_info[i].mutex = NULL; | ||
864 | acpi_gbl_mutex_info[i].owner_id = ACPI_MUTEX_NOT_ACQUIRED; | ||
865 | acpi_gbl_mutex_info[i].use_count = 0; | ||
866 | } | ||
867 | |||
868 | /* GPE support */ | ||
869 | |||
870 | acpi_gbl_gpe_xrupt_list_head = NULL; | ||
871 | acpi_gbl_gpe_fadt_blocks[0] = NULL; | ||
872 | acpi_gbl_gpe_fadt_blocks[1] = NULL; | ||
873 | |||
874 | /* Global notify handlers */ | ||
875 | |||
876 | acpi_gbl_system_notify.handler = NULL; | ||
877 | acpi_gbl_device_notify.handler = NULL; | ||
878 | acpi_gbl_exception_handler = NULL; | ||
879 | acpi_gbl_init_handler = NULL; | ||
880 | |||
881 | /* Global "typed" ACPI table pointers */ | ||
882 | |||
883 | acpi_gbl_RSDP = NULL; | ||
884 | acpi_gbl_XSDT = NULL; | ||
885 | acpi_gbl_FACS = NULL; | ||
886 | acpi_gbl_FADT = NULL; | ||
887 | acpi_gbl_DSDT = NULL; | ||
888 | |||
889 | /* Global Lock support */ | ||
890 | |||
891 | acpi_gbl_global_lock_acquired = FALSE; | ||
892 | acpi_gbl_global_lock_thread_count = 0; | ||
893 | acpi_gbl_global_lock_handle = 0; | ||
894 | |||
895 | /* Miscellaneous variables */ | ||
896 | |||
897 | acpi_gbl_table_flags = ACPI_PHYSICAL_POINTER; | ||
898 | acpi_gbl_rsdp_original_location = 0; | ||
899 | acpi_gbl_cm_single_step = FALSE; | ||
900 | acpi_gbl_db_terminate_threads = FALSE; | ||
901 | acpi_gbl_shutdown = FALSE; | ||
902 | acpi_gbl_ns_lookup_count = 0; | ||
903 | acpi_gbl_ps_find_count = 0; | ||
904 | acpi_gbl_acpi_hardware_present = TRUE; | ||
905 | acpi_gbl_next_table_owner_id = ACPI_FIRST_TABLE_ID; | ||
906 | acpi_gbl_next_method_owner_id = ACPI_FIRST_METHOD_ID; | ||
907 | acpi_gbl_debugger_configuration = DEBUGGER_THREADING; | ||
908 | acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; | ||
909 | |||
910 | /* Hardware oriented */ | ||
911 | |||
912 | acpi_gbl_events_initialized = FALSE; | ||
913 | acpi_gbl_system_awake_and_running = TRUE; | ||
914 | |||
915 | /* Namespace */ | ||
916 | |||
917 | acpi_gbl_root_node = NULL; | ||
918 | |||
919 | acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME; | ||
920 | acpi_gbl_root_node_struct.descriptor = ACPI_DESC_TYPE_NAMED; | ||
921 | acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE; | ||
922 | acpi_gbl_root_node_struct.child = NULL; | ||
923 | acpi_gbl_root_node_struct.peer = NULL; | ||
924 | acpi_gbl_root_node_struct.object = NULL; | ||
925 | acpi_gbl_root_node_struct.flags = ANOBJ_END_OF_PEER_LIST; | ||
926 | |||
927 | |||
928 | #ifdef ACPI_DEBUG_OUTPUT | ||
929 | acpi_gbl_lowest_stack_pointer = ACPI_SIZE_MAX; | ||
930 | #endif | ||
931 | |||
932 | return_VOID; | ||
933 | } | ||
934 | |||
935 | |||
diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c new file mode 100644 index 000000000000..bdbadaf48d29 --- /dev/null +++ b/drivers/acpi/utilities/utinit.c | |||
@@ -0,0 +1,266 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: utinit - Common ACPI subsystem initialization | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
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 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/acnamesp.h> | ||
47 | #include <acpi/acevents.h> | ||
48 | |||
49 | #define _COMPONENT ACPI_UTILITIES | ||
50 | ACPI_MODULE_NAME ("utinit") | ||
51 | |||
52 | |||
53 | /******************************************************************************* | ||
54 | * | ||
55 | * FUNCTION: acpi_ut_fadt_register_error | ||
56 | * | ||
57 | * PARAMETERS: *register_name - Pointer to string identifying register | ||
58 | * Value - Actual register contents value | ||
59 | * acpi_test_spec_section - TDS section containing assertion | ||
60 | * acpi_assertion - Assertion number being tested | ||
61 | * | ||
62 | * RETURN: AE_BAD_VALUE | ||
63 | * | ||
64 | * DESCRIPTION: Display failure message and link failure to TDS assertion | ||
65 | * | ||
66 | ******************************************************************************/ | ||
67 | |||
68 | static void | ||
69 | acpi_ut_fadt_register_error ( | ||
70 | char *register_name, | ||
71 | u32 value, | ||
72 | acpi_size offset) | ||
73 | { | ||
74 | |||
75 | ACPI_REPORT_WARNING ( | ||
76 | ("Invalid FADT value %s=%X at offset %X FADT=%p\n", | ||
77 | register_name, value, (u32) offset, acpi_gbl_FADT)); | ||
78 | } | ||
79 | |||
80 | |||
81 | /****************************************************************************** | ||
82 | * | ||
83 | * FUNCTION: acpi_ut_validate_fadt | ||
84 | * | ||
85 | * PARAMETERS: None | ||
86 | * | ||
87 | * RETURN: Status | ||
88 | * | ||
89 | * DESCRIPTION: Validate various ACPI registers in the FADT | ||
90 | * | ||
91 | ******************************************************************************/ | ||
92 | |||
93 | acpi_status | ||
94 | acpi_ut_validate_fadt ( | ||
95 | void) | ||
96 | { | ||
97 | |||
98 | /* | ||
99 | * Verify Fixed ACPI Description Table fields, | ||
100 | * but don't abort on any problems, just display error | ||
101 | */ | ||
102 | if (acpi_gbl_FADT->pm1_evt_len < 4) { | ||
103 | acpi_ut_fadt_register_error ("PM1_EVT_LEN", | ||
104 | (u32) acpi_gbl_FADT->pm1_evt_len, | ||
105 | ACPI_FADT_OFFSET (pm1_evt_len)); | ||
106 | } | ||
107 | |||
108 | if (!acpi_gbl_FADT->pm1_cnt_len) { | ||
109 | acpi_ut_fadt_register_error ("PM1_CNT_LEN", 0, | ||
110 | ACPI_FADT_OFFSET (pm1_cnt_len)); | ||
111 | } | ||
112 | |||
113 | if (!acpi_gbl_FADT->xpm1a_evt_blk.address) { | ||
114 | acpi_ut_fadt_register_error ("X_PM1a_EVT_BLK", 0, | ||
115 | ACPI_FADT_OFFSET (xpm1a_evt_blk.address)); | ||
116 | } | ||
117 | |||
118 | if (!acpi_gbl_FADT->xpm1a_cnt_blk.address) { | ||
119 | acpi_ut_fadt_register_error ("X_PM1a_CNT_BLK", 0, | ||
120 | ACPI_FADT_OFFSET (xpm1a_cnt_blk.address)); | ||
121 | } | ||
122 | |||
123 | if (!acpi_gbl_FADT->xpm_tmr_blk.address) { | ||
124 | acpi_ut_fadt_register_error ("X_PM_TMR_BLK", 0, | ||
125 | ACPI_FADT_OFFSET (xpm_tmr_blk.address)); | ||
126 | } | ||
127 | |||
128 | if ((acpi_gbl_FADT->xpm2_cnt_blk.address && | ||
129 | !acpi_gbl_FADT->pm2_cnt_len)) { | ||
130 | acpi_ut_fadt_register_error ("PM2_CNT_LEN", | ||
131 | (u32) acpi_gbl_FADT->pm2_cnt_len, | ||
132 | ACPI_FADT_OFFSET (pm2_cnt_len)); | ||
133 | } | ||
134 | |||
135 | if (acpi_gbl_FADT->pm_tm_len < 4) { | ||
136 | acpi_ut_fadt_register_error ("PM_TM_LEN", | ||
137 | (u32) acpi_gbl_FADT->pm_tm_len, | ||
138 | ACPI_FADT_OFFSET (pm_tm_len)); | ||
139 | } | ||
140 | |||
141 | /* Length of GPE blocks must be a multiple of 2 */ | ||
142 | |||
143 | if (acpi_gbl_FADT->xgpe0_blk.address && | ||
144 | (acpi_gbl_FADT->gpe0_blk_len & 1)) { | ||
145 | acpi_ut_fadt_register_error ("(x)GPE0_BLK_LEN", | ||
146 | (u32) acpi_gbl_FADT->gpe0_blk_len, | ||
147 | ACPI_FADT_OFFSET (gpe0_blk_len)); | ||
148 | } | ||
149 | |||
150 | if (acpi_gbl_FADT->xgpe1_blk.address && | ||
151 | (acpi_gbl_FADT->gpe1_blk_len & 1)) { | ||
152 | acpi_ut_fadt_register_error ("(x)GPE1_BLK_LEN", | ||
153 | (u32) acpi_gbl_FADT->gpe1_blk_len, | ||
154 | ACPI_FADT_OFFSET (gpe1_blk_len)); | ||
155 | } | ||
156 | |||
157 | return (AE_OK); | ||
158 | } | ||
159 | |||
160 | |||
161 | /****************************************************************************** | ||
162 | * | ||
163 | * FUNCTION: acpi_ut_terminate | ||
164 | * | ||
165 | * PARAMETERS: none | ||
166 | * | ||
167 | * RETURN: none | ||
168 | * | ||
169 | * DESCRIPTION: free global memory | ||
170 | * | ||
171 | ******************************************************************************/ | ||
172 | |||
173 | void | ||
174 | acpi_ut_terminate (void) | ||
175 | { | ||
176 | struct acpi_gpe_block_info *gpe_block; | ||
177 | struct acpi_gpe_block_info *next_gpe_block; | ||
178 | struct acpi_gpe_xrupt_info *gpe_xrupt_info; | ||
179 | struct acpi_gpe_xrupt_info *next_gpe_xrupt_info; | ||
180 | |||
181 | |||
182 | ACPI_FUNCTION_TRACE ("ut_terminate"); | ||
183 | |||
184 | |||
185 | /* Free global tables, etc. */ | ||
186 | |||
187 | |||
188 | /* Free global GPE blocks and related info structures */ | ||
189 | |||
190 | gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head; | ||
191 | while (gpe_xrupt_info) { | ||
192 | gpe_block = gpe_xrupt_info->gpe_block_list_head; | ||
193 | while (gpe_block) { | ||
194 | next_gpe_block = gpe_block->next; | ||
195 | ACPI_MEM_FREE (gpe_block->event_info); | ||
196 | ACPI_MEM_FREE (gpe_block->register_info); | ||
197 | ACPI_MEM_FREE (gpe_block); | ||
198 | |||
199 | gpe_block = next_gpe_block; | ||
200 | } | ||
201 | next_gpe_xrupt_info = gpe_xrupt_info->next; | ||
202 | ACPI_MEM_FREE (gpe_xrupt_info); | ||
203 | gpe_xrupt_info = next_gpe_xrupt_info; | ||
204 | } | ||
205 | |||
206 | return_VOID; | ||
207 | } | ||
208 | |||
209 | |||
210 | /******************************************************************************* | ||
211 | * | ||
212 | * FUNCTION: acpi_ut_subsystem_shutdown | ||
213 | * | ||
214 | * PARAMETERS: none | ||
215 | * | ||
216 | * RETURN: none | ||
217 | * | ||
218 | * DESCRIPTION: Shutdown the various subsystems. Don't delete the mutex | ||
219 | * objects here -- because the AML debugger may be still running. | ||
220 | * | ||
221 | ******************************************************************************/ | ||
222 | |||
223 | void | ||
224 | acpi_ut_subsystem_shutdown (void) | ||
225 | { | ||
226 | |||
227 | ACPI_FUNCTION_TRACE ("ut_subsystem_shutdown"); | ||
228 | |||
229 | /* Just exit if subsystem is already shutdown */ | ||
230 | |||
231 | if (acpi_gbl_shutdown) { | ||
232 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "ACPI Subsystem is already terminated\n")); | ||
233 | return_VOID; | ||
234 | } | ||
235 | |||
236 | /* Subsystem appears active, go ahead and shut it down */ | ||
237 | |||
238 | acpi_gbl_shutdown = TRUE; | ||
239 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Shutting down ACPI Subsystem...\n")); | ||
240 | |||
241 | /* Close the acpi_event Handling */ | ||
242 | |||
243 | acpi_ev_terminate (); | ||
244 | |||
245 | /* Close the Namespace */ | ||
246 | |||
247 | acpi_ns_terminate (); | ||
248 | |||
249 | /* Close the globals */ | ||
250 | |||
251 | acpi_ut_terminate (); | ||
252 | |||
253 | /* Purge the local caches */ | ||
254 | |||
255 | (void) acpi_purge_cached_objects (); | ||
256 | |||
257 | /* Debug only - display leftover memory allocation, if any */ | ||
258 | |||
259 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
260 | acpi_ut_dump_allocations (ACPI_UINT32_MAX, NULL); | ||
261 | #endif | ||
262 | |||
263 | return_VOID; | ||
264 | } | ||
265 | |||
266 | |||
diff --git a/drivers/acpi/utilities/utmath.c b/drivers/acpi/utilities/utmath.c new file mode 100644 index 000000000000..2525c1a93547 --- /dev/null +++ b/drivers/acpi/utilities/utmath.c | |||
@@ -0,0 +1,333 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: utmath - Integer math support routines | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
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 | |||
45 | #include <acpi/acpi.h> | ||
46 | |||
47 | |||
48 | #define _COMPONENT ACPI_UTILITIES | ||
49 | ACPI_MODULE_NAME ("utmath") | ||
50 | |||
51 | /* | ||
52 | * Support for double-precision integer divide. This code is included here | ||
53 | * in order to support kernel environments where the double-precision math | ||
54 | * library is not available. | ||
55 | */ | ||
56 | |||
57 | #ifndef ACPI_USE_NATIVE_DIVIDE | ||
58 | /******************************************************************************* | ||
59 | * | ||
60 | * FUNCTION: acpi_ut_short_divide | ||
61 | * | ||
62 | * PARAMETERS: Dividend - 64-bit dividend | ||
63 | * Divisor - 32-bit divisor | ||
64 | * out_quotient - Pointer to where the quotient is returned | ||
65 | * out_remainder - Pointer to where the remainder is returned | ||
66 | * | ||
67 | * RETURN: Status (Checks for divide-by-zero) | ||
68 | * | ||
69 | * DESCRIPTION: Perform a short (maximum 64 bits divided by 32 bits) | ||
70 | * divide and modulo. The result is a 64-bit quotient and a | ||
71 | * 32-bit remainder. | ||
72 | * | ||
73 | ******************************************************************************/ | ||
74 | |||
75 | acpi_status | ||
76 | acpi_ut_short_divide ( | ||
77 | acpi_integer dividend, | ||
78 | u32 divisor, | ||
79 | acpi_integer *out_quotient, | ||
80 | u32 *out_remainder) | ||
81 | { | ||
82 | union uint64_overlay dividend_ovl; | ||
83 | union uint64_overlay quotient; | ||
84 | u32 remainder32; | ||
85 | |||
86 | |||
87 | ACPI_FUNCTION_TRACE ("ut_short_divide"); | ||
88 | |||
89 | |||
90 | /* Always check for a zero divisor */ | ||
91 | |||
92 | if (divisor == 0) { | ||
93 | ACPI_REPORT_ERROR (("acpi_ut_short_divide: Divide by zero\n")); | ||
94 | return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO); | ||
95 | } | ||
96 | |||
97 | dividend_ovl.full = dividend; | ||
98 | |||
99 | /* | ||
100 | * The quotient is 64 bits, the remainder is always 32 bits, | ||
101 | * and is generated by the second divide. | ||
102 | */ | ||
103 | ACPI_DIV_64_BY_32 (0, dividend_ovl.part.hi, divisor, | ||
104 | quotient.part.hi, remainder32); | ||
105 | ACPI_DIV_64_BY_32 (remainder32, dividend_ovl.part.lo, divisor, | ||
106 | quotient.part.lo, remainder32); | ||
107 | |||
108 | /* Return only what was requested */ | ||
109 | |||
110 | if (out_quotient) { | ||
111 | *out_quotient = quotient.full; | ||
112 | } | ||
113 | if (out_remainder) { | ||
114 | *out_remainder = remainder32; | ||
115 | } | ||
116 | |||
117 | return_ACPI_STATUS (AE_OK); | ||
118 | } | ||
119 | |||
120 | |||
121 | /******************************************************************************* | ||
122 | * | ||
123 | * FUNCTION: acpi_ut_divide | ||
124 | * | ||
125 | * PARAMETERS: in_dividend - Dividend | ||
126 | * in_divisor - Divisor | ||
127 | * out_quotient - Pointer to where the quotient is returned | ||
128 | * out_remainder - Pointer to where the remainder is returned | ||
129 | * | ||
130 | * RETURN: Status (Checks for divide-by-zero) | ||
131 | * | ||
132 | * DESCRIPTION: Perform a divide and modulo. | ||
133 | * | ||
134 | ******************************************************************************/ | ||
135 | |||
136 | acpi_status | ||
137 | acpi_ut_divide ( | ||
138 | acpi_integer in_dividend, | ||
139 | acpi_integer in_divisor, | ||
140 | acpi_integer *out_quotient, | ||
141 | acpi_integer *out_remainder) | ||
142 | { | ||
143 | union uint64_overlay dividend; | ||
144 | union uint64_overlay divisor; | ||
145 | union uint64_overlay quotient; | ||
146 | union uint64_overlay remainder; | ||
147 | union uint64_overlay normalized_dividend; | ||
148 | union uint64_overlay normalized_divisor; | ||
149 | u32 partial1; | ||
150 | union uint64_overlay partial2; | ||
151 | union uint64_overlay partial3; | ||
152 | |||
153 | |||
154 | ACPI_FUNCTION_TRACE ("ut_divide"); | ||
155 | |||
156 | |||
157 | /* Always check for a zero divisor */ | ||
158 | |||
159 | if (in_divisor == 0) { | ||
160 | ACPI_REPORT_ERROR (("acpi_ut_divide: Divide by zero\n")); | ||
161 | return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO); | ||
162 | } | ||
163 | |||
164 | divisor.full = in_divisor; | ||
165 | dividend.full = in_dividend; | ||
166 | if (divisor.part.hi == 0) { | ||
167 | /* | ||
168 | * 1) Simplest case is where the divisor is 32 bits, we can | ||
169 | * just do two divides | ||
170 | */ | ||
171 | remainder.part.hi = 0; | ||
172 | |||
173 | /* | ||
174 | * The quotient is 64 bits, the remainder is always 32 bits, | ||
175 | * and is generated by the second divide. | ||
176 | */ | ||
177 | ACPI_DIV_64_BY_32 (0, dividend.part.hi, divisor.part.lo, | ||
178 | quotient.part.hi, partial1); | ||
179 | ACPI_DIV_64_BY_32 (partial1, dividend.part.lo, divisor.part.lo, | ||
180 | quotient.part.lo, remainder.part.lo); | ||
181 | } | ||
182 | |||
183 | else { | ||
184 | /* | ||
185 | * 2) The general case where the divisor is a full 64 bits | ||
186 | * is more difficult | ||
187 | */ | ||
188 | quotient.part.hi = 0; | ||
189 | normalized_dividend = dividend; | ||
190 | normalized_divisor = divisor; | ||
191 | |||
192 | /* Normalize the operands (shift until the divisor is < 32 bits) */ | ||
193 | |||
194 | do { | ||
195 | ACPI_SHIFT_RIGHT_64 (normalized_divisor.part.hi, | ||
196 | normalized_divisor.part.lo); | ||
197 | ACPI_SHIFT_RIGHT_64 (normalized_dividend.part.hi, | ||
198 | normalized_dividend.part.lo); | ||
199 | |||
200 | } while (normalized_divisor.part.hi != 0); | ||
201 | |||
202 | /* Partial divide */ | ||
203 | |||
204 | ACPI_DIV_64_BY_32 (normalized_dividend.part.hi, | ||
205 | normalized_dividend.part.lo, | ||
206 | normalized_divisor.part.lo, | ||
207 | quotient.part.lo, partial1); | ||
208 | |||
209 | /* | ||
210 | * The quotient is always 32 bits, and simply requires adjustment. | ||
211 | * The 64-bit remainder must be generated. | ||
212 | */ | ||
213 | partial1 = quotient.part.lo * divisor.part.hi; | ||
214 | partial2.full = (acpi_integer) quotient.part.lo * divisor.part.lo; | ||
215 | partial3.full = (acpi_integer) partial2.part.hi + partial1; | ||
216 | |||
217 | remainder.part.hi = partial3.part.lo; | ||
218 | remainder.part.lo = partial2.part.lo; | ||
219 | |||
220 | if (partial3.part.hi == 0) { | ||
221 | if (partial3.part.lo >= dividend.part.hi) { | ||
222 | if (partial3.part.lo == dividend.part.hi) { | ||
223 | if (partial2.part.lo > dividend.part.lo) { | ||
224 | quotient.part.lo--; | ||
225 | remainder.full -= divisor.full; | ||
226 | } | ||
227 | } | ||
228 | else { | ||
229 | quotient.part.lo--; | ||
230 | remainder.full -= divisor.full; | ||
231 | } | ||
232 | } | ||
233 | |||
234 | remainder.full = remainder.full - dividend.full; | ||
235 | remainder.part.hi = (u32) -((s32) remainder.part.hi); | ||
236 | remainder.part.lo = (u32) -((s32) remainder.part.lo); | ||
237 | |||
238 | if (remainder.part.lo) { | ||
239 | remainder.part.hi--; | ||
240 | } | ||
241 | } | ||
242 | } | ||
243 | |||
244 | /* Return only what was requested */ | ||
245 | |||
246 | if (out_quotient) { | ||
247 | *out_quotient = quotient.full; | ||
248 | } | ||
249 | if (out_remainder) { | ||
250 | *out_remainder = remainder.full; | ||
251 | } | ||
252 | |||
253 | return_ACPI_STATUS (AE_OK); | ||
254 | } | ||
255 | |||
256 | #else | ||
257 | |||
258 | /******************************************************************************* | ||
259 | * | ||
260 | * FUNCTION: acpi_ut_short_divide, acpi_ut_divide | ||
261 | * | ||
262 | * DESCRIPTION: Native versions of the ut_divide functions. Use these if either | ||
263 | * 1) The target is a 64-bit platform and therefore 64-bit | ||
264 | * integer math is supported directly by the machine. | ||
265 | * 2) The target is a 32-bit or 16-bit platform, and the | ||
266 | * double-precision integer math library is available to | ||
267 | * perform the divide. | ||
268 | * | ||
269 | ******************************************************************************/ | ||
270 | |||
271 | acpi_status | ||
272 | acpi_ut_short_divide ( | ||
273 | acpi_integer in_dividend, | ||
274 | u32 divisor, | ||
275 | acpi_integer *out_quotient, | ||
276 | u32 *out_remainder) | ||
277 | { | ||
278 | |||
279 | ACPI_FUNCTION_TRACE ("ut_short_divide"); | ||
280 | |||
281 | |||
282 | /* Always check for a zero divisor */ | ||
283 | |||
284 | if (divisor == 0) { | ||
285 | ACPI_REPORT_ERROR (("acpi_ut_short_divide: Divide by zero\n")); | ||
286 | return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO); | ||
287 | } | ||
288 | |||
289 | /* Return only what was requested */ | ||
290 | |||
291 | if (out_quotient) { | ||
292 | *out_quotient = in_dividend / divisor; | ||
293 | } | ||
294 | if (out_remainder) { | ||
295 | *out_remainder = (u32) in_dividend % divisor; | ||
296 | } | ||
297 | |||
298 | return_ACPI_STATUS (AE_OK); | ||
299 | } | ||
300 | |||
301 | acpi_status | ||
302 | acpi_ut_divide ( | ||
303 | acpi_integer in_dividend, | ||
304 | acpi_integer in_divisor, | ||
305 | acpi_integer *out_quotient, | ||
306 | acpi_integer *out_remainder) | ||
307 | { | ||
308 | ACPI_FUNCTION_TRACE ("ut_divide"); | ||
309 | |||
310 | |||
311 | /* Always check for a zero divisor */ | ||
312 | |||
313 | if (in_divisor == 0) { | ||
314 | ACPI_REPORT_ERROR (("acpi_ut_divide: Divide by zero\n")); | ||
315 | return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO); | ||
316 | } | ||
317 | |||
318 | |||
319 | /* Return only what was requested */ | ||
320 | |||
321 | if (out_quotient) { | ||
322 | *out_quotient = in_dividend / in_divisor; | ||
323 | } | ||
324 | if (out_remainder) { | ||
325 | *out_remainder = in_dividend % in_divisor; | ||
326 | } | ||
327 | |||
328 | return_ACPI_STATUS (AE_OK); | ||
329 | } | ||
330 | |||
331 | #endif | ||
332 | |||
333 | |||
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c new file mode 100644 index 000000000000..f6598547389b --- /dev/null +++ b/drivers/acpi/utilities/utmisc.c | |||
@@ -0,0 +1,1516 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: utmisc - common utility procedures | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
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 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/acnamesp.h> | ||
47 | |||
48 | |||
49 | #define _COMPONENT ACPI_UTILITIES | ||
50 | ACPI_MODULE_NAME ("utmisc") | ||
51 | |||
52 | |||
53 | /******************************************************************************* | ||
54 | * | ||
55 | * FUNCTION: acpi_ut_print_string | ||
56 | * | ||
57 | * PARAMETERS: String - Null terminated ASCII string | ||
58 | * | ||
59 | * RETURN: None | ||
60 | * | ||
61 | * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape | ||
62 | * sequences. | ||
63 | * | ||
64 | ******************************************************************************/ | ||
65 | |||
66 | void | ||
67 | acpi_ut_print_string ( | ||
68 | char *string, | ||
69 | u8 max_length) | ||
70 | { | ||
71 | u32 i; | ||
72 | |||
73 | |||
74 | if (!string) { | ||
75 | acpi_os_printf ("<\"NULL STRING PTR\">"); | ||
76 | return; | ||
77 | } | ||
78 | |||
79 | acpi_os_printf ("\""); | ||
80 | for (i = 0; string[i] && (i < max_length); i++) { | ||
81 | /* Escape sequences */ | ||
82 | |||
83 | switch (string[i]) { | ||
84 | case 0x07: | ||
85 | acpi_os_printf ("\\a"); /* BELL */ | ||
86 | break; | ||
87 | |||
88 | case 0x08: | ||
89 | acpi_os_printf ("\\b"); /* BACKSPACE */ | ||
90 | break; | ||
91 | |||
92 | case 0x0C: | ||
93 | acpi_os_printf ("\\f"); /* FORMFEED */ | ||
94 | break; | ||
95 | |||
96 | case 0x0A: | ||
97 | acpi_os_printf ("\\n"); /* LINEFEED */ | ||
98 | break; | ||
99 | |||
100 | case 0x0D: | ||
101 | acpi_os_printf ("\\r"); /* CARRIAGE RETURN*/ | ||
102 | break; | ||
103 | |||
104 | case 0x09: | ||
105 | acpi_os_printf ("\\t"); /* HORIZONTAL TAB */ | ||
106 | break; | ||
107 | |||
108 | case 0x0B: | ||
109 | acpi_os_printf ("\\v"); /* VERTICAL TAB */ | ||
110 | break; | ||
111 | |||
112 | case '\'': /* Single Quote */ | ||
113 | case '\"': /* Double Quote */ | ||
114 | case '\\': /* Backslash */ | ||
115 | acpi_os_printf ("\\%c", (int) string[i]); | ||
116 | break; | ||
117 | |||
118 | default: | ||
119 | |||
120 | /* Check for printable character or hex escape */ | ||
121 | |||
122 | if (ACPI_IS_PRINT (string[i])) | ||
123 | { | ||
124 | /* This is a normal character */ | ||
125 | |||
126 | acpi_os_printf ("%c", (int) string[i]); | ||
127 | } | ||
128 | else | ||
129 | { | ||
130 | /* All others will be Hex escapes */ | ||
131 | |||
132 | acpi_os_printf ("\\x%2.2X", (s32) string[i]); | ||
133 | } | ||
134 | break; | ||
135 | } | ||
136 | } | ||
137 | acpi_os_printf ("\""); | ||
138 | |||
139 | if (i == max_length && string[i]) { | ||
140 | acpi_os_printf ("..."); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | |||
145 | /******************************************************************************* | ||
146 | * | ||
147 | * FUNCTION: acpi_ut_dword_byte_swap | ||
148 | * | ||
149 | * PARAMETERS: Value - Value to be converted | ||
150 | * | ||
151 | * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes) | ||
152 | * | ||
153 | ******************************************************************************/ | ||
154 | |||
155 | u32 | ||
156 | acpi_ut_dword_byte_swap ( | ||
157 | u32 value) | ||
158 | { | ||
159 | union { | ||
160 | u32 value; | ||
161 | u8 bytes[4]; | ||
162 | } out; | ||
163 | |||
164 | union { | ||
165 | u32 value; | ||
166 | u8 bytes[4]; | ||
167 | } in; | ||
168 | |||
169 | |||
170 | ACPI_FUNCTION_ENTRY (); | ||
171 | |||
172 | |||
173 | in.value = value; | ||
174 | |||
175 | out.bytes[0] = in.bytes[3]; | ||
176 | out.bytes[1] = in.bytes[2]; | ||
177 | out.bytes[2] = in.bytes[1]; | ||
178 | out.bytes[3] = in.bytes[0]; | ||
179 | |||
180 | return (out.value); | ||
181 | } | ||
182 | |||
183 | |||
184 | /******************************************************************************* | ||
185 | * | ||
186 | * FUNCTION: acpi_ut_set_integer_width | ||
187 | * | ||
188 | * PARAMETERS: Revision From DSDT header | ||
189 | * | ||
190 | * RETURN: None | ||
191 | * | ||
192 | * DESCRIPTION: Set the global integer bit width based upon the revision | ||
193 | * of the DSDT. For Revision 1 and 0, Integers are 32 bits. | ||
194 | * For Revision 2 and above, Integers are 64 bits. Yes, this | ||
195 | * makes a difference. | ||
196 | * | ||
197 | ******************************************************************************/ | ||
198 | |||
199 | void | ||
200 | acpi_ut_set_integer_width ( | ||
201 | u8 revision) | ||
202 | { | ||
203 | |||
204 | if (revision <= 1) { | ||
205 | acpi_gbl_integer_bit_width = 32; | ||
206 | acpi_gbl_integer_nybble_width = 8; | ||
207 | acpi_gbl_integer_byte_width = 4; | ||
208 | } | ||
209 | else { | ||
210 | acpi_gbl_integer_bit_width = 64; | ||
211 | acpi_gbl_integer_nybble_width = 16; | ||
212 | acpi_gbl_integer_byte_width = 8; | ||
213 | } | ||
214 | } | ||
215 | |||
216 | |||
217 | #ifdef ACPI_DEBUG_OUTPUT | ||
218 | /******************************************************************************* | ||
219 | * | ||
220 | * FUNCTION: acpi_ut_display_init_pathname | ||
221 | * | ||
222 | * PARAMETERS: obj_handle - Handle whose pathname will be displayed | ||
223 | * Path - Additional path string to be appended. | ||
224 | * (NULL if no extra path) | ||
225 | * | ||
226 | * RETURN: acpi_status | ||
227 | * | ||
228 | * DESCRIPTION: Display full pathname of an object, DEBUG ONLY | ||
229 | * | ||
230 | ******************************************************************************/ | ||
231 | |||
232 | void | ||
233 | acpi_ut_display_init_pathname ( | ||
234 | u8 type, | ||
235 | struct acpi_namespace_node *obj_handle, | ||
236 | char *path) | ||
237 | { | ||
238 | acpi_status status; | ||
239 | struct acpi_buffer buffer; | ||
240 | |||
241 | |||
242 | ACPI_FUNCTION_ENTRY (); | ||
243 | |||
244 | |||
245 | /* Only print the path if the appropriate debug level is enabled */ | ||
246 | |||
247 | if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) { | ||
248 | return; | ||
249 | } | ||
250 | |||
251 | /* Get the full pathname to the node */ | ||
252 | |||
253 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | ||
254 | status = acpi_ns_handle_to_pathname (obj_handle, &buffer); | ||
255 | if (ACPI_FAILURE (status)) { | ||
256 | return; | ||
257 | } | ||
258 | |||
259 | /* Print what we're doing */ | ||
260 | |||
261 | switch (type) { | ||
262 | case ACPI_TYPE_METHOD: | ||
263 | acpi_os_printf ("Executing "); | ||
264 | break; | ||
265 | |||
266 | default: | ||
267 | acpi_os_printf ("Initializing "); | ||
268 | break; | ||
269 | } | ||
270 | |||
271 | /* Print the object type and pathname */ | ||
272 | |||
273 | acpi_os_printf ("%-12s %s", acpi_ut_get_type_name (type), (char *) buffer.pointer); | ||
274 | |||
275 | /* Extra path is used to append names like _STA, _INI, etc. */ | ||
276 | |||
277 | if (path) { | ||
278 | acpi_os_printf (".%s", path); | ||
279 | } | ||
280 | acpi_os_printf ("\n"); | ||
281 | |||
282 | ACPI_MEM_FREE (buffer.pointer); | ||
283 | } | ||
284 | #endif | ||
285 | |||
286 | |||
287 | /******************************************************************************* | ||
288 | * | ||
289 | * FUNCTION: acpi_ut_valid_acpi_name | ||
290 | * | ||
291 | * PARAMETERS: Character - The character to be examined | ||
292 | * | ||
293 | * RETURN: 1 if Character may appear in a name, else 0 | ||
294 | * | ||
295 | * DESCRIPTION: Check for a valid ACPI name. Each character must be one of: | ||
296 | * 1) Upper case alpha | ||
297 | * 2) numeric | ||
298 | * 3) underscore | ||
299 | * | ||
300 | ******************************************************************************/ | ||
301 | |||
302 | u8 | ||
303 | acpi_ut_valid_acpi_name ( | ||
304 | u32 name) | ||
305 | { | ||
306 | char *name_ptr = (char *) &name; | ||
307 | char character; | ||
308 | acpi_native_uint i; | ||
309 | |||
310 | |||
311 | ACPI_FUNCTION_ENTRY (); | ||
312 | |||
313 | |||
314 | for (i = 0; i < ACPI_NAME_SIZE; i++) { | ||
315 | character = *name_ptr; | ||
316 | name_ptr++; | ||
317 | |||
318 | if (!((character == '_') || | ||
319 | (character >= 'A' && character <= 'Z') || | ||
320 | (character >= '0' && character <= '9'))) { | ||
321 | return (FALSE); | ||
322 | } | ||
323 | } | ||
324 | |||
325 | return (TRUE); | ||
326 | } | ||
327 | |||
328 | |||
329 | /******************************************************************************* | ||
330 | * | ||
331 | * FUNCTION: acpi_ut_valid_acpi_character | ||
332 | * | ||
333 | * PARAMETERS: Character - The character to be examined | ||
334 | * | ||
335 | * RETURN: 1 if Character may appear in a name, else 0 | ||
336 | * | ||
337 | * DESCRIPTION: Check for a printable character | ||
338 | * | ||
339 | ******************************************************************************/ | ||
340 | |||
341 | u8 | ||
342 | acpi_ut_valid_acpi_character ( | ||
343 | char character) | ||
344 | { | ||
345 | |||
346 | ACPI_FUNCTION_ENTRY (); | ||
347 | |||
348 | return ((u8) ((character == '_') || | ||
349 | (character >= 'A' && character <= 'Z') || | ||
350 | (character >= '0' && character <= '9'))); | ||
351 | } | ||
352 | |||
353 | |||
354 | /******************************************************************************* | ||
355 | * | ||
356 | * FUNCTION: acpi_ut_strtoul64 | ||
357 | * | ||
358 | * PARAMETERS: String - Null terminated string | ||
359 | * Base - Radix of the string: 10, 16, or ACPI_ANY_BASE | ||
360 | * ret_integer - Where the converted integer is returned | ||
361 | * | ||
362 | * RETURN: Status and Converted value | ||
363 | * | ||
364 | * DESCRIPTION: Convert a string into an unsigned value. | ||
365 | * NOTE: Does not support Octal strings, not needed. | ||
366 | * | ||
367 | ******************************************************************************/ | ||
368 | |||
369 | acpi_status | ||
370 | acpi_ut_strtoul64 ( | ||
371 | char *string, | ||
372 | u32 base, | ||
373 | acpi_integer *ret_integer) | ||
374 | { | ||
375 | u32 this_digit = 0; | ||
376 | acpi_integer return_value = 0; | ||
377 | acpi_integer quotient; | ||
378 | |||
379 | |||
380 | ACPI_FUNCTION_TRACE ("ut_stroul64"); | ||
381 | |||
382 | |||
383 | if ((!string) || !(*string)) { | ||
384 | goto error_exit; | ||
385 | } | ||
386 | |||
387 | switch (base) { | ||
388 | case ACPI_ANY_BASE: | ||
389 | case 10: | ||
390 | case 16: | ||
391 | break; | ||
392 | |||
393 | default: | ||
394 | /* Invalid Base */ | ||
395 | return_ACPI_STATUS (AE_BAD_PARAMETER); | ||
396 | } | ||
397 | |||
398 | /* Skip over any white space in the buffer */ | ||
399 | |||
400 | while (ACPI_IS_SPACE (*string) || *string == '\t') { | ||
401 | string++; | ||
402 | } | ||
403 | |||
404 | /* | ||
405 | * If the input parameter Base is zero, then we need to | ||
406 | * determine if it is decimal or hexadecimal: | ||
407 | */ | ||
408 | if (base == 0) { | ||
409 | if ((*string == '0') && | ||
410 | (ACPI_TOLOWER (*(string + 1)) == 'x')) { | ||
411 | base = 16; | ||
412 | string += 2; | ||
413 | } | ||
414 | else { | ||
415 | base = 10; | ||
416 | } | ||
417 | } | ||
418 | |||
419 | /* | ||
420 | * For hexadecimal base, skip over the leading | ||
421 | * 0 or 0x, if they are present. | ||
422 | */ | ||
423 | if ((base == 16) && | ||
424 | (*string == '0') && | ||
425 | (ACPI_TOLOWER (*(string + 1)) == 'x')) { | ||
426 | string += 2; | ||
427 | } | ||
428 | |||
429 | /* Any string left? */ | ||
430 | |||
431 | if (!(*string)) { | ||
432 | goto error_exit; | ||
433 | } | ||
434 | |||
435 | /* Main loop: convert the string to a 64-bit integer */ | ||
436 | |||
437 | while (*string) { | ||
438 | if (ACPI_IS_DIGIT (*string)) { | ||
439 | /* Convert ASCII 0-9 to Decimal value */ | ||
440 | |||
441 | this_digit = ((u8) *string) - '0'; | ||
442 | } | ||
443 | else { | ||
444 | if (base == 10) { | ||
445 | /* Digit is out of range */ | ||
446 | |||
447 | goto error_exit; | ||
448 | } | ||
449 | |||
450 | this_digit = (u8) ACPI_TOUPPER (*string); | ||
451 | if (ACPI_IS_XDIGIT ((char) this_digit)) { | ||
452 | /* Convert ASCII Hex char to value */ | ||
453 | |||
454 | this_digit = this_digit - 'A' + 10; | ||
455 | } | ||
456 | else { | ||
457 | /* | ||
458 | * We allow non-hex chars, just stop now, same as end-of-string. | ||
459 | * See ACPI spec, string-to-integer conversion. | ||
460 | */ | ||
461 | break; | ||
462 | } | ||
463 | } | ||
464 | |||
465 | /* Divide the digit into the correct position */ | ||
466 | |||
467 | (void) acpi_ut_short_divide ((ACPI_INTEGER_MAX - (acpi_integer) this_digit), | ||
468 | base, "ient, NULL); | ||
469 | if (return_value > quotient) { | ||
470 | goto error_exit; | ||
471 | } | ||
472 | |||
473 | return_value *= base; | ||
474 | return_value += this_digit; | ||
475 | string++; | ||
476 | } | ||
477 | |||
478 | /* All done, normal exit */ | ||
479 | |||
480 | *ret_integer = return_value; | ||
481 | return_ACPI_STATUS (AE_OK); | ||
482 | |||
483 | |||
484 | error_exit: | ||
485 | /* Base was set/validated above */ | ||
486 | |||
487 | if (base == 10) { | ||
488 | return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT); | ||
489 | } | ||
490 | else { | ||
491 | return_ACPI_STATUS (AE_BAD_HEX_CONSTANT); | ||
492 | } | ||
493 | } | ||
494 | |||
495 | |||
496 | /******************************************************************************* | ||
497 | * | ||
498 | * FUNCTION: acpi_ut_strupr | ||
499 | * | ||
500 | * PARAMETERS: src_string - The source string to convert to | ||
501 | * | ||
502 | * RETURN: src_string | ||
503 | * | ||
504 | * DESCRIPTION: Convert string to uppercase | ||
505 | * | ||
506 | ******************************************************************************/ | ||
507 | #ifdef ACPI_FUTURE_USAGE | ||
508 | char * | ||
509 | acpi_ut_strupr ( | ||
510 | char *src_string) | ||
511 | { | ||
512 | char *string; | ||
513 | |||
514 | |||
515 | ACPI_FUNCTION_ENTRY (); | ||
516 | |||
517 | |||
518 | /* Walk entire string, uppercasing the letters */ | ||
519 | |||
520 | for (string = src_string; *string; ) { | ||
521 | *string = (char) ACPI_TOUPPER (*string); | ||
522 | string++; | ||
523 | } | ||
524 | |||
525 | return (src_string); | ||
526 | } | ||
527 | #endif /* ACPI_FUTURE_USAGE */ | ||
528 | |||
529 | |||
530 | /******************************************************************************* | ||
531 | * | ||
532 | * FUNCTION: acpi_ut_mutex_initialize | ||
533 | * | ||
534 | * PARAMETERS: None. | ||
535 | * | ||
536 | * RETURN: Status | ||
537 | * | ||
538 | * DESCRIPTION: Create the system mutex objects. | ||
539 | * | ||
540 | ******************************************************************************/ | ||
541 | |||
542 | acpi_status | ||
543 | acpi_ut_mutex_initialize ( | ||
544 | void) | ||
545 | { | ||
546 | u32 i; | ||
547 | acpi_status status; | ||
548 | |||
549 | |||
550 | ACPI_FUNCTION_TRACE ("ut_mutex_initialize"); | ||
551 | |||
552 | |||
553 | /* | ||
554 | * Create each of the predefined mutex objects | ||
555 | */ | ||
556 | for (i = 0; i < NUM_MUTEX; i++) { | ||
557 | status = acpi_ut_create_mutex (i); | ||
558 | if (ACPI_FAILURE (status)) { | ||
559 | return_ACPI_STATUS (status); | ||
560 | } | ||
561 | } | ||
562 | |||
563 | status = acpi_os_create_lock (&acpi_gbl_gpe_lock); | ||
564 | return_ACPI_STATUS (status); | ||
565 | } | ||
566 | |||
567 | |||
568 | /******************************************************************************* | ||
569 | * | ||
570 | * FUNCTION: acpi_ut_mutex_terminate | ||
571 | * | ||
572 | * PARAMETERS: None. | ||
573 | * | ||
574 | * RETURN: None. | ||
575 | * | ||
576 | * DESCRIPTION: Delete all of the system mutex objects. | ||
577 | * | ||
578 | ******************************************************************************/ | ||
579 | |||
580 | void | ||
581 | acpi_ut_mutex_terminate ( | ||
582 | void) | ||
583 | { | ||
584 | u32 i; | ||
585 | |||
586 | |||
587 | ACPI_FUNCTION_TRACE ("ut_mutex_terminate"); | ||
588 | |||
589 | |||
590 | /* | ||
591 | * Delete each predefined mutex object | ||
592 | */ | ||
593 | for (i = 0; i < NUM_MUTEX; i++) { | ||
594 | (void) acpi_ut_delete_mutex (i); | ||
595 | } | ||
596 | |||
597 | acpi_os_delete_lock (acpi_gbl_gpe_lock); | ||
598 | return_VOID; | ||
599 | } | ||
600 | |||
601 | |||
602 | /******************************************************************************* | ||
603 | * | ||
604 | * FUNCTION: acpi_ut_create_mutex | ||
605 | * | ||
606 | * PARAMETERS: mutex_iD - ID of the mutex to be created | ||
607 | * | ||
608 | * RETURN: Status | ||
609 | * | ||
610 | * DESCRIPTION: Create a mutex object. | ||
611 | * | ||
612 | ******************************************************************************/ | ||
613 | |||
614 | acpi_status | ||
615 | acpi_ut_create_mutex ( | ||
616 | acpi_mutex_handle mutex_id) | ||
617 | { | ||
618 | acpi_status status = AE_OK; | ||
619 | |||
620 | |||
621 | ACPI_FUNCTION_TRACE_U32 ("ut_create_mutex", mutex_id); | ||
622 | |||
623 | |||
624 | if (mutex_id > MAX_MUTEX) { | ||
625 | return_ACPI_STATUS (AE_BAD_PARAMETER); | ||
626 | } | ||
627 | |||
628 | if (!acpi_gbl_mutex_info[mutex_id].mutex) { | ||
629 | status = acpi_os_create_semaphore (1, 1, | ||
630 | &acpi_gbl_mutex_info[mutex_id].mutex); | ||
631 | acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; | ||
632 | acpi_gbl_mutex_info[mutex_id].use_count = 0; | ||
633 | } | ||
634 | |||
635 | return_ACPI_STATUS (status); | ||
636 | } | ||
637 | |||
638 | |||
639 | /******************************************************************************* | ||
640 | * | ||
641 | * FUNCTION: acpi_ut_delete_mutex | ||
642 | * | ||
643 | * PARAMETERS: mutex_iD - ID of the mutex to be deleted | ||
644 | * | ||
645 | * RETURN: Status | ||
646 | * | ||
647 | * DESCRIPTION: Delete a mutex object. | ||
648 | * | ||
649 | ******************************************************************************/ | ||
650 | |||
651 | acpi_status | ||
652 | acpi_ut_delete_mutex ( | ||
653 | acpi_mutex_handle mutex_id) | ||
654 | { | ||
655 | acpi_status status; | ||
656 | |||
657 | |||
658 | ACPI_FUNCTION_TRACE_U32 ("ut_delete_mutex", mutex_id); | ||
659 | |||
660 | |||
661 | if (mutex_id > MAX_MUTEX) { | ||
662 | return_ACPI_STATUS (AE_BAD_PARAMETER); | ||
663 | } | ||
664 | |||
665 | status = acpi_os_delete_semaphore (acpi_gbl_mutex_info[mutex_id].mutex); | ||
666 | |||
667 | acpi_gbl_mutex_info[mutex_id].mutex = NULL; | ||
668 | acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; | ||
669 | |||
670 | return_ACPI_STATUS (status); | ||
671 | } | ||
672 | |||
673 | |||
674 | /******************************************************************************* | ||
675 | * | ||
676 | * FUNCTION: acpi_ut_acquire_mutex | ||
677 | * | ||
678 | * PARAMETERS: mutex_iD - ID of the mutex to be acquired | ||
679 | * | ||
680 | * RETURN: Status | ||
681 | * | ||
682 | * DESCRIPTION: Acquire a mutex object. | ||
683 | * | ||
684 | ******************************************************************************/ | ||
685 | |||
686 | acpi_status | ||
687 | acpi_ut_acquire_mutex ( | ||
688 | acpi_mutex_handle mutex_id) | ||
689 | { | ||
690 | acpi_status status; | ||
691 | u32 this_thread_id; | ||
692 | |||
693 | |||
694 | ACPI_FUNCTION_NAME ("ut_acquire_mutex"); | ||
695 | |||
696 | |||
697 | if (mutex_id > MAX_MUTEX) { | ||
698 | return (AE_BAD_PARAMETER); | ||
699 | } | ||
700 | |||
701 | this_thread_id = acpi_os_get_thread_id (); | ||
702 | |||
703 | #ifdef ACPI_MUTEX_DEBUG | ||
704 | { | ||
705 | u32 i; | ||
706 | /* | ||
707 | * Mutex debug code, for internal debugging only. | ||
708 | * | ||
709 | * Deadlock prevention. Check if this thread owns any mutexes of value | ||
710 | * greater than or equal to this one. If so, the thread has violated | ||
711 | * the mutex ordering rule. This indicates a coding error somewhere in | ||
712 | * the ACPI subsystem code. | ||
713 | */ | ||
714 | for (i = mutex_id; i < MAX_MUTEX; i++) { | ||
715 | if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) { | ||
716 | if (i == mutex_id) { | ||
717 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
718 | "Mutex [%s] already acquired by this thread [%X]\n", | ||
719 | acpi_ut_get_mutex_name (mutex_id), this_thread_id)); | ||
720 | |||
721 | return (AE_ALREADY_ACQUIRED); | ||
722 | } | ||
723 | |||
724 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
725 | "Invalid acquire order: Thread %X owns [%s], wants [%s]\n", | ||
726 | this_thread_id, acpi_ut_get_mutex_name (i), | ||
727 | acpi_ut_get_mutex_name (mutex_id))); | ||
728 | |||
729 | return (AE_ACQUIRE_DEADLOCK); | ||
730 | } | ||
731 | } | ||
732 | } | ||
733 | #endif | ||
734 | |||
735 | ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, | ||
736 | "Thread %X attempting to acquire Mutex [%s]\n", | ||
737 | this_thread_id, acpi_ut_get_mutex_name (mutex_id))); | ||
738 | |||
739 | status = acpi_os_wait_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, | ||
740 | 1, ACPI_WAIT_FOREVER); | ||
741 | if (ACPI_SUCCESS (status)) { | ||
742 | ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X acquired Mutex [%s]\n", | ||
743 | this_thread_id, acpi_ut_get_mutex_name (mutex_id))); | ||
744 | |||
745 | acpi_gbl_mutex_info[mutex_id].use_count++; | ||
746 | acpi_gbl_mutex_info[mutex_id].owner_id = this_thread_id; | ||
747 | } | ||
748 | else { | ||
749 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not acquire Mutex [%s] %s\n", | ||
750 | this_thread_id, acpi_ut_get_mutex_name (mutex_id), | ||
751 | acpi_format_exception (status))); | ||
752 | } | ||
753 | |||
754 | return (status); | ||
755 | } | ||
756 | |||
757 | |||
758 | /******************************************************************************* | ||
759 | * | ||
760 | * FUNCTION: acpi_ut_release_mutex | ||
761 | * | ||
762 | * PARAMETERS: mutex_iD - ID of the mutex to be released | ||
763 | * | ||
764 | * RETURN: Status | ||
765 | * | ||
766 | * DESCRIPTION: Release a mutex object. | ||
767 | * | ||
768 | ******************************************************************************/ | ||
769 | |||
770 | acpi_status | ||
771 | acpi_ut_release_mutex ( | ||
772 | acpi_mutex_handle mutex_id) | ||
773 | { | ||
774 | acpi_status status; | ||
775 | u32 i; | ||
776 | u32 this_thread_id; | ||
777 | |||
778 | |||
779 | ACPI_FUNCTION_NAME ("ut_release_mutex"); | ||
780 | |||
781 | |||
782 | this_thread_id = acpi_os_get_thread_id (); | ||
783 | ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, | ||
784 | "Thread %X releasing Mutex [%s]\n", this_thread_id, | ||
785 | acpi_ut_get_mutex_name (mutex_id))); | ||
786 | |||
787 | if (mutex_id > MAX_MUTEX) { | ||
788 | return (AE_BAD_PARAMETER); | ||
789 | } | ||
790 | |||
791 | /* | ||
792 | * Mutex must be acquired in order to release it! | ||
793 | */ | ||
794 | if (acpi_gbl_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) { | ||
795 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
796 | "Mutex [%s] is not acquired, cannot release\n", | ||
797 | acpi_ut_get_mutex_name (mutex_id))); | ||
798 | |||
799 | return (AE_NOT_ACQUIRED); | ||
800 | } | ||
801 | |||
802 | /* | ||
803 | * Deadlock prevention. Check if this thread owns any mutexes of value | ||
804 | * greater than this one. If so, the thread has violated the mutex | ||
805 | * ordering rule. This indicates a coding error somewhere in | ||
806 | * the ACPI subsystem code. | ||
807 | */ | ||
808 | for (i = mutex_id; i < MAX_MUTEX; i++) { | ||
809 | if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) { | ||
810 | if (i == mutex_id) { | ||
811 | continue; | ||
812 | } | ||
813 | |||
814 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
815 | "Invalid release order: owns [%s], releasing [%s]\n", | ||
816 | acpi_ut_get_mutex_name (i), acpi_ut_get_mutex_name (mutex_id))); | ||
817 | |||
818 | return (AE_RELEASE_DEADLOCK); | ||
819 | } | ||
820 | } | ||
821 | |||
822 | /* Mark unlocked FIRST */ | ||
823 | |||
824 | acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; | ||
825 | |||
826 | status = acpi_os_signal_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, 1); | ||
827 | |||
828 | if (ACPI_FAILURE (status)) { | ||
829 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not release Mutex [%s] %s\n", | ||
830 | this_thread_id, acpi_ut_get_mutex_name (mutex_id), | ||
831 | acpi_format_exception (status))); | ||
832 | } | ||
833 | else { | ||
834 | ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X released Mutex [%s]\n", | ||
835 | this_thread_id, acpi_ut_get_mutex_name (mutex_id))); | ||
836 | } | ||
837 | |||
838 | return (status); | ||
839 | } | ||
840 | |||
841 | |||
842 | /******************************************************************************* | ||
843 | * | ||
844 | * FUNCTION: acpi_ut_create_update_state_and_push | ||
845 | * | ||
846 | * PARAMETERS: *Object - Object to be added to the new state | ||
847 | * Action - Increment/Decrement | ||
848 | * state_list - List the state will be added to | ||
849 | * | ||
850 | * RETURN: None | ||
851 | * | ||
852 | * DESCRIPTION: Create a new state and push it | ||
853 | * | ||
854 | ******************************************************************************/ | ||
855 | |||
856 | acpi_status | ||
857 | acpi_ut_create_update_state_and_push ( | ||
858 | union acpi_operand_object *object, | ||
859 | u16 action, | ||
860 | union acpi_generic_state **state_list) | ||
861 | { | ||
862 | union acpi_generic_state *state; | ||
863 | |||
864 | |||
865 | ACPI_FUNCTION_ENTRY (); | ||
866 | |||
867 | |||
868 | /* Ignore null objects; these are expected */ | ||
869 | |||
870 | if (!object) { | ||
871 | return (AE_OK); | ||
872 | } | ||
873 | |||
874 | state = acpi_ut_create_update_state (object, action); | ||
875 | if (!state) { | ||
876 | return (AE_NO_MEMORY); | ||
877 | } | ||
878 | |||
879 | acpi_ut_push_generic_state (state_list, state); | ||
880 | return (AE_OK); | ||
881 | } | ||
882 | |||
883 | |||
884 | /******************************************************************************* | ||
885 | * | ||
886 | * FUNCTION: acpi_ut_create_pkg_state_and_push | ||
887 | * | ||
888 | * PARAMETERS: *Object - Object to be added to the new state | ||
889 | * Action - Increment/Decrement | ||
890 | * state_list - List the state will be added to | ||
891 | * | ||
892 | * RETURN: None | ||
893 | * | ||
894 | * DESCRIPTION: Create a new state and push it | ||
895 | * | ||
896 | ******************************************************************************/ | ||
897 | #ifdef ACPI_FUTURE_USAGE | ||
898 | acpi_status | ||
899 | acpi_ut_create_pkg_state_and_push ( | ||
900 | void *internal_object, | ||
901 | void *external_object, | ||
902 | u16 index, | ||
903 | union acpi_generic_state **state_list) | ||
904 | { | ||
905 | union acpi_generic_state *state; | ||
906 | |||
907 | |||
908 | ACPI_FUNCTION_ENTRY (); | ||
909 | |||
910 | |||
911 | state = acpi_ut_create_pkg_state (internal_object, external_object, index); | ||
912 | if (!state) { | ||
913 | return (AE_NO_MEMORY); | ||
914 | } | ||
915 | |||
916 | acpi_ut_push_generic_state (state_list, state); | ||
917 | return (AE_OK); | ||
918 | } | ||
919 | #endif /* ACPI_FUTURE_USAGE */ | ||
920 | |||
921 | /******************************************************************************* | ||
922 | * | ||
923 | * FUNCTION: acpi_ut_push_generic_state | ||
924 | * | ||
925 | * PARAMETERS: list_head - Head of the state stack | ||
926 | * State - State object to push | ||
927 | * | ||
928 | * RETURN: Status | ||
929 | * | ||
930 | * DESCRIPTION: Push a state object onto a state stack | ||
931 | * | ||
932 | ******************************************************************************/ | ||
933 | |||
934 | void | ||
935 | acpi_ut_push_generic_state ( | ||
936 | union acpi_generic_state **list_head, | ||
937 | union acpi_generic_state *state) | ||
938 | { | ||
939 | ACPI_FUNCTION_TRACE ("ut_push_generic_state"); | ||
940 | |||
941 | |||
942 | /* Push the state object onto the front of the list (stack) */ | ||
943 | |||
944 | state->common.next = *list_head; | ||
945 | *list_head = state; | ||
946 | |||
947 | return_VOID; | ||
948 | } | ||
949 | |||
950 | |||
951 | /******************************************************************************* | ||
952 | * | ||
953 | * FUNCTION: acpi_ut_pop_generic_state | ||
954 | * | ||
955 | * PARAMETERS: list_head - Head of the state stack | ||
956 | * | ||
957 | * RETURN: Status | ||
958 | * | ||
959 | * DESCRIPTION: Pop a state object from a state stack | ||
960 | * | ||
961 | ******************************************************************************/ | ||
962 | |||
963 | union acpi_generic_state * | ||
964 | acpi_ut_pop_generic_state ( | ||
965 | union acpi_generic_state **list_head) | ||
966 | { | ||
967 | union acpi_generic_state *state; | ||
968 | |||
969 | |||
970 | ACPI_FUNCTION_TRACE ("ut_pop_generic_state"); | ||
971 | |||
972 | |||
973 | /* Remove the state object at the head of the list (stack) */ | ||
974 | |||
975 | state = *list_head; | ||
976 | if (state) { | ||
977 | /* Update the list head */ | ||
978 | |||
979 | *list_head = state->common.next; | ||
980 | } | ||
981 | |||
982 | return_PTR (state); | ||
983 | } | ||
984 | |||
985 | |||
986 | /******************************************************************************* | ||
987 | * | ||
988 | * FUNCTION: acpi_ut_create_generic_state | ||
989 | * | ||
990 | * PARAMETERS: None | ||
991 | * | ||
992 | * RETURN: Status | ||
993 | * | ||
994 | * DESCRIPTION: Create a generic state object. Attempt to obtain one from | ||
995 | * the global state cache; If none available, create a new one. | ||
996 | * | ||
997 | ******************************************************************************/ | ||
998 | |||
999 | union acpi_generic_state * | ||
1000 | acpi_ut_create_generic_state (void) | ||
1001 | { | ||
1002 | union acpi_generic_state *state; | ||
1003 | |||
1004 | |||
1005 | ACPI_FUNCTION_ENTRY (); | ||
1006 | |||
1007 | |||
1008 | state = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_STATE); | ||
1009 | |||
1010 | /* Initialize */ | ||
1011 | |||
1012 | if (state) { | ||
1013 | state->common.data_type = ACPI_DESC_TYPE_STATE; | ||
1014 | } | ||
1015 | |||
1016 | return (state); | ||
1017 | } | ||
1018 | |||
1019 | |||
1020 | /******************************************************************************* | ||
1021 | * | ||
1022 | * FUNCTION: acpi_ut_create_thread_state | ||
1023 | * | ||
1024 | * PARAMETERS: None | ||
1025 | * | ||
1026 | * RETURN: Thread State | ||
1027 | * | ||
1028 | * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used | ||
1029 | * to track per-thread info during method execution | ||
1030 | * | ||
1031 | ******************************************************************************/ | ||
1032 | |||
1033 | struct acpi_thread_state * | ||
1034 | acpi_ut_create_thread_state ( | ||
1035 | void) | ||
1036 | { | ||
1037 | union acpi_generic_state *state; | ||
1038 | |||
1039 | |||
1040 | ACPI_FUNCTION_TRACE ("ut_create_thread_state"); | ||
1041 | |||
1042 | |||
1043 | /* Create the generic state object */ | ||
1044 | |||
1045 | state = acpi_ut_create_generic_state (); | ||
1046 | if (!state) { | ||
1047 | return_PTR (NULL); | ||
1048 | } | ||
1049 | |||
1050 | /* Init fields specific to the update struct */ | ||
1051 | |||
1052 | state->common.data_type = ACPI_DESC_TYPE_STATE_THREAD; | ||
1053 | state->thread.thread_id = acpi_os_get_thread_id (); | ||
1054 | |||
1055 | return_PTR ((struct acpi_thread_state *) state); | ||
1056 | } | ||
1057 | |||
1058 | |||
1059 | /******************************************************************************* | ||
1060 | * | ||
1061 | * FUNCTION: acpi_ut_create_update_state | ||
1062 | * | ||
1063 | * PARAMETERS: Object - Initial Object to be installed in the | ||
1064 | * state | ||
1065 | * Action - Update action to be performed | ||
1066 | * | ||
1067 | * RETURN: Status | ||
1068 | * | ||
1069 | * DESCRIPTION: Create an "Update State" - a flavor of the generic state used | ||
1070 | * to update reference counts and delete complex objects such | ||
1071 | * as packages. | ||
1072 | * | ||
1073 | ******************************************************************************/ | ||
1074 | |||
1075 | union acpi_generic_state * | ||
1076 | acpi_ut_create_update_state ( | ||
1077 | union acpi_operand_object *object, | ||
1078 | u16 action) | ||
1079 | { | ||
1080 | union acpi_generic_state *state; | ||
1081 | |||
1082 | |||
1083 | ACPI_FUNCTION_TRACE_PTR ("ut_create_update_state", object); | ||
1084 | |||
1085 | |||
1086 | /* Create the generic state object */ | ||
1087 | |||
1088 | state = acpi_ut_create_generic_state (); | ||
1089 | if (!state) { | ||
1090 | return_PTR (NULL); | ||
1091 | } | ||
1092 | |||
1093 | /* Init fields specific to the update struct */ | ||
1094 | |||
1095 | state->common.data_type = ACPI_DESC_TYPE_STATE_UPDATE; | ||
1096 | state->update.object = object; | ||
1097 | state->update.value = action; | ||
1098 | |||
1099 | return_PTR (state); | ||
1100 | } | ||
1101 | |||
1102 | |||
1103 | /******************************************************************************* | ||
1104 | * | ||
1105 | * FUNCTION: acpi_ut_create_pkg_state | ||
1106 | * | ||
1107 | * PARAMETERS: Object - Initial Object to be installed in the | ||
1108 | * state | ||
1109 | * Action - Update action to be performed | ||
1110 | * | ||
1111 | * RETURN: Status | ||
1112 | * | ||
1113 | * DESCRIPTION: Create a "Package State" | ||
1114 | * | ||
1115 | ******************************************************************************/ | ||
1116 | |||
1117 | union acpi_generic_state * | ||
1118 | acpi_ut_create_pkg_state ( | ||
1119 | void *internal_object, | ||
1120 | void *external_object, | ||
1121 | u16 index) | ||
1122 | { | ||
1123 | union acpi_generic_state *state; | ||
1124 | |||
1125 | |||
1126 | ACPI_FUNCTION_TRACE_PTR ("ut_create_pkg_state", internal_object); | ||
1127 | |||
1128 | |||
1129 | /* Create the generic state object */ | ||
1130 | |||
1131 | state = acpi_ut_create_generic_state (); | ||
1132 | if (!state) { | ||
1133 | return_PTR (NULL); | ||
1134 | } | ||
1135 | |||
1136 | /* Init fields specific to the update struct */ | ||
1137 | |||
1138 | state->common.data_type = ACPI_DESC_TYPE_STATE_PACKAGE; | ||
1139 | state->pkg.source_object = (union acpi_operand_object *) internal_object; | ||
1140 | state->pkg.dest_object = external_object; | ||
1141 | state->pkg.index = index; | ||
1142 | state->pkg.num_packages = 1; | ||
1143 | |||
1144 | return_PTR (state); | ||
1145 | } | ||
1146 | |||
1147 | |||
1148 | /******************************************************************************* | ||
1149 | * | ||
1150 | * FUNCTION: acpi_ut_create_control_state | ||
1151 | * | ||
1152 | * PARAMETERS: None | ||
1153 | * | ||
1154 | * RETURN: Status | ||
1155 | * | ||
1156 | * DESCRIPTION: Create a "Control State" - a flavor of the generic state used | ||
1157 | * to support nested IF/WHILE constructs in the AML. | ||
1158 | * | ||
1159 | ******************************************************************************/ | ||
1160 | |||
1161 | union acpi_generic_state * | ||
1162 | acpi_ut_create_control_state ( | ||
1163 | void) | ||
1164 | { | ||
1165 | union acpi_generic_state *state; | ||
1166 | |||
1167 | |||
1168 | ACPI_FUNCTION_TRACE ("ut_create_control_state"); | ||
1169 | |||
1170 | |||
1171 | /* Create the generic state object */ | ||
1172 | |||
1173 | state = acpi_ut_create_generic_state (); | ||
1174 | if (!state) { | ||
1175 | return_PTR (NULL); | ||
1176 | } | ||
1177 | |||
1178 | /* Init fields specific to the control struct */ | ||
1179 | |||
1180 | state->common.data_type = ACPI_DESC_TYPE_STATE_CONTROL; | ||
1181 | state->common.state = ACPI_CONTROL_CONDITIONAL_EXECUTING; | ||
1182 | |||
1183 | return_PTR (state); | ||
1184 | } | ||
1185 | |||
1186 | |||
1187 | /******************************************************************************* | ||
1188 | * | ||
1189 | * FUNCTION: acpi_ut_delete_generic_state | ||
1190 | * | ||
1191 | * PARAMETERS: State - The state object to be deleted | ||
1192 | * | ||
1193 | * RETURN: Status | ||
1194 | * | ||
1195 | * DESCRIPTION: Put a state object back into the global state cache. The object | ||
1196 | * is not actually freed at this time. | ||
1197 | * | ||
1198 | ******************************************************************************/ | ||
1199 | |||
1200 | void | ||
1201 | acpi_ut_delete_generic_state ( | ||
1202 | union acpi_generic_state *state) | ||
1203 | { | ||
1204 | ACPI_FUNCTION_TRACE ("ut_delete_generic_state"); | ||
1205 | |||
1206 | |||
1207 | acpi_ut_release_to_cache (ACPI_MEM_LIST_STATE, state); | ||
1208 | return_VOID; | ||
1209 | } | ||
1210 | |||
1211 | |||
1212 | #ifdef ACPI_ENABLE_OBJECT_CACHE | ||
1213 | /******************************************************************************* | ||
1214 | * | ||
1215 | * FUNCTION: acpi_ut_delete_generic_state_cache | ||
1216 | * | ||
1217 | * PARAMETERS: None | ||
1218 | * | ||
1219 | * RETURN: Status | ||
1220 | * | ||
1221 | * DESCRIPTION: Purge the global state object cache. Used during subsystem | ||
1222 | * termination. | ||
1223 | * | ||
1224 | ******************************************************************************/ | ||
1225 | |||
1226 | void | ||
1227 | acpi_ut_delete_generic_state_cache ( | ||
1228 | void) | ||
1229 | { | ||
1230 | ACPI_FUNCTION_TRACE ("ut_delete_generic_state_cache"); | ||
1231 | |||
1232 | |||
1233 | acpi_ut_delete_generic_cache (ACPI_MEM_LIST_STATE); | ||
1234 | return_VOID; | ||
1235 | } | ||
1236 | #endif | ||
1237 | |||
1238 | |||
1239 | /******************************************************************************* | ||
1240 | * | ||
1241 | * FUNCTION: acpi_ut_walk_package_tree | ||
1242 | * | ||
1243 | * PARAMETERS: obj_desc - The Package object on which to resolve refs | ||
1244 | * | ||
1245 | * RETURN: Status | ||
1246 | * | ||
1247 | * DESCRIPTION: Walk through a package | ||
1248 | * | ||
1249 | ******************************************************************************/ | ||
1250 | |||
1251 | acpi_status | ||
1252 | acpi_ut_walk_package_tree ( | ||
1253 | union acpi_operand_object *source_object, | ||
1254 | void *target_object, | ||
1255 | acpi_pkg_callback walk_callback, | ||
1256 | void *context) | ||
1257 | { | ||
1258 | acpi_status status = AE_OK; | ||
1259 | union acpi_generic_state *state_list = NULL; | ||
1260 | union acpi_generic_state *state; | ||
1261 | u32 this_index; | ||
1262 | union acpi_operand_object *this_source_obj; | ||
1263 | |||
1264 | |||
1265 | ACPI_FUNCTION_TRACE ("ut_walk_package_tree"); | ||
1266 | |||
1267 | |||
1268 | state = acpi_ut_create_pkg_state (source_object, target_object, 0); | ||
1269 | if (!state) { | ||
1270 | return_ACPI_STATUS (AE_NO_MEMORY); | ||
1271 | } | ||
1272 | |||
1273 | while (state) { | ||
1274 | /* Get one element of the package */ | ||
1275 | |||
1276 | this_index = state->pkg.index; | ||
1277 | this_source_obj = (union acpi_operand_object *) | ||
1278 | state->pkg.source_object->package.elements[this_index]; | ||
1279 | |||
1280 | /* | ||
1281 | * Check for: | ||
1282 | * 1) An uninitialized package element. It is completely | ||
1283 | * legal to declare a package and leave it uninitialized | ||
1284 | * 2) Not an internal object - can be a namespace node instead | ||
1285 | * 3) Any type other than a package. Packages are handled in else | ||
1286 | * case below. | ||
1287 | */ | ||
1288 | if ((!this_source_obj) || | ||
1289 | (ACPI_GET_DESCRIPTOR_TYPE (this_source_obj) != ACPI_DESC_TYPE_OPERAND) || | ||
1290 | (ACPI_GET_OBJECT_TYPE (this_source_obj) != ACPI_TYPE_PACKAGE)) { | ||
1291 | status = walk_callback (ACPI_COPY_TYPE_SIMPLE, this_source_obj, | ||
1292 | state, context); | ||
1293 | if (ACPI_FAILURE (status)) { | ||
1294 | return_ACPI_STATUS (status); | ||
1295 | } | ||
1296 | |||
1297 | state->pkg.index++; | ||
1298 | while (state->pkg.index >= state->pkg.source_object->package.count) { | ||
1299 | /* | ||
1300 | * We've handled all of the objects at this level, This means | ||
1301 | * that we have just completed a package. That package may | ||
1302 | * have contained one or more packages itself. | ||
1303 | * | ||
1304 | * Delete this state and pop the previous state (package). | ||
1305 | */ | ||
1306 | acpi_ut_delete_generic_state (state); | ||
1307 | state = acpi_ut_pop_generic_state (&state_list); | ||
1308 | |||
1309 | /* Finished when there are no more states */ | ||
1310 | |||
1311 | if (!state) { | ||
1312 | /* | ||
1313 | * We have handled all of the objects in the top level | ||
1314 | * package just add the length of the package objects | ||
1315 | * and exit | ||
1316 | */ | ||
1317 | return_ACPI_STATUS (AE_OK); | ||
1318 | } | ||
1319 | |||
1320 | /* | ||
1321 | * Go back up a level and move the index past the just | ||
1322 | * completed package object. | ||
1323 | */ | ||
1324 | state->pkg.index++; | ||
1325 | } | ||
1326 | } | ||
1327 | else { | ||
1328 | /* This is a subobject of type package */ | ||
1329 | |||
1330 | status = walk_callback (ACPI_COPY_TYPE_PACKAGE, this_source_obj, | ||
1331 | state, context); | ||
1332 | if (ACPI_FAILURE (status)) { | ||
1333 | return_ACPI_STATUS (status); | ||
1334 | } | ||
1335 | |||
1336 | /* | ||
1337 | * Push the current state and create a new one | ||
1338 | * The callback above returned a new target package object. | ||
1339 | */ | ||
1340 | acpi_ut_push_generic_state (&state_list, state); | ||
1341 | state = acpi_ut_create_pkg_state (this_source_obj, | ||
1342 | state->pkg.this_target_obj, 0); | ||
1343 | if (!state) { | ||
1344 | return_ACPI_STATUS (AE_NO_MEMORY); | ||
1345 | } | ||
1346 | } | ||
1347 | } | ||
1348 | |||
1349 | /* We should never get here */ | ||
1350 | |||
1351 | return_ACPI_STATUS (AE_AML_INTERNAL); | ||
1352 | } | ||
1353 | |||
1354 | |||
1355 | /******************************************************************************* | ||
1356 | * | ||
1357 | * FUNCTION: acpi_ut_generate_checksum | ||
1358 | * | ||
1359 | * PARAMETERS: Buffer - Buffer to be scanned | ||
1360 | * Length - number of bytes to examine | ||
1361 | * | ||
1362 | * RETURN: checksum | ||
1363 | * | ||
1364 | * DESCRIPTION: Generate a checksum on a raw buffer | ||
1365 | * | ||
1366 | ******************************************************************************/ | ||
1367 | |||
1368 | u8 | ||
1369 | acpi_ut_generate_checksum ( | ||
1370 | u8 *buffer, | ||
1371 | u32 length) | ||
1372 | { | ||
1373 | u32 i; | ||
1374 | signed char sum = 0; | ||
1375 | |||
1376 | |||
1377 | for (i = 0; i < length; i++) { | ||
1378 | sum = (signed char) (sum + buffer[i]); | ||
1379 | } | ||
1380 | |||
1381 | return ((u8) (0 - sum)); | ||
1382 | } | ||
1383 | |||
1384 | |||
1385 | /******************************************************************************* | ||
1386 | * | ||
1387 | * FUNCTION: acpi_ut_get_resource_end_tag | ||
1388 | * | ||
1389 | * PARAMETERS: obj_desc - The resource template buffer object | ||
1390 | * | ||
1391 | * RETURN: Pointer to the end tag | ||
1392 | * | ||
1393 | * DESCRIPTION: Find the END_TAG resource descriptor in a resource template | ||
1394 | * | ||
1395 | ******************************************************************************/ | ||
1396 | |||
1397 | |||
1398 | u8 * | ||
1399 | acpi_ut_get_resource_end_tag ( | ||
1400 | union acpi_operand_object *obj_desc) | ||
1401 | { | ||
1402 | u8 buffer_byte; | ||
1403 | u8 *buffer; | ||
1404 | u8 *end_buffer; | ||
1405 | |||
1406 | |||
1407 | buffer = obj_desc->buffer.pointer; | ||
1408 | end_buffer = buffer + obj_desc->buffer.length; | ||
1409 | |||
1410 | while (buffer < end_buffer) { | ||
1411 | buffer_byte = *buffer; | ||
1412 | if (buffer_byte & ACPI_RDESC_TYPE_MASK) { | ||
1413 | /* Large Descriptor - Length is next 2 bytes */ | ||
1414 | |||
1415 | buffer += ((*(buffer+1) | (*(buffer+2) << 8)) + 3); | ||
1416 | } | ||
1417 | else { | ||
1418 | /* Small Descriptor. End Tag will be found here */ | ||
1419 | |||
1420 | if ((buffer_byte & ACPI_RDESC_SMALL_MASK) == ACPI_RDESC_TYPE_END_TAG) { | ||
1421 | /* Found the end tag descriptor, all done. */ | ||
1422 | |||
1423 | return (buffer); | ||
1424 | } | ||
1425 | |||
1426 | /* Length is in the header */ | ||
1427 | |||
1428 | buffer += ((buffer_byte & 0x07) + 1); | ||
1429 | } | ||
1430 | } | ||
1431 | |||
1432 | /* End tag not found */ | ||
1433 | |||
1434 | return (NULL); | ||
1435 | } | ||
1436 | |||
1437 | |||
1438 | /******************************************************************************* | ||
1439 | * | ||
1440 | * FUNCTION: acpi_ut_report_error | ||
1441 | * | ||
1442 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
1443 | * line_number - Caller's line number (for error output) | ||
1444 | * component_id - Caller's component ID (for error output) | ||
1445 | * Message - Error message to use on failure | ||
1446 | * | ||
1447 | * RETURN: None | ||
1448 | * | ||
1449 | * DESCRIPTION: Print error message | ||
1450 | * | ||
1451 | ******************************************************************************/ | ||
1452 | |||
1453 | void | ||
1454 | acpi_ut_report_error ( | ||
1455 | char *module_name, | ||
1456 | u32 line_number, | ||
1457 | u32 component_id) | ||
1458 | { | ||
1459 | |||
1460 | |||
1461 | acpi_os_printf ("%8s-%04d: *** Error: ", module_name, line_number); | ||
1462 | } | ||
1463 | |||
1464 | |||
1465 | /******************************************************************************* | ||
1466 | * | ||
1467 | * FUNCTION: acpi_ut_report_warning | ||
1468 | * | ||
1469 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
1470 | * line_number - Caller's line number (for error output) | ||
1471 | * component_id - Caller's component ID (for error output) | ||
1472 | * Message - Error message to use on failure | ||
1473 | * | ||
1474 | * RETURN: None | ||
1475 | * | ||
1476 | * DESCRIPTION: Print warning message | ||
1477 | * | ||
1478 | ******************************************************************************/ | ||
1479 | |||
1480 | void | ||
1481 | acpi_ut_report_warning ( | ||
1482 | char *module_name, | ||
1483 | u32 line_number, | ||
1484 | u32 component_id) | ||
1485 | { | ||
1486 | |||
1487 | acpi_os_printf ("%8s-%04d: *** Warning: ", module_name, line_number); | ||
1488 | } | ||
1489 | |||
1490 | |||
1491 | /******************************************************************************* | ||
1492 | * | ||
1493 | * FUNCTION: acpi_ut_report_info | ||
1494 | * | ||
1495 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
1496 | * line_number - Caller's line number (for error output) | ||
1497 | * component_id - Caller's component ID (for error output) | ||
1498 | * Message - Error message to use on failure | ||
1499 | * | ||
1500 | * RETURN: None | ||
1501 | * | ||
1502 | * DESCRIPTION: Print information message | ||
1503 | * | ||
1504 | ******************************************************************************/ | ||
1505 | |||
1506 | void | ||
1507 | acpi_ut_report_info ( | ||
1508 | char *module_name, | ||
1509 | u32 line_number, | ||
1510 | u32 component_id) | ||
1511 | { | ||
1512 | |||
1513 | acpi_os_printf ("%8s-%04d: *** Info: ", module_name, line_number); | ||
1514 | } | ||
1515 | |||
1516 | |||
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c new file mode 100644 index 000000000000..9ee40a484e07 --- /dev/null +++ b/drivers/acpi/utilities/utobject.c | |||
@@ -0,0 +1,671 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: utobject - ACPI object create/delete/size/cache routines | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
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 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/acnamesp.h> | ||
47 | #include <acpi/amlcode.h> | ||
48 | |||
49 | |||
50 | #define _COMPONENT ACPI_UTILITIES | ||
51 | ACPI_MODULE_NAME ("utobject") | ||
52 | |||
53 | |||
54 | /******************************************************************************* | ||
55 | * | ||
56 | * FUNCTION: acpi_ut_create_internal_object_dbg | ||
57 | * | ||
58 | * PARAMETERS: module_name - Source file name of caller | ||
59 | * line_number - Line number of caller | ||
60 | * component_id - Component type of caller | ||
61 | * Type - ACPI Type of the new object | ||
62 | * | ||
63 | * RETURN: Object - The new object. Null on failure | ||
64 | * | ||
65 | * DESCRIPTION: Create and initialize a new internal object. | ||
66 | * | ||
67 | * NOTE: We always allocate the worst-case object descriptor because | ||
68 | * these objects are cached, and we want them to be | ||
69 | * one-size-satisifies-any-request. This in itself may not be | ||
70 | * the most memory efficient, but the efficiency of the object | ||
71 | * cache should more than make up for this! | ||
72 | * | ||
73 | ******************************************************************************/ | ||
74 | |||
75 | union acpi_operand_object * | ||
76 | acpi_ut_create_internal_object_dbg ( | ||
77 | char *module_name, | ||
78 | u32 line_number, | ||
79 | u32 component_id, | ||
80 | acpi_object_type type) | ||
81 | { | ||
82 | union acpi_operand_object *object; | ||
83 | union acpi_operand_object *second_object; | ||
84 | |||
85 | |||
86 | ACPI_FUNCTION_TRACE_STR ("ut_create_internal_object_dbg", acpi_ut_get_type_name (type)); | ||
87 | |||
88 | |||
89 | /* Allocate the raw object descriptor */ | ||
90 | |||
91 | object = acpi_ut_allocate_object_desc_dbg (module_name, line_number, component_id); | ||
92 | if (!object) { | ||
93 | return_PTR (NULL); | ||
94 | } | ||
95 | |||
96 | switch (type) { | ||
97 | case ACPI_TYPE_REGION: | ||
98 | case ACPI_TYPE_BUFFER_FIELD: | ||
99 | |||
100 | /* These types require a secondary object */ | ||
101 | |||
102 | second_object = acpi_ut_allocate_object_desc_dbg (module_name, line_number, component_id); | ||
103 | if (!second_object) { | ||
104 | acpi_ut_delete_object_desc (object); | ||
105 | return_PTR (NULL); | ||
106 | } | ||
107 | |||
108 | second_object->common.type = ACPI_TYPE_LOCAL_EXTRA; | ||
109 | second_object->common.reference_count = 1; | ||
110 | |||
111 | /* Link the second object to the first */ | ||
112 | |||
113 | object->common.next_object = second_object; | ||
114 | break; | ||
115 | |||
116 | default: | ||
117 | /* All others have no secondary object */ | ||
118 | break; | ||
119 | } | ||
120 | |||
121 | /* Save the object type in the object descriptor */ | ||
122 | |||
123 | object->common.type = (u8) type; | ||
124 | |||
125 | /* Init the reference count */ | ||
126 | |||
127 | object->common.reference_count = 1; | ||
128 | |||
129 | /* Any per-type initialization should go here */ | ||
130 | |||
131 | return_PTR (object); | ||
132 | } | ||
133 | |||
134 | |||
135 | /******************************************************************************* | ||
136 | * | ||
137 | * FUNCTION: acpi_ut_create_buffer_object | ||
138 | * | ||
139 | * PARAMETERS: buffer_size - Size of buffer to be created | ||
140 | * | ||
141 | * RETURN: Pointer to a new Buffer object | ||
142 | * | ||
143 | * DESCRIPTION: Create a fully initialized buffer object | ||
144 | * | ||
145 | ******************************************************************************/ | ||
146 | |||
147 | union acpi_operand_object * | ||
148 | acpi_ut_create_buffer_object ( | ||
149 | acpi_size buffer_size) | ||
150 | { | ||
151 | union acpi_operand_object *buffer_desc; | ||
152 | u8 *buffer = NULL; | ||
153 | |||
154 | |||
155 | ACPI_FUNCTION_TRACE_U32 ("ut_create_buffer_object", buffer_size); | ||
156 | |||
157 | |||
158 | /* Create a new Buffer object */ | ||
159 | |||
160 | buffer_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER); | ||
161 | if (!buffer_desc) { | ||
162 | return_PTR (NULL); | ||
163 | } | ||
164 | |||
165 | /* Create an actual buffer only if size > 0 */ | ||
166 | |||
167 | if (buffer_size > 0) { | ||
168 | /* Allocate the actual buffer */ | ||
169 | |||
170 | buffer = ACPI_MEM_CALLOCATE (buffer_size); | ||
171 | if (!buffer) { | ||
172 | ACPI_REPORT_ERROR (("create_buffer: could not allocate size %X\n", | ||
173 | (u32) buffer_size)); | ||
174 | acpi_ut_remove_reference (buffer_desc); | ||
175 | return_PTR (NULL); | ||
176 | } | ||
177 | } | ||
178 | |||
179 | /* Complete buffer object initialization */ | ||
180 | |||
181 | buffer_desc->buffer.flags |= AOPOBJ_DATA_VALID; | ||
182 | buffer_desc->buffer.pointer = buffer; | ||
183 | buffer_desc->buffer.length = (u32) buffer_size; | ||
184 | |||
185 | /* Return the new buffer descriptor */ | ||
186 | |||
187 | return_PTR (buffer_desc); | ||
188 | } | ||
189 | |||
190 | |||
191 | /******************************************************************************* | ||
192 | * | ||
193 | * FUNCTION: acpi_ut_create_string_object | ||
194 | * | ||
195 | * PARAMETERS: string_size - Size of string to be created. Does not | ||
196 | * include NULL terminator, this is added | ||
197 | * automatically. | ||
198 | * | ||
199 | * RETURN: Pointer to a new String object | ||
200 | * | ||
201 | * DESCRIPTION: Create a fully initialized string object | ||
202 | * | ||
203 | ******************************************************************************/ | ||
204 | |||
205 | union acpi_operand_object * | ||
206 | acpi_ut_create_string_object ( | ||
207 | acpi_size string_size) | ||
208 | { | ||
209 | union acpi_operand_object *string_desc; | ||
210 | char *string; | ||
211 | |||
212 | |||
213 | ACPI_FUNCTION_TRACE_U32 ("ut_create_string_object", string_size); | ||
214 | |||
215 | |||
216 | /* Create a new String object */ | ||
217 | |||
218 | string_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING); | ||
219 | if (!string_desc) { | ||
220 | return_PTR (NULL); | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | * Allocate the actual string buffer -- (Size + 1) for NULL terminator. | ||
225 | * NOTE: Zero-length strings are NULL terminated | ||
226 | */ | ||
227 | string = ACPI_MEM_CALLOCATE (string_size + 1); | ||
228 | if (!string) { | ||
229 | ACPI_REPORT_ERROR (("create_string: could not allocate size %X\n", | ||
230 | (u32) string_size)); | ||
231 | acpi_ut_remove_reference (string_desc); | ||
232 | return_PTR (NULL); | ||
233 | } | ||
234 | |||
235 | /* Complete string object initialization */ | ||
236 | |||
237 | string_desc->string.pointer = string; | ||
238 | string_desc->string.length = (u32) string_size; | ||
239 | |||
240 | /* Return the new string descriptor */ | ||
241 | |||
242 | return_PTR (string_desc); | ||
243 | } | ||
244 | |||
245 | |||
246 | /******************************************************************************* | ||
247 | * | ||
248 | * FUNCTION: acpi_ut_valid_internal_object | ||
249 | * | ||
250 | * PARAMETERS: Object - Object to be validated | ||
251 | * | ||
252 | * RETURN: Validate a pointer to be an union acpi_operand_object | ||
253 | * | ||
254 | ******************************************************************************/ | ||
255 | |||
256 | u8 | ||
257 | acpi_ut_valid_internal_object ( | ||
258 | void *object) | ||
259 | { | ||
260 | |||
261 | ACPI_FUNCTION_NAME ("ut_valid_internal_object"); | ||
262 | |||
263 | |||
264 | /* Check for a null pointer */ | ||
265 | |||
266 | if (!object) { | ||
267 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Null Object Ptr\n")); | ||
268 | return (FALSE); | ||
269 | } | ||
270 | |||
271 | /* Check the descriptor type field */ | ||
272 | |||
273 | switch (ACPI_GET_DESCRIPTOR_TYPE (object)) { | ||
274 | case ACPI_DESC_TYPE_OPERAND: | ||
275 | |||
276 | /* The object appears to be a valid union acpi_operand_object */ | ||
277 | |||
278 | return (TRUE); | ||
279 | |||
280 | default: | ||
281 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, | ||
282 | "%p is not not an ACPI operand obj [%s]\n", | ||
283 | object, acpi_ut_get_descriptor_name (object))); | ||
284 | break; | ||
285 | } | ||
286 | |||
287 | return (FALSE); | ||
288 | } | ||
289 | |||
290 | |||
291 | /******************************************************************************* | ||
292 | * | ||
293 | * FUNCTION: acpi_ut_allocate_object_desc_dbg | ||
294 | * | ||
295 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
296 | * line_number - Caller's line number (for error output) | ||
297 | * component_id - Caller's component ID (for error output) | ||
298 | * | ||
299 | * RETURN: Pointer to newly allocated object descriptor. Null on error | ||
300 | * | ||
301 | * DESCRIPTION: Allocate a new object descriptor. Gracefully handle | ||
302 | * error conditions. | ||
303 | * | ||
304 | ******************************************************************************/ | ||
305 | |||
306 | void * | ||
307 | acpi_ut_allocate_object_desc_dbg ( | ||
308 | char *module_name, | ||
309 | u32 line_number, | ||
310 | u32 component_id) | ||
311 | { | ||
312 | union acpi_operand_object *object; | ||
313 | |||
314 | |||
315 | ACPI_FUNCTION_TRACE ("ut_allocate_object_desc_dbg"); | ||
316 | |||
317 | |||
318 | object = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_OPERAND); | ||
319 | if (!object) { | ||
320 | _ACPI_REPORT_ERROR (module_name, line_number, component_id, | ||
321 | ("Could not allocate an object descriptor\n")); | ||
322 | |||
323 | return_PTR (NULL); | ||
324 | } | ||
325 | |||
326 | /* Mark the descriptor type */ | ||
327 | |||
328 | ACPI_SET_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_OPERAND); | ||
329 | |||
330 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p Size %X\n", | ||
331 | object, (u32) sizeof (union acpi_operand_object))); | ||
332 | |||
333 | return_PTR (object); | ||
334 | } | ||
335 | |||
336 | |||
337 | /******************************************************************************* | ||
338 | * | ||
339 | * FUNCTION: acpi_ut_delete_object_desc | ||
340 | * | ||
341 | * PARAMETERS: Object - An Acpi internal object to be deleted | ||
342 | * | ||
343 | * RETURN: None. | ||
344 | * | ||
345 | * DESCRIPTION: Free an ACPI object descriptor or add it to the object cache | ||
346 | * | ||
347 | ******************************************************************************/ | ||
348 | |||
349 | void | ||
350 | acpi_ut_delete_object_desc ( | ||
351 | union acpi_operand_object *object) | ||
352 | { | ||
353 | ACPI_FUNCTION_TRACE_PTR ("ut_delete_object_desc", object); | ||
354 | |||
355 | |||
356 | /* Object must be an union acpi_operand_object */ | ||
357 | |||
358 | if (ACPI_GET_DESCRIPTOR_TYPE (object) != ACPI_DESC_TYPE_OPERAND) { | ||
359 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
360 | "%p is not an ACPI Operand object [%s]\n", object, | ||
361 | acpi_ut_get_descriptor_name (object))); | ||
362 | return_VOID; | ||
363 | } | ||
364 | |||
365 | acpi_ut_release_to_cache (ACPI_MEM_LIST_OPERAND, object); | ||
366 | |||
367 | return_VOID; | ||
368 | } | ||
369 | |||
370 | |||
371 | #ifdef ACPI_ENABLE_OBJECT_CACHE | ||
372 | /******************************************************************************* | ||
373 | * | ||
374 | * FUNCTION: acpi_ut_delete_object_cache | ||
375 | * | ||
376 | * PARAMETERS: None | ||
377 | * | ||
378 | * RETURN: None | ||
379 | * | ||
380 | * DESCRIPTION: Purge the global state object cache. Used during subsystem | ||
381 | * termination. | ||
382 | * | ||
383 | ******************************************************************************/ | ||
384 | |||
385 | void | ||
386 | acpi_ut_delete_object_cache ( | ||
387 | void) | ||
388 | { | ||
389 | ACPI_FUNCTION_TRACE ("ut_delete_object_cache"); | ||
390 | |||
391 | |||
392 | acpi_ut_delete_generic_cache (ACPI_MEM_LIST_OPERAND); | ||
393 | return_VOID; | ||
394 | } | ||
395 | #endif | ||
396 | |||
397 | |||
398 | /******************************************************************************* | ||
399 | * | ||
400 | * FUNCTION: acpi_ut_get_simple_object_size | ||
401 | * | ||
402 | * PARAMETERS: *internal_object - Pointer to the object we are examining | ||
403 | * *obj_length - Where the length is returned | ||
404 | * | ||
405 | * RETURN: Status | ||
406 | * | ||
407 | * DESCRIPTION: This function is called to determine the space required to | ||
408 | * contain a simple object for return to an external user. | ||
409 | * | ||
410 | * The length includes the object structure plus any additional | ||
411 | * needed space. | ||
412 | * | ||
413 | ******************************************************************************/ | ||
414 | |||
415 | acpi_status | ||
416 | acpi_ut_get_simple_object_size ( | ||
417 | union acpi_operand_object *internal_object, | ||
418 | acpi_size *obj_length) | ||
419 | { | ||
420 | acpi_size length; | ||
421 | acpi_status status = AE_OK; | ||
422 | |||
423 | |||
424 | ACPI_FUNCTION_TRACE_PTR ("ut_get_simple_object_size", internal_object); | ||
425 | |||
426 | |||
427 | /* Handle a null object (Could be a uninitialized package element -- which is legal) */ | ||
428 | |||
429 | if (!internal_object) { | ||
430 | *obj_length = 0; | ||
431 | return_ACPI_STATUS (AE_OK); | ||
432 | } | ||
433 | |||
434 | /* Start with the length of the Acpi object */ | ||
435 | |||
436 | length = sizeof (union acpi_object); | ||
437 | |||
438 | if (ACPI_GET_DESCRIPTOR_TYPE (internal_object) == ACPI_DESC_TYPE_NAMED) { | ||
439 | /* Object is a named object (reference), just return the length */ | ||
440 | |||
441 | *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD (length); | ||
442 | return_ACPI_STATUS (status); | ||
443 | } | ||
444 | |||
445 | /* | ||
446 | * The final length depends on the object type | ||
447 | * Strings and Buffers are packed right up against the parent object and | ||
448 | * must be accessed bytewise or there may be alignment problems on | ||
449 | * certain processors | ||
450 | */ | ||
451 | switch (ACPI_GET_OBJECT_TYPE (internal_object)) { | ||
452 | case ACPI_TYPE_STRING: | ||
453 | |||
454 | length += (acpi_size) internal_object->string.length + 1; | ||
455 | break; | ||
456 | |||
457 | |||
458 | case ACPI_TYPE_BUFFER: | ||
459 | |||
460 | length += (acpi_size) internal_object->buffer.length; | ||
461 | break; | ||
462 | |||
463 | |||
464 | case ACPI_TYPE_INTEGER: | ||
465 | case ACPI_TYPE_PROCESSOR: | ||
466 | case ACPI_TYPE_POWER: | ||
467 | |||
468 | /* | ||
469 | * No extra data for these types | ||
470 | */ | ||
471 | break; | ||
472 | |||
473 | |||
474 | case ACPI_TYPE_LOCAL_REFERENCE: | ||
475 | |||
476 | switch (internal_object->reference.opcode) { | ||
477 | case AML_INT_NAMEPATH_OP: | ||
478 | |||
479 | /* | ||
480 | * Get the actual length of the full pathname to this object. | ||
481 | * The reference will be converted to the pathname to the object | ||
482 | */ | ||
483 | length += ACPI_ROUND_UP_TO_NATIVE_WORD (acpi_ns_get_pathname_length (internal_object->reference.node)); | ||
484 | break; | ||
485 | |||
486 | default: | ||
487 | |||
488 | /* | ||
489 | * No other reference opcodes are supported. | ||
490 | * Notably, Locals and Args are not supported, but this may be | ||
491 | * required eventually. | ||
492 | */ | ||
493 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
494 | "Unsupported Reference opcode=%X in object %p\n", | ||
495 | internal_object->reference.opcode, internal_object)); | ||
496 | status = AE_TYPE; | ||
497 | break; | ||
498 | } | ||
499 | break; | ||
500 | |||
501 | |||
502 | default: | ||
503 | |||
504 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported type=%X in object %p\n", | ||
505 | ACPI_GET_OBJECT_TYPE (internal_object), internal_object)); | ||
506 | status = AE_TYPE; | ||
507 | break; | ||
508 | } | ||
509 | |||
510 | /* | ||
511 | * Account for the space required by the object rounded up to the next | ||
512 | * multiple of the machine word size. This keeps each object aligned | ||
513 | * on a machine word boundary. (preventing alignment faults on some | ||
514 | * machines.) | ||
515 | */ | ||
516 | *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD (length); | ||
517 | return_ACPI_STATUS (status); | ||
518 | } | ||
519 | |||
520 | |||
521 | /******************************************************************************* | ||
522 | * | ||
523 | * FUNCTION: acpi_ut_get_element_length | ||
524 | * | ||
525 | * PARAMETERS: acpi_pkg_callback | ||
526 | * | ||
527 | * RETURN: Status | ||
528 | * | ||
529 | * DESCRIPTION: Get the length of one package element. | ||
530 | * | ||
531 | ******************************************************************************/ | ||
532 | |||
533 | acpi_status | ||
534 | acpi_ut_get_element_length ( | ||
535 | u8 object_type, | ||
536 | union acpi_operand_object *source_object, | ||
537 | union acpi_generic_state *state, | ||
538 | void *context) | ||
539 | { | ||
540 | acpi_status status = AE_OK; | ||
541 | struct acpi_pkg_info *info = (struct acpi_pkg_info *) context; | ||
542 | acpi_size object_space; | ||
543 | |||
544 | |||
545 | switch (object_type) { | ||
546 | case ACPI_COPY_TYPE_SIMPLE: | ||
547 | |||
548 | /* | ||
549 | * Simple object - just get the size (Null object/entry is handled | ||
550 | * here also) and sum it into the running package length | ||
551 | */ | ||
552 | status = acpi_ut_get_simple_object_size (source_object, &object_space); | ||
553 | if (ACPI_FAILURE (status)) { | ||
554 | return (status); | ||
555 | } | ||
556 | |||
557 | info->length += object_space; | ||
558 | break; | ||
559 | |||
560 | |||
561 | case ACPI_COPY_TYPE_PACKAGE: | ||
562 | |||
563 | /* Package object - nothing much to do here, let the walk handle it */ | ||
564 | |||
565 | info->num_packages++; | ||
566 | state->pkg.this_target_obj = NULL; | ||
567 | break; | ||
568 | |||
569 | |||
570 | default: | ||
571 | |||
572 | /* No other types allowed */ | ||
573 | |||
574 | return (AE_BAD_PARAMETER); | ||
575 | } | ||
576 | |||
577 | return (status); | ||
578 | } | ||
579 | |||
580 | |||
581 | /******************************************************************************* | ||
582 | * | ||
583 | * FUNCTION: acpi_ut_get_package_object_size | ||
584 | * | ||
585 | * PARAMETERS: *internal_object - Pointer to the object we are examining | ||
586 | * *obj_length - Where the length is returned | ||
587 | * | ||
588 | * RETURN: Status | ||
589 | * | ||
590 | * DESCRIPTION: This function is called to determine the space required to | ||
591 | * contain a package object for return to an external user. | ||
592 | * | ||
593 | * This is moderately complex since a package contains other | ||
594 | * objects including packages. | ||
595 | * | ||
596 | ******************************************************************************/ | ||
597 | |||
598 | acpi_status | ||
599 | acpi_ut_get_package_object_size ( | ||
600 | union acpi_operand_object *internal_object, | ||
601 | acpi_size *obj_length) | ||
602 | { | ||
603 | acpi_status status; | ||
604 | struct acpi_pkg_info info; | ||
605 | |||
606 | |||
607 | ACPI_FUNCTION_TRACE_PTR ("ut_get_package_object_size", internal_object); | ||
608 | |||
609 | |||
610 | info.length = 0; | ||
611 | info.object_space = 0; | ||
612 | info.num_packages = 1; | ||
613 | |||
614 | status = acpi_ut_walk_package_tree (internal_object, NULL, | ||
615 | acpi_ut_get_element_length, &info); | ||
616 | if (ACPI_FAILURE (status)) { | ||
617 | return_ACPI_STATUS (status); | ||
618 | } | ||
619 | |||
620 | /* | ||
621 | * We have handled all of the objects in all levels of the package. | ||
622 | * just add the length of the package objects themselves. | ||
623 | * Round up to the next machine word. | ||
624 | */ | ||
625 | info.length += ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object)) * | ||
626 | (acpi_size) info.num_packages; | ||
627 | |||
628 | /* Return the total package length */ | ||
629 | |||
630 | *obj_length = info.length; | ||
631 | return_ACPI_STATUS (status); | ||
632 | } | ||
633 | |||
634 | |||
635 | /******************************************************************************* | ||
636 | * | ||
637 | * FUNCTION: acpi_ut_get_object_size | ||
638 | * | ||
639 | * PARAMETERS: *internal_object - Pointer to the object we are examining | ||
640 | * *obj_length - Where the length will be returned | ||
641 | * | ||
642 | * RETURN: Status | ||
643 | * | ||
644 | * DESCRIPTION: This function is called to determine the space required to | ||
645 | * contain an object for return to an API user. | ||
646 | * | ||
647 | ******************************************************************************/ | ||
648 | |||
649 | acpi_status | ||
650 | acpi_ut_get_object_size( | ||
651 | union acpi_operand_object *internal_object, | ||
652 | acpi_size *obj_length) | ||
653 | { | ||
654 | acpi_status status; | ||
655 | |||
656 | |||
657 | ACPI_FUNCTION_ENTRY (); | ||
658 | |||
659 | |||
660 | if ((ACPI_GET_DESCRIPTOR_TYPE (internal_object) == ACPI_DESC_TYPE_OPERAND) && | ||
661 | (ACPI_GET_OBJECT_TYPE (internal_object) == ACPI_TYPE_PACKAGE)) { | ||
662 | status = acpi_ut_get_package_object_size (internal_object, obj_length); | ||
663 | } | ||
664 | else { | ||
665 | status = acpi_ut_get_simple_object_size (internal_object, obj_length); | ||
666 | } | ||
667 | |||
668 | return (status); | ||
669 | } | ||
670 | |||
671 | |||
diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c new file mode 100644 index 000000000000..97a91f3f06f0 --- /dev/null +++ b/drivers/acpi/utilities/utxface.c | |||
@@ -0,0 +1,525 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: utxface - External interfaces for "global" ACPI functions | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
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 <linux/module.h> | ||
45 | |||
46 | #include <acpi/acpi.h> | ||
47 | #include <acpi/acevents.h> | ||
48 | #include <acpi/acnamesp.h> | ||
49 | #include <acpi/acparser.h> | ||
50 | #include <acpi/acdispat.h> | ||
51 | #include <acpi/acdebug.h> | ||
52 | |||
53 | #define _COMPONENT ACPI_UTILITIES | ||
54 | ACPI_MODULE_NAME ("utxface") | ||
55 | |||
56 | |||
57 | /******************************************************************************* | ||
58 | * | ||
59 | * FUNCTION: acpi_initialize_subsystem | ||
60 | * | ||
61 | * PARAMETERS: None | ||
62 | * | ||
63 | * RETURN: Status | ||
64 | * | ||
65 | * DESCRIPTION: Initializes all global variables. This is the first function | ||
66 | * called, so any early initialization belongs here. | ||
67 | * | ||
68 | ******************************************************************************/ | ||
69 | |||
70 | acpi_status | ||
71 | acpi_initialize_subsystem ( | ||
72 | void) | ||
73 | { | ||
74 | acpi_status status; | ||
75 | |||
76 | ACPI_FUNCTION_TRACE ("acpi_initialize_subsystem"); | ||
77 | |||
78 | |||
79 | ACPI_DEBUG_EXEC (acpi_ut_init_stack_ptr_trace ()); | ||
80 | |||
81 | |||
82 | /* Initialize all globals used by the subsystem */ | ||
83 | |||
84 | acpi_ut_init_globals (); | ||
85 | |||
86 | /* Initialize the OS-Dependent layer */ | ||
87 | |||
88 | status = acpi_os_initialize (); | ||
89 | if (ACPI_FAILURE (status)) { | ||
90 | ACPI_REPORT_ERROR (("OSD failed to initialize, %s\n", | ||
91 | acpi_format_exception (status))); | ||
92 | return_ACPI_STATUS (status); | ||
93 | } | ||
94 | |||
95 | /* Create the default mutex objects */ | ||
96 | |||
97 | status = acpi_ut_mutex_initialize (); | ||
98 | if (ACPI_FAILURE (status)) { | ||
99 | ACPI_REPORT_ERROR (("Global mutex creation failure, %s\n", | ||
100 | acpi_format_exception (status))); | ||
101 | return_ACPI_STATUS (status); | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * Initialize the namespace manager and | ||
106 | * the root of the namespace tree | ||
107 | */ | ||
108 | |||
109 | status = acpi_ns_root_initialize (); | ||
110 | if (ACPI_FAILURE (status)) { | ||
111 | ACPI_REPORT_ERROR (("Namespace initialization failure, %s\n", | ||
112 | acpi_format_exception (status))); | ||
113 | return_ACPI_STATUS (status); | ||
114 | } | ||
115 | |||
116 | |||
117 | /* If configured, initialize the AML debugger */ | ||
118 | |||
119 | ACPI_DEBUGGER_EXEC (status = acpi_db_initialize ()); | ||
120 | |||
121 | return_ACPI_STATUS (status); | ||
122 | } | ||
123 | |||
124 | |||
125 | /******************************************************************************* | ||
126 | * | ||
127 | * FUNCTION: acpi_enable_subsystem | ||
128 | * | ||
129 | * PARAMETERS: Flags - Init/enable Options | ||
130 | * | ||
131 | * RETURN: Status | ||
132 | * | ||
133 | * DESCRIPTION: Completes the subsystem initialization including hardware. | ||
134 | * Puts system into ACPI mode if it isn't already. | ||
135 | * | ||
136 | ******************************************************************************/ | ||
137 | |||
138 | acpi_status | ||
139 | acpi_enable_subsystem ( | ||
140 | u32 flags) | ||
141 | { | ||
142 | acpi_status status = AE_OK; | ||
143 | |||
144 | |||
145 | ACPI_FUNCTION_TRACE ("acpi_enable_subsystem"); | ||
146 | |||
147 | |||
148 | /* | ||
149 | * We must initialize the hardware before we can enable ACPI. | ||
150 | * The values from the FADT are validated here. | ||
151 | */ | ||
152 | if (!(flags & ACPI_NO_HARDWARE_INIT)) { | ||
153 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI hardware\n")); | ||
154 | |||
155 | status = acpi_hw_initialize (); | ||
156 | if (ACPI_FAILURE (status)) { | ||
157 | return_ACPI_STATUS (status); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | /* Enable ACPI mode */ | ||
162 | |||
163 | if (!(flags & ACPI_NO_ACPI_ENABLE)) { | ||
164 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Going into ACPI mode\n")); | ||
165 | |||
166 | acpi_gbl_original_mode = acpi_hw_get_mode(); | ||
167 | |||
168 | status = acpi_enable (); | ||
169 | if (ACPI_FAILURE (status)) { | ||
170 | ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "acpi_enable failed.\n")); | ||
171 | return_ACPI_STATUS (status); | ||
172 | } | ||
173 | } | ||
174 | |||
175 | /* | ||
176 | * Install the default op_region handlers. These are installed unless | ||
177 | * other handlers have already been installed via the | ||
178 | * install_address_space_handler interface. | ||
179 | */ | ||
180 | if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) { | ||
181 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n")); | ||
182 | |||
183 | status = acpi_ev_install_region_handlers (); | ||
184 | if (ACPI_FAILURE (status)) { | ||
185 | return_ACPI_STATUS (status); | ||
186 | } | ||
187 | } | ||
188 | |||
189 | /* | ||
190 | * Initialize ACPI Event handling (Fixed and General Purpose) | ||
191 | * | ||
192 | * NOTE: We must have the hardware AND events initialized before we can execute | ||
193 | * ANY control methods SAFELY. Any control method can require ACPI hardware | ||
194 | * support, so the hardware MUST be initialized before execution! | ||
195 | */ | ||
196 | if (!(flags & ACPI_NO_EVENT_INIT)) { | ||
197 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI events\n")); | ||
198 | |||
199 | status = acpi_ev_initialize_events (); | ||
200 | if (ACPI_FAILURE (status)) { | ||
201 | return_ACPI_STATUS (status); | ||
202 | } | ||
203 | } | ||
204 | |||
205 | /* Install the SCI handler and Global Lock handler */ | ||
206 | |||
207 | if (!(flags & ACPI_NO_HANDLER_INIT)) { | ||
208 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing SCI/GL handlers\n")); | ||
209 | |||
210 | status = acpi_ev_install_xrupt_handlers (); | ||
211 | if (ACPI_FAILURE (status)) { | ||
212 | return_ACPI_STATUS (status); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | return_ACPI_STATUS (status); | ||
217 | } | ||
218 | |||
219 | /******************************************************************************* | ||
220 | * | ||
221 | * FUNCTION: acpi_initialize_objects | ||
222 | * | ||
223 | * PARAMETERS: Flags - Init/enable Options | ||
224 | * | ||
225 | * RETURN: Status | ||
226 | * | ||
227 | * DESCRIPTION: Completes namespace initialization by initializing device | ||
228 | * objects and executing AML code for Regions, buffers, etc. | ||
229 | * | ||
230 | ******************************************************************************/ | ||
231 | |||
232 | acpi_status | ||
233 | acpi_initialize_objects ( | ||
234 | u32 flags) | ||
235 | { | ||
236 | acpi_status status = AE_OK; | ||
237 | |||
238 | |||
239 | ACPI_FUNCTION_TRACE ("acpi_initialize_objects"); | ||
240 | |||
241 | |||
242 | /* | ||
243 | * Run all _REG methods | ||
244 | * | ||
245 | * NOTE: Any objects accessed | ||
246 | * by the _REG methods will be automatically initialized, even if they | ||
247 | * contain executable AML (see call to acpi_ns_initialize_objects below). | ||
248 | */ | ||
249 | if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) { | ||
250 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Executing _REG op_region methods\n")); | ||
251 | |||
252 | status = acpi_ev_initialize_op_regions (); | ||
253 | if (ACPI_FAILURE (status)) { | ||
254 | return_ACPI_STATUS (status); | ||
255 | } | ||
256 | } | ||
257 | |||
258 | /* | ||
259 | * Initialize the objects that remain uninitialized. This | ||
260 | * runs the executable AML that may be part of the declaration of these | ||
261 | * objects: operation_regions, buffer_fields, Buffers, and Packages. | ||
262 | */ | ||
263 | if (!(flags & ACPI_NO_OBJECT_INIT)) { | ||
264 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Completing Initialization of ACPI Objects\n")); | ||
265 | |||
266 | status = acpi_ns_initialize_objects (); | ||
267 | if (ACPI_FAILURE (status)) { | ||
268 | return_ACPI_STATUS (status); | ||
269 | } | ||
270 | } | ||
271 | |||
272 | /* | ||
273 | * Initialize all device objects in the namespace | ||
274 | * This runs the _STA and _INI methods. | ||
275 | */ | ||
276 | if (!(flags & ACPI_NO_DEVICE_INIT)) { | ||
277 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Devices\n")); | ||
278 | |||
279 | status = acpi_ns_initialize_devices (); | ||
280 | if (ACPI_FAILURE (status)) { | ||
281 | return_ACPI_STATUS (status); | ||
282 | } | ||
283 | } | ||
284 | |||
285 | /* | ||
286 | * Empty the caches (delete the cached objects) on the assumption that | ||
287 | * the table load filled them up more than they will be at runtime -- | ||
288 | * thus wasting non-paged memory. | ||
289 | */ | ||
290 | status = acpi_purge_cached_objects (); | ||
291 | |||
292 | acpi_gbl_startup_flags |= ACPI_INITIALIZED_OK; | ||
293 | return_ACPI_STATUS (status); | ||
294 | } | ||
295 | |||
296 | |||
297 | /******************************************************************************* | ||
298 | * | ||
299 | * FUNCTION: acpi_terminate | ||
300 | * | ||
301 | * PARAMETERS: None | ||
302 | * | ||
303 | * RETURN: Status | ||
304 | * | ||
305 | * DESCRIPTION: Shutdown the ACPI subsystem. Release all resources. | ||
306 | * | ||
307 | ******************************************************************************/ | ||
308 | |||
309 | acpi_status | ||
310 | acpi_terminate (void) | ||
311 | { | ||
312 | acpi_status status; | ||
313 | |||
314 | |||
315 | ACPI_FUNCTION_TRACE ("acpi_terminate"); | ||
316 | |||
317 | |||
318 | /* Terminate the AML Debugger if present */ | ||
319 | |||
320 | ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE); | ||
321 | |||
322 | /* Shutdown and free all resources */ | ||
323 | |||
324 | acpi_ut_subsystem_shutdown (); | ||
325 | |||
326 | |||
327 | /* Free the mutex objects */ | ||
328 | |||
329 | acpi_ut_mutex_terminate (); | ||
330 | |||
331 | |||
332 | #ifdef ACPI_DEBUGGER | ||
333 | |||
334 | /* Shut down the debugger */ | ||
335 | |||
336 | acpi_db_terminate (); | ||
337 | #endif | ||
338 | |||
339 | /* Now we can shutdown the OS-dependent layer */ | ||
340 | |||
341 | status = acpi_os_terminate (); | ||
342 | return_ACPI_STATUS (status); | ||
343 | } | ||
344 | |||
345 | |||
346 | #ifdef ACPI_FUTURE_USAGE | ||
347 | |||
348 | /***************************************************************************** | ||
349 | * | ||
350 | * FUNCTION: acpi_subsystem_status | ||
351 | * | ||
352 | * PARAMETERS: None | ||
353 | * | ||
354 | * RETURN: Status of the ACPI subsystem | ||
355 | * | ||
356 | * DESCRIPTION: Other drivers that use the ACPI subsystem should call this | ||
357 | * before making any other calls, to ensure the subsystem initial- | ||
358 | * ized successfully. | ||
359 | * | ||
360 | ****************************************************************************/ | ||
361 | |||
362 | acpi_status | ||
363 | acpi_subsystem_status (void) | ||
364 | { | ||
365 | if (acpi_gbl_startup_flags & ACPI_INITIALIZED_OK) { | ||
366 | return (AE_OK); | ||
367 | } | ||
368 | else { | ||
369 | return (AE_ERROR); | ||
370 | } | ||
371 | } | ||
372 | |||
373 | |||
374 | /****************************************************************************** | ||
375 | * | ||
376 | * FUNCTION: acpi_get_system_info | ||
377 | * | ||
378 | * PARAMETERS: out_buffer - a pointer to a buffer to receive the | ||
379 | * resources for the device | ||
380 | * buffer_length - the number of bytes available in the buffer | ||
381 | * | ||
382 | * RETURN: Status - the status of the call | ||
383 | * | ||
384 | * DESCRIPTION: This function is called to get information about the current | ||
385 | * state of the ACPI subsystem. It will return system information | ||
386 | * in the out_buffer. | ||
387 | * | ||
388 | * If the function fails an appropriate status will be returned | ||
389 | * and the value of out_buffer is undefined. | ||
390 | * | ||
391 | ******************************************************************************/ | ||
392 | |||
393 | acpi_status | ||
394 | acpi_get_system_info ( | ||
395 | struct acpi_buffer *out_buffer) | ||
396 | { | ||
397 | struct acpi_system_info *info_ptr; | ||
398 | u32 i; | ||
399 | acpi_status status; | ||
400 | |||
401 | |||
402 | ACPI_FUNCTION_TRACE ("acpi_get_system_info"); | ||
403 | |||
404 | |||
405 | /* Parameter validation */ | ||
406 | |||
407 | status = acpi_ut_validate_buffer (out_buffer); | ||
408 | if (ACPI_FAILURE (status)) { | ||
409 | return_ACPI_STATUS (status); | ||
410 | } | ||
411 | |||
412 | /* Validate/Allocate/Clear caller buffer */ | ||
413 | |||
414 | status = acpi_ut_initialize_buffer (out_buffer, sizeof (struct acpi_system_info)); | ||
415 | if (ACPI_FAILURE (status)) { | ||
416 | return_ACPI_STATUS (status); | ||
417 | } | ||
418 | |||
419 | /* | ||
420 | * Populate the return buffer | ||
421 | */ | ||
422 | info_ptr = (struct acpi_system_info *) out_buffer->pointer; | ||
423 | |||
424 | info_ptr->acpi_ca_version = ACPI_CA_VERSION; | ||
425 | |||
426 | /* System flags (ACPI capabilities) */ | ||
427 | |||
428 | info_ptr->flags = ACPI_SYS_MODE_ACPI; | ||
429 | |||
430 | /* Timer resolution - 24 or 32 bits */ | ||
431 | |||
432 | if (!acpi_gbl_FADT) { | ||
433 | info_ptr->timer_resolution = 0; | ||
434 | } | ||
435 | else if (acpi_gbl_FADT->tmr_val_ext == 0) { | ||
436 | info_ptr->timer_resolution = 24; | ||
437 | } | ||
438 | else { | ||
439 | info_ptr->timer_resolution = 32; | ||
440 | } | ||
441 | |||
442 | /* Clear the reserved fields */ | ||
443 | |||
444 | info_ptr->reserved1 = 0; | ||
445 | info_ptr->reserved2 = 0; | ||
446 | |||
447 | /* Current debug levels */ | ||
448 | |||
449 | info_ptr->debug_layer = acpi_dbg_layer; | ||
450 | info_ptr->debug_level = acpi_dbg_level; | ||
451 | |||
452 | /* Current status of the ACPI tables, per table type */ | ||
453 | |||
454 | info_ptr->num_table_types = NUM_ACPI_TABLE_TYPES; | ||
455 | for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) { | ||
456 | info_ptr->table_info[i].count = acpi_gbl_table_lists[i].count; | ||
457 | } | ||
458 | |||
459 | return_ACPI_STATUS (AE_OK); | ||
460 | } | ||
461 | EXPORT_SYMBOL(acpi_get_system_info); | ||
462 | |||
463 | |||
464 | /***************************************************************************** | ||
465 | * | ||
466 | * FUNCTION: acpi_install_initialization_handler | ||
467 | * | ||
468 | * PARAMETERS: Handler - Callback procedure | ||
469 | * | ||
470 | * RETURN: Status | ||
471 | * | ||
472 | * DESCRIPTION: Install an initialization handler | ||
473 | * | ||
474 | * TBD: When a second function is added, must save the Function also. | ||
475 | * | ||
476 | ****************************************************************************/ | ||
477 | |||
478 | acpi_status | ||
479 | acpi_install_initialization_handler ( | ||
480 | acpi_init_handler handler, | ||
481 | u32 function) | ||
482 | { | ||
483 | |||
484 | if (!handler) { | ||
485 | return (AE_BAD_PARAMETER); | ||
486 | } | ||
487 | |||
488 | if (acpi_gbl_init_handler) { | ||
489 | return (AE_ALREADY_EXISTS); | ||
490 | } | ||
491 | |||
492 | acpi_gbl_init_handler = handler; | ||
493 | return AE_OK; | ||
494 | } | ||
495 | |||
496 | #endif /* ACPI_FUTURE_USAGE */ | ||
497 | |||
498 | |||
499 | /***************************************************************************** | ||
500 | * | ||
501 | * FUNCTION: acpi_purge_cached_objects | ||
502 | * | ||
503 | * PARAMETERS: None | ||
504 | * | ||
505 | * RETURN: Status | ||
506 | * | ||
507 | * DESCRIPTION: Empty all caches (delete the cached objects) | ||
508 | * | ||
509 | ****************************************************************************/ | ||
510 | |||
511 | acpi_status | ||
512 | acpi_purge_cached_objects (void) | ||
513 | { | ||
514 | ACPI_FUNCTION_TRACE ("acpi_purge_cached_objects"); | ||
515 | |||
516 | |||
517 | #ifdef ACPI_ENABLE_OBJECT_CACHE | ||
518 | acpi_ut_delete_generic_state_cache (); | ||
519 | acpi_ut_delete_object_cache (); | ||
520 | acpi_ds_delete_walk_state_cache (); | ||
521 | acpi_ps_delete_parse_cache (); | ||
522 | #endif | ||
523 | |||
524 | return_ACPI_STATUS (AE_OK); | ||
525 | } | ||