Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 |