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