ACPICA: re-factor table init routines for benefit of iASL
[linux-2.6] / drivers / acpi / tables / tbxface.c
1 /******************************************************************************
2  *
3  * Module Name: tbxface - Public interfaces to the ACPI subsystem
4  *                         ACPI table oriented interfaces
5  *
6  *****************************************************************************/
7
8 /*
9  * Copyright (C) 2000 - 2006, R. Byron Moore
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions, and the following disclaimer,
17  *    without modification.
18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19  *    substantially similar to the "NO WARRANTY" disclaimer below
20  *    ("Disclaimer") and any redistribution must be conditioned upon
21  *    including a substantially similar Disclaimer requirement for further
22  *    binary redistribution.
23  * 3. Neither the names of the above-listed copyright holders nor the names
24  *    of any contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * Alternatively, this software may be distributed under the terms of the
28  * GNU General Public License ("GPL") version 2 as published by the Free
29  * Software Foundation.
30  *
31  * NO WARRANTY
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42  * POSSIBILITY OF SUCH DAMAGES.
43  */
44
45 #include <acpi/acpi.h>
46 #include <acpi/acnamesp.h>
47 #include <acpi/actables.h>
48
49 #define _COMPONENT          ACPI_TABLES
50 ACPI_MODULE_NAME("tbxface")
51
52 /* Local prototypes */
53 static acpi_status acpi_tb_load_namespace(void);
54
55 /*******************************************************************************
56  *
57  * FUNCTION:    acpi_allocate_root_table
58  *
59  * PARAMETERS:  initial_table_count - Size of initial_table_array, in number of
60  *                                    struct acpi_table_desc structures
61  *
62  * RETURN:      Status
63  *
64  * DESCRIPTION: Allocate a root table array. Used by i_aSL compiler and
65  *              acpi_initialize_tables.
66  *
67  ******************************************************************************/
68
69 acpi_status acpi_allocate_root_table(u32 initial_table_count)
70 {
71
72         acpi_gbl_root_table_list.size = initial_table_count;
73         acpi_gbl_root_table_list.flags = ACPI_ROOT_ALLOW_RESIZE;
74
75         return (acpi_tb_resize_root_table_list());
76 }
77
78 /*******************************************************************************
79  *
80  * FUNCTION:    acpi_initialize_tables
81  *
82  * PARAMETERS:  initial_table_array - Pointer to an array of pre-allocated
83  *                                    struct acpi_table_desc structures. If NULL, the
84  *                                    array is dynamically allocated.
85  *              initial_table_count - Size of initial_table_array, in number of
86  *                                    struct acpi_table_desc structures
87  *              allow_realloc       - Flag to tell Table Manager if resize of
88  *                                    pre-allocated array is allowed. Ignored
89  *                                    if initial_table_array is NULL.
90  *
91  * RETURN:      Status
92  *
93  * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT.
94  *
95  * NOTE:        Allows static allocation of the initial table array in order
96  *              to avoid the use of dynamic memory in confined environments
97  *              such as the kernel boot sequence where it may not be available.
98  *
99  *              If the host OS memory managers are initialized, use NULL for
100  *              initial_table_array, and the table will be dynamically allocated.
101  *
102  ******************************************************************************/
103
104 acpi_status __init
105 acpi_initialize_tables(struct acpi_table_desc * initial_table_array,
106                        u32 initial_table_count, u8 allow_resize)
107 {
108         acpi_physical_address rsdp_address;
109         acpi_status status;
110
111         ACPI_FUNCTION_TRACE(acpi_initialize_tables);
112
113         /*
114          * Set up the Root Table Array
115          * Allocate the table array if requested
116          */
117         if (!initial_table_array) {
118                 status = acpi_allocate_root_table(initial_table_count);
119                 if (ACPI_FAILURE(status)) {
120                         return_ACPI_STATUS(status);
121                 }
122         } else {
123                 /* Root Table Array has been statically allocated by the host */
124
125                 ACPI_MEMSET(initial_table_array, 0,
126                             initial_table_count *
127                             sizeof(struct acpi_table_desc));
128
129                 acpi_gbl_root_table_list.tables = initial_table_array;
130                 acpi_gbl_root_table_list.size = initial_table_count;
131                 acpi_gbl_root_table_list.flags = ACPI_ROOT_ORIGIN_UNKNOWN;
132                 if (allow_resize) {
133                         acpi_gbl_root_table_list.flags |=
134                             ACPI_ROOT_ALLOW_RESIZE;
135                 }
136         }
137
138         /* Get the address of the RSDP */
139
140         rsdp_address = acpi_os_get_root_pointer();
141         if (!rsdp_address) {
142                 return_ACPI_STATUS(AE_NOT_FOUND);
143         }
144
145         /*
146          * Get the root table (RSDT or XSDT) and extract all entries to the local
147          * Root Table Array. This array contains the information of the RSDT/XSDT
148          * in a common, more useable format.
149          */
150         status =
151             acpi_tb_parse_root_table(rsdp_address, ACPI_TABLE_ORIGIN_MAPPED);
152         return_ACPI_STATUS(status);
153 }
154
155 /*******************************************************************************
156  *
157  * FUNCTION:    acpi_reallocate_root_table
158  *
159  * PARAMETERS:  None
160  *
161  * RETURN:      Status
162  *
163  * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
164  *              root list from the previously provided scratch area. Should
165  *              be called once dynamic memory allocation is available in the
166  *              kernel
167  *
168  ******************************************************************************/
169 acpi_status acpi_reallocate_root_table(void)
170 {
171         struct acpi_table_desc *tables;
172         acpi_size new_size;
173
174         ACPI_FUNCTION_TRACE(acpi_reallocate_root_table);
175
176         /*
177          * Only reallocate the root table if the host provided a static buffer
178          * for the table array in the call to acpi_initialize_tables.
179          */
180         if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
181                 return_ACPI_STATUS(AE_SUPPORT);
182         }
183
184         new_size =
185             (acpi_gbl_root_table_list.count +
186              ACPI_ROOT_TABLE_SIZE_INCREMENT) * sizeof(struct acpi_table_desc);
187
188         /* Create new array and copy the old array */
189
190         tables = ACPI_ALLOCATE_ZEROED(new_size);
191         if (!tables) {
192                 return_ACPI_STATUS(AE_NO_MEMORY);
193         }
194
195         ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, new_size);
196
197         acpi_gbl_root_table_list.size = acpi_gbl_root_table_list.count;
198         acpi_gbl_root_table_list.tables = tables;
199         acpi_gbl_root_table_list.flags =
200             ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE;
201
202         return_ACPI_STATUS(AE_OK);
203 }
204 /*******************************************************************************
205  *
206  * FUNCTION:    acpi_load_table
207  *
208  * PARAMETERS:  table_ptr       - pointer to a buffer containing the entire
209  *                                table to be loaded
210  *
211  * RETURN:      Status
212  *
213  * DESCRIPTION: This function is called to load a table from the caller's
214  *              buffer. The buffer must contain an entire ACPI Table including
215  *              a valid header. The header fields will be verified, and if it
216  *              is determined that the table is invalid, the call will fail.
217  *
218  ******************************************************************************/
219 acpi_status acpi_load_table(struct acpi_table_header *table_ptr)
220 {
221         acpi_status status;
222         acpi_native_uint table_index;
223
224         /*
225          * Install the new table into the local data structures
226          */
227         status = acpi_tb_add_table(table_ptr, &table_index);
228         if (ACPI_FAILURE(status)) {
229                 return_ACPI_STATUS(status);
230         }
231         status = acpi_ns_load_table(table_index, acpi_gbl_root_node);
232         return_ACPI_STATUS(status);
233 }
234
235 ACPI_EXPORT_SYMBOL(acpi_load_table)
236
237 /******************************************************************************
238  *
239  * FUNCTION:    acpi_get_table_header
240  *
241  * PARAMETERS:  Signature           - ACPI signature of needed table
242  *              Instance            - Which instance (for SSDTs)
243  *              out_table_header    - Where the pointer to the table header
244  *                                    is returned
245  *
246  * RETURN:      Status and pointer to mapped table header
247  *
248  * DESCRIPTION: Finds an ACPI table header.
249  *
250  * NOTE:        Caller is responsible in unmapping the header with
251  *              acpi_os_unmap_memory
252  *
253  *****************************************************************************/
254 acpi_status
255 acpi_get_table_header(char *signature,
256                       acpi_native_uint instance,
257                       struct acpi_table_header **out_table_header)
258 {
259         acpi_native_uint i;
260         acpi_native_uint j;
261
262         /* Parameter validation */
263
264         if (!signature || !out_table_header) {
265                 return (AE_BAD_PARAMETER);
266         }
267
268         /*
269          * Walk the root table list
270          */
271         for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
272                 if (!ACPI_COMPARE_NAME
273                     (&(acpi_gbl_root_table_list.tables[i].signature),
274                      signature)) {
275                         continue;
276                 }
277
278                 if (++j < instance) {
279                         continue;
280                 }
281
282                 *out_table_header =
283                     acpi_tb_map(acpi_gbl_root_table_list.tables[i].address,
284                                 (u32) sizeof(struct acpi_table_header),
285                                 acpi_gbl_root_table_list.tables[i].
286                                 flags & ACPI_TABLE_ORIGIN_MASK);
287
288                 if (!(*out_table_header)) {
289                         return (AE_NO_MEMORY);
290                 }
291
292                 return (AE_OK);
293         }
294
295         return (AE_NOT_FOUND);
296 }
297
298 ACPI_EXPORT_SYMBOL(acpi_get_table_header)
299
300
301 /******************************************************************************
302  *
303  * FUNCTION:    acpi_unload_table_id
304  *
305  * PARAMETERS:  id            - Owner ID of the table to be removed.
306  *
307  * RETURN:      Status
308  *
309  * DESCRIPTION: This routine is used to force the unload of a table (by id)
310  *
311  ******************************************************************************/
312 acpi_status acpi_unload_table_id(acpi_owner_id id)
313 {
314         int i;
315         acpi_status status = AE_NOT_EXIST;
316
317         ACPI_FUNCTION_TRACE(acpi_unload_table);
318
319         /* Find table from the requested type list */
320         for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
321                 if (id != acpi_gbl_root_table_list.tables[i].owner_id) {
322                         continue;
323                 }
324                 /*
325                 * Delete all namespace objects owned by this table. Note that these
326                 * objects can appear anywhere in the namespace by virtue of the AML
327                 * "Scope" operator. Thus, we need to track ownership by an ID, not
328                 * simply a position within the hierarchy
329                 */
330                 acpi_tb_delete_namespace_by_owner(i);
331                 acpi_tb_release_owner_id(i);
332                 acpi_tb_set_table_loaded_flag(i, FALSE);
333         }
334         return_ACPI_STATUS(status);
335 }
336
337 ACPI_EXPORT_SYMBOL(acpi_unload_table_id)
338
339 /*******************************************************************************
340  *
341  * FUNCTION:    acpi_get_table
342  *
343  * PARAMETERS:  Signature           - ACPI signature of needed table
344  *              Instance            - Which instance (for SSDTs)
345  *              out_table           - Where the pointer to the table is returned
346  *
347  * RETURN:      Status and pointer to table
348  *
349  * DESCRIPTION: Finds and verifies an ACPI table.
350  *
351  *****************************************************************************/
352 acpi_status
353 acpi_get_table(char *signature,
354                acpi_native_uint instance, struct acpi_table_header ** out_table)
355 {
356         acpi_native_uint i;
357         acpi_native_uint j;
358         acpi_status status;
359
360         /* Parameter validation */
361
362         if (!signature || !out_table) {
363                 return (AE_BAD_PARAMETER);
364         }
365
366         /*
367          * Walk the root table list
368          */
369         for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
370                 if (!ACPI_COMPARE_NAME
371                     (&(acpi_gbl_root_table_list.tables[i].signature),
372                      signature)) {
373                         continue;
374                 }
375
376                 if (++j < instance) {
377                         continue;
378                 }
379
380                 status =
381                     acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]);
382                 if (ACPI_SUCCESS(status)) {
383                         *out_table = acpi_gbl_root_table_list.tables[i].pointer;
384                 }
385
386                 if (!acpi_gbl_permanent_mmap) {
387                         acpi_gbl_root_table_list.tables[i].pointer = 0;
388                 }
389
390                 return (status);
391         }
392
393         return (AE_NOT_FOUND);
394 }
395
396 ACPI_EXPORT_SYMBOL(acpi_get_table)
397
398 /*******************************************************************************
399  *
400  * FUNCTION:    acpi_get_table_by_index
401  *
402  * PARAMETERS:  table_index         - Table index
403  *              Table               - Where the pointer to the table is returned
404  *
405  * RETURN:      Status and pointer to the table
406  *
407  * DESCRIPTION: Obtain a table by an index into the global table list.
408  *
409  ******************************************************************************/
410 acpi_status
411 acpi_get_table_by_index(acpi_native_uint table_index,
412                         struct acpi_table_header ** table)
413 {
414         acpi_status status;
415
416         ACPI_FUNCTION_TRACE(acpi_get_table_by_index);
417
418         /* Parameter validation */
419
420         if (!table) {
421                 return_ACPI_STATUS(AE_BAD_PARAMETER);
422         }
423
424         (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
425
426         /* Validate index */
427
428         if (table_index >= acpi_gbl_root_table_list.count) {
429                 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
430                 return_ACPI_STATUS(AE_BAD_PARAMETER);
431         }
432
433         if (!acpi_gbl_root_table_list.tables[table_index].pointer) {
434
435                 /* Table is not mapped, map it */
436
437                 status =
438                     acpi_tb_verify_table(&acpi_gbl_root_table_list.
439                                          tables[table_index]);
440                 if (ACPI_FAILURE(status)) {
441                         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
442                         return_ACPI_STATUS(status);
443                 }
444         }
445
446         *table = acpi_gbl_root_table_list.tables[table_index].pointer;
447         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
448         return_ACPI_STATUS(AE_OK);
449 }
450
451 ACPI_EXPORT_SYMBOL(acpi_get_table_by_index)
452
453 /*******************************************************************************
454  *
455  * FUNCTION:    acpi_tb_load_namespace
456  *
457  * PARAMETERS:  None
458  *
459  * RETURN:      Status
460  *
461  * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in
462  *              the RSDT/XSDT.
463  *
464  ******************************************************************************/
465 static acpi_status acpi_tb_load_namespace(void)
466 {
467         acpi_status status;
468         struct acpi_table_header *table;
469         acpi_native_uint i;
470
471         ACPI_FUNCTION_TRACE(tb_load_namespace);
472
473         (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
474
475         /*
476          * Load the namespace. The DSDT is required, but any SSDT and PSDT tables
477          * are optional.
478          */
479         if (!acpi_gbl_root_table_list.count ||
480             !ACPI_COMPARE_NAME(&
481                                (acpi_gbl_root_table_list.
482                                 tables[ACPI_TABLE_INDEX_DSDT].signature),
483                                ACPI_SIG_DSDT)
484             ||
485             ACPI_FAILURE(acpi_tb_verify_table
486                          (&acpi_gbl_root_table_list.
487                           tables[ACPI_TABLE_INDEX_DSDT]))) {
488                 status = AE_NO_ACPI_TABLES;
489                 goto unlock_and_exit;
490         }
491
492         /*
493          * Find DSDT table
494          */
495         status =
496             acpi_os_table_override(acpi_gbl_root_table_list.
497                                    tables[ACPI_TABLE_INDEX_DSDT].pointer,
498                                    &table);
499         if (ACPI_SUCCESS(status) && table) {
500                 /*
501                  * DSDT table has been found
502                  */
503                 acpi_tb_delete_table(ACPI_TABLE_INDEX_DSDT);
504                 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer =
505                     table;
506                 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length =
507                     table->length;
508                 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags =
509                     ACPI_TABLE_ORIGIN_UNKNOWN;
510
511                 ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS"));
512                 acpi_tb_print_table_header(0, table);
513         }
514
515         status =
516             acpi_tb_verify_table(&acpi_gbl_root_table_list.
517                                  tables[ACPI_TABLE_INDEX_DSDT]);
518         if (ACPI_FAILURE(status)) {
519
520                 /* A valid DSDT is required */
521
522                 status = AE_NO_ACPI_TABLES;
523                 goto unlock_and_exit;
524         }
525
526         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
527
528         /*
529          * Load and parse tables.
530          */
531         status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node);
532         if (ACPI_FAILURE(status)) {
533                 return_ACPI_STATUS(status);
534         }
535
536         /*
537          * Load any SSDT or PSDT tables. Note: Loop leaves tables locked
538          */
539         (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
540         for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
541                 if ((!ACPI_COMPARE_NAME
542                      (&(acpi_gbl_root_table_list.tables[i].signature),
543                       ACPI_SIG_SSDT)
544                      &&
545                      !ACPI_COMPARE_NAME(&
546                                         (acpi_gbl_root_table_list.tables[i].
547                                          signature), ACPI_SIG_PSDT))
548                     ||
549                     ACPI_FAILURE(acpi_tb_verify_table
550                                  (&acpi_gbl_root_table_list.tables[i]))) {
551                         continue;
552                 }
553
554                 /* Ignore errors while loading tables, get as many as possible */
555
556                 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
557                 (void)acpi_ns_load_table(i, acpi_gbl_root_node);
558                 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
559         }
560
561         ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
562
563       unlock_and_exit:
564         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
565         return_ACPI_STATUS(status);
566 }
567
568 /*******************************************************************************
569  *
570  * FUNCTION:    acpi_load_tables
571  *
572  * PARAMETERS:  None
573  *
574  * RETURN:      Status
575  *
576  * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT
577  *
578  ******************************************************************************/
579
580 acpi_status acpi_load_tables(void)
581 {
582         acpi_status status;
583
584         ACPI_FUNCTION_TRACE(acpi_load_tables);
585
586         /*
587          * Load the namespace from the tables
588          */
589         status = acpi_tb_load_namespace();
590         if (ACPI_FAILURE(status)) {
591                 ACPI_EXCEPTION((AE_INFO, status,
592                                 "While loading namespace from ACPI tables"));
593         }
594
595         return_ACPI_STATUS(status);
596 }
597
598 ACPI_EXPORT_SYMBOL(acpi_load_tables)