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/utmisc.c |
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/utmisc.c')
-rw-r--r-- | drivers/acpi/utilities/utmisc.c | 1516 |
1 files changed, 1516 insertions, 0 deletions
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 | |||