2005-04-17 02:20:36 +04:00
/******************************************************************************
*
* Module Name : tbxface - Public interfaces to the ACPI subsystem
* ACPI table oriented interfaces
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
2008-04-24 07:00:13 +04:00
* Copyright ( C ) 2000 - 2008 , Intel Corp .
2005-04-17 02:20:36 +04:00
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions , and the following disclaimer ,
* without modification .
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the " NO WARRANTY " disclaimer below
* ( " Disclaimer " ) and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution .
* 3. Neither the names of the above - listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission .
*
* Alternatively , this software may be distributed under the terms of the
* GNU General Public License ( " GPL " ) version 2 as published by the Free
* Software Foundation .
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* " AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
* DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION )
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT ,
* STRICT LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES .
*/
# include <acpi/acpi.h>
2009-01-09 08:30:03 +03:00
# include "accommon.h"
# include "acnamesp.h"
# include "actables.h"
2005-04-17 02:20:36 +04:00
# define _COMPONENT ACPI_TABLES
2005-08-05 08:44:28 +04:00
ACPI_MODULE_NAME ( " tbxface " )
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
/* Local prototypes */
static acpi_status acpi_tb_load_namespace ( void ) ;
2007-07-26 08:50:06 +04:00
static int no_auto_ssdt ;
2007-02-02 19:48:20 +03:00
/*******************************************************************************
*
* FUNCTION : acpi_allocate_root_table
*
* PARAMETERS : initial_table_count - Size of initial_table_array , in number of
* struct acpi_table_desc structures
*
* RETURN : Status
*
* DESCRIPTION : Allocate a root table array . Used by i_aSL compiler and
* acpi_initialize_tables .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
acpi_status acpi_allocate_root_table ( u32 initial_table_count )
{
acpi_gbl_root_table_list . size = initial_table_count ;
acpi_gbl_root_table_list . flags = ACPI_ROOT_ALLOW_RESIZE ;
return ( acpi_tb_resize_root_table_list ( ) ) ;
}
2005-04-17 02:20:36 +04:00
/*******************************************************************************
*
2007-02-02 19:48:18 +03:00
* FUNCTION : acpi_initialize_tables
2005-04-17 02:20:36 +04:00
*
2007-02-02 19:48:18 +03:00
* PARAMETERS : initial_table_array - Pointer to an array of pre - allocated
* struct acpi_table_desc structures . If NULL , the
* array is dynamically allocated .
* initial_table_count - Size of initial_table_array , in number of
* struct acpi_table_desc structures
* allow_realloc - Flag to tell Table Manager if resize of
* pre - allocated array is allowed . Ignored
* if initial_table_array is NULL .
2005-04-17 02:20:36 +04:00
*
* RETURN : Status
*
2007-02-02 19:48:18 +03:00
* DESCRIPTION : Initialize the table manager , get the RSDP and RSDT / XSDT .
*
* NOTE : Allows static allocation of the initial table array in order
* to avoid the use of dynamic memory in confined environments
* such as the kernel boot sequence where it may not be available .
*
* If the host OS memory managers are initialized , use NULL for
* initial_table_array , and the table will be dynamically allocated .
2005-04-17 02:20:36 +04:00
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-02-02 19:48:18 +03:00
2007-02-02 19:48:19 +03:00
acpi_status __init
2007-02-02 19:48:20 +03:00
acpi_initialize_tables ( struct acpi_table_desc * initial_table_array ,
2007-02-02 19:48:18 +03:00
u32 initial_table_count , u8 allow_resize )
2005-04-17 02:20:36 +04:00
{
2007-02-02 19:48:19 +03:00
acpi_physical_address rsdp_address ;
2005-08-05 08:44:28 +04:00
acpi_status status ;
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
ACPI_FUNCTION_TRACE ( acpi_initialize_tables ) ;
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
/*
* Set up the Root Table Array
* Allocate the table array if requested
*/
if ( ! initial_table_array ) {
2007-02-02 19:48:20 +03:00
status = acpi_allocate_root_table ( initial_table_count ) ;
2007-02-02 19:48:18 +03:00
if ( ACPI_FAILURE ( status ) ) {
return_ACPI_STATUS ( status ) ;
}
} else {
/* Root Table Array has been statically allocated by the host */
2007-02-02 19:48:19 +03:00
ACPI_MEMSET ( initial_table_array , 0 ,
2008-06-10 09:42:13 +04:00
( acpi_size ) initial_table_count *
2007-02-02 19:48:19 +03:00
sizeof ( struct acpi_table_desc ) ) ;
2007-02-02 19:48:19 +03:00
2007-02-02 19:48:18 +03:00
acpi_gbl_root_table_list . tables = initial_table_array ;
acpi_gbl_root_table_list . size = initial_table_count ;
2007-02-02 19:48:19 +03:00
acpi_gbl_root_table_list . flags = ACPI_ROOT_ORIGIN_UNKNOWN ;
2007-02-02 19:48:18 +03:00
if ( allow_resize ) {
2007-02-02 19:48:19 +03:00
acpi_gbl_root_table_list . flags | =
ACPI_ROOT_ALLOW_RESIZE ;
2007-02-02 19:48:18 +03:00
}
2005-04-17 02:20:36 +04:00
}
2007-02-02 19:48:19 +03:00
/* Get the address of the RSDP */
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:19 +03:00
rsdp_address = acpi_os_get_root_pointer ( ) ;
if ( ! rsdp_address ) {
2007-02-02 19:48:18 +03:00
return_ACPI_STATUS ( AE_NOT_FOUND ) ;
}
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
/*
* Get the root table ( RSDT or XSDT ) and extract all entries to the local
* Root Table Array . This array contains the information of the RSDT / XSDT
* in a common , more useable format .
*/
2007-02-02 19:48:19 +03:00
status =
acpi_tb_parse_root_table ( rsdp_address , ACPI_TABLE_ORIGIN_MAPPED ) ;
2007-02-02 19:48:18 +03:00
return_ACPI_STATUS ( status ) ;
}
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
/*******************************************************************************
*
* FUNCTION : acpi_reallocate_root_table
*
* PARAMETERS : None
*
* RETURN : Status
*
* DESCRIPTION : Reallocate Root Table List into dynamic memory . Copies the
* root list from the previously provided scratch area . Should
* be called once dynamic memory allocation is available in the
* kernel
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
acpi_status acpi_reallocate_root_table ( void )
{
struct acpi_table_desc * tables ;
acpi_size new_size ;
ACPI_FUNCTION_TRACE ( acpi_reallocate_root_table ) ;
/*
* Only reallocate the root table if the host provided a static buffer
* for the table array in the call to acpi_initialize_tables .
*/
2007-02-02 19:48:19 +03:00
if ( acpi_gbl_root_table_list . flags & ACPI_ROOT_ORIGIN_ALLOCATED ) {
2007-02-02 19:48:18 +03:00
return_ACPI_STATUS ( AE_SUPPORT ) ;
2005-04-17 02:20:36 +04:00
}
2008-06-10 09:42:13 +04:00
new_size = ( ( acpi_size ) acpi_gbl_root_table_list . count +
ACPI_ROOT_TABLE_SIZE_INCREMENT ) *
sizeof ( struct acpi_table_desc ) ;
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
/* Create new array and copy the old array */
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
tables = ACPI_ALLOCATE_ZEROED ( new_size ) ;
if ( ! tables ) {
return_ACPI_STATUS ( AE_NO_MEMORY ) ;
2005-04-17 02:20:36 +04:00
}
2007-02-02 19:48:18 +03:00
ACPI_MEMCPY ( tables , acpi_gbl_root_table_list . tables , new_size ) ;
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
acpi_gbl_root_table_list . size = acpi_gbl_root_table_list . count ;
acpi_gbl_root_table_list . tables = tables ;
acpi_gbl_root_table_list . flags =
2007-02-02 19:48:19 +03:00
ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE ;
2006-10-03 08:00:00 +04:00
2007-02-02 19:48:18 +03:00
return_ACPI_STATUS ( AE_OK ) ;
}
2007-05-10 07:34:35 +04:00
2005-04-17 02:20:36 +04:00
/*******************************************************************************
*
* FUNCTION : acpi_load_table
*
* PARAMETERS : table_ptr - pointer to a buffer containing the entire
* table to be loaded
*
* RETURN : Status
*
* DESCRIPTION : This function is called to load a table from the caller ' s
2006-07-08 04:44:38 +04:00
* buffer . The buffer must contain an entire ACPI Table including
* a valid header . The header fields will be verified , and if it
2005-04-17 02:20:36 +04:00
* is determined that the table is invalid , the call will fail .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-08-05 08:44:28 +04:00
acpi_status acpi_load_table ( struct acpi_table_header * table_ptr )
2005-04-17 02:20:36 +04:00
{
2005-08-05 08:44:28 +04:00
acpi_status status ;
2008-06-10 09:42:13 +04:00
u32 table_index ;
2007-02-02 19:48:22 +03:00
struct acpi_table_desc table_desc ;
if ( ! table_ptr )
return AE_BAD_PARAMETER ;
ACPI_MEMSET ( & table_desc , 0 , sizeof ( struct acpi_table_desc ) ) ;
table_desc . pointer = table_ptr ;
table_desc . length = table_ptr - > length ;
table_desc . flags = ACPI_TABLE_ORIGIN_UNKNOWN ;
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
/*
* Install the new table into the local data structures
*/
2007-02-02 19:48:22 +03:00
status = acpi_tb_add_table ( & table_desc , & table_index ) ;
2005-08-05 08:44:28 +04:00
if ( ACPI_FAILURE ( status ) ) {
2007-02-02 19:48:22 +03:00
return status ;
2005-07-30 02:15:00 +04:00
}
2007-02-02 19:48:18 +03:00
status = acpi_ns_load_table ( table_index , acpi_gbl_root_node ) ;
2007-02-02 19:48:22 +03:00
return status ;
2007-02-02 19:48:18 +03:00
}
2005-07-30 02:15:00 +04:00
2007-02-02 19:48:18 +03:00
ACPI_EXPORT_SYMBOL ( acpi_load_table )
2006-10-02 08:00:00 +04:00
2007-02-02 19:48:18 +03:00
/******************************************************************************
*
* FUNCTION : acpi_get_table_header
*
* PARAMETERS : Signature - ACPI signature of needed table
* Instance - Which instance ( for SSDTs )
2007-02-02 19:48:22 +03:00
* out_table_header - The pointer to the table header to fill
2007-02-02 19:48:18 +03:00
*
* RETURN : Status and pointer to mapped table header
*
* DESCRIPTION : Finds an ACPI table header .
*
* NOTE : Caller is responsible in unmapping the header with
* acpi_os_unmap_memory
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
acpi_status
acpi_get_table_header ( char * signature ,
2008-06-10 09:42:13 +04:00
u32 instance , struct acpi_table_header * out_table_header )
2007-02-02 19:48:18 +03:00
{
2008-06-10 09:42:13 +04:00
u32 i ;
u32 j ;
2007-02-02 19:48:22 +03:00
struct acpi_table_header * header ;
2005-07-30 02:15:00 +04:00
2007-02-02 19:48:19 +03:00
/* Parameter validation */
if ( ! signature | | ! out_table_header ) {
return ( AE_BAD_PARAMETER ) ;
}
2007-02-02 19:48:18 +03:00
/*
* Walk the root table list
*/
for ( i = 0 , j = 0 ; i < acpi_gbl_root_table_list . count ; i + + ) {
if ( ! ACPI_COMPARE_NAME
( & ( acpi_gbl_root_table_list . tables [ i ] . signature ) ,
signature ) ) {
continue ;
2005-07-30 02:15:00 +04:00
}
2007-02-02 19:48:18 +03:00
if ( + + j < instance ) {
continue ;
}
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:22 +03:00
if ( ! acpi_gbl_root_table_list . tables [ i ] . pointer ) {
if ( ( acpi_gbl_root_table_list . tables [ i ] .
flags & ACPI_TABLE_ORIGIN_MASK ) = =
ACPI_TABLE_ORIGIN_MAPPED ) {
header =
acpi_os_map_memory ( acpi_gbl_root_table_list .
tables [ i ] . address ,
sizeof ( struct
acpi_table_header ) ) ;
if ( ! header ) {
return AE_NO_MEMORY ;
}
ACPI_MEMCPY ( out_table_header , header ,
sizeof ( struct acpi_table_header ) ) ;
acpi_os_unmap_memory ( header ,
sizeof ( struct
acpi_table_header ) ) ;
} else {
return AE_NOT_FOUND ;
}
} else {
ACPI_MEMCPY ( out_table_header ,
acpi_gbl_root_table_list . tables [ i ] . pointer ,
sizeof ( struct acpi_table_header ) ) ;
2007-02-02 19:48:18 +03:00
}
return ( AE_OK ) ;
2005-04-17 02:20:36 +04:00
}
2007-02-02 19:48:18 +03:00
return ( AE_NOT_FOUND ) ;
2005-04-17 02:20:36 +04:00
}
2007-02-02 19:48:18 +03:00
ACPI_EXPORT_SYMBOL ( acpi_get_table_header )
2006-10-03 08:00:00 +04:00
2007-02-02 19:48:18 +03:00
/******************************************************************************
2006-12-19 23:56:19 +03:00
*
* FUNCTION : acpi_unload_table_id
*
2007-02-02 19:48:18 +03:00
* PARAMETERS : id - Owner ID of the table to be removed .
2006-12-19 23:56:19 +03:00
*
* RETURN : Status
*
* DESCRIPTION : This routine is used to force the unload of a table ( by id )
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-02-02 19:48:18 +03:00
acpi_status acpi_unload_table_id ( acpi_owner_id id )
2006-12-19 23:56:19 +03:00
{
2007-02-02 19:48:18 +03:00
int i ;
acpi_status status = AE_NOT_EXIST ;
2006-12-19 23:56:19 +03:00
2007-02-15 23:08:30 +03:00
ACPI_FUNCTION_TRACE ( acpi_unload_table_id ) ;
2006-12-19 23:56:19 +03:00
2007-02-15 23:08:30 +03:00
/* Find table in the global table list */
2007-02-02 19:48:18 +03:00
for ( i = 0 ; i < acpi_gbl_root_table_list . count ; + + i ) {
if ( id ! = acpi_gbl_root_table_list . tables [ i ] . owner_id ) {
continue ;
}
/*
2007-05-10 07:34:35 +04:00
* Delete all namespace objects owned by this table . Note that these
* objects can appear anywhere in the namespace by virtue of the AML
* " Scope " operator . Thus , we need to track ownership by an ID , not
* simply a position within the hierarchy
*/
2007-02-02 19:48:18 +03:00
acpi_tb_delete_namespace_by_owner ( i ) ;
2007-02-15 23:08:30 +03:00
status = acpi_tb_release_owner_id ( i ) ;
2007-02-02 19:48:18 +03:00
acpi_tb_set_table_loaded_flag ( i , FALSE ) ;
2007-02-15 23:08:30 +03:00
break ;
2007-02-02 19:48:18 +03:00
}
return_ACPI_STATUS ( status ) ;
2006-12-19 23:56:19 +03:00
}
ACPI_EXPORT_SYMBOL ( acpi_unload_table_id )
2005-04-17 02:20:36 +04:00
/*******************************************************************************
*
2007-02-02 19:48:18 +03:00
* FUNCTION : acpi_get_table
2005-04-17 02:20:36 +04:00
*
2007-02-02 19:48:18 +03:00
* PARAMETERS : Signature - ACPI signature of needed table
* Instance - Which instance ( for SSDTs )
* out_table - Where the pointer to the table is returned
2005-04-17 02:20:36 +04:00
*
2007-02-02 19:48:18 +03:00
* RETURN : Status and pointer to table
2005-04-17 02:20:36 +04:00
*
2007-02-02 19:48:18 +03:00
* DESCRIPTION : Finds and verifies an ACPI table .
2005-04-17 02:20:36 +04:00
*
2007-02-02 19:48:18 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
acpi_status
acpi_get_table ( char * signature ,
2008-06-10 09:42:13 +04:00
u32 instance , struct acpi_table_header * * out_table )
2005-04-17 02:20:36 +04:00
{
2008-06-10 09:42:13 +04:00
u32 i ;
u32 j ;
2007-02-02 19:48:18 +03:00
acpi_status status ;
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:19 +03:00
/* Parameter validation */
if ( ! signature | | ! out_table ) {
return ( AE_BAD_PARAMETER ) ;
}
2007-02-02 19:48:18 +03:00
/*
* Walk the root table list
*/
for ( i = 0 , j = 0 ; i < acpi_gbl_root_table_list . count ; i + + ) {
if ( ! ACPI_COMPARE_NAME
( & ( acpi_gbl_root_table_list . tables [ i ] . signature ) ,
signature ) ) {
continue ;
}
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
if ( + + j < instance ) {
continue ;
}
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
status =
acpi_tb_verify_table ( & acpi_gbl_root_table_list . tables [ i ] ) ;
if ( ACPI_SUCCESS ( status ) ) {
* out_table = acpi_gbl_root_table_list . tables [ i ] . pointer ;
}
2006-07-08 04:44:38 +04:00
2007-02-02 19:48:19 +03:00
if ( ! acpi_gbl_permanent_mmap ) {
2007-02-14 03:11:36 +03:00
acpi_gbl_root_table_list . tables [ i ] . pointer = NULL ;
2007-02-02 19:48:19 +03:00
}
2007-02-02 19:48:18 +03:00
return ( status ) ;
2005-04-17 02:20:36 +04:00
}
2007-02-02 19:48:18 +03:00
return ( AE_NOT_FOUND ) ;
2005-04-17 02:20:36 +04:00
}
2007-02-02 19:48:18 +03:00
ACPI_EXPORT_SYMBOL ( acpi_get_table )
2006-10-03 08:00:00 +04:00
2005-04-17 02:20:36 +04:00
/*******************************************************************************
*
2007-02-02 19:48:18 +03:00
* FUNCTION : acpi_get_table_by_index
2005-04-17 02:20:36 +04:00
*
2007-02-02 19:48:18 +03:00
* PARAMETERS : table_index - Table index
* Table - Where the pointer to the table is returned
2005-04-17 02:20:36 +04:00
*
2007-02-02 19:48:18 +03:00
* RETURN : Status and pointer to the table
2005-04-17 02:20:36 +04:00
*
2007-02-02 19:48:18 +03:00
* DESCRIPTION : Obtain a table by an index into the global table list .
2005-04-17 02:20:36 +04:00
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
acpi_status
2008-06-10 09:42:13 +04:00
acpi_get_table_by_index ( u32 table_index , struct acpi_table_header * * table )
2005-04-17 02:20:36 +04:00
{
2005-08-05 08:44:28 +04:00
acpi_status status ;
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
ACPI_FUNCTION_TRACE ( acpi_get_table_by_index ) ;
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:19 +03:00
/* Parameter validation */
if ( ! table ) {
return_ACPI_STATUS ( AE_BAD_PARAMETER ) ;
}
2007-02-02 19:48:18 +03:00
( void ) acpi_ut_acquire_mutex ( ACPI_MTX_TABLES ) ;
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
/* Validate index */
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
if ( table_index > = acpi_gbl_root_table_list . count ) {
( void ) acpi_ut_release_mutex ( ACPI_MTX_TABLES ) ;
2005-08-05 08:44:28 +04:00
return_ACPI_STATUS ( AE_BAD_PARAMETER ) ;
2005-04-17 02:20:36 +04:00
}
2007-02-02 19:48:18 +03:00
if ( ! acpi_gbl_root_table_list . tables [ table_index ] . pointer ) {
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
/* Table is not mapped, map it */
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
status =
acpi_tb_verify_table ( & acpi_gbl_root_table_list .
tables [ table_index ] ) ;
if ( ACPI_FAILURE ( status ) ) {
( void ) acpi_ut_release_mutex ( ACPI_MTX_TABLES ) ;
return_ACPI_STATUS ( status ) ;
}
2005-04-17 02:20:36 +04:00
}
2007-02-02 19:48:18 +03:00
* table = acpi_gbl_root_table_list . tables [ table_index ] . pointer ;
( void ) acpi_ut_release_mutex ( ACPI_MTX_TABLES ) ;
return_ACPI_STATUS ( AE_OK ) ;
2005-04-17 02:20:36 +04:00
}
2007-02-02 19:48:18 +03:00
ACPI_EXPORT_SYMBOL ( acpi_get_table_by_index )
2005-04-17 02:20:36 +04:00
/*******************************************************************************
*
2007-02-02 19:48:18 +03:00
* FUNCTION : acpi_tb_load_namespace
2005-04-17 02:20:36 +04:00
*
2007-02-02 19:48:18 +03:00
* PARAMETERS : None
2005-04-17 02:20:36 +04:00
*
* RETURN : Status
*
2007-02-02 19:48:18 +03:00
* DESCRIPTION : Load the namespace from the DSDT and all SSDTs / PSDTs found in
* the RSDT / XSDT .
2005-04-17 02:20:36 +04:00
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-02-02 19:48:18 +03:00
static acpi_status acpi_tb_load_namespace ( void )
2005-04-17 02:20:36 +04:00
{
2005-08-05 08:44:28 +04:00
acpi_status status ;
2007-02-02 19:48:18 +03:00
struct acpi_table_header * table ;
2008-06-10 09:42:13 +04:00
u32 i ;
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
ACPI_FUNCTION_TRACE ( tb_load_namespace ) ;
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
( void ) acpi_ut_acquire_mutex ( ACPI_MTX_TABLES ) ;
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
/*
* Load the namespace . The DSDT is required , but any SSDT and PSDT tables
* are optional .
*/
if ( ! acpi_gbl_root_table_list . count | |
! ACPI_COMPARE_NAME ( &
( acpi_gbl_root_table_list .
tables [ ACPI_TABLE_INDEX_DSDT ] . signature ) ,
ACPI_SIG_DSDT )
| |
ACPI_FAILURE ( acpi_tb_verify_table
( & acpi_gbl_root_table_list .
tables [ ACPI_TABLE_INDEX_DSDT ] ) ) ) {
status = AE_NO_ACPI_TABLES ;
goto unlock_and_exit ;
2005-04-17 02:20:36 +04:00
}
2007-02-02 19:48:18 +03:00
/*
* Find DSDT table
*/
status =
acpi_os_table_override ( acpi_gbl_root_table_list .
tables [ ACPI_TABLE_INDEX_DSDT ] . pointer ,
& table ) ;
if ( ACPI_SUCCESS ( status ) & & table ) {
/*
* DSDT table has been found
*/
2007-02-02 19:48:24 +03:00
acpi_tb_delete_table ( & acpi_gbl_root_table_list .
tables [ ACPI_TABLE_INDEX_DSDT ] ) ;
2007-02-02 19:48:18 +03:00
acpi_gbl_root_table_list . tables [ ACPI_TABLE_INDEX_DSDT ] . pointer =
table ;
acpi_gbl_root_table_list . tables [ ACPI_TABLE_INDEX_DSDT ] . length =
table - > length ;
acpi_gbl_root_table_list . tables [ ACPI_TABLE_INDEX_DSDT ] . flags =
ACPI_TABLE_ORIGIN_UNKNOWN ;
ACPI_INFO ( ( AE_INFO , " Table DSDT replaced by host OS " ) ) ;
acpi_tb_print_table_header ( 0 , table ) ;
2007-07-26 08:50:06 +04:00
if ( no_auto_ssdt = = 0 ) {
2008-05-12 22:13:09 +04:00
printk ( KERN_WARNING " ACPI: DSDT override uses original SSDTs unless \" acpi_no_auto_ssdt \" \n " ) ;
2007-07-26 08:50:06 +04:00
}
2005-04-17 02:20:36 +04:00
}
2007-02-02 19:48:18 +03:00
status =
acpi_tb_verify_table ( & acpi_gbl_root_table_list .
tables [ ACPI_TABLE_INDEX_DSDT ] ) ;
if ( ACPI_FAILURE ( status ) ) {
/* A valid DSDT is required */
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
status = AE_NO_ACPI_TABLES ;
goto unlock_and_exit ;
2005-04-17 02:20:36 +04:00
}
2007-02-02 19:48:18 +03:00
( void ) acpi_ut_release_mutex ( ACPI_MTX_TABLES ) ;
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
/*
* Load and parse tables .
*/
status = acpi_ns_load_table ( ACPI_TABLE_INDEX_DSDT , acpi_gbl_root_node ) ;
2005-08-05 08:44:28 +04:00
if ( ACPI_FAILURE ( status ) ) {
return_ACPI_STATUS ( status ) ;
2005-04-17 02:20:36 +04:00
}
/*
2007-02-02 19:48:18 +03:00
* Load any SSDT or PSDT tables . Note : Loop leaves tables locked
2005-04-17 02:20:36 +04:00
*/
2007-02-02 19:48:18 +03:00
( void ) acpi_ut_acquire_mutex ( ACPI_MTX_TABLES ) ;
for ( i = 0 ; i < acpi_gbl_root_table_list . count ; + + i ) {
if ( ( ! ACPI_COMPARE_NAME
( & ( acpi_gbl_root_table_list . tables [ i ] . signature ) ,
ACPI_SIG_SSDT )
& &
! ACPI_COMPARE_NAME ( &
( acpi_gbl_root_table_list . tables [ i ] .
signature ) , ACPI_SIG_PSDT ) )
| |
ACPI_FAILURE ( acpi_tb_verify_table
( & acpi_gbl_root_table_list . tables [ i ] ) ) ) {
continue ;
}
2007-07-26 08:50:06 +04:00
if ( no_auto_ssdt ) {
printk ( KERN_WARNING " ACPI: SSDT ignored due to \" acpi_no_auto_ssdt \" \n " ) ;
continue ;
}
2007-02-02 19:48:18 +03:00
/* Ignore errors while loading tables, get as many as possible */
( void ) acpi_ut_release_mutex ( ACPI_MTX_TABLES ) ;
( void ) acpi_ns_load_table ( i , acpi_gbl_root_node ) ;
( void ) acpi_ut_acquire_mutex ( ACPI_MTX_TABLES ) ;
2005-04-17 02:20:36 +04:00
}
2007-02-02 19:48:18 +03:00
ACPI_DEBUG_PRINT ( ( ACPI_DB_INIT , " ACPI Tables successfully acquired \n " ) ) ;
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
unlock_and_exit :
( void ) acpi_ut_release_mutex ( ACPI_MTX_TABLES ) ;
return_ACPI_STATUS ( status ) ;
}
2006-10-02 08:00:00 +04:00
2007-02-02 19:48:18 +03:00
/*******************************************************************************
*
* FUNCTION : acpi_load_tables
*
* PARAMETERS : None
*
* RETURN : Status
*
* DESCRIPTION : Load the ACPI tables from the RSDT / XSDT
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-04-19 06:49:35 +04:00
2007-02-02 19:48:18 +03:00
acpi_status acpi_load_tables ( void )
{
acpi_status status ;
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
ACPI_FUNCTION_TRACE ( acpi_load_tables ) ;
2005-04-17 02:20:36 +04:00
2007-02-02 19:48:18 +03:00
/*
* Load the namespace from the tables
*/
status = acpi_tb_load_namespace ( ) ;
2005-08-05 08:44:28 +04:00
if ( ACPI_FAILURE ( status ) ) {
2007-02-02 19:48:18 +03:00
ACPI_EXCEPTION ( ( AE_INFO , status ,
" While loading namespace from ACPI tables " ) ) ;
2005-04-17 02:20:36 +04:00
}
2007-02-02 19:48:18 +03:00
return_ACPI_STATUS ( status ) ;
2005-04-17 02:20:36 +04:00
}
2007-02-02 19:48:18 +03:00
ACPI_EXPORT_SYMBOL ( acpi_load_tables )
2007-07-26 08:50:06 +04:00
2008-04-10 19:06:38 +04:00
/*******************************************************************************
*
* FUNCTION : acpi_install_table_handler
*
* PARAMETERS : Handler - Table event handler
* Context - Value passed to the handler on each event
*
* RETURN : Status
*
* DESCRIPTION : Install table event handler
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
acpi_status
acpi_install_table_handler ( acpi_tbl_handler handler , void * context )
{
acpi_status status ;
ACPI_FUNCTION_TRACE ( acpi_install_table_handler ) ;
if ( ! handler ) {
return_ACPI_STATUS ( AE_BAD_PARAMETER ) ;
}
status = acpi_ut_acquire_mutex ( ACPI_MTX_EVENTS ) ;
if ( ACPI_FAILURE ( status ) ) {
return_ACPI_STATUS ( status ) ;
}
/* Don't allow more than one handler */
if ( acpi_gbl_table_handler ) {
status = AE_ALREADY_EXISTS ;
goto cleanup ;
}
/* Install the handler */
acpi_gbl_table_handler = handler ;
acpi_gbl_table_handler_context = context ;
cleanup :
( void ) acpi_ut_release_mutex ( ACPI_MTX_EVENTS ) ;
return_ACPI_STATUS ( status ) ;
}
ACPI_EXPORT_SYMBOL ( acpi_install_table_handler )
/*******************************************************************************
*
* FUNCTION : acpi_remove_table_handler
*
* PARAMETERS : Handler - Table event handler that was installed
* previously .
*
* RETURN : Status
*
* DESCRIPTION : Remove table event handler
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
acpi_status acpi_remove_table_handler ( acpi_tbl_handler handler )
{
acpi_status status ;
ACPI_FUNCTION_TRACE ( acpi_remove_table_handler ) ;
status = acpi_ut_acquire_mutex ( ACPI_MTX_EVENTS ) ;
if ( ACPI_FAILURE ( status ) ) {
return_ACPI_STATUS ( status ) ;
}
/* Make sure that the installed handler is the same */
if ( ! handler | | handler ! = acpi_gbl_table_handler ) {
status = AE_BAD_PARAMETER ;
goto cleanup ;
}
/* Remove the handler */
acpi_gbl_table_handler = NULL ;
cleanup :
( void ) acpi_ut_release_mutex ( ACPI_MTX_EVENTS ) ;
return_ACPI_STATUS ( status ) ;
}
ACPI_EXPORT_SYMBOL ( acpi_remove_table_handler )
2007-07-26 08:50:06 +04:00
static int __init acpi_no_auto_ssdt_setup ( char * s ) {
printk ( KERN_NOTICE " ACPI: SSDT auto-load disabled \n " ) ;
no_auto_ssdt = 1 ;
return 1 ;
}
__setup ( " acpi_no_auto_ssdt " , acpi_no_auto_ssdt_setup ) ;