blob: df715cd89105ca5e4805209f3b65c99990fb2fa1 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*******************************************************************************
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
Robert Moore44f6c012005-04-18 22:49:35 -040052
53/*******************************************************************************
54 *
Robert Mooref9f46012005-07-08 00:00:00 -040055 * FUNCTION: acpi_ut_allocate_owner_id
56 *
57 * PARAMETERS: owner_id - Where the new owner ID is returned
58 *
59 * DESCRIPTION: Allocate a table or method owner id
60 *
61 ******************************************************************************/
62
63acpi_status
64acpi_ut_allocate_owner_id (
65 acpi_owner_id *owner_id)
66{
67 acpi_native_uint i;
68 acpi_status status;
69
70
71 ACPI_FUNCTION_TRACE ("ut_allocate_owner_id");
72
73
74 status = acpi_ut_acquire_mutex (ACPI_MTX_CACHES);
75 if (ACPI_FAILURE (status)) {
76 return_ACPI_STATUS (status);
77 }
78
79 /* Find a free owner ID */
80
81 for (i = 0; i < 32; i++) {
82 if (!(acpi_gbl_owner_id_mask & (1 << i))) {
83 acpi_gbl_owner_id_mask |= (1 << i);
84 *owner_id = (acpi_owner_id) i;
85 goto exit;
86 }
87 }
88
89 /*
90 * If we are here, all owner_ids have been allocated. This probably should
91 * not happen since the IDs are reused after deallocation. The IDs are
92 * allocated upon table load (one per table) and method execution, and
93 * they are released when a table is unloaded or a method completes
94 * execution.
95 */
96 status = AE_OWNER_ID_LIMIT;
97 ACPI_REPORT_ERROR ((
98 "Could not allocate new owner_id (32 max), AE_OWNER_ID_LIMIT\n"));
99
100exit:
101 (void) acpi_ut_release_mutex (ACPI_MTX_CACHES);
102 return_ACPI_STATUS (status);
103}
104
105
106/*******************************************************************************
107 *
108 * FUNCTION: acpi_ut_release_owner_id
109 *
110 * PARAMETERS: owner_id - A previously allocated owner ID
111 *
112 * DESCRIPTION: Release a table or method owner id
113 *
114 ******************************************************************************/
115
116acpi_status
117acpi_ut_release_owner_id (
118 acpi_owner_id owner_id)
119{
120 acpi_status status;
121
122
123 ACPI_FUNCTION_TRACE ("ut_release_owner_id");
124
125
126 status = acpi_ut_acquire_mutex (ACPI_MTX_CACHES);
127 if (ACPI_FAILURE (status)) {
128 return_ACPI_STATUS (status);
129 }
130
131 /* Free the owner ID */
132
133 if (acpi_gbl_owner_id_mask & (1 << owner_id)) {
134 acpi_gbl_owner_id_mask ^= (1 << owner_id);
135 }
136 else {
137 /* This owner_id has not been allocated */
138
139 status = AE_NOT_EXIST;
140 }
141
142 (void) acpi_ut_release_mutex (ACPI_MTX_CACHES);
143 return_ACPI_STATUS (status);
144}
145
146
147/*******************************************************************************
148 *
Robert Moore44f6c012005-04-18 22:49:35 -0400149 * FUNCTION: acpi_ut_strupr (strupr)
150 *
151 * PARAMETERS: src_string - The source string to convert
152 *
153 * RETURN: Converted src_string (same as input pointer)
154 *
155 * DESCRIPTION: Convert string to uppercase
156 *
157 * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
158 *
159 ******************************************************************************/
160
161char *
162acpi_ut_strupr (
163 char *src_string)
164{
165 char *string;
166
167
168 ACPI_FUNCTION_ENTRY ();
169
170
Robert Moore73459f72005-06-24 00:00:00 -0400171 if (!src_string) {
172 return (NULL);
173 }
174
Robert Moore44f6c012005-04-18 22:49:35 -0400175 /* Walk entire string, uppercasing the letters */
176
177 for (string = src_string; *string; string++) {
178 *string = (char) ACPI_TOUPPER (*string);
179 }
180
181 return (src_string);
182}
183
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184
185/*******************************************************************************
186 *
187 * FUNCTION: acpi_ut_print_string
188 *
189 * PARAMETERS: String - Null terminated ASCII string
Robert Moore44f6c012005-04-18 22:49:35 -0400190 * max_length - Maximum output length
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191 *
192 * RETURN: None
193 *
194 * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
195 * sequences.
196 *
197 ******************************************************************************/
198
199void
200acpi_ut_print_string (
201 char *string,
202 u8 max_length)
203{
204 u32 i;
205
206
207 if (!string) {
208 acpi_os_printf ("<\"NULL STRING PTR\">");
209 return;
210 }
211
212 acpi_os_printf ("\"");
213 for (i = 0; string[i] && (i < max_length); i++) {
214 /* Escape sequences */
215
216 switch (string[i]) {
217 case 0x07:
218 acpi_os_printf ("\\a"); /* BELL */
219 break;
220
221 case 0x08:
222 acpi_os_printf ("\\b"); /* BACKSPACE */
223 break;
224
225 case 0x0C:
226 acpi_os_printf ("\\f"); /* FORMFEED */
227 break;
228
229 case 0x0A:
230 acpi_os_printf ("\\n"); /* LINEFEED */
231 break;
232
233 case 0x0D:
234 acpi_os_printf ("\\r"); /* CARRIAGE RETURN*/
235 break;
236
237 case 0x09:
238 acpi_os_printf ("\\t"); /* HORIZONTAL TAB */
239 break;
240
241 case 0x0B:
242 acpi_os_printf ("\\v"); /* VERTICAL TAB */
243 break;
244
245 case '\'': /* Single Quote */
246 case '\"': /* Double Quote */
247 case '\\': /* Backslash */
248 acpi_os_printf ("\\%c", (int) string[i]);
249 break;
250
251 default:
252
253 /* Check for printable character or hex escape */
254
255 if (ACPI_IS_PRINT (string[i]))
256 {
257 /* This is a normal character */
258
259 acpi_os_printf ("%c", (int) string[i]);
260 }
261 else
262 {
263 /* All others will be Hex escapes */
264
265 acpi_os_printf ("\\x%2.2X", (s32) string[i]);
266 }
267 break;
268 }
269 }
270 acpi_os_printf ("\"");
271
272 if (i == max_length && string[i]) {
273 acpi_os_printf ("...");
274 }
275}
276
277
278/*******************************************************************************
279 *
280 * FUNCTION: acpi_ut_dword_byte_swap
281 *
282 * PARAMETERS: Value - Value to be converted
283 *
Robert Moore44f6c012005-04-18 22:49:35 -0400284 * RETURN: u32 integer with bytes swapped
285 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286 * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
287 *
288 ******************************************************************************/
289
290u32
291acpi_ut_dword_byte_swap (
292 u32 value)
293{
294 union {
295 u32 value;
296 u8 bytes[4];
297 } out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298 union {
299 u32 value;
300 u8 bytes[4];
301 } in;
302
303
304 ACPI_FUNCTION_ENTRY ();
305
306
307 in.value = value;
308
309 out.bytes[0] = in.bytes[3];
310 out.bytes[1] = in.bytes[2];
311 out.bytes[2] = in.bytes[1];
312 out.bytes[3] = in.bytes[0];
313
314 return (out.value);
315}
316
317
318/*******************************************************************************
319 *
320 * FUNCTION: acpi_ut_set_integer_width
321 *
322 * PARAMETERS: Revision From DSDT header
323 *
324 * RETURN: None
325 *
326 * DESCRIPTION: Set the global integer bit width based upon the revision
327 * of the DSDT. For Revision 1 and 0, Integers are 32 bits.
328 * For Revision 2 and above, Integers are 64 bits. Yes, this
329 * makes a difference.
330 *
331 ******************************************************************************/
332
333void
334acpi_ut_set_integer_width (
335 u8 revision)
336{
337
338 if (revision <= 1) {
339 acpi_gbl_integer_bit_width = 32;
340 acpi_gbl_integer_nybble_width = 8;
341 acpi_gbl_integer_byte_width = 4;
342 }
343 else {
344 acpi_gbl_integer_bit_width = 64;
345 acpi_gbl_integer_nybble_width = 16;
346 acpi_gbl_integer_byte_width = 8;
347 }
348}
349
350
351#ifdef ACPI_DEBUG_OUTPUT
352/*******************************************************************************
353 *
354 * FUNCTION: acpi_ut_display_init_pathname
355 *
Robert Moore44f6c012005-04-18 22:49:35 -0400356 * PARAMETERS: Type - Object type of the node
357 * obj_handle - Handle whose pathname will be displayed
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358 * Path - Additional path string to be appended.
359 * (NULL if no extra path)
360 *
361 * RETURN: acpi_status
362 *
363 * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
364 *
365 ******************************************************************************/
366
367void
368acpi_ut_display_init_pathname (
369 u8 type,
370 struct acpi_namespace_node *obj_handle,
371 char *path)
372{
373 acpi_status status;
374 struct acpi_buffer buffer;
375
376
377 ACPI_FUNCTION_ENTRY ();
378
379
380 /* Only print the path if the appropriate debug level is enabled */
381
382 if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
383 return;
384 }
385
386 /* Get the full pathname to the node */
387
388 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
389 status = acpi_ns_handle_to_pathname (obj_handle, &buffer);
390 if (ACPI_FAILURE (status)) {
391 return;
392 }
393
394 /* Print what we're doing */
395
396 switch (type) {
397 case ACPI_TYPE_METHOD:
398 acpi_os_printf ("Executing ");
399 break;
400
401 default:
402 acpi_os_printf ("Initializing ");
403 break;
404 }
405
406 /* Print the object type and pathname */
407
Robert Moore44f6c012005-04-18 22:49:35 -0400408 acpi_os_printf ("%-12s %s",
409 acpi_ut_get_type_name (type), (char *) buffer.pointer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410
411 /* Extra path is used to append names like _STA, _INI, etc. */
412
413 if (path) {
414 acpi_os_printf (".%s", path);
415 }
416 acpi_os_printf ("\n");
417
418 ACPI_MEM_FREE (buffer.pointer);
419}
420#endif
421
422
423/*******************************************************************************
424 *
425 * FUNCTION: acpi_ut_valid_acpi_name
426 *
Robert Moore44f6c012005-04-18 22:49:35 -0400427 * PARAMETERS: Name - The name to be examined
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428 *
Robert Moore44f6c012005-04-18 22:49:35 -0400429 * RETURN: TRUE if the name is valid, FALSE otherwise
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430 *
431 * DESCRIPTION: Check for a valid ACPI name. Each character must be one of:
432 * 1) Upper case alpha
433 * 2) numeric
434 * 3) underscore
435 *
436 ******************************************************************************/
437
438u8
439acpi_ut_valid_acpi_name (
440 u32 name)
441{
442 char *name_ptr = (char *) &name;
443 char character;
444 acpi_native_uint i;
445
446
447 ACPI_FUNCTION_ENTRY ();
448
449
450 for (i = 0; i < ACPI_NAME_SIZE; i++) {
451 character = *name_ptr;
452 name_ptr++;
453
454 if (!((character == '_') ||
455 (character >= 'A' && character <= 'Z') ||
456 (character >= '0' && character <= '9'))) {
457 return (FALSE);
458 }
459 }
460
461 return (TRUE);
462}
463
464
465/*******************************************************************************
466 *
467 * FUNCTION: acpi_ut_valid_acpi_character
468 *
469 * PARAMETERS: Character - The character to be examined
470 *
471 * RETURN: 1 if Character may appear in a name, else 0
472 *
473 * DESCRIPTION: Check for a printable character
474 *
475 ******************************************************************************/
476
477u8
478acpi_ut_valid_acpi_character (
479 char character)
480{
481
482 ACPI_FUNCTION_ENTRY ();
483
484 return ((u8) ((character == '_') ||
485 (character >= 'A' && character <= 'Z') ||
486 (character >= '0' && character <= '9')));
487}
488
489
490/*******************************************************************************
491 *
492 * FUNCTION: acpi_ut_strtoul64
493 *
494 * PARAMETERS: String - Null terminated string
495 * Base - Radix of the string: 10, 16, or ACPI_ANY_BASE
496 * ret_integer - Where the converted integer is returned
497 *
498 * RETURN: Status and Converted value
499 *
500 * DESCRIPTION: Convert a string into an unsigned value.
501 * NOTE: Does not support Octal strings, not needed.
502 *
503 ******************************************************************************/
504
505acpi_status
506acpi_ut_strtoul64 (
507 char *string,
508 u32 base,
509 acpi_integer *ret_integer)
510{
511 u32 this_digit = 0;
512 acpi_integer return_value = 0;
513 acpi_integer quotient;
514
515
516 ACPI_FUNCTION_TRACE ("ut_stroul64");
517
518
519 if ((!string) || !(*string)) {
520 goto error_exit;
521 }
522
523 switch (base) {
524 case ACPI_ANY_BASE:
525 case 10:
526 case 16:
527 break;
528
529 default:
530 /* Invalid Base */
531 return_ACPI_STATUS (AE_BAD_PARAMETER);
532 }
533
534 /* Skip over any white space in the buffer */
535
536 while (ACPI_IS_SPACE (*string) || *string == '\t') {
537 string++;
538 }
539
540 /*
541 * If the input parameter Base is zero, then we need to
542 * determine if it is decimal or hexadecimal:
543 */
544 if (base == 0) {
545 if ((*string == '0') &&
546 (ACPI_TOLOWER (*(string + 1)) == 'x')) {
547 base = 16;
548 string += 2;
549 }
550 else {
551 base = 10;
552 }
553 }
554
555 /*
556 * For hexadecimal base, skip over the leading
557 * 0 or 0x, if they are present.
558 */
559 if ((base == 16) &&
560 (*string == '0') &&
561 (ACPI_TOLOWER (*(string + 1)) == 'x')) {
562 string += 2;
563 }
564
565 /* Any string left? */
566
567 if (!(*string)) {
568 goto error_exit;
569 }
570
571 /* Main loop: convert the string to a 64-bit integer */
572
573 while (*string) {
574 if (ACPI_IS_DIGIT (*string)) {
575 /* Convert ASCII 0-9 to Decimal value */
576
577 this_digit = ((u8) *string) - '0';
578 }
579 else {
580 if (base == 10) {
581 /* Digit is out of range */
582
583 goto error_exit;
584 }
585
586 this_digit = (u8) ACPI_TOUPPER (*string);
587 if (ACPI_IS_XDIGIT ((char) this_digit)) {
588 /* Convert ASCII Hex char to value */
589
590 this_digit = this_digit - 'A' + 10;
591 }
592 else {
593 /*
594 * We allow non-hex chars, just stop now, same as end-of-string.
595 * See ACPI spec, string-to-integer conversion.
596 */
597 break;
598 }
599 }
600
601 /* Divide the digit into the correct position */
602
603 (void) acpi_ut_short_divide ((ACPI_INTEGER_MAX - (acpi_integer) this_digit),
604 base, &quotient, NULL);
605 if (return_value > quotient) {
606 goto error_exit;
607 }
608
609 return_value *= base;
610 return_value += this_digit;
611 string++;
612 }
613
614 /* All done, normal exit */
615
616 *ret_integer = return_value;
617 return_ACPI_STATUS (AE_OK);
618
619
620error_exit:
621 /* Base was set/validated above */
622
623 if (base == 10) {
624 return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT);
625 }
626 else {
627 return_ACPI_STATUS (AE_BAD_HEX_CONSTANT);
628 }
629}
630
631
632/*******************************************************************************
633 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634 * FUNCTION: acpi_ut_create_update_state_and_push
635 *
Robert Moore44f6c012005-04-18 22:49:35 -0400636 * PARAMETERS: Object - Object to be added to the new state
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 * Action - Increment/Decrement
638 * state_list - List the state will be added to
639 *
Robert Moore44f6c012005-04-18 22:49:35 -0400640 * RETURN: Status
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641 *
642 * DESCRIPTION: Create a new state and push it
643 *
644 ******************************************************************************/
645
646acpi_status
647acpi_ut_create_update_state_and_push (
648 union acpi_operand_object *object,
649 u16 action,
650 union acpi_generic_state **state_list)
651{
652 union acpi_generic_state *state;
653
654
655 ACPI_FUNCTION_ENTRY ();
656
657
658 /* Ignore null objects; these are expected */
659
660 if (!object) {
661 return (AE_OK);
662 }
663
664 state = acpi_ut_create_update_state (object, action);
665 if (!state) {
666 return (AE_NO_MEMORY);
667 }
668
669 acpi_ut_push_generic_state (state_list, state);
670 return (AE_OK);
671}
672
673
674/*******************************************************************************
675 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700676 * FUNCTION: acpi_ut_walk_package_tree
677 *
Robert Moore44f6c012005-04-18 22:49:35 -0400678 * PARAMETERS: source_object - The package to walk
679 * target_object - Target object (if package is being copied)
680 * walk_callback - Called once for each package element
681 * Context - Passed to the callback function
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 *
683 * RETURN: Status
684 *
685 * DESCRIPTION: Walk through a package
686 *
687 ******************************************************************************/
688
689acpi_status
690acpi_ut_walk_package_tree (
691 union acpi_operand_object *source_object,
692 void *target_object,
693 acpi_pkg_callback walk_callback,
694 void *context)
695{
696 acpi_status status = AE_OK;
697 union acpi_generic_state *state_list = NULL;
698 union acpi_generic_state *state;
699 u32 this_index;
700 union acpi_operand_object *this_source_obj;
701
702
703 ACPI_FUNCTION_TRACE ("ut_walk_package_tree");
704
705
706 state = acpi_ut_create_pkg_state (source_object, target_object, 0);
707 if (!state) {
708 return_ACPI_STATUS (AE_NO_MEMORY);
709 }
710
711 while (state) {
712 /* Get one element of the package */
713
714 this_index = state->pkg.index;
715 this_source_obj = (union acpi_operand_object *)
716 state->pkg.source_object->package.elements[this_index];
717
718 /*
719 * Check for:
720 * 1) An uninitialized package element. It is completely
721 * legal to declare a package and leave it uninitialized
722 * 2) Not an internal object - can be a namespace node instead
723 * 3) Any type other than a package. Packages are handled in else
724 * case below.
725 */
726 if ((!this_source_obj) ||
727 (ACPI_GET_DESCRIPTOR_TYPE (this_source_obj) != ACPI_DESC_TYPE_OPERAND) ||
728 (ACPI_GET_OBJECT_TYPE (this_source_obj) != ACPI_TYPE_PACKAGE)) {
729 status = walk_callback (ACPI_COPY_TYPE_SIMPLE, this_source_obj,
730 state, context);
731 if (ACPI_FAILURE (status)) {
732 return_ACPI_STATUS (status);
733 }
734
735 state->pkg.index++;
736 while (state->pkg.index >= state->pkg.source_object->package.count) {
737 /*
738 * We've handled all of the objects at this level, This means
739 * that we have just completed a package. That package may
740 * have contained one or more packages itself.
741 *
742 * Delete this state and pop the previous state (package).
743 */
744 acpi_ut_delete_generic_state (state);
745 state = acpi_ut_pop_generic_state (&state_list);
746
747 /* Finished when there are no more states */
748
749 if (!state) {
750 /*
751 * We have handled all of the objects in the top level
752 * package just add the length of the package objects
753 * and exit
754 */
755 return_ACPI_STATUS (AE_OK);
756 }
757
758 /*
759 * Go back up a level and move the index past the just
760 * completed package object.
761 */
762 state->pkg.index++;
763 }
764 }
765 else {
766 /* This is a subobject of type package */
767
768 status = walk_callback (ACPI_COPY_TYPE_PACKAGE, this_source_obj,
769 state, context);
770 if (ACPI_FAILURE (status)) {
771 return_ACPI_STATUS (status);
772 }
773
774 /*
775 * Push the current state and create a new one
776 * The callback above returned a new target package object.
777 */
778 acpi_ut_push_generic_state (&state_list, state);
779 state = acpi_ut_create_pkg_state (this_source_obj,
780 state->pkg.this_target_obj, 0);
781 if (!state) {
782 return_ACPI_STATUS (AE_NO_MEMORY);
783 }
784 }
785 }
786
787 /* We should never get here */
788
789 return_ACPI_STATUS (AE_AML_INTERNAL);
790}
791
792
793/*******************************************************************************
794 *
795 * FUNCTION: acpi_ut_generate_checksum
796 *
797 * PARAMETERS: Buffer - Buffer to be scanned
798 * Length - number of bytes to examine
799 *
Robert Moore44f6c012005-04-18 22:49:35 -0400800 * RETURN: The generated checksum
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801 *
802 * DESCRIPTION: Generate a checksum on a raw buffer
803 *
804 ******************************************************************************/
805
806u8
807acpi_ut_generate_checksum (
808 u8 *buffer,
809 u32 length)
810{
811 u32 i;
812 signed char sum = 0;
813
814
815 for (i = 0; i < length; i++) {
816 sum = (signed char) (sum + buffer[i]);
817 }
818
819 return ((u8) (0 - sum));
820}
821
822
823/*******************************************************************************
824 *
825 * FUNCTION: acpi_ut_get_resource_end_tag
826 *
827 * PARAMETERS: obj_desc - The resource template buffer object
828 *
829 * RETURN: Pointer to the end tag
830 *
831 * DESCRIPTION: Find the END_TAG resource descriptor in a resource template
832 *
833 ******************************************************************************/
834
835
836u8 *
837acpi_ut_get_resource_end_tag (
838 union acpi_operand_object *obj_desc)
839{
840 u8 buffer_byte;
841 u8 *buffer;
842 u8 *end_buffer;
843
844
845 buffer = obj_desc->buffer.pointer;
846 end_buffer = buffer + obj_desc->buffer.length;
847
848 while (buffer < end_buffer) {
849 buffer_byte = *buffer;
850 if (buffer_byte & ACPI_RDESC_TYPE_MASK) {
851 /* Large Descriptor - Length is next 2 bytes */
852
853 buffer += ((*(buffer+1) | (*(buffer+2) << 8)) + 3);
854 }
855 else {
856 /* Small Descriptor. End Tag will be found here */
857
858 if ((buffer_byte & ACPI_RDESC_SMALL_MASK) == ACPI_RDESC_TYPE_END_TAG) {
859 /* Found the end tag descriptor, all done. */
860
861 return (buffer);
862 }
863
864 /* Length is in the header */
865
866 buffer += ((buffer_byte & 0x07) + 1);
867 }
868 }
869
870 /* End tag not found */
871
872 return (NULL);
873}
874
875
876/*******************************************************************************
877 *
878 * FUNCTION: acpi_ut_report_error
879 *
880 * PARAMETERS: module_name - Caller's module name (for error output)
881 * line_number - Caller's line number (for error output)
882 * component_id - Caller's component ID (for error output)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883 *
884 * RETURN: None
885 *
886 * DESCRIPTION: Print error message
887 *
888 ******************************************************************************/
889
890void
891acpi_ut_report_error (
892 char *module_name,
893 u32 line_number,
894 u32 component_id)
895{
896
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897 acpi_os_printf ("%8s-%04d: *** Error: ", module_name, line_number);
898}
899
900
901/*******************************************************************************
902 *
903 * FUNCTION: acpi_ut_report_warning
904 *
905 * PARAMETERS: module_name - Caller's module name (for error output)
906 * line_number - Caller's line number (for error output)
907 * component_id - Caller's component ID (for error output)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908 *
909 * RETURN: None
910 *
911 * DESCRIPTION: Print warning message
912 *
913 ******************************************************************************/
914
915void
916acpi_ut_report_warning (
917 char *module_name,
918 u32 line_number,
919 u32 component_id)
920{
921
922 acpi_os_printf ("%8s-%04d: *** Warning: ", module_name, line_number);
923}
924
925
926/*******************************************************************************
927 *
928 * FUNCTION: acpi_ut_report_info
929 *
930 * PARAMETERS: module_name - Caller's module name (for error output)
931 * line_number - Caller's line number (for error output)
932 * component_id - Caller's component ID (for error output)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700933 *
934 * RETURN: None
935 *
936 * DESCRIPTION: Print information message
937 *
938 ******************************************************************************/
939
940void
941acpi_ut_report_info (
942 char *module_name,
943 u32 line_number,
944 u32 component_id)
945{
946
947 acpi_os_printf ("%8s-%04d: *** Info: ", module_name, line_number);
948}
949
950