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