2005-04-17 02:20:36 +04:00
/******************************************************************************
*
* Module Name : excreate - Named object creation
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
2006-01-14 00:22:00 +03:00
* Copyright ( C ) 2000 - 2006 , R . Byron Moore
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>
# include <acpi/acinterp.h>
# include <acpi/amlcode.h>
# include <acpi/acnamesp.h>
# include <acpi/acevents.h>
# include <acpi/actables.h>
# define _COMPONENT ACPI_EXECUTER
2005-08-05 08:44:28 +04:00
ACPI_MODULE_NAME ( " excreate " )
2005-04-17 02:20:36 +04:00
# ifndef ACPI_NO_METHOD_EXECUTION
2005-04-19 06:49:35 +04:00
/*******************************************************************************
2005-04-17 02:20:36 +04:00
*
* FUNCTION : acpi_ex_create_alias
*
* PARAMETERS : walk_state - Current state , contains operands
*
* RETURN : Status
*
* DESCRIPTION : Create a new named alias
*
2005-04-19 06:49:35 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-08-05 08:44:28 +04:00
acpi_status acpi_ex_create_alias ( struct acpi_walk_state * walk_state )
2005-04-17 02:20:36 +04:00
{
2005-08-05 08:44:28 +04:00
struct acpi_namespace_node * target_node ;
struct acpi_namespace_node * alias_node ;
acpi_status status = AE_OK ;
2005-04-17 02:20:36 +04:00
2005-08-05 08:44:28 +04:00
ACPI_FUNCTION_TRACE ( " ex_create_alias " ) ;
2005-04-17 02:20:36 +04:00
/* Get the source/alias operands (both namespace nodes) */
2005-08-05 08:44:28 +04:00
alias_node = ( struct acpi_namespace_node * ) walk_state - > operands [ 0 ] ;
target_node = ( struct acpi_namespace_node * ) walk_state - > operands [ 1 ] ;
2005-04-17 02:20:36 +04:00
if ( ( target_node - > type = = ACPI_TYPE_LOCAL_ALIAS ) | |
2005-08-05 08:44:28 +04:00
( target_node - > type = = ACPI_TYPE_LOCAL_METHOD_ALIAS ) ) {
2005-04-17 02:20:36 +04:00
/*
* Dereference an existing alias so that we don ' t create a chain
* of aliases . With this code , we guarantee that an alias is
* always exactly one level of indirection away from the
* actual aliased name .
*/
2005-08-05 08:44:28 +04:00
target_node =
ACPI_CAST_PTR ( struct acpi_namespace_node ,
target_node - > object ) ;
2005-04-17 02:20:36 +04:00
}
/*
* For objects that can never change ( i . e . , the NS node will
* permanently point to the same object ) , we can simply attach
* the object to the new NS node . For other objects ( such as
* Integers , buffers , etc . ) , we have to point the Alias node
* to the original Node .
*/
switch ( target_node - > type ) {
case ACPI_TYPE_INTEGER :
case ACPI_TYPE_STRING :
case ACPI_TYPE_BUFFER :
case ACPI_TYPE_PACKAGE :
case ACPI_TYPE_BUFFER_FIELD :
/*
* The new alias has the type ALIAS and points to the original
* NS node , not the object itself . This is because for these
* types , the object can change dynamically via a Store .
*/
alias_node - > type = ACPI_TYPE_LOCAL_ALIAS ;
2005-08-05 08:44:28 +04:00
alias_node - > object =
ACPI_CAST_PTR ( union acpi_operand_object , target_node ) ;
2005-04-17 02:20:36 +04:00
break ;
case ACPI_TYPE_METHOD :
/*
* The new alias has the type ALIAS and points to the original
* NS node , not the object itself . This is because for these
* types , the object can change dynamically via a Store .
*/
alias_node - > type = ACPI_TYPE_LOCAL_METHOD_ALIAS ;
2005-08-05 08:44:28 +04:00
alias_node - > object =
ACPI_CAST_PTR ( union acpi_operand_object , target_node ) ;
2005-04-17 02:20:36 +04:00
break ;
default :
/* Attach the original source object to the new Alias Node */
/*
* The new alias assumes the type of the target , and it points
* to the same object . The reference count of the object has an
* additional reference to prevent deletion out from under either the
* target node or the alias Node
*/
2005-08-05 08:44:28 +04:00
status = acpi_ns_attach_object ( alias_node ,
acpi_ns_get_attached_object
( target_node ) ,
target_node - > type ) ;
2005-04-17 02:20:36 +04:00
break ;
}
/* Since both operands are Nodes, we don't need to delete them */
2005-08-05 08:44:28 +04:00
return_ACPI_STATUS ( status ) ;
2005-04-17 02:20:36 +04:00
}
2005-04-19 06:49:35 +04:00
/*******************************************************************************
2005-04-17 02:20:36 +04:00
*
* FUNCTION : acpi_ex_create_event
*
* PARAMETERS : walk_state - Current state
*
* RETURN : Status
*
* DESCRIPTION : Create a new event object
*
2005-04-19 06:49:35 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-04-17 02:20:36 +04:00
2005-08-05 08:44:28 +04:00
acpi_status acpi_ex_create_event ( struct acpi_walk_state * walk_state )
2005-04-17 02:20:36 +04:00
{
2005-08-05 08:44:28 +04:00
acpi_status status ;
union acpi_operand_object * obj_desc ;
2005-04-17 02:20:36 +04:00
2005-08-05 08:44:28 +04:00
ACPI_FUNCTION_TRACE ( " ex_create_event " ) ;
2005-04-17 02:20:36 +04:00
2005-08-05 08:44:28 +04:00
obj_desc = acpi_ut_create_internal_object ( ACPI_TYPE_EVENT ) ;
2005-04-17 02:20:36 +04:00
if ( ! obj_desc ) {
status = AE_NO_MEMORY ;
goto cleanup ;
}
/*
* Create the actual OS semaphore , with zero initial units - - meaning
* that the event is created in an unsignalled state
*/
2005-08-05 08:44:28 +04:00
status = acpi_os_create_semaphore ( ACPI_NO_UNIT_LIMIT , 0 ,
& obj_desc - > event . semaphore ) ;
if ( ACPI_FAILURE ( status ) ) {
2005-04-17 02:20:36 +04:00
goto cleanup ;
}
/* Attach object to the Node */
2005-08-05 08:44:28 +04:00
status =
acpi_ns_attach_object ( ( struct acpi_namespace_node * ) walk_state - >
operands [ 0 ] , obj_desc , ACPI_TYPE_EVENT ) ;
2005-04-17 02:20:36 +04:00
2005-08-05 08:44:28 +04:00
cleanup :
2005-04-17 02:20:36 +04:00
/*
* Remove local reference to the object ( on error , will cause deletion
* of both object and semaphore if present . )
*/
2005-08-05 08:44:28 +04:00
acpi_ut_remove_reference ( obj_desc ) ;
return_ACPI_STATUS ( status ) ;
2005-04-17 02:20:36 +04:00
}
2005-04-19 06:49:35 +04:00
/*******************************************************************************
2005-04-17 02:20:36 +04:00
*
* FUNCTION : acpi_ex_create_mutex
*
* PARAMETERS : walk_state - Current state
*
* RETURN : Status
*
* DESCRIPTION : Create a new mutex object
*
* Mutex ( Name [ 0 ] , sync_level [ 1 ] )
*
2005-04-19 06:49:35 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-04-17 02:20:36 +04:00
2005-08-05 08:44:28 +04:00
acpi_status acpi_ex_create_mutex ( struct acpi_walk_state * walk_state )
2005-04-17 02:20:36 +04:00
{
2005-08-05 08:44:28 +04:00
acpi_status status = AE_OK ;
union acpi_operand_object * obj_desc ;
2005-04-17 02:20:36 +04:00
2005-08-05 08:44:28 +04:00
ACPI_FUNCTION_TRACE_PTR ( " ex_create_mutex " , ACPI_WALK_OPERANDS ) ;
2005-04-17 02:20:36 +04:00
/* Create the new mutex object */
2005-08-05 08:44:28 +04:00
obj_desc = acpi_ut_create_internal_object ( ACPI_TYPE_MUTEX ) ;
2005-04-17 02:20:36 +04:00
if ( ! obj_desc ) {
status = AE_NO_MEMORY ;
goto cleanup ;
}
/*
* Create the actual OS semaphore .
* One unit max to make it a mutex , with one initial unit to allow
* the mutex to be acquired .
*/
2005-08-05 08:44:28 +04:00
status = acpi_os_create_semaphore ( 1 , 1 , & obj_desc - > mutex . semaphore ) ;
if ( ACPI_FAILURE ( status ) ) {
2005-04-17 02:20:36 +04:00
goto cleanup ;
}
/* Init object and attach to NS node */
2005-08-05 08:44:28 +04:00
obj_desc - > mutex . sync_level =
( u8 ) walk_state - > operands [ 1 ] - > integer . value ;
obj_desc - > mutex . node =
( struct acpi_namespace_node * ) walk_state - > operands [ 0 ] ;
2005-04-17 02:20:36 +04:00
2006-03-18 00:44:00 +03:00
status =
acpi_ns_attach_object ( obj_desc - > mutex . node , obj_desc ,
ACPI_TYPE_MUTEX ) ;
2005-04-17 02:20:36 +04:00
2005-08-05 08:44:28 +04:00
cleanup :
2005-04-17 02:20:36 +04:00
/*
* Remove local reference to the object ( on error , will cause deletion
* of both object and semaphore if present . )
*/
2005-08-05 08:44:28 +04:00
acpi_ut_remove_reference ( obj_desc ) ;
return_ACPI_STATUS ( status ) ;
2005-04-17 02:20:36 +04:00
}
2005-04-19 06:49:35 +04:00
/*******************************************************************************
2005-04-17 02:20:36 +04:00
*
* FUNCTION : acpi_ex_create_region
*
* PARAMETERS : aml_start - Pointer to the region declaration AML
* aml_length - Max length of the declaration AML
2005-04-19 06:49:35 +04:00
* region_space - space_iD for the region
2005-04-17 02:20:36 +04:00
* walk_state - Current state
*
* RETURN : Status
*
* DESCRIPTION : Create a new operation region object
*
2005-04-19 06:49:35 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-04-17 02:20:36 +04:00
acpi_status
2005-08-05 08:44:28 +04:00
acpi_ex_create_region ( u8 * aml_start ,
u32 aml_length ,
u8 region_space , struct acpi_walk_state * walk_state )
2005-04-17 02:20:36 +04:00
{
2005-08-05 08:44:28 +04:00
acpi_status status ;
union acpi_operand_object * obj_desc ;
struct acpi_namespace_node * node ;
union acpi_operand_object * region_obj2 ;
2005-04-17 02:20:36 +04:00
2005-08-05 08:44:28 +04:00
ACPI_FUNCTION_TRACE ( " ex_create_region " ) ;
2005-04-17 02:20:36 +04:00
/* Get the Namespace Node */
node = walk_state - > op - > common . node ;
/*
* If the region object is already attached to this node ,
* just return
*/
2005-08-05 08:44:28 +04:00
if ( acpi_ns_get_attached_object ( node ) ) {
return_ACPI_STATUS ( AE_OK ) ;
2005-04-17 02:20:36 +04:00
}
/*
* Space ID must be one of the predefined IDs , or in the user - defined
* range
*/
if ( ( region_space > = ACPI_NUM_PREDEFINED_REGIONS ) & &
2005-08-05 08:44:28 +04:00
( region_space < ACPI_USER_REGION_BEGIN ) ) {
2006-01-28 00:43:00 +03:00
ACPI_ERROR ( ( AE_INFO , " Invalid address_space type %X " ,
region_space ) ) ;
2005-08-05 08:44:28 +04:00
return_ACPI_STATUS ( AE_AML_INVALID_SPACE_ID ) ;
2005-04-17 02:20:36 +04:00
}
2005-08-05 08:44:28 +04:00
ACPI_DEBUG_PRINT ( ( ACPI_DB_LOAD , " Region Type - %s (%X) \n " ,
acpi_ut_get_region_name ( region_space ) , region_space ) ) ;
2005-04-17 02:20:36 +04:00
/* Create the region descriptor */
2005-08-05 08:44:28 +04:00
obj_desc = acpi_ut_create_internal_object ( ACPI_TYPE_REGION ) ;
2005-04-17 02:20:36 +04:00
if ( ! obj_desc ) {
status = AE_NO_MEMORY ;
goto cleanup ;
}
/*
* Remember location in AML stream of address & length
* operands since they need to be evaluated at run time .
*/
2005-08-05 08:44:28 +04:00
region_obj2 = obj_desc - > common . next_object ;
2005-04-17 02:20:36 +04:00
region_obj2 - > extra . aml_start = aml_start ;
region_obj2 - > extra . aml_length = aml_length ;
/* Init the region from the operands */
obj_desc - > region . space_id = region_space ;
obj_desc - > region . address = 0 ;
obj_desc - > region . length = 0 ;
2005-08-05 08:44:28 +04:00
obj_desc - > region . node = node ;
2005-04-17 02:20:36 +04:00
/* Install the new region object in the parent Node */
2005-08-05 08:44:28 +04:00
status = acpi_ns_attach_object ( node , obj_desc , ACPI_TYPE_REGION ) ;
2005-04-17 02:20:36 +04:00
2005-08-05 08:44:28 +04:00
cleanup :
2005-04-17 02:20:36 +04:00
/* Remove local reference to the object */
2005-08-05 08:44:28 +04:00
acpi_ut_remove_reference ( obj_desc ) ;
return_ACPI_STATUS ( status ) ;
2005-04-17 02:20:36 +04:00
}
2005-04-19 06:49:35 +04:00
/*******************************************************************************
2005-04-17 02:20:36 +04:00
*
* FUNCTION : acpi_ex_create_table_region
*
* PARAMETERS : walk_state - Current state
*
* RETURN : Status
*
* DESCRIPTION : Create a new data_table_region object
*
2005-04-19 06:49:35 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-04-17 02:20:36 +04:00
2005-08-05 08:44:28 +04:00
acpi_status acpi_ex_create_table_region ( struct acpi_walk_state * walk_state )
2005-04-17 02:20:36 +04:00
{
2005-08-05 08:44:28 +04:00
acpi_status status ;
union acpi_operand_object * * operand = & walk_state - > operands [ 0 ] ;
union acpi_operand_object * obj_desc ;
struct acpi_namespace_node * node ;
struct acpi_table_header * table ;
union acpi_operand_object * region_obj2 ;
2005-04-17 02:20:36 +04:00
2005-08-05 08:44:28 +04:00
ACPI_FUNCTION_TRACE ( " ex_create_table_region " ) ;
2005-04-17 02:20:36 +04:00
/* Get the Node from the object stack */
node = walk_state - > op - > common . node ;
/*
* If the region object is already attached to this node ,
* just return
*/
2005-08-05 08:44:28 +04:00
if ( acpi_ns_get_attached_object ( node ) ) {
return_ACPI_STATUS ( AE_OK ) ;
2005-04-17 02:20:36 +04:00
}
/* Find the ACPI table */
2005-08-05 08:44:28 +04:00
status = acpi_tb_find_table ( operand [ 1 ] - > string . pointer ,
operand [ 2 ] - > string . pointer ,
operand [ 3 ] - > string . pointer , & table ) ;
if ( ACPI_FAILURE ( status ) ) {
return_ACPI_STATUS ( status ) ;
2005-04-17 02:20:36 +04:00
}
/* Create the region descriptor */
2005-08-05 08:44:28 +04:00
obj_desc = acpi_ut_create_internal_object ( ACPI_TYPE_REGION ) ;
2005-04-17 02:20:36 +04:00
if ( ! obj_desc ) {
2005-08-05 08:44:28 +04:00
return_ACPI_STATUS ( AE_NO_MEMORY ) ;
2005-04-17 02:20:36 +04:00
}
2005-08-05 08:44:28 +04:00
region_obj2 = obj_desc - > common . next_object ;
2005-04-17 02:20:36 +04:00
region_obj2 - > extra . region_context = NULL ;
/* Init the region from the operands */
obj_desc - > region . space_id = REGION_DATA_TABLE ;
2005-08-05 08:44:28 +04:00
obj_desc - > region . address =
( acpi_physical_address ) ACPI_TO_INTEGER ( table ) ;
2005-04-17 02:20:36 +04:00
obj_desc - > region . length = table - > length ;
2005-08-05 08:44:28 +04:00
obj_desc - > region . node = node ;
obj_desc - > region . flags = AOPOBJ_DATA_VALID ;
2005-04-17 02:20:36 +04:00
/* Install the new region object in the parent Node */
2005-08-05 08:44:28 +04:00
status = acpi_ns_attach_object ( node , obj_desc , ACPI_TYPE_REGION ) ;
if ( ACPI_FAILURE ( status ) ) {
2005-04-17 02:20:36 +04:00
goto cleanup ;
}
2005-08-05 08:44:28 +04:00
status = acpi_ev_initialize_region ( obj_desc , FALSE ) ;
if ( ACPI_FAILURE ( status ) ) {
2005-04-17 02:20:36 +04:00
if ( status = = AE_NOT_EXIST ) {
status = AE_OK ;
2005-08-05 08:44:28 +04:00
} else {
2005-04-17 02:20:36 +04:00
goto cleanup ;
}
}
obj_desc - > region . flags | = AOPOBJ_SETUP_COMPLETE ;
2005-08-05 08:44:28 +04:00
cleanup :
2005-04-17 02:20:36 +04:00
/* Remove local reference to the object */
2005-08-05 08:44:28 +04:00
acpi_ut_remove_reference ( obj_desc ) ;
return_ACPI_STATUS ( status ) ;
2005-04-17 02:20:36 +04:00
}
2005-04-19 06:49:35 +04:00
/*******************************************************************************
2005-04-17 02:20:36 +04:00
*
* FUNCTION : acpi_ex_create_processor
*
* PARAMETERS : walk_state - Current state
*
* RETURN : Status
*
* DESCRIPTION : Create a new processor object and populate the fields
*
* Processor ( Name [ 0 ] , cpu_iD [ 1 ] , pblock_addr [ 2 ] , pblock_length [ 3 ] )
*
2005-04-19 06:49:35 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-04-17 02:20:36 +04:00
2005-08-05 08:44:28 +04:00
acpi_status acpi_ex_create_processor ( struct acpi_walk_state * walk_state )
2005-04-17 02:20:36 +04:00
{
2005-08-05 08:44:28 +04:00
union acpi_operand_object * * operand = & walk_state - > operands [ 0 ] ;
union acpi_operand_object * obj_desc ;
acpi_status status ;
2005-04-17 02:20:36 +04:00
2005-08-05 08:44:28 +04:00
ACPI_FUNCTION_TRACE_PTR ( " ex_create_processor " , walk_state ) ;
2005-04-17 02:20:36 +04:00
/* Create the processor object */
2005-08-05 08:44:28 +04:00
obj_desc = acpi_ut_create_internal_object ( ACPI_TYPE_PROCESSOR ) ;
2005-04-17 02:20:36 +04:00
if ( ! obj_desc ) {
2005-08-05 08:44:28 +04:00
return_ACPI_STATUS ( AE_NO_MEMORY ) ;
2005-04-17 02:20:36 +04:00
}
2005-04-19 06:49:35 +04:00
/* Initialize the processor object from the operands */
2005-08-05 08:44:28 +04:00
obj_desc - > processor . proc_id = ( u8 ) operand [ 1 ] - > integer . value ;
2006-03-18 00:44:00 +03:00
obj_desc - > processor . length = ( u8 ) operand [ 3 ] - > integer . value ;
2005-08-05 08:44:28 +04:00
obj_desc - > processor . address =
( acpi_io_address ) operand [ 2 ] - > integer . value ;
2005-04-17 02:20:36 +04:00
/* Install the processor object in the parent Node */
2005-08-05 08:44:28 +04:00
status = acpi_ns_attach_object ( ( struct acpi_namespace_node * ) operand [ 0 ] ,
obj_desc , ACPI_TYPE_PROCESSOR ) ;
2005-04-17 02:20:36 +04:00
/* Remove local reference to the object */
2005-08-05 08:44:28 +04:00
acpi_ut_remove_reference ( obj_desc ) ;
return_ACPI_STATUS ( status ) ;
2005-04-17 02:20:36 +04:00
}
2005-04-19 06:49:35 +04:00
/*******************************************************************************
2005-04-17 02:20:36 +04:00
*
* FUNCTION : acpi_ex_create_power_resource
*
* PARAMETERS : walk_state - Current state
*
* RETURN : Status
*
* DESCRIPTION : Create a new power_resource object and populate the fields
*
* power_resource ( Name [ 0 ] , system_level [ 1 ] , resource_order [ 2 ] )
*
2005-04-19 06:49:35 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-04-17 02:20:36 +04:00
2005-08-05 08:44:28 +04:00
acpi_status acpi_ex_create_power_resource ( struct acpi_walk_state * walk_state )
2005-04-17 02:20:36 +04:00
{
2005-08-05 08:44:28 +04:00
union acpi_operand_object * * operand = & walk_state - > operands [ 0 ] ;
acpi_status status ;
union acpi_operand_object * obj_desc ;
2005-04-17 02:20:36 +04:00
2005-08-05 08:44:28 +04:00
ACPI_FUNCTION_TRACE_PTR ( " ex_create_power_resource " , walk_state ) ;
2005-04-17 02:20:36 +04:00
/* Create the power resource object */
2005-08-05 08:44:28 +04:00
obj_desc = acpi_ut_create_internal_object ( ACPI_TYPE_POWER ) ;
2005-04-17 02:20:36 +04:00
if ( ! obj_desc ) {
2005-08-05 08:44:28 +04:00
return_ACPI_STATUS ( AE_NO_MEMORY ) ;
2005-04-17 02:20:36 +04:00
}
/* Initialize the power object from the operands */
obj_desc - > power_resource . system_level = ( u8 ) operand [ 1 ] - > integer . value ;
2005-08-05 08:44:28 +04:00
obj_desc - > power_resource . resource_order =
( u16 ) operand [ 2 ] - > integer . value ;
2005-04-17 02:20:36 +04:00
/* Install the power resource object in the parent Node */
2005-08-05 08:44:28 +04:00
status = acpi_ns_attach_object ( ( struct acpi_namespace_node * ) operand [ 0 ] ,
obj_desc , ACPI_TYPE_POWER ) ;
2005-04-17 02:20:36 +04:00
/* Remove local reference to the object */
2005-08-05 08:44:28 +04:00
acpi_ut_remove_reference ( obj_desc ) ;
return_ACPI_STATUS ( status ) ;
2005-04-17 02:20:36 +04:00
}
# endif
2005-04-19 06:49:35 +04:00
/*******************************************************************************
2005-04-17 02:20:36 +04:00
*
* FUNCTION : acpi_ex_create_method
*
* PARAMETERS : aml_start - First byte of the method ' s AML
* aml_length - AML byte count for this method
* walk_state - Current state
*
* RETURN : Status
*
* DESCRIPTION : Create a new method object
*
2005-04-19 06:49:35 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-04-17 02:20:36 +04:00
acpi_status
2005-08-05 08:44:28 +04:00
acpi_ex_create_method ( u8 * aml_start ,
u32 aml_length , struct acpi_walk_state * walk_state )
2005-04-17 02:20:36 +04:00
{
2005-08-05 08:44:28 +04:00
union acpi_operand_object * * operand = & walk_state - > operands [ 0 ] ;
union acpi_operand_object * obj_desc ;
acpi_status status ;
u8 method_flags ;
2005-04-17 02:20:36 +04:00
2005-08-05 08:44:28 +04:00
ACPI_FUNCTION_TRACE_PTR ( " ex_create_method " , walk_state ) ;
2005-04-17 02:20:36 +04:00
/* Create a new method object */
2005-08-05 08:44:28 +04:00
obj_desc = acpi_ut_create_internal_object ( ACPI_TYPE_METHOD ) ;
2005-04-17 02:20:36 +04:00
if ( ! obj_desc ) {
2005-08-05 08:44:28 +04:00
return_ACPI_STATUS ( AE_NO_MEMORY ) ;
2005-04-17 02:20:36 +04:00
}
/* Save the method's AML pointer and length */
obj_desc - > method . aml_start = aml_start ;
obj_desc - > method . aml_length = aml_length ;
/*
* Disassemble the method flags . Split off the Arg Count
* for efficiency
*/
method_flags = ( u8 ) operand [ 1 ] - > integer . value ;
2005-08-05 08:44:28 +04:00
obj_desc - > method . method_flags =
( u8 ) ( method_flags & ~ AML_METHOD_ARG_COUNT ) ;
obj_desc - > method . param_count =
( u8 ) ( method_flags & AML_METHOD_ARG_COUNT ) ;
2005-04-17 02:20:36 +04:00
/*
* Get the concurrency count . If required , a semaphore will be
* created for this method when it is parsed .
*/
if ( acpi_gbl_all_methods_serialized ) {
obj_desc - > method . concurrency = 1 ;
obj_desc - > method . method_flags | = AML_METHOD_SERIALIZED ;
2005-08-05 08:44:28 +04:00
} else if ( method_flags & AML_METHOD_SERIALIZED ) {
2005-04-17 02:20:36 +04:00
/*
* ACPI 1.0 : Concurrency = 1
* ACPI 2.0 : Concurrency = ( sync_level ( in method declaration ) + 1 )
*/
obj_desc - > method . concurrency = ( u8 )
2005-08-05 08:44:28 +04:00
( ( ( method_flags & AML_METHOD_SYNCH_LEVEL ) > > 4 ) + 1 ) ;
} else {
2005-04-17 02:20:36 +04:00
obj_desc - > method . concurrency = ACPI_INFINITE_CONCURRENCY ;
}
/* Attach the new object to the method Node */
2005-08-05 08:44:28 +04:00
status = acpi_ns_attach_object ( ( struct acpi_namespace_node * ) operand [ 0 ] ,
obj_desc , ACPI_TYPE_METHOD ) ;
2005-04-17 02:20:36 +04:00
/* Remove local reference to the object */
2005-08-05 08:44:28 +04:00
acpi_ut_remove_reference ( obj_desc ) ;
2005-04-17 02:20:36 +04:00
/* Remove a reference to the operand */
2005-08-05 08:44:28 +04:00
acpi_ut_remove_reference ( operand [ 1 ] ) ;
return_ACPI_STATUS ( status ) ;
2005-04-17 02:20:36 +04:00
}