aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/tables/tbinstal.c
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2007-02-02 11:48:18 -0500
committerLen Brown <len.brown@intel.com>2007-02-02 21:14:21 -0500
commitf3d2e7865c816258c699ff965768e46b50d536d3 (patch)
tree83d21269e506109275b77d3ed161883bba8a39cf /drivers/acpi/tables/tbinstal.c
parent2e42005bcdb4f63bed1cea7f537a5534d4bd7a57 (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/tables/tbinstal.c')
-rw-r--r--drivers/acpi/tables/tbinstal.c650
1 files changed, 317 insertions, 333 deletions
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
index 1668a232fb67..9076ca0913b7 100644
--- a/drivers/acpi/tables/tbinstal.c
+++ b/drivers/acpi/tables/tbinstal.c
@@ -42,510 +42,494 @@
42 */ 42 */
43 43
44#include <acpi/acpi.h> 44#include <acpi/acpi.h>
45#include <acpi/acnamesp.h>
45#include <acpi/actables.h> 46#include <acpi/actables.h>
46 47
47#define _COMPONENT ACPI_TABLES 48#define _COMPONENT ACPI_TABLES
48ACPI_MODULE_NAME("tbinstal") 49ACPI_MODULE_NAME("tbinstal")
49 50
50/* Local prototypes */ 51/******************************************************************************
51static acpi_status
52acpi_tb_match_signature(char *signature,
53 struct acpi_table_desc *table_info, u8 search_type);
54
55/*******************************************************************************
56 * 52 *
57 * FUNCTION: acpi_tb_match_signature 53 * FUNCTION: acpi_tb_verify_table
58 * 54 *
59 * PARAMETERS: Signature - Table signature to match 55 * PARAMETERS: table_desc - table
60 * table_info - Return data
61 * search_type - Table type to match (primary/secondary)
62 * 56 *
63 * RETURN: Status 57 * RETURN: Status
64 * 58 *
65 * DESCRIPTION: Compare signature against the list of "ACPI-subsystem-owned" 59 * DESCRIPTION: this function is called to verify and map table
66 * tables (DSDT/FADT/SSDT, etc.) Returns the table_type_iD on match.
67 * 60 *
68 ******************************************************************************/ 61 *****************************************************************************/
69 62acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
70static acpi_status
71acpi_tb_match_signature(char *signature,
72 struct acpi_table_desc *table_info, u8 search_type)
73{ 63{
74 acpi_native_uint i; 64 u8 checksum;
75 65
76 ACPI_FUNCTION_TRACE(tb_match_signature); 66 ACPI_FUNCTION_TRACE(tb_verify_table);
77 67
78 /* Search for a signature match among the known table types */ 68 /* Map the table if necessary */
79 69
80 for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) { 70 if (!table_desc->pointer) {
81 if (!(acpi_gbl_table_data[i].flags & search_type)) { 71 table_desc->pointer =
82 continue; 72 acpi_tb_map(table_desc->address, table_desc->length,
73 table_desc->flags & ACPI_TABLE_ORIGIN_MASK);
74 if (!table_desc->pointer) {
75 return_ACPI_STATUS(AE_NO_MEMORY);
83 } 76 }
77 }
84 78
85 if (!ACPI_STRNCMP(signature, acpi_gbl_table_data[i].signature, 79 /* FACS is the odd table, has no standard ACPI header and no checksum */
86 acpi_gbl_table_data[i].sig_length)) {
87 80
88 /* Found a signature match, return index if requested */ 81 if (ACPI_COMPARE_NAME(&(table_desc->signature), ACPI_SIG_FACS)) {
82 return_ACPI_STATUS(AE_OK);
83 }
89 84
90 if (table_info) { 85 /* Always calculate checksum, ignore bad checksum if requested */
91 table_info->type = (u8) i;
92 }
93 86
94 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 87 checksum = acpi_tb_checksum(ACPI_CAST_PTR(void, table_desc->pointer),
95 "Table [%4.4s] is an ACPI table consumed by the core subsystem\n", 88 table_desc->length);
96 (char *)acpi_gbl_table_data[i].
97 signature));
98 89
99 return_ACPI_STATUS(AE_OK); 90#if (ACPI_CHECKSUM_ABORT)
100 }
101 }
102 91
103 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 92 if (checksum) {
104 "Table [%4.4s] is not an ACPI table consumed by the core subsystem - ignored\n", 93 return_ACPI_STATUS(AE_BAD_CHECKSUM);
105 (char *)signature)); 94 }
95#endif
106 96
107 return_ACPI_STATUS(AE_TABLE_NOT_SUPPORTED); 97 return_ACPI_STATUS(AE_OK);
108} 98}
109 99
110/******************************************************************************* 100/*******************************************************************************
111 * 101 *
112 * FUNCTION: acpi_tb_install_table 102 * FUNCTION: acpi_tb_add_table
113 * 103 *
114 * PARAMETERS: table_info - Return value from acpi_tb_get_table_body 104 * PARAMETERS: Table - Pointer to the table header
105 * table_index - Where the table index is returned
115 * 106 *
116 * RETURN: Status 107 * RETURN: Status
117 * 108 *
118 * DESCRIPTION: Install the table into the global data structures. 109 * DESCRIPTION: This function is called to add the ACPI table
119 * 110 *
120 ******************************************************************************/ 111 ******************************************************************************/
121 112
122acpi_status acpi_tb_install_table(struct acpi_table_desc *table_info) 113acpi_status
114acpi_tb_add_table(struct acpi_table_header *table,
115 acpi_native_uint * table_index)
123{ 116{
124 acpi_status status; 117 acpi_native_uint i;
118 acpi_native_uint length;
119 acpi_status status = AE_OK;
125 120
126 ACPI_FUNCTION_TRACE(tb_install_table); 121 ACPI_FUNCTION_TRACE(tb_add_table);
127 122
128 /* Lock tables while installing */ 123 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
129 124
130 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 125 /* Check if table is already registered */
131 if (ACPI_FAILURE(status)) { 126
132 ACPI_EXCEPTION((AE_INFO, status, 127 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
133 "Could not acquire table mutex")); 128 if (!acpi_gbl_root_table_list.tables[i].pointer) {
134 return_ACPI_STATUS(status); 129 status =
130 acpi_tb_verify_table(&acpi_gbl_root_table_list.
131 tables[i]);
132 if (ACPI_FAILURE(status)
133 || !acpi_gbl_root_table_list.tables[i].pointer) {
134 continue;
135 }
136 }
137
138 length = ACPI_MIN(table->length,
139 acpi_gbl_root_table_list.tables[i].pointer->
140 length);
141 if (ACPI_MEMCMP
142 (table, acpi_gbl_root_table_list.tables[i].pointer,
143 length)) {
144 continue;
145 }
146
147 /* Table is already registered */
148
149 ACPI_FREE(table);
150 *table_index = i;
151 goto release;
135 } 152 }
136 153
137 /* 154 /*
138 * Ignore a table that is already installed. For example, some BIOS 155 * Add the table to the global table list
139 * ASL code will repeatedly attempt to load the same SSDT.
140 */ 156 */
141 status = acpi_tb_is_table_installed(table_info); 157 status = acpi_tb_store_table(ACPI_TO_INTEGER(table),
158 table, table->length,
159 ACPI_TABLE_ORIGIN_ALLOCATED, table_index);
142 if (ACPI_FAILURE(status)) { 160 if (ACPI_FAILURE(status)) {
143 goto unlock_and_exit; 161 goto release;
144 } 162 }
145 163
146 /* Install the table into the global data structure */ 164 acpi_tb_print_table_header(0, table);
147 165
148 status = acpi_tb_init_table_descriptor(table_info->type, table_info); 166 release:
149 if (ACPI_FAILURE(status)) {
150 ACPI_EXCEPTION((AE_INFO, status,
151 "Could not install table [%4.4s]",
152 table_info->pointer->signature));
153 }
154
155 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s located at %p\n",
156 acpi_gbl_table_data[table_info->type].name,
157 table_info->pointer));
158
159 unlock_and_exit:
160 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 167 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
161 return_ACPI_STATUS(status); 168 return_ACPI_STATUS(status);
162} 169}
163 170
164/******************************************************************************* 171/*******************************************************************************
165 * 172 *
166 * FUNCTION: acpi_tb_recognize_table 173 * FUNCTION: acpi_tb_resize_root_table_list
167 * 174 *
168 * PARAMETERS: table_info - Return value from acpi_tb_get_table_body 175 * PARAMETERS: None
169 * search_type - Table type to match (primary/secondary)
170 * 176 *
171 * RETURN: Status 177 * RETURN: Status
172 * 178 *
173 * DESCRIPTION: Check a table signature for a match against known table types 179 * DESCRIPTION: Expand the size of global table array
174 *
175 * NOTE: All table pointers are validated as follows:
176 * 1) Table pointer must point to valid physical memory
177 * 2) Signature must be 4 ASCII chars, even if we don't recognize the
178 * name
179 * 3) Table must be readable for length specified in the header
180 * 4) Table checksum must be valid (with the exception of the FACS
181 * which has no checksum for some odd reason)
182 * 180 *
183 ******************************************************************************/ 181 ******************************************************************************/
184 182
185acpi_status 183acpi_status acpi_tb_resize_root_table_list(void)
186acpi_tb_recognize_table(struct acpi_table_desc *table_info, u8 search_type)
187{ 184{
188 struct acpi_table_header *table_header; 185 struct acpi_table_desc *tables;
189 acpi_status status;
190 186
191 ACPI_FUNCTION_TRACE(tb_recognize_table); 187 ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
192 188
193 /* Ensure that we have a valid table pointer */ 189 /* allow_resize flag is a parameter to acpi_initialize_tables */
194 190
195 table_header = (struct acpi_table_header *)table_info->pointer; 191 if (!(acpi_gbl_root_table_list.flags & ACPI_TABLE_FLAGS_ALLOW_RESIZE)) {
196 if (!table_header) { 192 ACPI_ERROR((AE_INFO,
197 return_ACPI_STATUS(AE_BAD_PARAMETER); 193 "Resize of Root Table Array is not allowed"));
194 return_ACPI_STATUS(AE_SUPPORT);
198 } 195 }
199 196
200 /* 197 /* Increase the Table Array size */
201 * We only "recognize" a limited number of ACPI tables -- namely, the 198
202 * ones that are used by the subsystem (DSDT, FADT, etc.) 199 tables = ACPI_ALLOCATE_ZEROED((acpi_gbl_root_table_list.size +
203 * 200 ACPI_ROOT_TABLE_SIZE_INCREMENT)
204 * An AE_TABLE_NOT_SUPPORTED means that the table was not recognized. 201 * sizeof(struct acpi_table_desc));
205 * This can be any one of many valid ACPI tables, it just isn't one of 202 if (!tables) {
206 * the tables that is consumed by the core subsystem 203 ACPI_ERROR((AE_INFO,
207 */ 204 "Could not allocate new root table array"));
208 status = acpi_tb_match_signature(table_header->signature, 205 return_ACPI_STATUS(AE_NO_MEMORY);
209 table_info, search_type);
210 if (ACPI_FAILURE(status)) {
211 return_ACPI_STATUS(status);
212 } 206 }
213 207
214 status = acpi_tb_validate_table_header(table_header); 208 /* Copy and free the previous table array */
215 if (ACPI_FAILURE(status)) { 209
216 return_ACPI_STATUS(status); 210 if (acpi_gbl_root_table_list.tables) {
211 ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
212 acpi_gbl_root_table_list.size *
213 sizeof(struct acpi_table_desc));
214
215 if (acpi_gbl_root_table_list.flags & ACPI_TABLE_ORIGIN_MASK ==
216 ACPI_TABLE_ORIGIN_ALLOCATED) {
217 ACPI_FREE(acpi_gbl_root_table_list.tables);
218 }
217 } 219 }
218 220
219 /* Return the table type and length via the info struct */ 221 acpi_gbl_root_table_list.tables = tables;
222 acpi_gbl_root_table_list.size += ACPI_ROOT_TABLE_SIZE_INCREMENT;
223 acpi_gbl_root_table_list.flags = (u8) (ACPI_TABLE_ORIGIN_ALLOCATED |
224 (acpi_gbl_root_table_list.
225 flags &
226 ~ACPI_TABLE_ORIGIN_MASK));
220 227
221 table_info->length = (acpi_size) table_header->length; 228 return_ACPI_STATUS(AE_OK);
222 return_ACPI_STATUS(status);
223} 229}
224 230
225/******************************************************************************* 231/*******************************************************************************
226 * 232 *
227 * FUNCTION: acpi_tb_init_table_descriptor 233 * FUNCTION: acpi_tb_store_table
228 * 234 *
229 * PARAMETERS: table_type - The type of the table 235 * PARAMETERS: Address - Table address
230 * table_info - A table info struct 236 * Table - Table header
237 * Length - Table length
238 * Flags - flags
231 * 239 *
232 * RETURN: None. 240 * RETURN: Status and table index.
233 * 241 *
234 * DESCRIPTION: Install a table into the global data structs. 242 * DESCRIPTION: Add an ACPI table to the global table list
235 * 243 *
236 ******************************************************************************/ 244 ******************************************************************************/
237 245
238acpi_status 246acpi_status
239acpi_tb_init_table_descriptor(acpi_table_type table_type, 247acpi_tb_store_table(acpi_physical_address address,
240 struct acpi_table_desc *table_info) 248 struct acpi_table_header *table,
249 u32 length, u8 flags, acpi_native_uint * table_index)
241{ 250{
242 struct acpi_table_list *list_head; 251 acpi_status status = AE_OK;
243 struct acpi_table_desc *table_desc;
244 acpi_status status;
245
246 ACPI_FUNCTION_TRACE_U32(tb_init_table_descriptor, table_type);
247
248 /* Allocate a descriptor for this table */
249 252
250 table_desc = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_table_desc)); 253 /* Ensure that there is room for the table in the Root Table List */
251 if (!table_desc) {
252 return_ACPI_STATUS(AE_NO_MEMORY);
253 }
254
255 /* Get a new owner ID for the table */
256 254
257 status = acpi_ut_allocate_owner_id(&table_desc->owner_id); 255 if (acpi_gbl_root_table_list.count >= acpi_gbl_root_table_list.size) {
258 if (ACPI_FAILURE(status)) { 256 status = acpi_tb_resize_root_table_list();
259 goto error_exit1; 257 if (ACPI_FAILURE(status)) {
258 return (status);
259 }
260 } 260 }
261 261
262 /* Install the table into the global data structure */ 262 /* Initialize added table */
263 263
264 list_head = &acpi_gbl_table_lists[table_type]; 264 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
265 address = address;
266 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
267 pointer = table;
268 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].length =
269 length;
270 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
271 owner_id = 0;
272 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].flags =
273 flags;
274
275 ACPI_MOVE_32_TO_32(&
276 (acpi_gbl_root_table_list.
277 tables[acpi_gbl_root_table_list.count].signature),
278 table->signature);
279
280 *table_index = acpi_gbl_root_table_list.count;
281 acpi_gbl_root_table_list.count++;
282 return (status);
283}
265 284
266 /* 285/*******************************************************************************
267 * Two major types of tables: 1) Only one instance is allowed. This 286 *
268 * includes most ACPI tables such as the DSDT. 2) Multiple instances of 287 * FUNCTION: acpi_tb_delete_table
269 * the table are allowed. This includes SSDT and PSDTs. 288 *
270 */ 289 * PARAMETERS: table_index - Table index
271 if (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags)) { 290 *
272 /* 291 * RETURN: None
273 * Only one table allowed, and a table has alread been installed 292 *
274 * at this location, so return an error. 293 * DESCRIPTION: Delete one internal ACPI table
275 */ 294 *
276 if (list_head->next) { 295 ******************************************************************************/
277 status = AE_ALREADY_EXISTS;
278 goto error_exit2;
279 }
280 296
281 table_desc->next = list_head->next; 297void acpi_tb_delete_table(acpi_native_uint table_index)
282 list_head->next = table_desc; 298{
299 struct acpi_table_desc *table_desc;
283 300
284 if (table_desc->next) { 301 /* table_index assumed valid */
285 table_desc->next->prev = table_desc;
286 }
287 302
288 list_head->count++; 303 table_desc = &acpi_gbl_root_table_list.tables[table_index];
289 } else {
290 /*
291 * Link the new table in to the list of tables of this type.
292 * Insert at the end of the list, order IS IMPORTANT.
293 *
294 * table_desc->Prev & Next are already NULL from calloc()
295 */
296 list_head->count++;
297
298 if (!list_head->next) {
299 list_head->next = table_desc;
300 } else {
301 table_desc->next = list_head->next;
302 304
303 while (table_desc->next->next) { 305 /* Table must be mapped or allocated */
304 table_desc->next = table_desc->next->next;
305 }
306 306
307 table_desc->next->next = table_desc; 307 if (!table_desc->pointer) {
308 table_desc->prev = table_desc->next; 308 return;
309 table_desc->next = NULL;
310 }
311 } 309 }
312 310
313 /* Finish initialization of the table descriptor */ 311 if (table_desc->flags & ACPI_TABLE_ORIGIN_MAPPED) {
314 312 acpi_tb_unmap(table_desc->pointer, table_desc->length,
315 table_desc->loaded_into_namespace = FALSE; 313 table_desc->flags & ACPI_TABLE_ORIGIN_MASK);
316 table_desc->type = (u8) table_type; 314 } else if (table_desc->flags & ACPI_TABLE_ORIGIN_ALLOCATED) {
317 table_desc->pointer = table_info->pointer; 315 ACPI_FREE(table_desc->pointer);
318 table_desc->length = table_info->length;
319 table_desc->allocation = table_info->allocation;
320 table_desc->aml_start = (u8 *) (table_desc->pointer + 1),
321 table_desc->aml_length = (u32)
322 (table_desc->length - (u32) sizeof(struct acpi_table_header));
323
324 /*
325 * Set the appropriate global pointer (if there is one) to point to the
326 * newly installed table
327 */
328 if (acpi_gbl_table_data[table_type].global_ptr) {
329 *(acpi_gbl_table_data[table_type].global_ptr) =
330 table_info->pointer;
331 } 316 }
332 317
333 /* Return Data */ 318 table_desc->pointer = NULL;
334
335 table_info->owner_id = table_desc->owner_id;
336 table_info->installed_desc = table_desc;
337 return_ACPI_STATUS(AE_OK);
338
339 /* Error exit with cleanup */
340
341 error_exit2:
342
343 acpi_ut_release_owner_id(&table_desc->owner_id);
344
345 error_exit1:
346
347 ACPI_FREE(table_desc);
348 return_ACPI_STATUS(status);
349} 319}
350 320
351/******************************************************************************* 321/*******************************************************************************
352 * 322 *
353 * FUNCTION: acpi_tb_delete_all_tables 323 * FUNCTION: acpi_tb_terminate
354 * 324 *
355 * PARAMETERS: None. 325 * PARAMETERS: None
356 * 326 *
357 * RETURN: None. 327 * RETURN: None
358 * 328 *
359 * DESCRIPTION: Delete all internal ACPI tables 329 * DESCRIPTION: Delete all internal ACPI tables
360 * 330 *
361 ******************************************************************************/ 331 ******************************************************************************/
362 332
363void acpi_tb_delete_all_tables(void) 333void acpi_tb_terminate(void)
364{ 334{
365 acpi_table_type type; 335 acpi_native_uint i;
336
337 ACPI_FUNCTION_TRACE(tb_terminate);
338
339 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
340
341 /* Delete the individual tables */
342
343 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
344 acpi_tb_delete_table(i);
345 }
366 346
367 /* 347 /*
368 * Free memory allocated for ACPI tables 348 * Delete the root table array if allocated locally. Array cannot be
369 * Memory can either be mapped or allocated 349 * mapped, so we don't need to check for that flag.
370 */ 350 */
371 for (type = 0; type < (ACPI_TABLE_ID_MAX + 1); type++) { 351 if ((acpi_gbl_root_table_list.flags & ACPI_TABLE_ORIGIN_MASK) ==
372 acpi_tb_delete_tables_by_type(type); 352 ACPI_TABLE_ORIGIN_ALLOCATED) {
353 ACPI_FREE(acpi_gbl_root_table_list.tables);
373 } 354 }
355
356 acpi_gbl_root_table_list.tables = NULL;
357 acpi_gbl_root_table_list.flags = 0;
358 acpi_gbl_root_table_list.count = 0;
359
360 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
361 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
374} 362}
375 363
376/******************************************************************************* 364/*******************************************************************************
377 * 365 *
378 * FUNCTION: acpi_tb_delete_tables_by_type 366 * FUNCTION: acpi_tb_delete_namespace_by_owner
379 * 367 *
380 * PARAMETERS: Type - The table type to be deleted 368 * PARAMETERS: table_index - Table index
381 * 369 *
382 * RETURN: None. 370 * RETURN: None
383 * 371 *
384 * DESCRIPTION: Delete an internal ACPI table 372 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
385 * Locks the ACPI table mutex
386 * 373 *
387 ******************************************************************************/ 374 ******************************************************************************/
388 375
389void acpi_tb_delete_tables_by_type(acpi_table_type type) 376void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index)
390{ 377{
391 struct acpi_table_desc *table_desc; 378 acpi_owner_id owner_id;
392 u32 count;
393 u32 i;
394
395 ACPI_FUNCTION_TRACE_U32(tb_delete_tables_by_type, type);
396
397 if (type > ACPI_TABLE_ID_MAX) {
398 return_VOID;
399 }
400 379
401 if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_TABLES))) { 380 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
381 if (table_index < acpi_gbl_root_table_list.count) {
382 owner_id =
383 acpi_gbl_root_table_list.tables[table_index].owner_id;
384 } else {
385 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
402 return; 386 return;
403 } 387 }
404 388
405 /* Clear the appropriate "typed" global table pointer */ 389 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
406 390 acpi_ns_delete_namespace_by_owner(owner_id);
407 switch (type) { 391}
408 case ACPI_TABLE_ID_RSDP:
409 acpi_gbl_RSDP = NULL;
410 break;
411
412 case ACPI_TABLE_ID_DSDT:
413 acpi_gbl_DSDT = NULL;
414 break;
415
416 case ACPI_TABLE_ID_FADT:
417 acpi_gbl_FADT = NULL;
418 break;
419
420 case ACPI_TABLE_ID_FACS:
421 acpi_gbl_FACS = NULL;
422 break;
423 392
424 case ACPI_TABLE_ID_XSDT: 393/*******************************************************************************
425 acpi_gbl_XSDT = NULL; 394 *
426 break; 395 * FUNCTION: acpi_tb_allocate_owner_id
396 *
397 * PARAMETERS: table_index - Table index
398 *
399 * RETURN: Status
400 *
401 * DESCRIPTION: Allocates owner_id in table_desc
402 *
403 ******************************************************************************/
427 404
428 case ACPI_TABLE_ID_SSDT: 405acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index)
429 case ACPI_TABLE_ID_PSDT: 406{
430 default: 407 acpi_status status = AE_BAD_PARAMETER;
431 break;
432 }
433 408
434 /* 409 ACPI_FUNCTION_TRACE(tb_allocate_owner_id);
435 * Free the table
436 * 1) Get the head of the list
437 */
438 table_desc = acpi_gbl_table_lists[type].next;
439 count = acpi_gbl_table_lists[type].count;
440 410
441 /* 411 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
442 * 2) Walk the entire list, deleting both the allocated tables 412 if (table_index < acpi_gbl_root_table_list.count) {
443 * and the table descriptors 413 status = acpi_ut_allocate_owner_id
444 */ 414 (&(acpi_gbl_root_table_list.tables[table_index].owner_id));
445 for (i = 0; i < count; i++) {
446 table_desc = acpi_tb_uninstall_table(table_desc);
447 } 415 }
448 416
449 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 417 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
450 return_VOID; 418 return_ACPI_STATUS(status);
451} 419}
452 420
453/******************************************************************************* 421/*******************************************************************************
454 * 422 *
455 * FUNCTION: acpi_tb_delete_single_table 423 * FUNCTION: acpi_tb_release_owner_id
456 * 424 *
457 * PARAMETERS: table_info - A table info struct 425 * PARAMETERS: table_index - Table index
458 * 426 *
459 * RETURN: None. 427 * RETURN: Status
460 * 428 *
461 * DESCRIPTION: Low-level free for a single ACPI table. Handles cases where 429 * DESCRIPTION: Releases owner_id in table_desc
462 * the table was allocated a buffer or was mapped.
463 * 430 *
464 ******************************************************************************/ 431 ******************************************************************************/
465 432
466void acpi_tb_delete_single_table(struct acpi_table_desc *table_desc) 433acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index)
467{ 434{
435 acpi_status status = AE_BAD_PARAMETER;
468 436
469 /* Must have a valid table descriptor and pointer */ 437 ACPI_FUNCTION_TRACE(tb_release_owner_id);
470 438
471 if ((!table_desc) || (!table_desc->pointer)) { 439 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
472 return; 440 if (table_index < acpi_gbl_root_table_list.count) {
441 acpi_ut_release_owner_id(&
442 (acpi_gbl_root_table_list.
443 tables[table_index].owner_id));
444 status = AE_OK;
473 } 445 }
474 446
475 /* Valid table, determine type of memory allocation */ 447 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
476 448 return_ACPI_STATUS(status);
477 switch (table_desc->allocation) {
478 case ACPI_MEM_NOT_ALLOCATED:
479 break;
480
481 case ACPI_MEM_ALLOCATED:
482
483 ACPI_FREE(table_desc->pointer);
484 break;
485
486 case ACPI_MEM_MAPPED:
487
488 acpi_os_unmap_memory(table_desc->pointer, table_desc->length);
489 break;
490
491 default:
492 break;
493 }
494} 449}
495 450
496/******************************************************************************* 451/*******************************************************************************
497 * 452 *
498 * FUNCTION: acpi_tb_uninstall_table 453 * FUNCTION: acpi_tb_get_owner_id
499 * 454 *
500 * PARAMETERS: table_info - A table info struct 455 * PARAMETERS: table_index - Table index
456 * owner_id - Where the table owner_id is returned
501 * 457 *
502 * RETURN: Pointer to the next table in the list (of same type) 458 * RETURN: Status
503 * 459 *
504 * DESCRIPTION: Free the memory associated with an internal ACPI table that 460 * DESCRIPTION: returns owner_id for the ACPI table
505 * is either installed or has never been installed.
506 * Table mutex should be locked.
507 * 461 *
508 ******************************************************************************/ 462 ******************************************************************************/
509 463
510struct acpi_table_desc *acpi_tb_uninstall_table(struct acpi_table_desc 464acpi_status
511 *table_desc) 465acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id)
512{ 466{
513 struct acpi_table_desc *next_desc; 467 acpi_status status = AE_BAD_PARAMETER;
514 468
515 ACPI_FUNCTION_TRACE_PTR(tb_uninstall_table, table_desc); 469 ACPI_FUNCTION_TRACE(tb_get_owner_id);
516 470
517 if (!table_desc) { 471 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
518 return_PTR(NULL); 472 if (table_index < acpi_gbl_root_table_list.count) {
473 *owner_id =
474 acpi_gbl_root_table_list.tables[table_index].owner_id;
475 status = AE_OK;
519 } 476 }
520 477
521 /* Unlink the descriptor from the doubly linked list */ 478 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
479 return_ACPI_STATUS(status);
480}
522 481
523 if (table_desc->prev) { 482/*******************************************************************************
524 table_desc->prev->next = table_desc->next; 483 *
525 } else { 484 * FUNCTION: acpi_tb_is_table_loaded
526 /* Is first on list, update list head */ 485 *
486 * PARAMETERS: table_index - Table index
487 *
488 * RETURN: Table Loaded Flag
489 *
490 ******************************************************************************/
527 491
528 acpi_gbl_table_lists[table_desc->type].next = table_desc->next; 492u8 acpi_tb_is_table_loaded(acpi_native_uint table_index)
529 } 493{
494 u8 is_loaded = FALSE;
530 495
531 if (table_desc->next) { 496 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
532 table_desc->next->prev = table_desc->prev; 497 if (table_index < acpi_gbl_root_table_list.count) {
498 is_loaded = (u8)
499 (acpi_gbl_root_table_list.tables[table_index].
500 flags & ACPI_TABLE_FLAGS_LOADED);
533 } 501 }
534 502
535 /* Free the memory allocated for the table itself */ 503 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
536 504 return (is_loaded);
537 acpi_tb_delete_single_table(table_desc); 505}
538
539 /* Free the owner ID associated with this table */
540
541 acpi_ut_release_owner_id(&table_desc->owner_id);
542 506
543 /* Free the table descriptor */ 507/*******************************************************************************
508 *
509 * FUNCTION: acpi_tb_set_table_loaded_flag
510 *
511 * PARAMETERS: table_index - Table index
512 * is_loaded - TRUE if table is loaded, FALSE otherwise
513 *
514 * RETURN: None
515 *
516 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
517 *
518 ******************************************************************************/
544 519
545 next_desc = table_desc->next; 520void acpi_tb_set_table_loaded_flag(acpi_native_uint table_index, u8 is_loaded)
546 ACPI_FREE(table_desc); 521{
547 522
548 /* Return pointer to the next descriptor */ 523 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
524 if (table_index < acpi_gbl_root_table_list.count) {
525 if (is_loaded) {
526 acpi_gbl_root_table_list.tables[table_index].flags |=
527 ACPI_TABLE_FLAGS_LOADED;
528 } else {
529 acpi_gbl_root_table_list.tables[table_index].flags &=
530 ~ACPI_TABLE_FLAGS_LOADED;
531 }
532 }
549 533
550 return_PTR(next_desc); 534 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
551} 535}