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.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}