]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/acpi/acpica/tbinstal.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-2.6-nommu
[linux-2.6-omap-h63xx.git] / drivers / acpi / acpica / tbinstal.c
1 /******************************************************************************
2  *
3  * Module Name: tbinstal - ACPI table installation and removal
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2008, Intel Corp.
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
44 #include <acpi/acpi.h>
45 #include "accommon.h"
46 #include "acnamesp.h"
47 #include "actables.h"
48
49 #define _COMPONENT          ACPI_TABLES
50 ACPI_MODULE_NAME("tbinstal")
51
52 /******************************************************************************
53  *
54  * FUNCTION:    acpi_tb_verify_table
55  *
56  * PARAMETERS:  table_desc          - table
57  *
58  * RETURN:      Status
59  *
60  * DESCRIPTION: this function is called to verify and map table
61  *
62  *****************************************************************************/
63 acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
64 {
65         acpi_status status = AE_OK;
66
67         ACPI_FUNCTION_TRACE(tb_verify_table);
68
69         /* Map the table if necessary */
70
71         if (!table_desc->pointer) {
72                 if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) ==
73                     ACPI_TABLE_ORIGIN_MAPPED) {
74                         table_desc->pointer =
75                             acpi_os_map_memory(table_desc->address,
76                                                table_desc->length);
77                 }
78                 if (!table_desc->pointer) {
79                         return_ACPI_STATUS(AE_NO_MEMORY);
80                 }
81         }
82
83         /* FACS is the odd table, has no standard ACPI header and no checksum */
84
85         if (!ACPI_COMPARE_NAME(&table_desc->signature, ACPI_SIG_FACS)) {
86
87                 /* Always calculate checksum, ignore bad checksum if requested */
88
89                 status =
90                     acpi_tb_verify_checksum(table_desc->pointer,
91                                             table_desc->length);
92         }
93
94         return_ACPI_STATUS(status);
95 }
96
97 /*******************************************************************************
98  *
99  * FUNCTION:    acpi_tb_add_table
100  *
101  * PARAMETERS:  table_desc          - Table descriptor
102  *              table_index         - Where the table index is returned
103  *
104  * RETURN:      Status
105  *
106  * DESCRIPTION: This function is called to add the ACPI table
107  *
108  ******************************************************************************/
109
110 acpi_status
111 acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
112 {
113         u32 i;
114         acpi_status status = AE_OK;
115
116         ACPI_FUNCTION_TRACE(tb_add_table);
117
118         if (!table_desc->pointer) {
119                 status = acpi_tb_verify_table(table_desc);
120                 if (ACPI_FAILURE(status) || !table_desc->pointer) {
121                         return_ACPI_STATUS(status);
122                 }
123         }
124
125         /*
126          * Originally, we checked the table signature for "SSDT" or "PSDT" here.
127          * Next, we added support for OEMx tables, signature "OEM".
128          * Valid tables were encountered with a null signature, so we've just
129          * given up on validating the signature, since it seems to be a waste
130          * of code. The original code was removed (05/2008).
131          */
132
133         (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
134
135         /* Check if table is already registered */
136
137         for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
138                 if (!acpi_gbl_root_table_list.tables[i].pointer) {
139                         status =
140                             acpi_tb_verify_table(&acpi_gbl_root_table_list.
141                                                  tables[i]);
142                         if (ACPI_FAILURE(status)
143                             || !acpi_gbl_root_table_list.tables[i].pointer) {
144                                 continue;
145                         }
146                 }
147
148                 /*
149                  * Check for a table match on the entire table length,
150                  * not just the header.
151                  */
152                 if (table_desc->length !=
153                     acpi_gbl_root_table_list.tables[i].length) {
154                         continue;
155                 }
156
157                 if (ACPI_MEMCMP(table_desc->pointer,
158                                 acpi_gbl_root_table_list.tables[i].pointer,
159                                 acpi_gbl_root_table_list.tables[i].length)) {
160                         continue;
161                 }
162
163                 /*
164                  * Note: the current mechanism does not unregister a table if it is
165                  * dynamically unloaded. The related namespace entries are deleted,
166                  * but the table remains in the root table list.
167                  *
168                  * The assumption here is that the number of different tables that
169                  * will be loaded is actually small, and there is minimal overhead
170                  * in just keeping the table in case it is needed again.
171                  *
172                  * If this assumption changes in the future (perhaps on large
173                  * machines with many table load/unload operations), tables will
174                  * need to be unregistered when they are unloaded, and slots in the
175                  * root table list should be reused when empty.
176                  */
177
178                 /*
179                  * Table is already registered.
180                  * We can delete the table that was passed as a parameter.
181                  */
182                 acpi_tb_delete_table(table_desc);
183                 *table_index = i;
184
185                 if (acpi_gbl_root_table_list.tables[i].
186                     flags & ACPI_TABLE_IS_LOADED) {
187
188                         /* Table is still loaded, this is an error */
189
190                         status = AE_ALREADY_EXISTS;
191                         goto release;
192                 } else {
193                         /* Table was unloaded, allow it to be reloaded */
194
195                         table_desc->pointer =
196                             acpi_gbl_root_table_list.tables[i].pointer;
197                         table_desc->address =
198                             acpi_gbl_root_table_list.tables[i].address;
199                         status = AE_OK;
200                         goto print_header;
201                 }
202         }
203
204         /* Add the table to the global root table list */
205
206         status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
207                                      table_desc->length, table_desc->flags,
208                                      table_index);
209         if (ACPI_FAILURE(status)) {
210                 goto release;
211         }
212
213       print_header:
214         acpi_tb_print_table_header(table_desc->address, table_desc->pointer);
215
216       release:
217         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
218         return_ACPI_STATUS(status);
219 }
220
221 /*******************************************************************************
222  *
223  * FUNCTION:    acpi_tb_resize_root_table_list
224  *
225  * PARAMETERS:  None
226  *
227  * RETURN:      Status
228  *
229  * DESCRIPTION: Expand the size of global table array
230  *
231  ******************************************************************************/
232
233 acpi_status acpi_tb_resize_root_table_list(void)
234 {
235         struct acpi_table_desc *tables;
236
237         ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
238
239         /* allow_resize flag is a parameter to acpi_initialize_tables */
240
241         if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) {
242                 ACPI_ERROR((AE_INFO,
243                             "Resize of Root Table Array is not allowed"));
244                 return_ACPI_STATUS(AE_SUPPORT);
245         }
246
247         /* Increase the Table Array size */
248
249         tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list.
250                                        size + ACPI_ROOT_TABLE_SIZE_INCREMENT)
251                                       * sizeof(struct acpi_table_desc));
252         if (!tables) {
253                 ACPI_ERROR((AE_INFO,
254                             "Could not allocate new root table array"));
255                 return_ACPI_STATUS(AE_NO_MEMORY);
256         }
257
258         /* Copy and free the previous table array */
259
260         if (acpi_gbl_root_table_list.tables) {
261                 ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
262                             (acpi_size) acpi_gbl_root_table_list.size *
263                             sizeof(struct acpi_table_desc));
264
265                 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
266                         ACPI_FREE(acpi_gbl_root_table_list.tables);
267                 }
268         }
269
270         acpi_gbl_root_table_list.tables = tables;
271         acpi_gbl_root_table_list.size += ACPI_ROOT_TABLE_SIZE_INCREMENT;
272         acpi_gbl_root_table_list.flags |= (u8) ACPI_ROOT_ORIGIN_ALLOCATED;
273
274         return_ACPI_STATUS(AE_OK);
275 }
276
277 /*******************************************************************************
278  *
279  * FUNCTION:    acpi_tb_store_table
280  *
281  * PARAMETERS:  Address             - Table address
282  *              Table               - Table header
283  *              Length              - Table length
284  *              Flags               - flags
285  *
286  * RETURN:      Status and table index.
287  *
288  * DESCRIPTION: Add an ACPI table to the global table list
289  *
290  ******************************************************************************/
291
292 acpi_status
293 acpi_tb_store_table(acpi_physical_address address,
294                     struct acpi_table_header *table,
295                     u32 length, u8 flags, u32 *table_index)
296 {
297         acpi_status status = AE_OK;
298
299         /* Ensure that there is room for the table in the Root Table List */
300
301         if (acpi_gbl_root_table_list.count >= acpi_gbl_root_table_list.size) {
302                 status = acpi_tb_resize_root_table_list();
303                 if (ACPI_FAILURE(status)) {
304                         return (status);
305                 }
306         }
307
308         /* Initialize added table */
309
310         acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
311             address = address;
312         acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
313             pointer = table;
314         acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].length =
315             length;
316         acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
317             owner_id = 0;
318         acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].flags =
319             flags;
320
321         ACPI_MOVE_32_TO_32(&
322                            (acpi_gbl_root_table_list.
323                             tables[acpi_gbl_root_table_list.count].signature),
324                            table->signature);
325
326         *table_index = acpi_gbl_root_table_list.count;
327         acpi_gbl_root_table_list.count++;
328         return (status);
329 }
330
331 /*******************************************************************************
332  *
333  * FUNCTION:    acpi_tb_delete_table
334  *
335  * PARAMETERS:  table_index         - Table index
336  *
337  * RETURN:      None
338  *
339  * DESCRIPTION: Delete one internal ACPI table
340  *
341  ******************************************************************************/
342
343 void acpi_tb_delete_table(struct acpi_table_desc *table_desc)
344 {
345         /* Table must be mapped or allocated */
346         if (!table_desc->pointer) {
347                 return;
348         }
349         switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
350         case ACPI_TABLE_ORIGIN_MAPPED:
351                 acpi_os_unmap_memory(table_desc->pointer, table_desc->length);
352                 break;
353         case ACPI_TABLE_ORIGIN_ALLOCATED:
354                 ACPI_FREE(table_desc->pointer);
355                 break;
356         default:;
357         }
358
359         table_desc->pointer = NULL;
360 }
361
362 /*******************************************************************************
363  *
364  * FUNCTION:    acpi_tb_terminate
365  *
366  * PARAMETERS:  None
367  *
368  * RETURN:      None
369  *
370  * DESCRIPTION: Delete all internal ACPI tables
371  *
372  ******************************************************************************/
373
374 void acpi_tb_terminate(void)
375 {
376         u32 i;
377
378         ACPI_FUNCTION_TRACE(tb_terminate);
379
380         (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
381
382         /* Delete the individual tables */
383
384         for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
385                 acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]);
386         }
387
388         /*
389          * Delete the root table array if allocated locally. Array cannot be
390          * mapped, so we don't need to check for that flag.
391          */
392         if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
393                 ACPI_FREE(acpi_gbl_root_table_list.tables);
394         }
395
396         acpi_gbl_root_table_list.tables = NULL;
397         acpi_gbl_root_table_list.flags = 0;
398         acpi_gbl_root_table_list.count = 0;
399
400         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
401         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
402 }
403
404 /*******************************************************************************
405  *
406  * FUNCTION:    acpi_tb_delete_namespace_by_owner
407  *
408  * PARAMETERS:  table_index         - Table index
409  *
410  * RETURN:      None
411  *
412  * DESCRIPTION: Delete all namespace objects created when this table was loaded.
413  *
414  ******************************************************************************/
415
416 void acpi_tb_delete_namespace_by_owner(u32 table_index)
417 {
418         acpi_owner_id owner_id;
419
420         (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
421         if (table_index < acpi_gbl_root_table_list.count) {
422                 owner_id =
423                     acpi_gbl_root_table_list.tables[table_index].owner_id;
424         } else {
425                 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
426                 return;
427         }
428
429         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
430         acpi_ns_delete_namespace_by_owner(owner_id);
431 }
432
433 /*******************************************************************************
434  *
435  * FUNCTION:    acpi_tb_allocate_owner_id
436  *
437  * PARAMETERS:  table_index         - Table index
438  *
439  * RETURN:      Status
440  *
441  * DESCRIPTION: Allocates owner_id in table_desc
442  *
443  ******************************************************************************/
444
445 acpi_status acpi_tb_allocate_owner_id(u32 table_index)
446 {
447         acpi_status status = AE_BAD_PARAMETER;
448
449         ACPI_FUNCTION_TRACE(tb_allocate_owner_id);
450
451         (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
452         if (table_index < acpi_gbl_root_table_list.count) {
453                 status = acpi_ut_allocate_owner_id
454                     (&(acpi_gbl_root_table_list.tables[table_index].owner_id));
455         }
456
457         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
458         return_ACPI_STATUS(status);
459 }
460
461 /*******************************************************************************
462  *
463  * FUNCTION:    acpi_tb_release_owner_id
464  *
465  * PARAMETERS:  table_index         - Table index
466  *
467  * RETURN:      Status
468  *
469  * DESCRIPTION: Releases owner_id in table_desc
470  *
471  ******************************************************************************/
472
473 acpi_status acpi_tb_release_owner_id(u32 table_index)
474 {
475         acpi_status status = AE_BAD_PARAMETER;
476
477         ACPI_FUNCTION_TRACE(tb_release_owner_id);
478
479         (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
480         if (table_index < acpi_gbl_root_table_list.count) {
481                 acpi_ut_release_owner_id(&
482                                          (acpi_gbl_root_table_list.
483                                           tables[table_index].owner_id));
484                 status = AE_OK;
485         }
486
487         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
488         return_ACPI_STATUS(status);
489 }
490
491 /*******************************************************************************
492  *
493  * FUNCTION:    acpi_tb_get_owner_id
494  *
495  * PARAMETERS:  table_index         - Table index
496  *              owner_id            - Where the table owner_id is returned
497  *
498  * RETURN:      Status
499  *
500  * DESCRIPTION: returns owner_id for the ACPI table
501  *
502  ******************************************************************************/
503
504 acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id)
505 {
506         acpi_status status = AE_BAD_PARAMETER;
507
508         ACPI_FUNCTION_TRACE(tb_get_owner_id);
509
510         (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
511         if (table_index < acpi_gbl_root_table_list.count) {
512                 *owner_id =
513                     acpi_gbl_root_table_list.tables[table_index].owner_id;
514                 status = AE_OK;
515         }
516
517         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
518         return_ACPI_STATUS(status);
519 }
520
521 /*******************************************************************************
522  *
523  * FUNCTION:    acpi_tb_is_table_loaded
524  *
525  * PARAMETERS:  table_index         - Table index
526  *
527  * RETURN:      Table Loaded Flag
528  *
529  ******************************************************************************/
530
531 u8 acpi_tb_is_table_loaded(u32 table_index)
532 {
533         u8 is_loaded = FALSE;
534
535         (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
536         if (table_index < acpi_gbl_root_table_list.count) {
537                 is_loaded = (u8)
538                     (acpi_gbl_root_table_list.tables[table_index].
539                      flags & ACPI_TABLE_IS_LOADED);
540         }
541
542         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
543         return (is_loaded);
544 }
545
546 /*******************************************************************************
547  *
548  * FUNCTION:    acpi_tb_set_table_loaded_flag
549  *
550  * PARAMETERS:  table_index         - Table index
551  *              is_loaded           - TRUE if table is loaded, FALSE otherwise
552  *
553  * RETURN:      None
554  *
555  * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
556  *
557  ******************************************************************************/
558
559 void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded)
560 {
561
562         (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
563         if (table_index < acpi_gbl_root_table_list.count) {
564                 if (is_loaded) {
565                         acpi_gbl_root_table_list.tables[table_index].flags |=
566                             ACPI_TABLE_IS_LOADED;
567                 } else {
568                         acpi_gbl_root_table_list.tables[table_index].flags &=
569                             ~ACPI_TABLE_IS_LOADED;
570                 }
571         }
572
573         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
574 }