diff options
Diffstat (limited to 'drivers/acpi/utilities/utmisc.c')
-rw-r--r-- | drivers/acpi/utilities/utmisc.c | 799 |
1 files changed, 120 insertions, 679 deletions
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index f6de4ed3d527..1d350b302a34 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c | |||
@@ -49,15 +49,121 @@ | |||
49 | #define _COMPONENT ACPI_UTILITIES | 49 | #define _COMPONENT ACPI_UTILITIES |
50 | ACPI_MODULE_NAME ("utmisc") | 50 | ACPI_MODULE_NAME ("utmisc") |
51 | 51 | ||
52 | /* Local prototypes */ | ||
53 | 52 | ||
54 | static acpi_status | 53 | /******************************************************************************* |
55 | acpi_ut_create_mutex ( | 54 | * |
56 | acpi_mutex_handle mutex_id); | 55 | * FUNCTION: acpi_ut_allocate_owner_id |
56 | * | ||
57 | * PARAMETERS: owner_id - Where the new owner ID is returned | ||
58 | * | ||
59 | * RETURN: Status | ||
60 | * | ||
61 | * DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to | ||
62 | * track objects created by the table or method, to be deleted | ||
63 | * when the method exits or the table is unloaded. | ||
64 | * | ||
65 | ******************************************************************************/ | ||
66 | |||
67 | acpi_status | ||
68 | acpi_ut_allocate_owner_id ( | ||
69 | acpi_owner_id *owner_id) | ||
70 | { | ||
71 | acpi_native_uint i; | ||
72 | acpi_status status; | ||
73 | |||
74 | |||
75 | ACPI_FUNCTION_TRACE ("ut_allocate_owner_id"); | ||
57 | 76 | ||
58 | static acpi_status | 77 | |
59 | acpi_ut_delete_mutex ( | 78 | /* Mutex for the global ID mask */ |
60 | acpi_mutex_handle mutex_id); | 79 | |
80 | status = acpi_ut_acquire_mutex (ACPI_MTX_CACHES); | ||
81 | if (ACPI_FAILURE (status)) { | ||
82 | return_ACPI_STATUS (status); | ||
83 | } | ||
84 | |||
85 | /* Find a free owner ID */ | ||
86 | |||
87 | for (i = 0; i < 32; i++) { | ||
88 | if (!(acpi_gbl_owner_id_mask & (1 << i))) { | ||
89 | acpi_gbl_owner_id_mask |= (1 << i); | ||
90 | *owner_id = (acpi_owner_id) (i + 1); | ||
91 | goto exit; | ||
92 | } | ||
93 | } | ||
94 | |||
95 | /* | ||
96 | * If we are here, all owner_ids have been allocated. This probably should | ||
97 | * not happen since the IDs are reused after deallocation. The IDs are | ||
98 | * allocated upon table load (one per table) and method execution, and | ||
99 | * they are released when a table is unloaded or a method completes | ||
100 | * execution. | ||
101 | */ | ||
102 | *owner_id = 0; | ||
103 | status = AE_OWNER_ID_LIMIT; | ||
104 | ACPI_REPORT_ERROR (( | ||
105 | "Could not allocate new owner_id (32 max), AE_OWNER_ID_LIMIT\n")); | ||
106 | |||
107 | exit: | ||
108 | (void) acpi_ut_release_mutex (ACPI_MTX_CACHES); | ||
109 | return_ACPI_STATUS (status); | ||
110 | } | ||
111 | |||
112 | |||
113 | /******************************************************************************* | ||
114 | * | ||
115 | * FUNCTION: acpi_ut_release_owner_id | ||
116 | * | ||
117 | * PARAMETERS: owner_id_ptr - Pointer to a previously allocated owner_iD | ||
118 | * | ||
119 | * RETURN: None. No error is returned because we are either exiting a | ||
120 | * control method or unloading a table. Either way, we would | ||
121 | * ignore any error anyway. | ||
122 | * | ||
123 | * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 32 | ||
124 | * | ||
125 | ******************************************************************************/ | ||
126 | |||
127 | void | ||
128 | acpi_ut_release_owner_id ( | ||
129 | acpi_owner_id *owner_id_ptr) | ||
130 | { | ||
131 | acpi_owner_id owner_id = *owner_id_ptr; | ||
132 | acpi_status status; | ||
133 | |||
134 | |||
135 | ACPI_FUNCTION_TRACE ("ut_release_owner_id"); | ||
136 | |||
137 | |||
138 | /* Always clear the input owner_id (zero is an invalid ID) */ | ||
139 | |||
140 | *owner_id_ptr = 0; | ||
141 | |||
142 | /* Zero is not a valid owner_iD */ | ||
143 | |||
144 | if ((owner_id == 0) || (owner_id > 32)) { | ||
145 | ACPI_REPORT_ERROR (("Invalid owner_id: %2.2X\n", owner_id)); | ||
146 | return_VOID; | ||
147 | } | ||
148 | |||
149 | /* Mutex for the global ID mask */ | ||
150 | |||
151 | status = acpi_ut_acquire_mutex (ACPI_MTX_CACHES); | ||
152 | if (ACPI_FAILURE (status)) { | ||
153 | return_VOID; | ||
154 | } | ||
155 | |||
156 | owner_id--; /* Normalize to zero */ | ||
157 | |||
158 | /* Free the owner ID only if it is valid */ | ||
159 | |||
160 | if (acpi_gbl_owner_id_mask & (1 << owner_id)) { | ||
161 | acpi_gbl_owner_id_mask ^= (1 << owner_id); | ||
162 | } | ||
163 | |||
164 | (void) acpi_ut_release_mutex (ACPI_MTX_CACHES); | ||
165 | return_VOID; | ||
166 | } | ||
61 | 167 | ||
62 | 168 | ||
63 | /******************************************************************************* | 169 | /******************************************************************************* |
@@ -66,7 +172,7 @@ acpi_ut_delete_mutex ( | |||
66 | * | 172 | * |
67 | * PARAMETERS: src_string - The source string to convert | 173 | * PARAMETERS: src_string - The source string to convert |
68 | * | 174 | * |
69 | * RETURN: Converted src_string (same as input pointer) | 175 | * RETURN: None |
70 | * | 176 | * |
71 | * DESCRIPTION: Convert string to uppercase | 177 | * DESCRIPTION: Convert string to uppercase |
72 | * | 178 | * |
@@ -74,7 +180,7 @@ acpi_ut_delete_mutex ( | |||
74 | * | 180 | * |
75 | ******************************************************************************/ | 181 | ******************************************************************************/ |
76 | 182 | ||
77 | char * | 183 | void |
78 | acpi_ut_strupr ( | 184 | acpi_ut_strupr ( |
79 | char *src_string) | 185 | char *src_string) |
80 | { | 186 | { |
@@ -84,13 +190,17 @@ acpi_ut_strupr ( | |||
84 | ACPI_FUNCTION_ENTRY (); | 190 | ACPI_FUNCTION_ENTRY (); |
85 | 191 | ||
86 | 192 | ||
193 | if (!src_string) { | ||
194 | return; | ||
195 | } | ||
196 | |||
87 | /* Walk entire string, uppercasing the letters */ | 197 | /* Walk entire string, uppercasing the letters */ |
88 | 198 | ||
89 | for (string = src_string; *string; string++) { | 199 | for (string = src_string; *string; string++) { |
90 | *string = (char) ACPI_TOUPPER (*string); | 200 | *string = (char) ACPI_TOUPPER (*string); |
91 | } | 201 | } |
92 | 202 | ||
93 | return (src_string); | 203 | return; |
94 | } | 204 | } |
95 | 205 | ||
96 | 206 | ||
@@ -543,320 +653,6 @@ error_exit: | |||
543 | 653 | ||
544 | /******************************************************************************* | 654 | /******************************************************************************* |
545 | * | 655 | * |
546 | * FUNCTION: acpi_ut_mutex_initialize | ||
547 | * | ||
548 | * PARAMETERS: None. | ||
549 | * | ||
550 | * RETURN: Status | ||
551 | * | ||
552 | * DESCRIPTION: Create the system mutex objects. | ||
553 | * | ||
554 | ******************************************************************************/ | ||
555 | |||
556 | acpi_status | ||
557 | acpi_ut_mutex_initialize ( | ||
558 | void) | ||
559 | { | ||
560 | u32 i; | ||
561 | acpi_status status; | ||
562 | |||
563 | |||
564 | ACPI_FUNCTION_TRACE ("ut_mutex_initialize"); | ||
565 | |||
566 | |||
567 | /* | ||
568 | * Create each of the predefined mutex objects | ||
569 | */ | ||
570 | for (i = 0; i < NUM_MUTEX; i++) { | ||
571 | status = acpi_ut_create_mutex (i); | ||
572 | if (ACPI_FAILURE (status)) { | ||
573 | return_ACPI_STATUS (status); | ||
574 | } | ||
575 | } | ||
576 | |||
577 | status = acpi_os_create_lock (&acpi_gbl_gpe_lock); | ||
578 | return_ACPI_STATUS (status); | ||
579 | } | ||
580 | |||
581 | |||
582 | /******************************************************************************* | ||
583 | * | ||
584 | * FUNCTION: acpi_ut_mutex_terminate | ||
585 | * | ||
586 | * PARAMETERS: None. | ||
587 | * | ||
588 | * RETURN: None. | ||
589 | * | ||
590 | * DESCRIPTION: Delete all of the system mutex objects. | ||
591 | * | ||
592 | ******************************************************************************/ | ||
593 | |||
594 | void | ||
595 | acpi_ut_mutex_terminate ( | ||
596 | void) | ||
597 | { | ||
598 | u32 i; | ||
599 | |||
600 | |||
601 | ACPI_FUNCTION_TRACE ("ut_mutex_terminate"); | ||
602 | |||
603 | |||
604 | /* | ||
605 | * Delete each predefined mutex object | ||
606 | */ | ||
607 | for (i = 0; i < NUM_MUTEX; i++) { | ||
608 | (void) acpi_ut_delete_mutex (i); | ||
609 | } | ||
610 | |||
611 | acpi_os_delete_lock (acpi_gbl_gpe_lock); | ||
612 | return_VOID; | ||
613 | } | ||
614 | |||
615 | |||
616 | /******************************************************************************* | ||
617 | * | ||
618 | * FUNCTION: acpi_ut_create_mutex | ||
619 | * | ||
620 | * PARAMETERS: mutex_iD - ID of the mutex to be created | ||
621 | * | ||
622 | * RETURN: Status | ||
623 | * | ||
624 | * DESCRIPTION: Create a mutex object. | ||
625 | * | ||
626 | ******************************************************************************/ | ||
627 | |||
628 | static acpi_status | ||
629 | acpi_ut_create_mutex ( | ||
630 | acpi_mutex_handle mutex_id) | ||
631 | { | ||
632 | acpi_status status = AE_OK; | ||
633 | |||
634 | |||
635 | ACPI_FUNCTION_TRACE_U32 ("ut_create_mutex", mutex_id); | ||
636 | |||
637 | |||
638 | if (mutex_id > MAX_MUTEX) { | ||
639 | return_ACPI_STATUS (AE_BAD_PARAMETER); | ||
640 | } | ||
641 | |||
642 | if (!acpi_gbl_mutex_info[mutex_id].mutex) { | ||
643 | status = acpi_os_create_semaphore (1, 1, | ||
644 | &acpi_gbl_mutex_info[mutex_id].mutex); | ||
645 | acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; | ||
646 | acpi_gbl_mutex_info[mutex_id].use_count = 0; | ||
647 | } | ||
648 | |||
649 | return_ACPI_STATUS (status); | ||
650 | } | ||
651 | |||
652 | |||
653 | /******************************************************************************* | ||
654 | * | ||
655 | * FUNCTION: acpi_ut_delete_mutex | ||
656 | * | ||
657 | * PARAMETERS: mutex_iD - ID of the mutex to be deleted | ||
658 | * | ||
659 | * RETURN: Status | ||
660 | * | ||
661 | * DESCRIPTION: Delete a mutex object. | ||
662 | * | ||
663 | ******************************************************************************/ | ||
664 | |||
665 | static acpi_status | ||
666 | acpi_ut_delete_mutex ( | ||
667 | acpi_mutex_handle mutex_id) | ||
668 | { | ||
669 | acpi_status status; | ||
670 | |||
671 | |||
672 | ACPI_FUNCTION_TRACE_U32 ("ut_delete_mutex", mutex_id); | ||
673 | |||
674 | |||
675 | if (mutex_id > MAX_MUTEX) { | ||
676 | return_ACPI_STATUS (AE_BAD_PARAMETER); | ||
677 | } | ||
678 | |||
679 | status = acpi_os_delete_semaphore (acpi_gbl_mutex_info[mutex_id].mutex); | ||
680 | |||
681 | acpi_gbl_mutex_info[mutex_id].mutex = NULL; | ||
682 | acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; | ||
683 | |||
684 | return_ACPI_STATUS (status); | ||
685 | } | ||
686 | |||
687 | |||
688 | /******************************************************************************* | ||
689 | * | ||
690 | * FUNCTION: acpi_ut_acquire_mutex | ||
691 | * | ||
692 | * PARAMETERS: mutex_iD - ID of the mutex to be acquired | ||
693 | * | ||
694 | * RETURN: Status | ||
695 | * | ||
696 | * DESCRIPTION: Acquire a mutex object. | ||
697 | * | ||
698 | ******************************************************************************/ | ||
699 | |||
700 | acpi_status | ||
701 | acpi_ut_acquire_mutex ( | ||
702 | acpi_mutex_handle mutex_id) | ||
703 | { | ||
704 | acpi_status status; | ||
705 | u32 this_thread_id; | ||
706 | |||
707 | |||
708 | ACPI_FUNCTION_NAME ("ut_acquire_mutex"); | ||
709 | |||
710 | |||
711 | if (mutex_id > MAX_MUTEX) { | ||
712 | return (AE_BAD_PARAMETER); | ||
713 | } | ||
714 | |||
715 | this_thread_id = acpi_os_get_thread_id (); | ||
716 | |||
717 | #ifdef ACPI_MUTEX_DEBUG | ||
718 | { | ||
719 | u32 i; | ||
720 | /* | ||
721 | * Mutex debug code, for internal debugging only. | ||
722 | * | ||
723 | * Deadlock prevention. Check if this thread owns any mutexes of value | ||
724 | * greater than or equal to this one. If so, the thread has violated | ||
725 | * the mutex ordering rule. This indicates a coding error somewhere in | ||
726 | * the ACPI subsystem code. | ||
727 | */ | ||
728 | for (i = mutex_id; i < MAX_MUTEX; i++) { | ||
729 | if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) { | ||
730 | if (i == mutex_id) { | ||
731 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
732 | "Mutex [%s] already acquired by this thread [%X]\n", | ||
733 | acpi_ut_get_mutex_name (mutex_id), this_thread_id)); | ||
734 | |||
735 | return (AE_ALREADY_ACQUIRED); | ||
736 | } | ||
737 | |||
738 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
739 | "Invalid acquire order: Thread %X owns [%s], wants [%s]\n", | ||
740 | this_thread_id, acpi_ut_get_mutex_name (i), | ||
741 | acpi_ut_get_mutex_name (mutex_id))); | ||
742 | |||
743 | return (AE_ACQUIRE_DEADLOCK); | ||
744 | } | ||
745 | } | ||
746 | } | ||
747 | #endif | ||
748 | |||
749 | ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, | ||
750 | "Thread %X attempting to acquire Mutex [%s]\n", | ||
751 | this_thread_id, acpi_ut_get_mutex_name (mutex_id))); | ||
752 | |||
753 | status = acpi_os_wait_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, | ||
754 | 1, ACPI_WAIT_FOREVER); | ||
755 | if (ACPI_SUCCESS (status)) { | ||
756 | ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X acquired Mutex [%s]\n", | ||
757 | this_thread_id, acpi_ut_get_mutex_name (mutex_id))); | ||
758 | |||
759 | acpi_gbl_mutex_info[mutex_id].use_count++; | ||
760 | acpi_gbl_mutex_info[mutex_id].owner_id = this_thread_id; | ||
761 | } | ||
762 | else { | ||
763 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
764 | "Thread %X could not acquire Mutex [%s] %s\n", | ||
765 | this_thread_id, acpi_ut_get_mutex_name (mutex_id), | ||
766 | acpi_format_exception (status))); | ||
767 | } | ||
768 | |||
769 | return (status); | ||
770 | } | ||
771 | |||
772 | |||
773 | /******************************************************************************* | ||
774 | * | ||
775 | * FUNCTION: acpi_ut_release_mutex | ||
776 | * | ||
777 | * PARAMETERS: mutex_iD - ID of the mutex to be released | ||
778 | * | ||
779 | * RETURN: Status | ||
780 | * | ||
781 | * DESCRIPTION: Release a mutex object. | ||
782 | * | ||
783 | ******************************************************************************/ | ||
784 | |||
785 | acpi_status | ||
786 | acpi_ut_release_mutex ( | ||
787 | acpi_mutex_handle mutex_id) | ||
788 | { | ||
789 | acpi_status status; | ||
790 | u32 i; | ||
791 | u32 this_thread_id; | ||
792 | |||
793 | |||
794 | ACPI_FUNCTION_NAME ("ut_release_mutex"); | ||
795 | |||
796 | |||
797 | this_thread_id = acpi_os_get_thread_id (); | ||
798 | ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, | ||
799 | "Thread %X releasing Mutex [%s]\n", this_thread_id, | ||
800 | acpi_ut_get_mutex_name (mutex_id))); | ||
801 | |||
802 | if (mutex_id > MAX_MUTEX) { | ||
803 | return (AE_BAD_PARAMETER); | ||
804 | } | ||
805 | |||
806 | /* | ||
807 | * Mutex must be acquired in order to release it! | ||
808 | */ | ||
809 | if (acpi_gbl_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) { | ||
810 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
811 | "Mutex [%s] is not acquired, cannot release\n", | ||
812 | acpi_ut_get_mutex_name (mutex_id))); | ||
813 | |||
814 | return (AE_NOT_ACQUIRED); | ||
815 | } | ||
816 | |||
817 | /* | ||
818 | * Deadlock prevention. Check if this thread owns any mutexes of value | ||
819 | * greater than this one. If so, the thread has violated the mutex | ||
820 | * ordering rule. This indicates a coding error somewhere in | ||
821 | * the ACPI subsystem code. | ||
822 | */ | ||
823 | for (i = mutex_id; i < MAX_MUTEX; i++) { | ||
824 | if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) { | ||
825 | if (i == mutex_id) { | ||
826 | continue; | ||
827 | } | ||
828 | |||
829 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
830 | "Invalid release order: owns [%s], releasing [%s]\n", | ||
831 | acpi_ut_get_mutex_name (i), acpi_ut_get_mutex_name (mutex_id))); | ||
832 | |||
833 | return (AE_RELEASE_DEADLOCK); | ||
834 | } | ||
835 | } | ||
836 | |||
837 | /* Mark unlocked FIRST */ | ||
838 | |||
839 | acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; | ||
840 | |||
841 | status = acpi_os_signal_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, 1); | ||
842 | |||
843 | if (ACPI_FAILURE (status)) { | ||
844 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
845 | "Thread %X could not release Mutex [%s] %s\n", | ||
846 | this_thread_id, acpi_ut_get_mutex_name (mutex_id), | ||
847 | acpi_format_exception (status))); | ||
848 | } | ||
849 | else { | ||
850 | ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X released Mutex [%s]\n", | ||
851 | this_thread_id, acpi_ut_get_mutex_name (mutex_id))); | ||
852 | } | ||
853 | |||
854 | return (status); | ||
855 | } | ||
856 | |||
857 | |||
858 | /******************************************************************************* | ||
859 | * | ||
860 | * FUNCTION: acpi_ut_create_update_state_and_push | 656 | * FUNCTION: acpi_ut_create_update_state_and_push |
861 | * | 657 | * |
862 | * PARAMETERS: Object - Object to be added to the new state | 658 | * PARAMETERS: Object - Object to be added to the new state |
@@ -899,361 +695,6 @@ acpi_ut_create_update_state_and_push ( | |||
899 | 695 | ||
900 | /******************************************************************************* | 696 | /******************************************************************************* |
901 | * | 697 | * |
902 | * FUNCTION: acpi_ut_create_pkg_state_and_push | ||
903 | * | ||
904 | * PARAMETERS: Object - Object to be added to the new state | ||
905 | * Action - Increment/Decrement | ||
906 | * state_list - List the state will be added to | ||
907 | * | ||
908 | * RETURN: Status | ||
909 | * | ||
910 | * DESCRIPTION: Create a new state and push it | ||
911 | * | ||
912 | ******************************************************************************/ | ||
913 | |||
914 | #ifdef ACPI_FUTURE_USAGE | ||
915 | acpi_status | ||
916 | acpi_ut_create_pkg_state_and_push ( | ||
917 | void *internal_object, | ||
918 | void *external_object, | ||
919 | u16 index, | ||
920 | union acpi_generic_state **state_list) | ||
921 | { | ||
922 | union acpi_generic_state *state; | ||
923 | |||
924 | |||
925 | ACPI_FUNCTION_ENTRY (); | ||
926 | |||
927 | |||
928 | state = acpi_ut_create_pkg_state (internal_object, external_object, index); | ||
929 | if (!state) { | ||
930 | return (AE_NO_MEMORY); | ||
931 | } | ||
932 | |||
933 | acpi_ut_push_generic_state (state_list, state); | ||
934 | return (AE_OK); | ||
935 | } | ||
936 | #endif /* ACPI_FUTURE_USAGE */ | ||
937 | |||
938 | /******************************************************************************* | ||
939 | * | ||
940 | * FUNCTION: acpi_ut_push_generic_state | ||
941 | * | ||
942 | * PARAMETERS: list_head - Head of the state stack | ||
943 | * State - State object to push | ||
944 | * | ||
945 | * RETURN: None | ||
946 | * | ||
947 | * DESCRIPTION: Push a state object onto a state stack | ||
948 | * | ||
949 | ******************************************************************************/ | ||
950 | |||
951 | void | ||
952 | acpi_ut_push_generic_state ( | ||
953 | union acpi_generic_state **list_head, | ||
954 | union acpi_generic_state *state) | ||
955 | { | ||
956 | ACPI_FUNCTION_TRACE ("ut_push_generic_state"); | ||
957 | |||
958 | |||
959 | /* Push the state object onto the front of the list (stack) */ | ||
960 | |||
961 | state->common.next = *list_head; | ||
962 | *list_head = state; | ||
963 | |||
964 | return_VOID; | ||
965 | } | ||
966 | |||
967 | |||
968 | /******************************************************************************* | ||
969 | * | ||
970 | * FUNCTION: acpi_ut_pop_generic_state | ||
971 | * | ||
972 | * PARAMETERS: list_head - Head of the state stack | ||
973 | * | ||
974 | * RETURN: The popped state object | ||
975 | * | ||
976 | * DESCRIPTION: Pop a state object from a state stack | ||
977 | * | ||
978 | ******************************************************************************/ | ||
979 | |||
980 | union acpi_generic_state * | ||
981 | acpi_ut_pop_generic_state ( | ||
982 | union acpi_generic_state **list_head) | ||
983 | { | ||
984 | union acpi_generic_state *state; | ||
985 | |||
986 | |||
987 | ACPI_FUNCTION_TRACE ("ut_pop_generic_state"); | ||
988 | |||
989 | |||
990 | /* Remove the state object at the head of the list (stack) */ | ||
991 | |||
992 | state = *list_head; | ||
993 | if (state) { | ||
994 | /* Update the list head */ | ||
995 | |||
996 | *list_head = state->common.next; | ||
997 | } | ||
998 | |||
999 | return_PTR (state); | ||
1000 | } | ||
1001 | |||
1002 | |||
1003 | /******************************************************************************* | ||
1004 | * | ||
1005 | * FUNCTION: acpi_ut_create_generic_state | ||
1006 | * | ||
1007 | * PARAMETERS: None | ||
1008 | * | ||
1009 | * RETURN: The new state object. NULL on failure. | ||
1010 | * | ||
1011 | * DESCRIPTION: Create a generic state object. Attempt to obtain one from | ||
1012 | * the global state cache; If none available, create a new one. | ||
1013 | * | ||
1014 | ******************************************************************************/ | ||
1015 | |||
1016 | union acpi_generic_state * | ||
1017 | acpi_ut_create_generic_state ( | ||
1018 | void) | ||
1019 | { | ||
1020 | union acpi_generic_state *state; | ||
1021 | |||
1022 | |||
1023 | ACPI_FUNCTION_ENTRY (); | ||
1024 | |||
1025 | |||
1026 | state = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_STATE); | ||
1027 | |||
1028 | /* Initialize */ | ||
1029 | |||
1030 | if (state) { | ||
1031 | state->common.data_type = ACPI_DESC_TYPE_STATE; | ||
1032 | } | ||
1033 | |||
1034 | return (state); | ||
1035 | } | ||
1036 | |||
1037 | |||
1038 | /******************************************************************************* | ||
1039 | * | ||
1040 | * FUNCTION: acpi_ut_create_thread_state | ||
1041 | * | ||
1042 | * PARAMETERS: None | ||
1043 | * | ||
1044 | * RETURN: New Thread State. NULL on failure | ||
1045 | * | ||
1046 | * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used | ||
1047 | * to track per-thread info during method execution | ||
1048 | * | ||
1049 | ******************************************************************************/ | ||
1050 | |||
1051 | struct acpi_thread_state * | ||
1052 | acpi_ut_create_thread_state ( | ||
1053 | void) | ||
1054 | { | ||
1055 | union acpi_generic_state *state; | ||
1056 | |||
1057 | |||
1058 | ACPI_FUNCTION_TRACE ("ut_create_thread_state"); | ||
1059 | |||
1060 | |||
1061 | /* Create the generic state object */ | ||
1062 | |||
1063 | state = acpi_ut_create_generic_state (); | ||
1064 | if (!state) { | ||
1065 | return_PTR (NULL); | ||
1066 | } | ||
1067 | |||
1068 | /* Init fields specific to the update struct */ | ||
1069 | |||
1070 | state->common.data_type = ACPI_DESC_TYPE_STATE_THREAD; | ||
1071 | state->thread.thread_id = acpi_os_get_thread_id (); | ||
1072 | |||
1073 | return_PTR ((struct acpi_thread_state *) state); | ||
1074 | } | ||
1075 | |||
1076 | |||
1077 | /******************************************************************************* | ||
1078 | * | ||
1079 | * FUNCTION: acpi_ut_create_update_state | ||
1080 | * | ||
1081 | * PARAMETERS: Object - Initial Object to be installed in the state | ||
1082 | * Action - Update action to be performed | ||
1083 | * | ||
1084 | * RETURN: New state object, null on failure | ||
1085 | * | ||
1086 | * DESCRIPTION: Create an "Update State" - a flavor of the generic state used | ||
1087 | * to update reference counts and delete complex objects such | ||
1088 | * as packages. | ||
1089 | * | ||
1090 | ******************************************************************************/ | ||
1091 | |||
1092 | union acpi_generic_state * | ||
1093 | acpi_ut_create_update_state ( | ||
1094 | union acpi_operand_object *object, | ||
1095 | u16 action) | ||
1096 | { | ||
1097 | union acpi_generic_state *state; | ||
1098 | |||
1099 | |||
1100 | ACPI_FUNCTION_TRACE_PTR ("ut_create_update_state", object); | ||
1101 | |||
1102 | |||
1103 | /* Create the generic state object */ | ||
1104 | |||
1105 | state = acpi_ut_create_generic_state (); | ||
1106 | if (!state) { | ||
1107 | return_PTR (NULL); | ||
1108 | } | ||
1109 | |||
1110 | /* Init fields specific to the update struct */ | ||
1111 | |||
1112 | state->common.data_type = ACPI_DESC_TYPE_STATE_UPDATE; | ||
1113 | state->update.object = object; | ||
1114 | state->update.value = action; | ||
1115 | |||
1116 | return_PTR (state); | ||
1117 | } | ||
1118 | |||
1119 | |||
1120 | /******************************************************************************* | ||
1121 | * | ||
1122 | * FUNCTION: acpi_ut_create_pkg_state | ||
1123 | * | ||
1124 | * PARAMETERS: Object - Initial Object to be installed in the state | ||
1125 | * Action - Update action to be performed | ||
1126 | * | ||
1127 | * RETURN: New state object, null on failure | ||
1128 | * | ||
1129 | * DESCRIPTION: Create a "Package State" | ||
1130 | * | ||
1131 | ******************************************************************************/ | ||
1132 | |||
1133 | union acpi_generic_state * | ||
1134 | acpi_ut_create_pkg_state ( | ||
1135 | void *internal_object, | ||
1136 | void *external_object, | ||
1137 | u16 index) | ||
1138 | { | ||
1139 | union acpi_generic_state *state; | ||
1140 | |||
1141 | |||
1142 | ACPI_FUNCTION_TRACE_PTR ("ut_create_pkg_state", internal_object); | ||
1143 | |||
1144 | |||
1145 | /* Create the generic state object */ | ||
1146 | |||
1147 | state = acpi_ut_create_generic_state (); | ||
1148 | if (!state) { | ||
1149 | return_PTR (NULL); | ||
1150 | } | ||
1151 | |||
1152 | /* Init fields specific to the update struct */ | ||
1153 | |||
1154 | state->common.data_type = ACPI_DESC_TYPE_STATE_PACKAGE; | ||
1155 | state->pkg.source_object = (union acpi_operand_object *) internal_object; | ||
1156 | state->pkg.dest_object = external_object; | ||
1157 | state->pkg.index = index; | ||
1158 | state->pkg.num_packages = 1; | ||
1159 | |||
1160 | return_PTR (state); | ||
1161 | } | ||
1162 | |||
1163 | |||
1164 | /******************************************************************************* | ||
1165 | * | ||
1166 | * FUNCTION: acpi_ut_create_control_state | ||
1167 | * | ||
1168 | * PARAMETERS: None | ||
1169 | * | ||
1170 | * RETURN: New state object, null on failure | ||
1171 | * | ||
1172 | * DESCRIPTION: Create a "Control State" - a flavor of the generic state used | ||
1173 | * to support nested IF/WHILE constructs in the AML. | ||
1174 | * | ||
1175 | ******************************************************************************/ | ||
1176 | |||
1177 | union acpi_generic_state * | ||
1178 | acpi_ut_create_control_state ( | ||
1179 | void) | ||
1180 | { | ||
1181 | union acpi_generic_state *state; | ||
1182 | |||
1183 | |||
1184 | ACPI_FUNCTION_TRACE ("ut_create_control_state"); | ||
1185 | |||
1186 | |||
1187 | /* Create the generic state object */ | ||
1188 | |||
1189 | state = acpi_ut_create_generic_state (); | ||
1190 | if (!state) { | ||
1191 | return_PTR (NULL); | ||
1192 | } | ||
1193 | |||
1194 | /* Init fields specific to the control struct */ | ||
1195 | |||
1196 | state->common.data_type = ACPI_DESC_TYPE_STATE_CONTROL; | ||
1197 | state->common.state = ACPI_CONTROL_CONDITIONAL_EXECUTING; | ||
1198 | |||
1199 | return_PTR (state); | ||
1200 | } | ||
1201 | |||
1202 | |||
1203 | /******************************************************************************* | ||
1204 | * | ||
1205 | * FUNCTION: acpi_ut_delete_generic_state | ||
1206 | * | ||
1207 | * PARAMETERS: State - The state object to be deleted | ||
1208 | * | ||
1209 | * RETURN: None | ||
1210 | * | ||
1211 | * DESCRIPTION: Put a state object back into the global state cache. The object | ||
1212 | * is not actually freed at this time. | ||
1213 | * | ||
1214 | ******************************************************************************/ | ||
1215 | |||
1216 | void | ||
1217 | acpi_ut_delete_generic_state ( | ||
1218 | union acpi_generic_state *state) | ||
1219 | { | ||
1220 | ACPI_FUNCTION_TRACE ("ut_delete_generic_state"); | ||
1221 | |||
1222 | |||
1223 | acpi_ut_release_to_cache (ACPI_MEM_LIST_STATE, state); | ||
1224 | return_VOID; | ||
1225 | } | ||
1226 | |||
1227 | |||
1228 | #ifdef ACPI_ENABLE_OBJECT_CACHE | ||
1229 | /******************************************************************************* | ||
1230 | * | ||
1231 | * FUNCTION: acpi_ut_delete_generic_state_cache | ||
1232 | * | ||
1233 | * PARAMETERS: None | ||
1234 | * | ||
1235 | * RETURN: None | ||
1236 | * | ||
1237 | * DESCRIPTION: Purge the global state object cache. Used during subsystem | ||
1238 | * termination. | ||
1239 | * | ||
1240 | ******************************************************************************/ | ||
1241 | |||
1242 | void | ||
1243 | acpi_ut_delete_generic_state_cache ( | ||
1244 | void) | ||
1245 | { | ||
1246 | ACPI_FUNCTION_TRACE ("ut_delete_generic_state_cache"); | ||
1247 | |||
1248 | |||
1249 | acpi_ut_delete_generic_cache (ACPI_MEM_LIST_STATE); | ||
1250 | return_VOID; | ||
1251 | } | ||
1252 | #endif | ||
1253 | |||
1254 | |||
1255 | /******************************************************************************* | ||
1256 | * | ||
1257 | * FUNCTION: acpi_ut_walk_package_tree | 698 | * FUNCTION: acpi_ut_walk_package_tree |
1258 | * | 699 | * |
1259 | * PARAMETERS: source_object - The package to walk | 700 | * PARAMETERS: source_object - The package to walk |