diff options
author | Bob Moore <robert.moore@intel.com> | 2007-02-02 11:48:18 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-02-02 21:14:21 -0500 |
commit | f3d2e7865c816258c699ff965768e46b50d536d3 (patch) | |
tree | 83d21269e506109275b77d3ed161883bba8a39cf /drivers/acpi/namespace | |
parent | 2e42005bcdb4f63bed1cea7f537a5534d4bd7a57 (diff) |
ACPICA: Implement simplified Table Manager
The Table Manager component has been completely
redesigned and reimplemented. The new design is much
simpler, and reduces the overall code and data size of
the kernel-resident ACPICA by approximately 5%. Also,
it is now possible to obtain the ACPI tables very early
during kernel initialization, even before dynamic memory
management is initialized.
Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/namespace')
-rw-r--r-- | drivers/acpi/namespace/nsload.c | 158 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsparse.c | 46 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsutils.c | 7 |
3 files changed, 64 insertions, 147 deletions
diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c index fe75d888e183..5d555f8c167b 100644 --- a/drivers/acpi/namespace/nsload.c +++ b/drivers/acpi/namespace/nsload.c | |||
@@ -44,13 +44,12 @@ | |||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acnamesp.h> | 45 | #include <acpi/acnamesp.h> |
46 | #include <acpi/acdispat.h> | 46 | #include <acpi/acdispat.h> |
47 | #include <acpi/actables.h> | ||
47 | 48 | ||
48 | #define _COMPONENT ACPI_NAMESPACE | 49 | #define _COMPONENT ACPI_NAMESPACE |
49 | ACPI_MODULE_NAME("nsload") | 50 | ACPI_MODULE_NAME("nsload") |
50 | 51 | ||
51 | /* Local prototypes */ | 52 | /* Local prototypes */ |
52 | static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type); | ||
53 | |||
54 | #ifdef ACPI_FUTURE_IMPLEMENTATION | 53 | #ifdef ACPI_FUTURE_IMPLEMENTATION |
55 | acpi_status acpi_ns_unload_namespace(acpi_handle handle); | 54 | acpi_status acpi_ns_unload_namespace(acpi_handle handle); |
56 | 55 | ||
@@ -62,7 +61,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle); | |||
62 | * | 61 | * |
63 | * FUNCTION: acpi_ns_load_table | 62 | * FUNCTION: acpi_ns_load_table |
64 | * | 63 | * |
65 | * PARAMETERS: table_desc - Descriptor for table to be loaded | 64 | * PARAMETERS: table_index - Index for table to be loaded |
66 | * Node - Owning NS node | 65 | * Node - Owning NS node |
67 | * | 66 | * |
68 | * RETURN: Status | 67 | * RETURN: Status |
@@ -72,42 +71,13 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle); | |||
72 | ******************************************************************************/ | 71 | ******************************************************************************/ |
73 | 72 | ||
74 | acpi_status | 73 | acpi_status |
75 | acpi_ns_load_table(struct acpi_table_desc *table_desc, | 74 | acpi_ns_load_table(acpi_native_uint table_index, |
76 | struct acpi_namespace_node *node) | 75 | struct acpi_namespace_node *node) |
77 | { | 76 | { |
78 | acpi_status status; | 77 | acpi_status status; |
79 | 78 | ||
80 | ACPI_FUNCTION_TRACE(ns_load_table); | 79 | ACPI_FUNCTION_TRACE(ns_load_table); |
81 | 80 | ||
82 | /* Check if table contains valid AML (must be DSDT, PSDT, SSDT, etc.) */ | ||
83 | |||
84 | if (! | ||
85 | (acpi_gbl_table_data[table_desc->type]. | ||
86 | flags & ACPI_TABLE_EXECUTABLE)) { | ||
87 | |||
88 | /* Just ignore this table */ | ||
89 | |||
90 | return_ACPI_STATUS(AE_OK); | ||
91 | } | ||
92 | |||
93 | /* Check validity of the AML start and length */ | ||
94 | |||
95 | if (!table_desc->aml_start) { | ||
96 | ACPI_ERROR((AE_INFO, "Null AML pointer")); | ||
97 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
98 | } | ||
99 | |||
100 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AML block at %p\n", | ||
101 | table_desc->aml_start)); | ||
102 | |||
103 | /* Ignore table if there is no AML contained within */ | ||
104 | |||
105 | if (!table_desc->aml_length) { | ||
106 | ACPI_WARNING((AE_INFO, "Zero-length AML block in table [%4.4s]", | ||
107 | table_desc->pointer->signature)); | ||
108 | return_ACPI_STATUS(AE_OK); | ||
109 | } | ||
110 | |||
111 | /* | 81 | /* |
112 | * Parse the table and load the namespace with all named | 82 | * Parse the table and load the namespace with all named |
113 | * objects found within. Control methods are NOT parsed | 83 | * objects found within. Control methods are NOT parsed |
@@ -117,15 +87,34 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc, | |||
117 | * to another control method, we can't continue parsing | 87 | * to another control method, we can't continue parsing |
118 | * because we don't know how many arguments to parse next! | 88 | * because we don't know how many arguments to parse next! |
119 | */ | 89 | */ |
90 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
91 | if (ACPI_FAILURE(status)) { | ||
92 | return_ACPI_STATUS(status); | ||
93 | } | ||
94 | |||
95 | /* If table already loaded into namespace, just return */ | ||
96 | |||
97 | if (acpi_tb_is_table_loaded(table_index)) { | ||
98 | status = AE_ALREADY_EXISTS; | ||
99 | goto unlock; | ||
100 | } | ||
101 | |||
120 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 102 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
121 | "**** Loading table into namespace ****\n")); | 103 | "**** Loading table into namespace ****\n")); |
122 | 104 | ||
123 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | 105 | status = acpi_tb_allocate_owner_id(table_index); |
124 | if (ACPI_FAILURE(status)) { | 106 | if (ACPI_FAILURE(status)) { |
125 | return_ACPI_STATUS(status); | 107 | goto unlock; |
108 | } | ||
109 | |||
110 | status = acpi_ns_parse_table(table_index, node->child); | ||
111 | if (ACPI_SUCCESS(status)) { | ||
112 | acpi_tb_set_table_loaded_flag(table_index, TRUE); | ||
113 | } else { | ||
114 | acpi_tb_release_owner_id(table_index); | ||
126 | } | 115 | } |
127 | 116 | ||
128 | status = acpi_ns_parse_table(table_desc, node->child); | 117 | unlock: |
129 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 118 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
130 | 119 | ||
131 | if (ACPI_FAILURE(status)) { | 120 | if (ACPI_FAILURE(status)) { |
@@ -141,7 +130,7 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc, | |||
141 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 130 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
142 | "**** Begin Table Method Parsing and Object Initialization ****\n")); | 131 | "**** Begin Table Method Parsing and Object Initialization ****\n")); |
143 | 132 | ||
144 | status = acpi_ds_initialize_objects(table_desc, node); | 133 | status = acpi_ds_initialize_objects(table_index, node); |
145 | 134 | ||
146 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 135 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
147 | "**** Completed Table Method Parsing and Object Initialization ****\n")); | 136 | "**** Completed Table Method Parsing and Object Initialization ****\n")); |
@@ -149,99 +138,7 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc, | |||
149 | return_ACPI_STATUS(status); | 138 | return_ACPI_STATUS(status); |
150 | } | 139 | } |
151 | 140 | ||
152 | /******************************************************************************* | 141 | #ifdef ACPI_OBSOLETE_FUNCTIONS |
153 | * | ||
154 | * FUNCTION: acpi_ns_load_table_by_type | ||
155 | * | ||
156 | * PARAMETERS: table_type - Id of the table type to load | ||
157 | * | ||
158 | * RETURN: Status | ||
159 | * | ||
160 | * DESCRIPTION: Load an ACPI table or tables into the namespace. All tables | ||
161 | * of the given type are loaded. The mechanism allows this | ||
162 | * routine to be called repeatedly. | ||
163 | * | ||
164 | ******************************************************************************/ | ||
165 | |||
166 | static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type) | ||
167 | { | ||
168 | u32 i; | ||
169 | acpi_status status; | ||
170 | struct acpi_table_desc *table_desc; | ||
171 | |||
172 | ACPI_FUNCTION_TRACE(ns_load_table_by_type); | ||
173 | |||
174 | status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
175 | if (ACPI_FAILURE(status)) { | ||
176 | return_ACPI_STATUS(status); | ||
177 | } | ||
178 | |||
179 | /* | ||
180 | * Table types supported are: | ||
181 | * DSDT (one), SSDT/PSDT (multiple) | ||
182 | */ | ||
183 | switch (table_type) { | ||
184 | case ACPI_TABLE_ID_DSDT: | ||
185 | |||
186 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace load: DSDT\n")); | ||
187 | |||
188 | table_desc = acpi_gbl_table_lists[ACPI_TABLE_ID_DSDT].next; | ||
189 | |||
190 | /* If table already loaded into namespace, just return */ | ||
191 | |||
192 | if (table_desc->loaded_into_namespace) { | ||
193 | goto unlock_and_exit; | ||
194 | } | ||
195 | |||
196 | /* Now load the single DSDT */ | ||
197 | |||
198 | status = acpi_ns_load_table(table_desc, acpi_gbl_root_node); | ||
199 | if (ACPI_SUCCESS(status)) { | ||
200 | table_desc->loaded_into_namespace = TRUE; | ||
201 | } | ||
202 | break; | ||
203 | |||
204 | case ACPI_TABLE_ID_SSDT: | ||
205 | case ACPI_TABLE_ID_PSDT: | ||
206 | |||
207 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
208 | "Namespace load: %d SSDT or PSDTs\n", | ||
209 | acpi_gbl_table_lists[table_type].count)); | ||
210 | |||
211 | /* | ||
212 | * Traverse list of SSDT or PSDT tables | ||
213 | */ | ||
214 | table_desc = acpi_gbl_table_lists[table_type].next; | ||
215 | for (i = 0; i < acpi_gbl_table_lists[table_type].count; i++) { | ||
216 | /* | ||
217 | * Only attempt to load table into namespace if it is not | ||
218 | * already loaded! | ||
219 | */ | ||
220 | if (!table_desc->loaded_into_namespace) { | ||
221 | status = | ||
222 | acpi_ns_load_table(table_desc, | ||
223 | acpi_gbl_root_node); | ||
224 | if (ACPI_FAILURE(status)) { | ||
225 | break; | ||
226 | } | ||
227 | |||
228 | table_desc->loaded_into_namespace = TRUE; | ||
229 | } | ||
230 | |||
231 | table_desc = table_desc->next; | ||
232 | } | ||
233 | break; | ||
234 | |||
235 | default: | ||
236 | status = AE_SUPPORT; | ||
237 | break; | ||
238 | } | ||
239 | |||
240 | unlock_and_exit: | ||
241 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
242 | return_ACPI_STATUS(status); | ||
243 | } | ||
244 | |||
245 | /******************************************************************************* | 142 | /******************************************************************************* |
246 | * | 143 | * |
247 | * FUNCTION: acpi_load_namespace | 144 | * FUNCTION: acpi_load_namespace |
@@ -288,6 +185,7 @@ acpi_status acpi_ns_load_namespace(void) | |||
288 | 185 | ||
289 | return_ACPI_STATUS(status); | 186 | return_ACPI_STATUS(status); |
290 | } | 187 | } |
188 | #endif | ||
291 | 189 | ||
292 | #ifdef ACPI_FUTURE_IMPLEMENTATION | 190 | #ifdef ACPI_FUTURE_IMPLEMENTATION |
293 | /******************************************************************************* | 191 | /******************************************************************************* |
diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c index 155505a4ef69..2e224796d56f 100644 --- a/drivers/acpi/namespace/nsparse.c +++ b/drivers/acpi/namespace/nsparse.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <acpi/acnamesp.h> | 45 | #include <acpi/acnamesp.h> |
46 | #include <acpi/acparser.h> | 46 | #include <acpi/acparser.h> |
47 | #include <acpi/acdispat.h> | 47 | #include <acpi/acdispat.h> |
48 | #include <acpi/actables.h> | ||
48 | 49 | ||
49 | #define _COMPONENT ACPI_NAMESPACE | 50 | #define _COMPONENT ACPI_NAMESPACE |
50 | ACPI_MODULE_NAME("nsparse") | 51 | ACPI_MODULE_NAME("nsparse") |
@@ -62,14 +63,24 @@ ACPI_MODULE_NAME("nsparse") | |||
62 | * | 63 | * |
63 | ******************************************************************************/ | 64 | ******************************************************************************/ |
64 | acpi_status | 65 | acpi_status |
65 | acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc) | 66 | acpi_ns_one_complete_parse(acpi_native_uint pass_number, |
67 | acpi_native_uint table_index) | ||
66 | { | 68 | { |
67 | union acpi_parse_object *parse_root; | 69 | union acpi_parse_object *parse_root; |
68 | acpi_status status; | 70 | acpi_status status; |
71 | acpi_native_uint aml_length; | ||
72 | u8 *aml_start; | ||
69 | struct acpi_walk_state *walk_state; | 73 | struct acpi_walk_state *walk_state; |
74 | struct acpi_table_header *table; | ||
75 | acpi_owner_id owner_id; | ||
70 | 76 | ||
71 | ACPI_FUNCTION_TRACE(ns_one_complete_parse); | 77 | ACPI_FUNCTION_TRACE(ns_one_complete_parse); |
72 | 78 | ||
79 | status = acpi_tb_get_owner_id(table_index, &owner_id); | ||
80 | if (ACPI_FAILURE(status)) { | ||
81 | return_ACPI_STATUS(status); | ||
82 | } | ||
83 | |||
73 | /* Create and init a Root Node */ | 84 | /* Create and init a Root Node */ |
74 | 85 | ||
75 | parse_root = acpi_ps_create_scope_op(); | 86 | parse_root = acpi_ps_create_scope_op(); |
@@ -79,19 +90,34 @@ acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc) | |||
79 | 90 | ||
80 | /* Create and initialize a new walk state */ | 91 | /* Create and initialize a new walk state */ |
81 | 92 | ||
82 | walk_state = acpi_ds_create_walk_state(table_desc->owner_id, | 93 | walk_state = acpi_ds_create_walk_state(owner_id, NULL, NULL, NULL); |
83 | NULL, NULL, NULL); | ||
84 | if (!walk_state) { | 94 | if (!walk_state) { |
85 | acpi_ps_free_op(parse_root); | 95 | acpi_ps_free_op(parse_root); |
86 | return_ACPI_STATUS(AE_NO_MEMORY); | 96 | return_ACPI_STATUS(AE_NO_MEMORY); |
87 | } | 97 | } |
88 | 98 | ||
89 | status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, | 99 | status = acpi_get_table_by_index(table_index, &table); |
90 | table_desc->aml_start, | 100 | if (ACPI_FAILURE(status)) { |
91 | table_desc->aml_length, NULL, | 101 | acpi_ds_delete_walk_state(walk_state); |
92 | pass_number); | 102 | acpi_ps_free_op(parse_root); |
103 | return_ACPI_STATUS(status); | ||
104 | } | ||
105 | |||
106 | /* Table must consist of at least a complete header */ | ||
107 | |||
108 | if (table->length < sizeof(struct acpi_table_header)) { | ||
109 | status = AE_BAD_HEADER; | ||
110 | } else { | ||
111 | aml_start = (u8 *) table + sizeof(struct acpi_table_header); | ||
112 | aml_length = table->length - sizeof(struct acpi_table_header); | ||
113 | status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, | ||
114 | aml_start, aml_length, NULL, | ||
115 | (u8) pass_number); | ||
116 | } | ||
117 | |||
93 | if (ACPI_FAILURE(status)) { | 118 | if (ACPI_FAILURE(status)) { |
94 | acpi_ds_delete_walk_state(walk_state); | 119 | acpi_ds_delete_walk_state(walk_state); |
120 | acpi_ps_delete_parse_tree(parse_root); | ||
95 | return_ACPI_STATUS(status); | 121 | return_ACPI_STATUS(status); |
96 | } | 122 | } |
97 | 123 | ||
@@ -119,7 +145,7 @@ acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc) | |||
119 | ******************************************************************************/ | 145 | ******************************************************************************/ |
120 | 146 | ||
121 | acpi_status | 147 | acpi_status |
122 | acpi_ns_parse_table(struct acpi_table_desc *table_desc, | 148 | acpi_ns_parse_table(acpi_native_uint table_index, |
123 | struct acpi_namespace_node *start_node) | 149 | struct acpi_namespace_node *start_node) |
124 | { | 150 | { |
125 | acpi_status status; | 151 | acpi_status status; |
@@ -137,7 +163,7 @@ acpi_ns_parse_table(struct acpi_table_desc *table_desc, | |||
137 | * performs another complete parse of the AML.. | 163 | * performs another complete parse of the AML.. |
138 | */ | 164 | */ |
139 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n")); | 165 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n")); |
140 | status = acpi_ns_one_complete_parse(1, table_desc); | 166 | status = acpi_ns_one_complete_parse(1, table_index); |
141 | if (ACPI_FAILURE(status)) { | 167 | if (ACPI_FAILURE(status)) { |
142 | return_ACPI_STATUS(status); | 168 | return_ACPI_STATUS(status); |
143 | } | 169 | } |
@@ -152,7 +178,7 @@ acpi_ns_parse_table(struct acpi_table_desc *table_desc, | |||
152 | * parse objects are all cached. | 178 | * parse objects are all cached. |
153 | */ | 179 | */ |
154 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n")); | 180 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n")); |
155 | status = acpi_ns_one_complete_parse(2, table_desc); | 181 | status = acpi_ns_one_complete_parse(2, table_index); |
156 | if (ACPI_FAILURE(status)) { | 182 | if (ACPI_FAILURE(status)) { |
157 | return_ACPI_STATUS(status); | 183 | return_ACPI_STATUS(status); |
158 | } | 184 | } |
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c index aa4e799d9a8c..4eb155cc406f 100644 --- a/drivers/acpi/namespace/nsutils.c +++ b/drivers/acpi/namespace/nsutils.c | |||
@@ -770,13 +770,6 @@ void acpi_ns_terminate(void) | |||
770 | } | 770 | } |
771 | 771 | ||
772 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n")); | 772 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n")); |
773 | |||
774 | /* | ||
775 | * 2) Now we can delete the ACPI tables | ||
776 | */ | ||
777 | acpi_tb_delete_all_tables(); | ||
778 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); | ||
779 | |||
780 | return_VOID; | 773 | return_VOID; |
781 | } | 774 | } |
782 | 775 | ||