Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /******************************************************************************
  2  *
  3  * Module Name: tbinstal - ACPI table installation and removal
  4  *
  5  *****************************************************************************/
  6 
  7 /*
  8  * Copyright (C) 2000 - 2007, R. Byron Moore
  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                 goto release;
162         }
163 
164         /*
165          * Add the table to the global table list
166          */
167         status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
168                                      table_desc->length, table_desc->flags,
169                                      table_index);
170         if (ACPI_FAILURE(status)) {
171                 goto release;
172         }
173 
174         acpi_tb_print_table_header(table_desc->address, table_desc->pointer);
175 
176       release:
177         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
178         return_ACPI_STATUS(status);
179 }
180 
181 /*******************************************************************************
182  *
183  * FUNCTION:    acpi_tb_resize_root_table_list
184  *
185  * PARAMETERS:  None
186  *
187  * RETURN:      Status
188  *
189  * DESCRIPTION: Expand the size of global table array
190  *
191  ******************************************************************************/
192 
193 acpi_status acpi_tb_resize_root_table_list(void)
194 {
195         struct acpi_table_desc *tables;
196 
197         ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
198 
199         /* allow_resize flag is a parameter to acpi_initialize_tables */
200 
201         if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) {
202                 ACPI_ERROR((AE_INFO,
203                             "Resize of Root Table Array is not allowed"));
204                 return_ACPI_STATUS(AE_SUPPORT);
205         }
206 
207         /* Increase the Table Array size */
208 
209         tables = ACPI_ALLOCATE_ZEROED((acpi_gbl_root_table_list.size +
210                                        ACPI_ROOT_TABLE_SIZE_INCREMENT)
211                                       * sizeof(struct acpi_table_desc));
212         if (!tables) {
213                 ACPI_ERROR((AE_INFO,
214                             "Could not allocate new root table array"));
215                 return_ACPI_STATUS(AE_NO_MEMORY);
216         }
217 
218         /* Copy and free the previous table array */
219 
220         if (acpi_gbl_root_table_list.tables) {
221                 ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
222                             acpi_gbl_root_table_list.size *
223                             sizeof(struct acpi_table_desc));
224 
225                 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
226                         ACPI_FREE(acpi_gbl_root_table_list.tables);
227                 }
228         }
229 
230         acpi_gbl_root_table_list.tables = tables;
231         acpi_gbl_root_table_list.size += ACPI_ROOT_TABLE_SIZE_INCREMENT;
232         acpi_gbl_root_table_list.flags |= (u8) ACPI_ROOT_ORIGIN_ALLOCATED;
233 
234         return_ACPI_STATUS(AE_OK);
235 }
236 
237 /*******************************************************************************
238  *
239  * FUNCTION:    acpi_tb_store_table
240  *
241  * PARAMETERS:  Address             - Table address
242  *              Table               - Table header
243  *              Length              - Table length
244  *              Flags               - flags
245  *
246  * RETURN:      Status and table index.
247  *
248  * DESCRIPTION: Add an ACPI table to the global table list
249  *
250  ******************************************************************************/
251 
252 acpi_status
253 acpi_tb_store_table(acpi_physical_address address,
254                     struct acpi_table_header *table,
255                     u32 length, u8 flags, acpi_native_uint * table_index)
256 {
257         acpi_status status = AE_OK;
258 
259         /* Ensure that there is room for the table in the Root Table List */
260 
261         if (acpi_gbl_root_table_list.count >= acpi_gbl_root_table_list.size) {
262                 status = acpi_tb_resize_root_table_list();
263                 if (ACPI_FAILURE(status)) {
264                         return (status);
265                 }
266         }
267 
268         /* Initialize added table */
269 
270         acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
271             address = address;
272         acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
273             pointer = table;
274         acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].length =
275             length;
276         acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
277             owner_id = 0;
278         acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].flags =
279             flags;
280 
281         ACPI_MOVE_32_TO_32(&
282                            (acpi_gbl_root_table_list.
283                             tables[acpi_gbl_root_table_list.count].signature),
284                            table->signature);
285 
286         *table_index = acpi_gbl_root_table_list.count;
287         acpi_gbl_root_table_list.count++;
288         return (status);
289 }
290 
291 /*******************************************************************************
292  *
293  * FUNCTION:    acpi_tb_delete_table
294  *
295  * PARAMETERS:  table_index         - Table index
296  *
297  * RETURN:      None
298  *
299  * DESCRIPTION: Delete one internal ACPI table
300  *
301  ******************************************************************************/
302 
303 void acpi_tb_delete_table(struct acpi_table_desc *table_desc)
304 {
305         /* Table must be mapped or allocated */
306         if (!table_desc->pointer) {
307                 return;
308         }
309         switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
310         case ACPI_TABLE_ORIGIN_MAPPED:
311                 acpi_os_unmap_memory(table_desc->pointer, table_desc->length);
312                 break;
313         case ACPI_TABLE_ORIGIN_ALLOCATED:
314                 ACPI_FREE(table_desc->pointer);
315                 break;
316         default:;
317         }
318 
319         table_desc->pointer = NULL;
320 }
321 
322 /*******************************************************************************
323  *
324  * FUNCTION:    acpi_tb_terminate
325  *
326  * PARAMETERS:  None
327  *
328  * RETURN:      None
329  *
330  * DESCRIPTION: Delete all internal ACPI tables
331  *
332  ******************************************************************************/
333 
334 void acpi_tb_terminate(void)
335 {
336         acpi_native_uint i;
337 
338         ACPI_FUNCTION_TRACE(tb_terminate);
339 
340         (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
341 
342         /* Delete the individual tables */
343 
344         for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
345                 acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]);
346         }
347 
348         /*
349          * Delete the root table array if allocated locally. Array cannot be
350          * mapped, so we don't need to check for that flag.
351          */
352         if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
353                 ACPI_FREE(acpi_gbl_root_table_list.tables);
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);
362 }
363 
364 /*******************************************************************************
365  *
366  * FUNCTION:    acpi_tb_delete_namespace_by_owner
367  *
368  * PARAMETERS:  table_index         - Table index
369  *
370  * RETURN:      None
371  *
372  * DESCRIPTION: Delete all namespace objects created when this table was loaded.
373  *
374  ******************************************************************************/
375 
376 void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index)
377 {
378         acpi_owner_id owner_id;
379 
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);
386                 return;
387         }
388 
389         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
390         acpi_ns_delete_namespace_by_owner(owner_id);
391 }
392 
393 /*******************************************************************************
394  *
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  ******************************************************************************/
404 
405 acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index)
406 {
407         acpi_status status = AE_BAD_PARAMETER;
408 
409         ACPI_FUNCTION_TRACE(tb_allocate_owner_id);
410 
411         (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
412         if (table_index < acpi_gbl_root_table_list.count) {
413                 status = acpi_ut_allocate_owner_id
414                     (&(acpi_gbl_root_table_list.tables[table_index].owner_id));
415         }
416 
417         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
418         return_ACPI_STATUS(status);
419 }
420 
421 /*******************************************************************************
422  *
423  * FUNCTION:    acpi_tb_release_owner_id
424  *
425  * PARAMETERS:  table_index         - Table index
426  *
427  * RETURN:      Status
428  *
429  * DESCRIPTION: Releases owner_id in table_desc
430  *
431  ******************************************************************************/
432 
433 acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index)
434 {
435         acpi_status status = AE_BAD_PARAMETER;
436 
437         ACPI_FUNCTION_TRACE(tb_release_owner_id);
438 
439         (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
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;
445         }
446 
447         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
448         return_ACPI_STATUS(status);
449 }
450 
451 /*******************************************************************************
452  *
453  * FUNCTION:    acpi_tb_get_owner_id
454  *
455  * PARAMETERS:  table_index         - Table index
456  *              owner_id            - Where the table owner_id is returned
457  *
458  * RETURN:      Status
459  *
460  * DESCRIPTION: returns owner_id for the ACPI table
461  *
462  ******************************************************************************/
463 
464 acpi_status
465 acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id)
466 {
467         acpi_status status = AE_BAD_PARAMETER;
468 
469         ACPI_FUNCTION_TRACE(tb_get_owner_id);
470 
471         (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
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;
476         }
477 
478         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
479         return_ACPI_STATUS(status);
480 }
481 
482 /*******************************************************************************
483  *
484  * FUNCTION:    acpi_tb_is_table_loaded
485  *
486  * PARAMETERS:  table_index         - Table index
487  *
488  * RETURN:      Table Loaded Flag
489  *
490  ******************************************************************************/
491 
492 u8 acpi_tb_is_table_loaded(acpi_native_uint table_index)
493 {
494         u8 is_loaded = FALSE;
495 
496         (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
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_IS_LOADED);
501         }
502 
503         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
504         return (is_loaded);
505 }
506 
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  ******************************************************************************/
519 
520 void acpi_tb_set_table_loaded_flag(acpi_native_uint table_index, u8 is_loaded)
521 {
522 
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_IS_LOADED;
528                 } else {
529                         acpi_gbl_root_table_list.tables[table_index].flags &=
530                             ~ACPI_TABLE_IS_LOADED;
531                 }
532         }
533 
534         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
535 }
536 
  This page was automatically generated by the LXR engine.