[ACPI] ACPICA 20060210
[deliverable/linux.git] / drivers / acpi / tables / tbinstal.c
CommitLineData
1da177e4
LT
1/******************************************************************************
2 *
3 * Module Name: tbinstal - ACPI table installation and removal
4 *
5 *****************************************************************************/
6
7/*
4a90c7e8 8 * Copyright (C) 2000 - 2006, R. Byron Moore
1da177e4
LT
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
1da177e4
LT
44#include <acpi/acpi.h>
45#include <acpi/actables.h>
46
1da177e4 47#define _COMPONENT ACPI_TABLES
4be44fcd 48ACPI_MODULE_NAME("tbinstal")
1da177e4 49
44f6c012 50/* Local prototypes */
44f6c012 51static acpi_status
4be44fcd
LB
52acpi_tb_match_signature(char *signature,
53 struct acpi_table_desc *table_info, u8 search_type);
1da177e4
LT
54
55/*******************************************************************************
56 *
57 * FUNCTION: acpi_tb_match_signature
58 *
59 * PARAMETERS: Signature - Table signature to match
60 * table_info - Return data
44f6c012 61 * search_type - Table type to match (primary/secondary)
1da177e4
LT
62 *
63 * RETURN: Status
64 *
65 * DESCRIPTION: Compare signature against the list of "ACPI-subsystem-owned"
66 * tables (DSDT/FADT/SSDT, etc.) Returns the table_type_iD on match.
67 *
68 ******************************************************************************/
69
44f6c012 70static acpi_status
4be44fcd
LB
71acpi_tb_match_signature(char *signature,
72 struct acpi_table_desc *table_info, u8 search_type)
1da177e4 73{
4be44fcd 74 acpi_native_uint i;
1da177e4 75
4be44fcd 76 ACPI_FUNCTION_TRACE("tb_match_signature");
1da177e4 77
44f6c012
RM
78 /* Search for a signature match among the known table types */
79
1da177e4
LT
80 for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) {
81 if (!(acpi_gbl_table_data[i].flags & search_type)) {
82 continue;
83 }
84
4be44fcd
LB
85 if (!ACPI_STRNCMP(signature, acpi_gbl_table_data[i].signature,
86 acpi_gbl_table_data[i].sig_length)) {
52fc0b02 87
1da177e4
LT
88 /* Found a signature match, return index if requested */
89
90 if (table_info) {
91 table_info->type = (u8) i;
92 }
93
4be44fcd
LB
94 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
95 "Table [%4.4s] is an ACPI table consumed by the core subsystem\n",
96 (char *)acpi_gbl_table_data[i].
97 signature));
1da177e4 98
4be44fcd 99 return_ACPI_STATUS(AE_OK);
1da177e4
LT
100 }
101 }
102
4be44fcd
LB
103 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
104 "Table [%4.4s] is not an ACPI table consumed by the core subsystem - ignored\n",
105 (char *)signature));
1da177e4 106
4be44fcd 107 return_ACPI_STATUS(AE_TABLE_NOT_SUPPORTED);
1da177e4
LT
108}
109
1da177e4
LT
110/*******************************************************************************
111 *
112 * FUNCTION: acpi_tb_install_table
113 *
114 * PARAMETERS: table_info - Return value from acpi_tb_get_table_body
115 *
116 * RETURN: Status
117 *
0c9938cc 118 * DESCRIPTION: Install the table into the global data structures.
1da177e4
LT
119 *
120 ******************************************************************************/
121
4be44fcd 122acpi_status acpi_tb_install_table(struct acpi_table_desc *table_info)
1da177e4 123{
4be44fcd 124 acpi_status status;
1da177e4 125
4be44fcd 126 ACPI_FUNCTION_TRACE("tb_install_table");
1da177e4
LT
127
128 /* Lock tables while installing */
129
4be44fcd
LB
130 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
131 if (ACPI_FAILURE(status)) {
b8e4d893
BM
132 ACPI_EXCEPTION((AE_INFO, status,
133 "Could not acquire table mutex"));
4be44fcd 134 return_ACPI_STATUS(status);
1da177e4
LT
135 }
136
0c9938cc
RM
137 /*
138 * Ignore a table that is already installed. For example, some BIOS
139 * ASL code will repeatedly attempt to load the same SSDT.
140 */
4be44fcd
LB
141 status = acpi_tb_is_table_installed(table_info);
142 if (ACPI_FAILURE(status)) {
0c9938cc
RM
143 goto unlock_and_exit;
144 }
145
1da177e4
LT
146 /* Install the table into the global data structure */
147
4be44fcd
LB
148 status = acpi_tb_init_table_descriptor(table_info->type, table_info);
149 if (ACPI_FAILURE(status)) {
b8e4d893
BM
150 ACPI_EXCEPTION((AE_INFO, status,
151 "Could not install table [%4.4s]",
152 table_info->pointer->signature));
1da177e4
LT
153 }
154
4be44fcd
LB
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));
1da177e4 158
4be44fcd
LB
159 unlock_and_exit:
160 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
161 return_ACPI_STATUS(status);
1da177e4
LT
162}
163
1da177e4
LT
164/*******************************************************************************
165 *
166 * FUNCTION: acpi_tb_recognize_table
167 *
168 * PARAMETERS: table_info - Return value from acpi_tb_get_table_body
44f6c012 169 * search_type - Table type to match (primary/secondary)
1da177e4
LT
170 *
171 * RETURN: Status
172 *
173 * DESCRIPTION: Check a table signature for a match against known table types
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 *
183 ******************************************************************************/
184
185acpi_status
4be44fcd 186acpi_tb_recognize_table(struct acpi_table_desc *table_info, u8 search_type)
1da177e4 187{
4be44fcd
LB
188 struct acpi_table_header *table_header;
189 acpi_status status;
1da177e4 190
4be44fcd 191 ACPI_FUNCTION_TRACE("tb_recognize_table");
1da177e4
LT
192
193 /* Ensure that we have a valid table pointer */
194
4be44fcd 195 table_header = (struct acpi_table_header *)table_info->pointer;
1da177e4 196 if (!table_header) {
4be44fcd 197 return_ACPI_STATUS(AE_BAD_PARAMETER);
1da177e4
LT
198 }
199
200 /*
201 * We only "recognize" a limited number of ACPI tables -- namely, the
202 * ones that are used by the subsystem (DSDT, FADT, etc.)
203 *
204 * An AE_TABLE_NOT_SUPPORTED means that the table was not recognized.
205 * This can be any one of many valid ACPI tables, it just isn't one of
206 * the tables that is consumed by the core subsystem
207 */
4be44fcd
LB
208 status = acpi_tb_match_signature(table_header->signature,
209 table_info, search_type);
210 if (ACPI_FAILURE(status)) {
211 return_ACPI_STATUS(status);
1da177e4
LT
212 }
213
4be44fcd
LB
214 status = acpi_tb_validate_table_header(table_header);
215 if (ACPI_FAILURE(status)) {
216 return_ACPI_STATUS(status);
1da177e4
LT
217 }
218
219 /* Return the table type and length via the info struct */
220
221 table_info->length = (acpi_size) table_header->length;
222
4be44fcd 223 return_ACPI_STATUS(status);
1da177e4
LT
224}
225
1da177e4
LT
226/*******************************************************************************
227 *
228 * FUNCTION: acpi_tb_init_table_descriptor
229 *
230 * PARAMETERS: table_type - The type of the table
231 * table_info - A table info struct
232 *
233 * RETURN: None.
234 *
235 * DESCRIPTION: Install a table into the global data structs.
236 *
237 ******************************************************************************/
238
239acpi_status
4be44fcd
LB
240acpi_tb_init_table_descriptor(acpi_table_type table_type,
241 struct acpi_table_desc *table_info)
1da177e4 242{
4be44fcd
LB
243 struct acpi_table_list *list_head;
244 struct acpi_table_desc *table_desc;
245 acpi_status status;
1da177e4 246
4be44fcd 247 ACPI_FUNCTION_TRACE_U32("tb_init_table_descriptor", table_type);
1da177e4
LT
248
249 /* Allocate a descriptor for this table */
250
4be44fcd 251 table_desc = ACPI_MEM_CALLOCATE(sizeof(struct acpi_table_desc));
1da177e4 252 if (!table_desc) {
4be44fcd 253 return_ACPI_STATUS(AE_NO_MEMORY);
1da177e4
LT
254 }
255
f9f4601f
RM
256 /* Get a new owner ID for the table */
257
4be44fcd
LB
258 status = acpi_ut_allocate_owner_id(&table_desc->owner_id);
259 if (ACPI_FAILURE(status)) {
260 return_ACPI_STATUS(status);
f9f4601f
RM
261 }
262
44f6c012
RM
263 /* Install the table into the global data structure */
264
1da177e4
LT
265 list_head = &acpi_gbl_table_lists[table_type];
266
267 /*
268 * Two major types of tables: 1) Only one instance is allowed. This
269 * includes most ACPI tables such as the DSDT. 2) Multiple instances of
270 * the table are allowed. This includes SSDT and PSDTs.
271 */
4be44fcd 272 if (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags)) {
1da177e4
LT
273 /*
274 * Only one table allowed, and a table has alread been installed
275 * at this location, so return an error.
276 */
277 if (list_head->next) {
4be44fcd
LB
278 ACPI_MEM_FREE(table_desc);
279 return_ACPI_STATUS(AE_ALREADY_EXISTS);
1da177e4
LT
280 }
281
282 table_desc->next = list_head->next;
283 list_head->next = table_desc;
284
285 if (table_desc->next) {
286 table_desc->next->prev = table_desc;
287 }
288
289 list_head->count++;
4be44fcd 290 } else {
1da177e4
LT
291 /*
292 * Link the new table in to the list of tables of this type.
293 * Insert at the end of the list, order IS IMPORTANT.
294 *
295 * table_desc->Prev & Next are already NULL from calloc()
296 */
297 list_head->count++;
298
299 if (!list_head->next) {
300 list_head->next = table_desc;
4be44fcd 301 } else {
1da177e4
LT
302 table_desc->next = list_head->next;
303
304 while (table_desc->next->next) {
305 table_desc->next = table_desc->next->next;
306 }
307
308 table_desc->next->next = table_desc;
309 table_desc->prev = table_desc->next;
310 table_desc->next = NULL;
311 }
312 }
313
314 /* Finish initialization of the table descriptor */
315
4be44fcd
LB
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) (table_desc->length -
322 (u32) sizeof(struct
323 acpi_table_header));
1da177e4
LT
324 table_desc->loaded_into_namespace = FALSE;
325
326 /*
327 * Set the appropriate global pointer (if there is one) to point to the
328 * newly installed table
329 */
330 if (acpi_gbl_table_data[table_type].global_ptr) {
4be44fcd
LB
331 *(acpi_gbl_table_data[table_type].global_ptr) =
332 table_info->pointer;
1da177e4
LT
333 }
334
335 /* Return Data */
336
4be44fcd
LB
337 table_info->owner_id = table_desc->owner_id;
338 table_info->installed_desc = table_desc;
1da177e4 339
4be44fcd 340 return_ACPI_STATUS(AE_OK);
1da177e4
LT
341}
342
1da177e4
LT
343/*******************************************************************************
344 *
345 * FUNCTION: acpi_tb_delete_all_tables
346 *
347 * PARAMETERS: None.
348 *
349 * RETURN: None.
350 *
351 * DESCRIPTION: Delete all internal ACPI tables
352 *
353 ******************************************************************************/
354
4be44fcd 355void acpi_tb_delete_all_tables(void)
1da177e4 356{
4be44fcd 357 acpi_table_type type;
1da177e4
LT
358
359 /*
360 * Free memory allocated for ACPI tables
361 * Memory can either be mapped or allocated
362 */
363 for (type = 0; type < NUM_ACPI_TABLE_TYPES; type++) {
4be44fcd 364 acpi_tb_delete_tables_by_type(type);
1da177e4
LT
365 }
366}
367
1da177e4
LT
368/*******************************************************************************
369 *
370 * FUNCTION: acpi_tb_delete_tables_by_type
371 *
372 * PARAMETERS: Type - The table type to be deleted
373 *
374 * RETURN: None.
375 *
376 * DESCRIPTION: Delete an internal ACPI table
377 * Locks the ACPI table mutex
378 *
379 ******************************************************************************/
380
4be44fcd 381void acpi_tb_delete_tables_by_type(acpi_table_type type)
1da177e4 382{
4be44fcd
LB
383 struct acpi_table_desc *table_desc;
384 u32 count;
385 u32 i;
1da177e4 386
4be44fcd 387 ACPI_FUNCTION_TRACE_U32("tb_delete_tables_by_type", type);
1da177e4
LT
388
389 if (type > ACPI_TABLE_MAX) {
390 return_VOID;
391 }
392
4be44fcd 393 if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_TABLES))) {
1da177e4
LT
394 return;
395 }
396
397 /* Clear the appropriate "typed" global table pointer */
398
399 switch (type) {
400 case ACPI_TABLE_RSDP:
401 acpi_gbl_RSDP = NULL;
402 break;
403
404 case ACPI_TABLE_DSDT:
405 acpi_gbl_DSDT = NULL;
406 break;
407
408 case ACPI_TABLE_FADT:
409 acpi_gbl_FADT = NULL;
410 break;
411
412 case ACPI_TABLE_FACS:
413 acpi_gbl_FACS = NULL;
414 break;
415
416 case ACPI_TABLE_XSDT:
417 acpi_gbl_XSDT = NULL;
418 break;
419
420 case ACPI_TABLE_SSDT:
421 case ACPI_TABLE_PSDT:
422 default:
423 break;
424 }
425
426 /*
427 * Free the table
428 * 1) Get the head of the list
429 */
430 table_desc = acpi_gbl_table_lists[type].next;
4be44fcd 431 count = acpi_gbl_table_lists[type].count;
1da177e4
LT
432
433 /*
434 * 2) Walk the entire list, deleting both the allocated tables
435 * and the table descriptors
436 */
437 for (i = 0; i < count; i++) {
4be44fcd 438 table_desc = acpi_tb_uninstall_table(table_desc);
1da177e4
LT
439 }
440
4be44fcd 441 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
1da177e4
LT
442 return_VOID;
443}
444
1da177e4
LT
445/*******************************************************************************
446 *
447 * FUNCTION: acpi_tb_delete_single_table
448 *
449 * PARAMETERS: table_info - A table info struct
450 *
451 * RETURN: None.
452 *
453 * DESCRIPTION: Low-level free for a single ACPI table. Handles cases where
454 * the table was allocated a buffer or was mapped.
455 *
456 ******************************************************************************/
457
4be44fcd 458void acpi_tb_delete_single_table(struct acpi_table_desc *table_desc)
1da177e4
LT
459{
460
461 /* Must have a valid table descriptor and pointer */
462
4be44fcd 463 if ((!table_desc) || (!table_desc->pointer)) {
1da177e4
LT
464 return;
465 }
466
467 /* Valid table, determine type of memory allocation */
468
469 switch (table_desc->allocation) {
470 case ACPI_MEM_NOT_ALLOCATED:
471 break;
472
473 case ACPI_MEM_ALLOCATED:
474
4be44fcd 475 ACPI_MEM_FREE(table_desc->pointer);
1da177e4
LT
476 break;
477
478 case ACPI_MEM_MAPPED:
479
4be44fcd 480 acpi_os_unmap_memory(table_desc->pointer, table_desc->length);
1da177e4
LT
481 break;
482
483 default:
484 break;
485 }
486}
487
1da177e4
LT
488/*******************************************************************************
489 *
490 * FUNCTION: acpi_tb_uninstall_table
491 *
492 * PARAMETERS: table_info - A table info struct
493 *
494 * RETURN: Pointer to the next table in the list (of same type)
495 *
496 * DESCRIPTION: Free the memory associated with an internal ACPI table that
497 * is either installed or has never been installed.
498 * Table mutex should be locked.
499 *
500 ******************************************************************************/
501
4be44fcd
LB
502struct acpi_table_desc *acpi_tb_uninstall_table(struct acpi_table_desc
503 *table_desc)
1da177e4 504{
4be44fcd 505 struct acpi_table_desc *next_desc;
1da177e4 506
4be44fcd 507 ACPI_FUNCTION_TRACE_PTR("tb_uninstall_table", table_desc);
1da177e4
LT
508
509 if (!table_desc) {
4be44fcd 510 return_PTR(NULL);
1da177e4
LT
511 }
512
513 /* Unlink the descriptor from the doubly linked list */
514
515 if (table_desc->prev) {
516 table_desc->prev->next = table_desc->next;
4be44fcd 517 } else {
1da177e4
LT
518 /* Is first on list, update list head */
519
520 acpi_gbl_table_lists[table_desc->type].next = table_desc->next;
521 }
522
523 if (table_desc->next) {
524 table_desc->next->prev = table_desc->prev;
525 }
526
527 /* Free the memory allocated for the table itself */
528
4be44fcd 529 acpi_tb_delete_single_table(table_desc);
1da177e4
LT
530
531 /* Free the table descriptor */
532
533 next_desc = table_desc->next;
4be44fcd 534 ACPI_MEM_FREE(table_desc);
1da177e4
LT
535
536 /* Return pointer to the next descriptor */
537
4be44fcd 538 return_PTR(next_desc);
1da177e4 539}
This page took 0.235653 seconds and 5 git commands to generate.