2009-07-24 10:56:43 +08:00
/******************************************************************************
*
* Module Name : nsrepair - Repair for objects returned by predefined methods
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
2010-01-22 19:07:36 +08:00
* Copyright ( C ) 2000 - 2010 , Intel Corp .
2009-07-24 10:56:43 +08: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"
2009-10-13 10:23:20 +08:00
# include "acinterp.h"
2010-01-21 09:28:32 +08:00
# include "acpredef.h"
2009-07-24 10:56:43 +08:00
# define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME ( " nsrepair " )
2009-12-11 15:01:12 +08:00
/*******************************************************************************
*
* This module attempts to repair or convert objects returned by the
* predefined methods to an object type that is expected , as per the ACPI
* specification . The need for this code is dictated by the many machines that
* return incorrect types for the standard predefined methods . Performing these
* conversions here , in one place , eliminates the need for individual ACPI
* device drivers to do the same . Note : Most of these conversions are different
* than the internal object conversion routines used for implicit object
* conversion .
*
* The following conversions can be performed as necessary :
*
* Integer - > String
* Integer - > Buffer
* String - > Integer
* String - > Buffer
* Buffer - > Integer
* Buffer - > String
* Buffer - > Package of Integers
* Package - > Package of one Package
*
2010-01-21 09:28:32 +08:00
* Additional possible repairs :
*
* Optional / unnecessary NULL package elements removed
* Required package elements that are NULL replaced by Integer / String / Buffer
* Incorrect standalone package wrapped with required outer package
*
2009-12-11 15:01:12 +08:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Local prototypes */
static acpi_status
acpi_ns_convert_to_integer ( union acpi_operand_object * original_object ,
union acpi_operand_object * * return_object ) ;
static acpi_status
acpi_ns_convert_to_string ( union acpi_operand_object * original_object ,
union acpi_operand_object * * return_object ) ;
static acpi_status
acpi_ns_convert_to_buffer ( union acpi_operand_object * original_object ,
union acpi_operand_object * * return_object ) ;
static acpi_status
acpi_ns_convert_to_package ( union acpi_operand_object * original_object ,
union acpi_operand_object * * return_object ) ;
2009-07-24 10:56:43 +08:00
/*******************************************************************************
*
* FUNCTION : acpi_ns_repair_object
*
* PARAMETERS : Data - Pointer to validation data structure
* expected_btypes - Object types expected
* package_index - Index of object within parent package ( if
* applicable - ACPI_NOT_PACKAGE_ELEMENT
* otherwise )
* return_object_ptr - Pointer to the object returned from the
* evaluation of a method or object
*
* RETURN : Status . AE_OK if repair was successful .
*
* DESCRIPTION : Attempt to repair / convert a return object of a type that was
* not expected .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-12-11 15:01:12 +08:00
2009-07-24 10:56:43 +08:00
acpi_status
acpi_ns_repair_object ( struct acpi_predefined_data * data ,
u32 expected_btypes ,
u32 package_index ,
union acpi_operand_object * * return_object_ptr )
{
union acpi_operand_object * return_object = * return_object_ptr ;
union acpi_operand_object * new_object ;
2009-10-13 10:23:20 +08:00
acpi_status status ;
2009-07-24 10:56:43 +08:00
2009-12-11 15:23:22 +08:00
ACPI_FUNCTION_NAME ( ns_repair_object ) ;
2009-10-13 10:20:33 +08:00
/*
* At this point , we know that the type of the returned object was not
* one of the expected types for this predefined name . Attempt to
2009-12-11 15:01:12 +08:00
* repair the object by converting it to one of the expected object
* types for this predefined name .
*/
if ( expected_btypes & ACPI_RTYPE_INTEGER ) {
status = acpi_ns_convert_to_integer ( return_object , & new_object ) ;
if ( ACPI_SUCCESS ( status ) ) {
goto object_repaired ;
}
}
if ( expected_btypes & ACPI_RTYPE_STRING ) {
status = acpi_ns_convert_to_string ( return_object , & new_object ) ;
if ( ACPI_SUCCESS ( status ) ) {
goto object_repaired ;
}
}
if ( expected_btypes & ACPI_RTYPE_BUFFER ) {
status = acpi_ns_convert_to_buffer ( return_object , & new_object ) ;
if ( ACPI_SUCCESS ( status ) ) {
goto object_repaired ;
}
}
if ( expected_btypes & ACPI_RTYPE_PACKAGE ) {
status = acpi_ns_convert_to_package ( return_object , & new_object ) ;
if ( ACPI_SUCCESS ( status ) ) {
goto object_repaired ;
}
}
/* We cannot repair this object */
return ( AE_AML_OPERAND_TYPE ) ;
object_repaired :
/* Object was successfully repaired */
/*
* If the original object is a package element , we need to :
* 1. Set the reference count of the new object to match the
* reference count of the old object .
* 2. Decrement the reference count of the original object .
2009-10-13 10:20:33 +08:00
*/
2009-12-11 15:01:12 +08:00
if ( package_index ! = ACPI_NOT_PACKAGE_ELEMENT ) {
new_object - > common . reference_count =
return_object - > common . reference_count ;
if ( return_object - > common . reference_count > 1 ) {
return_object - > common . reference_count - - ;
}
2009-12-11 15:23:22 +08:00
ACPI_DEBUG_PRINT ( ( ACPI_DB_REPAIR ,
" %s: Converted %s to expected %s at index %u \n " ,
data - > pathname ,
acpi_ut_get_object_type_name ( return_object ) ,
acpi_ut_get_object_type_name ( new_object ) ,
package_index ) ) ;
2009-12-11 15:01:12 +08:00
} else {
2009-12-11 15:23:22 +08:00
ACPI_DEBUG_PRINT ( ( ACPI_DB_REPAIR ,
" %s: Converted %s to expected %s \n " ,
data - > pathname ,
acpi_ut_get_object_type_name ( return_object ) ,
acpi_ut_get_object_type_name ( new_object ) ) ) ;
2009-12-11 15:01:12 +08:00
}
/* Delete old object, install the new return object */
acpi_ut_remove_reference ( return_object ) ;
* return_object_ptr = new_object ;
data - > flags | = ACPI_OBJECT_REPAIRED ;
return ( AE_OK ) ;
}
/*******************************************************************************
*
* 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 .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static 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 ,
ACPI_ANY_BASE , & value ) ;
if ( ACPI_FAILURE ( status ) ) {
return ( status ) ;
}
break ;
2009-07-24 10:56:43 +08:00
case ACPI_TYPE_BUFFER :
2009-12-11 15:01:12 +08:00
/* Buffer-to-Integer conversion. Max buffer size is 64 bits. */
2009-07-24 10:56:43 +08:00
2009-12-11 15:01:12 +08:00
if ( original_object - > buffer . length > 8 ) {
2009-07-24 10:56:43 +08:00
return ( AE_AML_OPERAND_TYPE ) ;
}
2009-12-11 15:01:12 +08:00
/* Extract each buffer byte to create the integer */
for ( i = 0 ; i < original_object - > buffer . length ; i + + ) {
value | =
( ( u64 ) original_object - > buffer .
pointer [ i ] < < ( i * 8 ) ) ;
}
break ;
default :
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 .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static 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 :
2009-07-24 10:56:43 +08:00
/*
2009-12-11 15:01:12 +08:00
* 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 {
status =
acpi_ex_convert_to_string ( original_object ,
& new_object ,
ACPI_IMPLICIT_CONVERT_HEX ) ;
if ( ACPI_FAILURE ( status ) ) {
return ( status ) ;
}
}
break ;
case ACPI_TYPE_BUFFER :
/*
* Buffer - to - String conversion . Use a to_string
2009-07-24 10:56:43 +08:00
* 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 ;
2009-12-11 15:01:12 +08:00
while ( ( length < original_object - > buffer . length ) & &
( original_object - > buffer . pointer [ length ] ) ) {
2009-07-24 10:56:43 +08:00
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.
*/
ACPI_MEMCPY ( new_object - > string . pointer ,
2009-12-11 15:01:12 +08:00
original_object - > buffer . pointer , length ) ;
2009-10-13 10:20:33 +08:00
break ;
2009-07-24 10:56:43 +08:00
2009-12-11 15:01:12 +08:00
default :
return ( AE_AML_OPERAND_TYPE ) ;
}
2009-10-13 10:20:33 +08:00
2009-12-11 15:01:12 +08:00
* return_object = new_object ;
return ( AE_OK ) ;
}
2009-10-13 10:23:20 +08:00
2009-12-11 15:01:12 +08:00
/*******************************************************************************
*
* 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 .
*
2009-12-11 15:18:52 +08:00
* DESCRIPTION : Attempt to convert a Integer / String / Package object to a Buffer .
2009-12-11 15:01:12 +08:00
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-10-13 10:23:20 +08:00
2009-12-11 15:01:12 +08:00
static 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 ;
2009-12-11 15:18:52 +08:00
union acpi_operand_object * * elements ;
u32 * dword_buffer ;
u32 count ;
u32 i ;
2009-07-24 10:56:43 +08:00
2009-12-11 15:01:12 +08:00
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 ;
2009-07-24 10:56:43 +08:00
2009-12-11 15:01:12 +08:00
case ACPI_TYPE_STRING :
2009-10-13 10:20:33 +08:00
2009-12-11 15:01:12 +08:00
/* String-to-Buffer conversion. Simple data copy */
new_object =
acpi_ut_create_buffer_object ( original_object - > string .
length ) ;
if ( ! new_object ) {
return ( AE_NO_MEMORY ) ;
2009-07-24 10:56:43 +08:00
}
2009-12-11 15:01:12 +08:00
ACPI_MEMCPY ( new_object - > buffer . pointer ,
original_object - > string . pointer ,
original_object - > string . length ) ;
2009-10-13 10:20:33 +08:00
break ;
2009-07-24 10:56:43 +08:00
2009-12-11 15:18:52 +08:00
case ACPI_TYPE_PACKAGE :
2009-12-11 15:24:27 +08:00
/*
* 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 .
*/
2009-12-11 15:18:52 +08:00
/* 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 ;
2009-10-13 10:20:33 +08:00
default :
return ( AE_AML_OPERAND_TYPE ) ;
2009-07-24 10:56:43 +08:00
}
2009-12-11 15:01:12 +08:00
* return_object = new_object ;
return ( AE_OK ) ;
}
2009-10-13 10:20:33 +08:00
2009-12-11 15:01:12 +08:00
/*******************************************************************************
*
* FUNCTION : acpi_ns_convert_to_package
*
* 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 Buffer object to a Package . Each byte of
* the buffer is converted to a single integer package element .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-10-13 10:20:33 +08:00
2009-12-11 15:01:12 +08:00
static acpi_status
acpi_ns_convert_to_package ( union acpi_operand_object * original_object ,
union acpi_operand_object * * return_object )
{
union acpi_operand_object * new_object ;
union acpi_operand_object * * elements ;
u32 length ;
u8 * buffer ;
switch ( original_object - > common . type ) {
case ACPI_TYPE_BUFFER :
/* Buffer-to-Package conversion */
length = original_object - > buffer . length ;
new_object = acpi_ut_create_package_object ( length ) ;
if ( ! new_object ) {
return ( AE_NO_MEMORY ) ;
2009-10-13 10:20:33 +08:00
}
2009-12-11 15:01:12 +08:00
/* Convert each buffer byte to an integer package element */
2009-10-13 10:20:33 +08:00
2009-12-11 15:01:12 +08:00
elements = new_object - > package . elements ;
buffer = original_object - > buffer . pointer ;
2009-10-13 10:20:33 +08:00
2009-12-11 15:01:12 +08:00
while ( length - - ) {
2009-12-11 15:18:52 +08:00
* elements =
acpi_ut_create_integer_object ( ( u64 ) * buffer ) ;
2009-12-11 15:01:12 +08:00
if ( ! * elements ) {
acpi_ut_remove_reference ( new_object ) ;
return ( AE_NO_MEMORY ) ;
}
elements + + ;
buffer + + ;
}
break ;
default :
return ( AE_AML_OPERAND_TYPE ) ;
}
* return_object = new_object ;
2009-10-13 10:20:33 +08:00
return ( AE_OK ) ;
2009-07-24 10:56:43 +08:00
}
2009-07-24 11:03:09 +08:00
2010-01-21 09:28:32 +08:00
/*******************************************************************************
*
* FUNCTION : acpi_ns_repair_null_element
*
* PARAMETERS : Data - Pointer to validation data structure
* expected_btypes - Object types expected
* package_index - Index of object within parent package ( if
* applicable - ACPI_NOT_PACKAGE_ELEMENT
* otherwise )
* return_object_ptr - Pointer to the object returned from the
* evaluation of a method or object
*
* RETURN : Status . AE_OK if repair was successful .
*
* DESCRIPTION : Attempt to repair a NULL element of a returned Package object .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
acpi_status
acpi_ns_repair_null_element ( struct acpi_predefined_data * data ,
u32 expected_btypes ,
u32 package_index ,
union acpi_operand_object * * return_object_ptr )
{
union acpi_operand_object * return_object = * return_object_ptr ;
union acpi_operand_object * new_object ;
ACPI_FUNCTION_NAME ( ns_repair_null_element ) ;
/* No repair needed if return object is non-NULL */
if ( return_object ) {
return ( AE_OK ) ;
}
/*
* Attempt to repair a NULL element of a Package object . This applies to
* predefined names that return a fixed - length package and each element
* is required . It does not apply to variable - length packages where NULL
* elements are allowed , especially at the end of the package .
*/
if ( expected_btypes & ACPI_RTYPE_INTEGER ) {
/* Need an Integer - create a zero-value integer */
2010-07-06 10:35:55 +08:00
new_object = acpi_ut_create_integer_object ( ( u64 ) 0 ) ;
2010-01-21 09:28:32 +08:00
} else if ( expected_btypes & ACPI_RTYPE_STRING ) {
/* Need a String - create a NULL string */
new_object = acpi_ut_create_string_object ( 0 ) ;
} else if ( expected_btypes & ACPI_RTYPE_BUFFER ) {
/* Need a Buffer - create a zero-length buffer */
new_object = acpi_ut_create_buffer_object ( 0 ) ;
} else {
/* Error for all other expected types */
return ( AE_AML_OPERAND_TYPE ) ;
}
if ( ! new_object ) {
return ( AE_NO_MEMORY ) ;
}
/* Set the reference count according to the parent Package object */
new_object - > common . reference_count =
data - > parent_package - > common . reference_count ;
ACPI_DEBUG_PRINT ( ( ACPI_DB_REPAIR ,
" %s: Converted NULL package element to expected %s at index %u \n " ,
data - > pathname ,
acpi_ut_get_object_type_name ( new_object ) ,
package_index ) ) ;
* return_object_ptr = new_object ;
data - > flags | = ACPI_OBJECT_REPAIRED ;
return ( AE_OK ) ;
}
/******************************************************************************
*
* FUNCTION : acpi_ns_remove_null_elements
*
* PARAMETERS : Data - Pointer to validation data structure
* package_type - An acpi_return_package_types value
* obj_desc - A Package object
*
* RETURN : None .
*
* DESCRIPTION : Remove all NULL package elements from packages that contain
* a variable number of sub - packages . For these types of
* packages , NULL elements can be safely removed .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
acpi_ns_remove_null_elements ( struct acpi_predefined_data * data ,
u8 package_type ,
union acpi_operand_object * obj_desc )
{
union acpi_operand_object * * source ;
union acpi_operand_object * * dest ;
u32 count ;
u32 new_count ;
u32 i ;
ACPI_FUNCTION_NAME ( ns_remove_null_elements ) ;
/*
* PTYPE1 packages contain no subpackages .
* PTYPE2 packages contain a variable number of sub - packages . We can
* safely remove all NULL elements from the PTYPE2 packages .
*/
switch ( package_type ) {
case ACPI_PTYPE1_FIXED :
case ACPI_PTYPE1_VAR :
case ACPI_PTYPE1_OPTION :
return ;
case ACPI_PTYPE2 :
case ACPI_PTYPE2_COUNT :
case ACPI_PTYPE2_PKG_COUNT :
case ACPI_PTYPE2_FIXED :
case ACPI_PTYPE2_MIN :
case ACPI_PTYPE2_REV_FIXED :
break ;
default :
return ;
}
count = obj_desc - > package . count ;
new_count = count ;
source = obj_desc - > package . elements ;
dest = source ;
/* Examine all elements of the package object, remove nulls */
for ( i = 0 ; i < count ; i + + ) {
if ( ! * source ) {
new_count - - ;
} else {
* dest = * source ;
dest + + ;
}
source + + ;
}
/* Update parent package if any null elements were removed */
if ( new_count < count ) {
ACPI_DEBUG_PRINT ( ( ACPI_DB_REPAIR ,
" %s: Found and removed %u NULL elements \n " ,
data - > pathname , ( count - new_count ) ) ) ;
/* NULL terminate list and update the package count */
* dest = NULL ;
obj_desc - > package . count = new_count ;
}
}
2009-07-24 11:03:09 +08:00
/*******************************************************************************
*
* FUNCTION : acpi_ns_repair_package_list
*
* PARAMETERS : Data - Pointer to validation data structure
* obj_desc_ptr - Pointer to the object to repair . The new
* package object is returned here ,
* overwriting the old object .
*
* RETURN : Status , new object in * obj_desc_ptr
*
* DESCRIPTION : Repair a common problem with objects that are defined to return
* a variable - length Package of Packages . If the variable - length
* is one , some BIOS code mistakenly simply declares a single
* Package instead of a Package with one sub - Package . This
* function attempts to repair this error by wrapping a Package
* object around the original Package , creating the correct
* Package with one sub - Package .
*
* Names that can be repaired in this manner include :
* _ALR , _CSD , _HPX , _MLS , _PRT , _PSS , _TRT , TSS
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
acpi_status
acpi_ns_repair_package_list ( struct acpi_predefined_data * data ,
union acpi_operand_object * * obj_desc_ptr )
{
union acpi_operand_object * pkg_obj_desc ;
2009-12-11 15:23:22 +08:00
ACPI_FUNCTION_NAME ( ns_repair_package_list ) ;
2009-07-24 11:03:09 +08:00
/*
* Create the new outer package and populate it . The new package will
* have a single element , the lone subpackage .
*/
pkg_obj_desc = acpi_ut_create_package_object ( 1 ) ;
if ( ! pkg_obj_desc ) {
return ( AE_NO_MEMORY ) ;
}
pkg_obj_desc - > package . elements [ 0 ] = * obj_desc_ptr ;
/* Return the new object in the object pointer */
* obj_desc_ptr = pkg_obj_desc ;
data - > flags | = ACPI_OBJECT_REPAIRED ;
2009-12-11 15:23:22 +08:00
ACPI_DEBUG_PRINT ( ( ACPI_DB_REPAIR ,
" %s: Repaired incorrectly formed Package \n " ,
data - > pathname ) ) ;
2009-07-24 11:03:09 +08:00
return ( AE_OK ) ;
}