2013-03-08 09:23:16 +00:00
/******************************************************************************
*
* Module Name : nsconvert - Object conversions for objects returned by
* predefined methods
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
2016-01-15 08:17:03 +08:00
* Copyright ( C ) 2000 - 2016 , Intel Corp .
2013-03-08 09:23:16 +00: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 "accommon.h"
# include "acnamesp.h"
# include "acinterp.h"
# include "acpredef.h"
# include "amlresrc.h"
# define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME ( " nsconvert " )
/*******************************************************************************
*
* FUNCTION : acpi_ns_convert_to_integer
*
* PARAMETERS : original_object - Object to be converted
* return_object - Where the new converted object is returned
*
* RETURN : Status . AE_OK if conversion was successful .
*
* DESCRIPTION : Attempt to convert a String / Buffer object to an Integer .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
acpi_status
acpi_ns_convert_to_integer ( union acpi_operand_object * original_object ,
union acpi_operand_object * * return_object )
{
union acpi_operand_object * new_object ;
acpi_status status ;
u64 value = 0 ;
u32 i ;
switch ( original_object - > common . type ) {
case ACPI_TYPE_STRING :
/* String-to-Integer conversion */
status = acpi_ut_strtoul64 ( original_object - > string . pointer ,
2016-03-24 09:40:33 +08:00
acpi_gbl_integer_byte_width , & value ) ;
2013-03-08 09:23:16 +00:00
if ( ACPI_FAILURE ( status ) ) {
return ( status ) ;
}
break ;
case ACPI_TYPE_BUFFER :
/* Buffer-to-Integer conversion. Max buffer size is 64 bits. */
if ( original_object - > buffer . length > 8 ) {
return ( AE_AML_OPERAND_TYPE ) ;
}
/* Extract each buffer byte to create the integer */
for ( i = 0 ; i < original_object - > buffer . length ; i + + ) {
2015-12-29 13:54:36 +08:00
value | = ( ( u64 )
original_object - > buffer . pointer [ i ] < < ( i *
8 ) ) ;
2013-03-08 09:23:16 +00:00
}
break ;
default :
2013-06-08 00:58:14 +00:00
2013-03-08 09:23:16 +00:00
return ( AE_AML_OPERAND_TYPE ) ;
}
new_object = acpi_ut_create_integer_object ( value ) ;
if ( ! new_object ) {
return ( AE_NO_MEMORY ) ;
}
* return_object = new_object ;
return ( AE_OK ) ;
}
/*******************************************************************************
*
* FUNCTION : acpi_ns_convert_to_string
*
* PARAMETERS : original_object - Object to be converted
* return_object - Where the new converted object is returned
*
* RETURN : Status . AE_OK if conversion was successful .
*
* DESCRIPTION : Attempt to convert a Integer / Buffer object to a String .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
acpi_status
acpi_ns_convert_to_string ( union acpi_operand_object * original_object ,
union acpi_operand_object * * return_object )
{
union acpi_operand_object * new_object ;
acpi_size length ;
acpi_status status ;
switch ( original_object - > common . type ) {
case ACPI_TYPE_INTEGER :
/*
* Integer - to - String conversion . Commonly , convert
* an integer of value 0 to a NULL string . The last element of
* _BIF and _BIX packages occasionally need this fix .
*/
if ( original_object - > integer . value = = 0 ) {
/* Allocate a new NULL string object */
new_object = acpi_ut_create_string_object ( 0 ) ;
if ( ! new_object ) {
return ( AE_NO_MEMORY ) ;
}
} else {
2015-12-29 13:54:36 +08:00
status = acpi_ex_convert_to_string ( original_object ,
& new_object ,
ACPI_IMPLICIT_CONVERT_HEX ) ;
2013-03-08 09:23:16 +00:00
if ( ACPI_FAILURE ( status ) ) {
return ( status ) ;
}
}
break ;
case ACPI_TYPE_BUFFER :
/*
* Buffer - to - String conversion . Use a to_string
* conversion , no transform performed on the buffer data . The best
* example of this is the _BIF method , where the string data from
* the battery is often ( incorrectly ) returned as buffer object ( s ) .
*/
length = 0 ;
while ( ( length < original_object - > buffer . length ) & &
( original_object - > buffer . pointer [ length ] ) ) {
length + + ;
}
/* Allocate a new string object */
new_object = acpi_ut_create_string_object ( length ) ;
if ( ! new_object ) {
return ( AE_NO_MEMORY ) ;
}
/*
* Copy the raw buffer data with no transform . String is already NULL
* terminated at Length + 1.
*/
2015-07-01 14:45:11 +08:00
memcpy ( new_object - > string . pointer ,
original_object - > buffer . pointer , length ) ;
2013-03-08 09:23:16 +00:00
break ;
default :
2013-06-08 00:58:14 +00:00
2013-03-08 09:23:16 +00:00
return ( AE_AML_OPERAND_TYPE ) ;
}
* return_object = new_object ;
return ( AE_OK ) ;
}
/*******************************************************************************
*
* FUNCTION : acpi_ns_convert_to_buffer
*
* PARAMETERS : original_object - Object to be converted
* return_object - Where the new converted object is returned
*
* RETURN : Status . AE_OK if conversion was successful .
*
* DESCRIPTION : Attempt to convert a Integer / String / Package object to a Buffer .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
acpi_status
acpi_ns_convert_to_buffer ( union acpi_operand_object * original_object ,
union acpi_operand_object * * return_object )
{
union acpi_operand_object * new_object ;
acpi_status status ;
union acpi_operand_object * * elements ;
u32 * dword_buffer ;
u32 count ;
u32 i ;
switch ( original_object - > common . type ) {
case ACPI_TYPE_INTEGER :
/*
* Integer - to - Buffer conversion .
* Convert the Integer to a packed - byte buffer . _MAT and other
* objects need this sometimes , if a read has been performed on a
* Field object that is less than or equal to the global integer
* size ( 32 or 64 bits ) .
*/
status =
acpi_ex_convert_to_buffer ( original_object , & new_object ) ;
if ( ACPI_FAILURE ( status ) ) {
return ( status ) ;
}
break ;
case ACPI_TYPE_STRING :
/* String-to-Buffer conversion. Simple data copy */
2015-12-29 13:54:36 +08:00
new_object = acpi_ut_create_buffer_object
( original_object - > string . length ) ;
2013-03-08 09:23:16 +00:00
if ( ! new_object ) {
return ( AE_NO_MEMORY ) ;
}
2015-07-01 14:45:11 +08:00
memcpy ( new_object - > buffer . pointer ,
original_object - > string . pointer ,
original_object - > string . length ) ;
2013-03-08 09:23:16 +00:00
break ;
case ACPI_TYPE_PACKAGE :
/*
* This case is often seen for predefined names that must return a
* Buffer object with multiple DWORD integers within . For example ,
* _FDE and _GTM . The Package can be converted to a Buffer .
*/
/* All elements of the Package must be integers */
elements = original_object - > package . elements ;
count = original_object - > package . count ;
for ( i = 0 ; i < count ; i + + ) {
if ( ( ! * elements ) | |
( ( * elements ) - > common . type ! = ACPI_TYPE_INTEGER ) ) {
return ( AE_AML_OPERAND_TYPE ) ;
}
elements + + ;
}
/* Create the new buffer object to replace the Package */
new_object = acpi_ut_create_buffer_object ( ACPI_MUL_4 ( count ) ) ;
if ( ! new_object ) {
return ( AE_NO_MEMORY ) ;
}
/* Copy the package elements (integers) to the buffer as DWORDs */
elements = original_object - > package . elements ;
dword_buffer = ACPI_CAST_PTR ( u32 , new_object - > buffer . pointer ) ;
for ( i = 0 ; i < count ; i + + ) {
* dword_buffer = ( u32 ) ( * elements ) - > integer . value ;
dword_buffer + + ;
elements + + ;
}
break ;
default :
2013-06-08 00:58:14 +00:00
2013-03-08 09:23:16 +00:00
return ( AE_AML_OPERAND_TYPE ) ;
}
* return_object = new_object ;
return ( AE_OK ) ;
}
2013-03-08 09:23:24 +00:00
/*******************************************************************************
*
* FUNCTION : acpi_ns_convert_to_unicode
*
2015-12-29 13:57:38 +08:00
* PARAMETERS : scope - Namespace node for the method / object
* original_object - ASCII String Object to be converted
2013-03-08 09:23:24 +00:00
* return_object - Where the new converted object is returned
*
* RETURN : Status . AE_OK if conversion was successful .
*
* DESCRIPTION : Attempt to convert a String object to a Unicode string Buffer .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
acpi_status
2016-05-05 12:57:53 +08:00
acpi_ns_convert_to_unicode ( struct acpi_namespace_node * scope ,
2015-12-29 13:57:38 +08:00
union acpi_operand_object * original_object ,
2013-03-08 09:23:24 +00:00
union acpi_operand_object * * return_object )
{
union acpi_operand_object * new_object ;
char * ascii_string ;
u16 * unicode_buffer ;
u32 unicode_length ;
u32 i ;
if ( ! original_object ) {
return ( AE_OK ) ;
}
/* If a Buffer was returned, it must be at least two bytes long */
if ( original_object - > common . type = = ACPI_TYPE_BUFFER ) {
if ( original_object - > buffer . length < 2 ) {
return ( AE_AML_OPERAND_VALUE ) ;
}
* return_object = NULL ;
return ( AE_OK ) ;
}
/*
* The original object is an ASCII string . Convert this string to
* a unicode buffer .
*/
ascii_string = original_object - > string . pointer ;
unicode_length = ( original_object - > string . length * 2 ) + 2 ;
/* Create a new buffer object for the Unicode data */
new_object = acpi_ut_create_buffer_object ( unicode_length ) ;
if ( ! new_object ) {
return ( AE_NO_MEMORY ) ;
}
unicode_buffer = ACPI_CAST_PTR ( u16 , new_object - > buffer . pointer ) ;
/* Convert ASCII to Unicode */
for ( i = 0 ; i < original_object - > string . length ; i + + ) {
unicode_buffer [ i ] = ( u16 ) ascii_string [ i ] ;
}
* return_object = new_object ;
return ( AE_OK ) ;
}
2013-03-08 09:23:32 +00:00
/*******************************************************************************
*
* FUNCTION : acpi_ns_convert_to_resource
*
2015-12-29 13:57:38 +08:00
* PARAMETERS : scope - Namespace node for the method / object
* original_object - Object to be converted
2013-03-08 09:23:32 +00:00
* return_object - Where the new converted object is returned
*
* RETURN : Status . AE_OK if conversion was successful
*
* DESCRIPTION : Attempt to convert a Integer object to a resource_template
* Buffer .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
acpi_status
2016-05-05 12:57:53 +08:00
acpi_ns_convert_to_resource ( struct acpi_namespace_node * scope ,
2015-12-29 13:57:38 +08:00
union acpi_operand_object * original_object ,
2013-03-08 09:23:32 +00:00
union acpi_operand_object * * return_object )
{
union acpi_operand_object * new_object ;
u8 * buffer ;
/*
* We can fix the following cases for an expected resource template :
* 1. No return value ( interpreter slack mode is disabled )
* 2. A " Return (Zero) " statement
* 3. A " Return empty buffer " statement
*
* We will return a buffer containing a single end_tag
* resource descriptor .
*/
if ( original_object ) {
switch ( original_object - > common . type ) {
case ACPI_TYPE_INTEGER :
/* We can only repair an Integer==0 */
if ( original_object - > integer . value ) {
return ( AE_AML_OPERAND_TYPE ) ;
}
break ;
case ACPI_TYPE_BUFFER :
if ( original_object - > buffer . length ) {
/* Additional checks can be added in the future */
* return_object = NULL ;
return ( AE_OK ) ;
}
break ;
case ACPI_TYPE_STRING :
default :
return ( AE_AML_OPERAND_TYPE ) ;
}
}
/* Create the new buffer object for the resource descriptor */
new_object = acpi_ut_create_buffer_object ( 2 ) ;
if ( ! new_object ) {
return ( AE_NO_MEMORY ) ;
}
buffer = ACPI_CAST_PTR ( u8 , new_object - > buffer . pointer ) ;
/* Initialize the Buffer with a single end_tag descriptor */
buffer [ 0 ] = ( ACPI_RESOURCE_NAME_END_TAG | ASL_RDESC_END_TAG_SIZE ) ;
buffer [ 1 ] = 0x00 ;
* return_object = new_object ;
return ( AE_OK ) ;
}
2015-12-29 13:58:02 +08:00
/*******************************************************************************
*
* FUNCTION : acpi_ns_convert_to_reference
*
* PARAMETERS : scope - Namespace node for the method / object
* original_object - Object to be converted
* return_object - Where the new converted object is returned
*
* RETURN : Status . AE_OK if conversion was successful
*
* DESCRIPTION : Attempt to convert a Integer object to a object_reference .
* Buffer .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
acpi_status
2016-05-05 12:57:53 +08:00
acpi_ns_convert_to_reference ( struct acpi_namespace_node * scope ,
2015-12-29 13:58:02 +08:00
union acpi_operand_object * original_object ,
union acpi_operand_object * * return_object )
{
union acpi_operand_object * new_object = NULL ;
acpi_status status ;
struct acpi_namespace_node * node ;
union acpi_generic_state scope_info ;
char * name ;
ACPI_FUNCTION_NAME ( ns_convert_to_reference ) ;
/* Convert path into internal presentation */
status =
acpi_ns_internalize_name ( original_object - > string . pointer , & name ) ;
if ( ACPI_FAILURE ( status ) ) {
return_ACPI_STATUS ( status ) ;
}
/* Find the namespace node */
scope_info . scope . node =
ACPI_CAST_PTR ( struct acpi_namespace_node , scope ) ;
status =
acpi_ns_lookup ( & scope_info , name , ACPI_TYPE_ANY , ACPI_IMODE_EXECUTE ,
ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE ,
NULL , & node ) ;
if ( ACPI_FAILURE ( status ) ) {
/* Check if we are resolving a named reference within a package */
ACPI_ERROR_NAMESPACE ( original_object - > string . pointer , status ) ;
goto error_exit ;
}
/* Create and init a new internal ACPI object */
new_object = acpi_ut_create_internal_object ( ACPI_TYPE_LOCAL_REFERENCE ) ;
if ( ! new_object ) {
status = AE_NO_MEMORY ;
goto error_exit ;
}
new_object - > reference . node = node ;
new_object - > reference . object = node - > object ;
new_object - > reference . class = ACPI_REFCLASS_NAME ;
/*
* Increase reference of the object if needed ( the object is likely a
* null for device nodes ) .
*/
acpi_ut_add_reference ( node - > object ) ;
error_exit :
ACPI_FREE ( name ) ;
* return_object = new_object ;
return ( AE_OK ) ;
}