1b2deadd5SBob Moore /****************************************************************************** 2b2deadd5SBob Moore * 3b2deadd5SBob Moore * Module Name: nsrepair - Repair for objects returned by predefined methods 4b2deadd5SBob Moore * 5b2deadd5SBob Moore *****************************************************************************/ 6b2deadd5SBob Moore 7b2deadd5SBob Moore /* 8b2deadd5SBob Moore * Copyright (C) 2000 - 2009, Intel Corp. 9b2deadd5SBob Moore * All rights reserved. 10b2deadd5SBob Moore * 11b2deadd5SBob Moore * Redistribution and use in source and binary forms, with or without 12b2deadd5SBob Moore * modification, are permitted provided that the following conditions 13b2deadd5SBob Moore * are met: 14b2deadd5SBob Moore * 1. Redistributions of source code must retain the above copyright 15b2deadd5SBob Moore * notice, this list of conditions, and the following disclaimer, 16b2deadd5SBob Moore * without modification. 17b2deadd5SBob Moore * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18b2deadd5SBob Moore * substantially similar to the "NO WARRANTY" disclaimer below 19b2deadd5SBob Moore * ("Disclaimer") and any redistribution must be conditioned upon 20b2deadd5SBob Moore * including a substantially similar Disclaimer requirement for further 21b2deadd5SBob Moore * binary redistribution. 22b2deadd5SBob Moore * 3. Neither the names of the above-listed copyright holders nor the names 23b2deadd5SBob Moore * of any contributors may be used to endorse or promote products derived 24b2deadd5SBob Moore * from this software without specific prior written permission. 25b2deadd5SBob Moore * 26b2deadd5SBob Moore * Alternatively, this software may be distributed under the terms of the 27b2deadd5SBob Moore * GNU General Public License ("GPL") version 2 as published by the Free 28b2deadd5SBob Moore * Software Foundation. 29b2deadd5SBob Moore * 30b2deadd5SBob Moore * NO WARRANTY 31b2deadd5SBob Moore * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32b2deadd5SBob Moore * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33b2deadd5SBob Moore * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34b2deadd5SBob Moore * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35b2deadd5SBob Moore * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36b2deadd5SBob Moore * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37b2deadd5SBob Moore * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38b2deadd5SBob Moore * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39b2deadd5SBob Moore * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40b2deadd5SBob Moore * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41b2deadd5SBob Moore * POSSIBILITY OF SUCH DAMAGES. 42b2deadd5SBob Moore */ 43b2deadd5SBob Moore 44b2deadd5SBob Moore #include <acpi/acpi.h> 45b2deadd5SBob Moore #include "accommon.h" 46b2deadd5SBob Moore #include "acnamesp.h" 470240d7b4SLin Ming #include "acinterp.h" 48b2deadd5SBob Moore 49b2deadd5SBob Moore #define _COMPONENT ACPI_NAMESPACE 50b2deadd5SBob Moore ACPI_MODULE_NAME("nsrepair") 51b2deadd5SBob Moore 52b2deadd5SBob Moore /******************************************************************************* 53b2deadd5SBob Moore * 5447e11d54SBob Moore * This module attempts to repair or convert objects returned by the 5547e11d54SBob Moore * predefined methods to an object type that is expected, as per the ACPI 5647e11d54SBob Moore * specification. The need for this code is dictated by the many machines that 5747e11d54SBob Moore * return incorrect types for the standard predefined methods. Performing these 5847e11d54SBob Moore * conversions here, in one place, eliminates the need for individual ACPI 5947e11d54SBob Moore * device drivers to do the same. Note: Most of these conversions are different 6047e11d54SBob Moore * than the internal object conversion routines used for implicit object 6147e11d54SBob Moore * conversion. 6247e11d54SBob Moore * 6347e11d54SBob Moore * The following conversions can be performed as necessary: 6447e11d54SBob Moore * 6547e11d54SBob Moore * Integer -> String 6647e11d54SBob Moore * Integer -> Buffer 6747e11d54SBob Moore * String -> Integer 6847e11d54SBob Moore * String -> Buffer 6947e11d54SBob Moore * Buffer -> Integer 7047e11d54SBob Moore * Buffer -> String 7147e11d54SBob Moore * Buffer -> Package of Integers 7247e11d54SBob Moore * Package -> Package of one Package 7347e11d54SBob Moore * 7447e11d54SBob Moore ******************************************************************************/ 7547e11d54SBob Moore /* Local prototypes */ 7647e11d54SBob Moore static acpi_status 7747e11d54SBob Moore acpi_ns_convert_to_integer(union acpi_operand_object *original_object, 7847e11d54SBob Moore union acpi_operand_object **return_object); 7947e11d54SBob Moore 8047e11d54SBob Moore static acpi_status 8147e11d54SBob Moore acpi_ns_convert_to_string(union acpi_operand_object *original_object, 8247e11d54SBob Moore union acpi_operand_object **return_object); 8347e11d54SBob Moore 8447e11d54SBob Moore static acpi_status 8547e11d54SBob Moore acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, 8647e11d54SBob Moore union acpi_operand_object **return_object); 8747e11d54SBob Moore 8847e11d54SBob Moore static acpi_status 8947e11d54SBob Moore acpi_ns_convert_to_package(union acpi_operand_object *original_object, 9047e11d54SBob Moore union acpi_operand_object **return_object); 9147e11d54SBob Moore 9247e11d54SBob Moore /******************************************************************************* 9347e11d54SBob Moore * 94b2deadd5SBob Moore * FUNCTION: acpi_ns_repair_object 95b2deadd5SBob Moore * 96b2deadd5SBob Moore * PARAMETERS: Data - Pointer to validation data structure 97b2deadd5SBob Moore * expected_btypes - Object types expected 98b2deadd5SBob Moore * package_index - Index of object within parent package (if 99b2deadd5SBob Moore * applicable - ACPI_NOT_PACKAGE_ELEMENT 100b2deadd5SBob Moore * otherwise) 101b2deadd5SBob Moore * return_object_ptr - Pointer to the object returned from the 102b2deadd5SBob Moore * evaluation of a method or object 103b2deadd5SBob Moore * 104b2deadd5SBob Moore * RETURN: Status. AE_OK if repair was successful. 105b2deadd5SBob Moore * 106b2deadd5SBob Moore * DESCRIPTION: Attempt to repair/convert a return object of a type that was 107b2deadd5SBob Moore * not expected. 108b2deadd5SBob Moore * 109b2deadd5SBob Moore ******************************************************************************/ 11047e11d54SBob Moore 111b2deadd5SBob Moore acpi_status 112b2deadd5SBob Moore acpi_ns_repair_object(struct acpi_predefined_data *data, 113b2deadd5SBob Moore u32 expected_btypes, 114b2deadd5SBob Moore u32 package_index, 115b2deadd5SBob Moore union acpi_operand_object **return_object_ptr) 116b2deadd5SBob Moore { 117b2deadd5SBob Moore union acpi_operand_object *return_object = *return_object_ptr; 118b2deadd5SBob Moore union acpi_operand_object *new_object; 1190240d7b4SLin Ming acpi_status status; 120b2deadd5SBob Moore 12127526993SBob Moore /* 12227526993SBob Moore * At this point, we know that the type of the returned object was not 12327526993SBob Moore * one of the expected types for this predefined name. Attempt to 12447e11d54SBob Moore * repair the object by converting it to one of the expected object 12547e11d54SBob Moore * types for this predefined name. 12627526993SBob Moore */ 12747e11d54SBob Moore if (expected_btypes & ACPI_RTYPE_INTEGER) { 12847e11d54SBob Moore status = acpi_ns_convert_to_integer(return_object, &new_object); 12947e11d54SBob Moore if (ACPI_SUCCESS(status)) { 13047e11d54SBob Moore goto object_repaired; 131b2deadd5SBob Moore } 132b2deadd5SBob Moore } 13347e11d54SBob Moore if (expected_btypes & ACPI_RTYPE_STRING) { 13447e11d54SBob Moore status = acpi_ns_convert_to_string(return_object, &new_object); 13547e11d54SBob Moore if (ACPI_SUCCESS(status)) { 13647e11d54SBob Moore goto object_repaired; 137b2deadd5SBob Moore } 13847e11d54SBob Moore } 1390240d7b4SLin Ming if (expected_btypes & ACPI_RTYPE_BUFFER) { 14047e11d54SBob Moore status = acpi_ns_convert_to_buffer(return_object, &new_object); 14147e11d54SBob Moore if (ACPI_SUCCESS(status)) { 14247e11d54SBob Moore goto object_repaired; 1430240d7b4SLin Ming } 1440240d7b4SLin Ming } 14547e11d54SBob Moore if (expected_btypes & ACPI_RTYPE_PACKAGE) { 14647e11d54SBob Moore status = acpi_ns_convert_to_package(return_object, &new_object); 14747e11d54SBob Moore if (ACPI_SUCCESS(status)) { 14847e11d54SBob Moore goto object_repaired; 14927526993SBob Moore } 15027526993SBob Moore } 15127526993SBob Moore 15227526993SBob Moore /* We cannot repair this object */ 15327526993SBob Moore 15427526993SBob Moore return (AE_AML_OPERAND_TYPE); 15547e11d54SBob Moore 15647e11d54SBob Moore object_repaired: 15727526993SBob Moore 15827526993SBob Moore /* Object was successfully repaired */ 159b2deadd5SBob Moore 160b2deadd5SBob Moore /* 161b2deadd5SBob Moore * If the original object is a package element, we need to: 162b2deadd5SBob Moore * 1. Set the reference count of the new object to match the 163b2deadd5SBob Moore * reference count of the old object. 164b2deadd5SBob Moore * 2. Decrement the reference count of the original object. 165b2deadd5SBob Moore */ 166b2deadd5SBob Moore if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { 167b2deadd5SBob Moore new_object->common.reference_count = 168b2deadd5SBob Moore return_object->common.reference_count; 169b2deadd5SBob Moore 170b2deadd5SBob Moore if (return_object->common.reference_count > 1) { 171b2deadd5SBob Moore return_object->common.reference_count--; 172b2deadd5SBob Moore } 173b2deadd5SBob Moore 1747df200cdSBob Moore ACPI_INFO_PREDEFINED((AE_INFO, data->pathname, data->node_flags, 17527526993SBob Moore "Converted %s to expected %s at index %u", 17627526993SBob Moore acpi_ut_get_object_type_name 17727526993SBob Moore (return_object), 17827526993SBob Moore acpi_ut_get_object_type_name(new_object), 179b2deadd5SBob Moore package_index)); 180b2deadd5SBob Moore } else { 1817df200cdSBob Moore ACPI_INFO_PREDEFINED((AE_INFO, data->pathname, data->node_flags, 18227526993SBob Moore "Converted %s to expected %s", 18327526993SBob Moore acpi_ut_get_object_type_name 18427526993SBob Moore (return_object), 18527526993SBob Moore acpi_ut_get_object_type_name 18627526993SBob Moore (new_object))); 187b2deadd5SBob Moore } 188b2deadd5SBob Moore 189b2deadd5SBob Moore /* Delete old object, install the new return object */ 190b2deadd5SBob Moore 191b2deadd5SBob Moore acpi_ut_remove_reference(return_object); 192b2deadd5SBob Moore *return_object_ptr = new_object; 193b2deadd5SBob Moore data->flags |= ACPI_OBJECT_REPAIRED; 194b2deadd5SBob Moore return (AE_OK); 195b2deadd5SBob Moore } 196e5f69d6eSBob Moore 197e5f69d6eSBob Moore /******************************************************************************* 198e5f69d6eSBob Moore * 19947e11d54SBob Moore * FUNCTION: acpi_ns_convert_to_integer 20047e11d54SBob Moore * 20147e11d54SBob Moore * PARAMETERS: original_object - Object to be converted 20247e11d54SBob Moore * return_object - Where the new converted object is returned 20347e11d54SBob Moore * 20447e11d54SBob Moore * RETURN: Status. AE_OK if conversion was successful. 20547e11d54SBob Moore * 20647e11d54SBob Moore * DESCRIPTION: Attempt to convert a String/Buffer object to an Integer. 20747e11d54SBob Moore * 20847e11d54SBob Moore ******************************************************************************/ 20947e11d54SBob Moore 21047e11d54SBob Moore static acpi_status 21147e11d54SBob Moore acpi_ns_convert_to_integer(union acpi_operand_object *original_object, 21247e11d54SBob Moore union acpi_operand_object **return_object) 21347e11d54SBob Moore { 21447e11d54SBob Moore union acpi_operand_object *new_object; 21547e11d54SBob Moore acpi_status status; 21647e11d54SBob Moore u64 value = 0; 21747e11d54SBob Moore u32 i; 21847e11d54SBob Moore 21947e11d54SBob Moore switch (original_object->common.type) { 22047e11d54SBob Moore case ACPI_TYPE_STRING: 22147e11d54SBob Moore 22247e11d54SBob Moore /* String-to-Integer conversion */ 22347e11d54SBob Moore 22447e11d54SBob Moore status = acpi_ut_strtoul64(original_object->string.pointer, 22547e11d54SBob Moore ACPI_ANY_BASE, &value); 22647e11d54SBob Moore if (ACPI_FAILURE(status)) { 22747e11d54SBob Moore return (status); 22847e11d54SBob Moore } 22947e11d54SBob Moore break; 23047e11d54SBob Moore 23147e11d54SBob Moore case ACPI_TYPE_BUFFER: 23247e11d54SBob Moore 23347e11d54SBob Moore /* Buffer-to-Integer conversion. Max buffer size is 64 bits. */ 23447e11d54SBob Moore 23547e11d54SBob Moore if (original_object->buffer.length > 8) { 23647e11d54SBob Moore return (AE_AML_OPERAND_TYPE); 23747e11d54SBob Moore } 23847e11d54SBob Moore 23947e11d54SBob Moore /* Extract each buffer byte to create the integer */ 24047e11d54SBob Moore 24147e11d54SBob Moore for (i = 0; i < original_object->buffer.length; i++) { 24247e11d54SBob Moore value |= 24347e11d54SBob Moore ((u64) original_object->buffer. 24447e11d54SBob Moore pointer[i] << (i * 8)); 24547e11d54SBob Moore } 24647e11d54SBob Moore break; 24747e11d54SBob Moore 24847e11d54SBob Moore default: 24947e11d54SBob Moore return (AE_AML_OPERAND_TYPE); 25047e11d54SBob Moore } 25147e11d54SBob Moore 25247e11d54SBob Moore new_object = acpi_ut_create_integer_object(value); 25347e11d54SBob Moore if (!new_object) { 25447e11d54SBob Moore return (AE_NO_MEMORY); 25547e11d54SBob Moore } 25647e11d54SBob Moore 25747e11d54SBob Moore *return_object = new_object; 25847e11d54SBob Moore return (AE_OK); 25947e11d54SBob Moore } 26047e11d54SBob Moore 26147e11d54SBob Moore /******************************************************************************* 26247e11d54SBob Moore * 26347e11d54SBob Moore * FUNCTION: acpi_ns_convert_to_string 26447e11d54SBob Moore * 26547e11d54SBob Moore * PARAMETERS: original_object - Object to be converted 26647e11d54SBob Moore * return_object - Where the new converted object is returned 26747e11d54SBob Moore * 26847e11d54SBob Moore * RETURN: Status. AE_OK if conversion was successful. 26947e11d54SBob Moore * 27047e11d54SBob Moore * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String. 27147e11d54SBob Moore * 27247e11d54SBob Moore ******************************************************************************/ 27347e11d54SBob Moore 27447e11d54SBob Moore static acpi_status 27547e11d54SBob Moore acpi_ns_convert_to_string(union acpi_operand_object *original_object, 27647e11d54SBob Moore union acpi_operand_object **return_object) 27747e11d54SBob Moore { 27847e11d54SBob Moore union acpi_operand_object *new_object; 27947e11d54SBob Moore acpi_size length; 28047e11d54SBob Moore acpi_status status; 28147e11d54SBob Moore 28247e11d54SBob Moore switch (original_object->common.type) { 28347e11d54SBob Moore case ACPI_TYPE_INTEGER: 28447e11d54SBob Moore /* 28547e11d54SBob Moore * Integer-to-String conversion. Commonly, convert 28647e11d54SBob Moore * an integer of value 0 to a NULL string. The last element of 28747e11d54SBob Moore * _BIF and _BIX packages occasionally need this fix. 28847e11d54SBob Moore */ 28947e11d54SBob Moore if (original_object->integer.value == 0) { 29047e11d54SBob Moore 29147e11d54SBob Moore /* Allocate a new NULL string object */ 29247e11d54SBob Moore 29347e11d54SBob Moore new_object = acpi_ut_create_string_object(0); 29447e11d54SBob Moore if (!new_object) { 29547e11d54SBob Moore return (AE_NO_MEMORY); 29647e11d54SBob Moore } 29747e11d54SBob Moore } else { 29847e11d54SBob Moore status = 29947e11d54SBob Moore acpi_ex_convert_to_string(original_object, 30047e11d54SBob Moore &new_object, 30147e11d54SBob Moore ACPI_IMPLICIT_CONVERT_HEX); 30247e11d54SBob Moore if (ACPI_FAILURE(status)) { 30347e11d54SBob Moore return (status); 30447e11d54SBob Moore } 30547e11d54SBob Moore } 30647e11d54SBob Moore break; 30747e11d54SBob Moore 30847e11d54SBob Moore case ACPI_TYPE_BUFFER: 30947e11d54SBob Moore /* 31047e11d54SBob Moore * Buffer-to-String conversion. Use a to_string 31147e11d54SBob Moore * conversion, no transform performed on the buffer data. The best 31247e11d54SBob Moore * example of this is the _BIF method, where the string data from 31347e11d54SBob Moore * the battery is often (incorrectly) returned as buffer object(s). 31447e11d54SBob Moore */ 31547e11d54SBob Moore length = 0; 31647e11d54SBob Moore while ((length < original_object->buffer.length) && 31747e11d54SBob Moore (original_object->buffer.pointer[length])) { 31847e11d54SBob Moore length++; 31947e11d54SBob Moore } 32047e11d54SBob Moore 32147e11d54SBob Moore /* Allocate a new string object */ 32247e11d54SBob Moore 32347e11d54SBob Moore new_object = acpi_ut_create_string_object(length); 32447e11d54SBob Moore if (!new_object) { 32547e11d54SBob Moore return (AE_NO_MEMORY); 32647e11d54SBob Moore } 32747e11d54SBob Moore 32847e11d54SBob Moore /* 32947e11d54SBob Moore * Copy the raw buffer data with no transform. String is already NULL 33047e11d54SBob Moore * terminated at Length+1. 33147e11d54SBob Moore */ 33247e11d54SBob Moore ACPI_MEMCPY(new_object->string.pointer, 33347e11d54SBob Moore original_object->buffer.pointer, length); 33447e11d54SBob Moore break; 33547e11d54SBob Moore 33647e11d54SBob Moore default: 33747e11d54SBob Moore return (AE_AML_OPERAND_TYPE); 33847e11d54SBob Moore } 33947e11d54SBob Moore 34047e11d54SBob Moore *return_object = new_object; 34147e11d54SBob Moore return (AE_OK); 34247e11d54SBob Moore } 34347e11d54SBob Moore 34447e11d54SBob Moore /******************************************************************************* 34547e11d54SBob Moore * 34647e11d54SBob Moore * FUNCTION: acpi_ns_convert_to_buffer 34747e11d54SBob Moore * 34847e11d54SBob Moore * PARAMETERS: original_object - Object to be converted 34947e11d54SBob Moore * return_object - Where the new converted object is returned 35047e11d54SBob Moore * 35147e11d54SBob Moore * RETURN: Status. AE_OK if conversion was successful. 35247e11d54SBob Moore * 353ea7c5ec1SBob Moore * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer. 35447e11d54SBob Moore * 35547e11d54SBob Moore ******************************************************************************/ 35647e11d54SBob Moore 35747e11d54SBob Moore static acpi_status 35847e11d54SBob Moore acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, 35947e11d54SBob Moore union acpi_operand_object **return_object) 36047e11d54SBob Moore { 36147e11d54SBob Moore union acpi_operand_object *new_object; 36247e11d54SBob Moore acpi_status status; 363ea7c5ec1SBob Moore union acpi_operand_object **elements; 364ea7c5ec1SBob Moore u32 *dword_buffer; 365ea7c5ec1SBob Moore u32 count; 366ea7c5ec1SBob Moore u32 i; 36747e11d54SBob Moore 36847e11d54SBob Moore switch (original_object->common.type) { 36947e11d54SBob Moore case ACPI_TYPE_INTEGER: 37047e11d54SBob Moore /* 37147e11d54SBob Moore * Integer-to-Buffer conversion. 37247e11d54SBob Moore * Convert the Integer to a packed-byte buffer. _MAT and other 37347e11d54SBob Moore * objects need this sometimes, if a read has been performed on a 37447e11d54SBob Moore * Field object that is less than or equal to the global integer 37547e11d54SBob Moore * size (32 or 64 bits). 37647e11d54SBob Moore */ 37747e11d54SBob Moore status = 37847e11d54SBob Moore acpi_ex_convert_to_buffer(original_object, &new_object); 37947e11d54SBob Moore if (ACPI_FAILURE(status)) { 38047e11d54SBob Moore return (status); 38147e11d54SBob Moore } 38247e11d54SBob Moore break; 38347e11d54SBob Moore 38447e11d54SBob Moore case ACPI_TYPE_STRING: 38547e11d54SBob Moore 38647e11d54SBob Moore /* String-to-Buffer conversion. Simple data copy */ 38747e11d54SBob Moore 38847e11d54SBob Moore new_object = 38947e11d54SBob Moore acpi_ut_create_buffer_object(original_object->string. 39047e11d54SBob Moore length); 39147e11d54SBob Moore if (!new_object) { 39247e11d54SBob Moore return (AE_NO_MEMORY); 39347e11d54SBob Moore } 39447e11d54SBob Moore 39547e11d54SBob Moore ACPI_MEMCPY(new_object->buffer.pointer, 39647e11d54SBob Moore original_object->string.pointer, 39747e11d54SBob Moore original_object->string.length); 39847e11d54SBob Moore break; 39947e11d54SBob Moore 400ea7c5ec1SBob Moore case ACPI_TYPE_PACKAGE: 401ea7c5ec1SBob Moore 402ea7c5ec1SBob Moore /* All elements of the Package must be integers */ 403ea7c5ec1SBob Moore 404ea7c5ec1SBob Moore elements = original_object->package.elements; 405ea7c5ec1SBob Moore count = original_object->package.count; 406ea7c5ec1SBob Moore 407ea7c5ec1SBob Moore for (i = 0; i < count; i++) { 408ea7c5ec1SBob Moore if ((!*elements) || 409ea7c5ec1SBob Moore ((*elements)->common.type != ACPI_TYPE_INTEGER)) { 410ea7c5ec1SBob Moore return (AE_AML_OPERAND_TYPE); 411ea7c5ec1SBob Moore } 412ea7c5ec1SBob Moore elements++; 413ea7c5ec1SBob Moore } 414ea7c5ec1SBob Moore 415ea7c5ec1SBob Moore /* Create the new buffer object to replace the Package */ 416ea7c5ec1SBob Moore 417ea7c5ec1SBob Moore new_object = acpi_ut_create_buffer_object(ACPI_MUL_4(count)); 418ea7c5ec1SBob Moore if (!new_object) { 419ea7c5ec1SBob Moore return (AE_NO_MEMORY); 420ea7c5ec1SBob Moore } 421ea7c5ec1SBob Moore 422ea7c5ec1SBob Moore /* Copy the package elements (integers) to the buffer as DWORDs */ 423ea7c5ec1SBob Moore 424ea7c5ec1SBob Moore elements = original_object->package.elements; 425ea7c5ec1SBob Moore dword_buffer = ACPI_CAST_PTR(u32, new_object->buffer.pointer); 426ea7c5ec1SBob Moore 427ea7c5ec1SBob Moore for (i = 0; i < count; i++) { 428ea7c5ec1SBob Moore *dword_buffer = (u32) (*elements)->integer.value; 429ea7c5ec1SBob Moore dword_buffer++; 430ea7c5ec1SBob Moore elements++; 431ea7c5ec1SBob Moore } 432ea7c5ec1SBob Moore break; 433ea7c5ec1SBob Moore 43447e11d54SBob Moore default: 43547e11d54SBob Moore return (AE_AML_OPERAND_TYPE); 43647e11d54SBob Moore } 43747e11d54SBob Moore 43847e11d54SBob Moore *return_object = new_object; 43947e11d54SBob Moore return (AE_OK); 44047e11d54SBob Moore } 44147e11d54SBob Moore 44247e11d54SBob Moore /******************************************************************************* 44347e11d54SBob Moore * 44447e11d54SBob Moore * FUNCTION: acpi_ns_convert_to_package 44547e11d54SBob Moore * 44647e11d54SBob Moore * PARAMETERS: original_object - Object to be converted 44747e11d54SBob Moore * return_object - Where the new converted object is returned 44847e11d54SBob Moore * 44947e11d54SBob Moore * RETURN: Status. AE_OK if conversion was successful. 45047e11d54SBob Moore * 45147e11d54SBob Moore * DESCRIPTION: Attempt to convert a Buffer object to a Package. Each byte of 45247e11d54SBob Moore * the buffer is converted to a single integer package element. 45347e11d54SBob Moore * 45447e11d54SBob Moore ******************************************************************************/ 45547e11d54SBob Moore 45647e11d54SBob Moore static acpi_status 45747e11d54SBob Moore acpi_ns_convert_to_package(union acpi_operand_object *original_object, 45847e11d54SBob Moore union acpi_operand_object **return_object) 45947e11d54SBob Moore { 46047e11d54SBob Moore union acpi_operand_object *new_object; 46147e11d54SBob Moore union acpi_operand_object **elements; 46247e11d54SBob Moore u32 length; 46347e11d54SBob Moore u8 *buffer; 46447e11d54SBob Moore 46547e11d54SBob Moore switch (original_object->common.type) { 46647e11d54SBob Moore case ACPI_TYPE_BUFFER: 46747e11d54SBob Moore 46847e11d54SBob Moore /* Buffer-to-Package conversion */ 46947e11d54SBob Moore 47047e11d54SBob Moore length = original_object->buffer.length; 47147e11d54SBob Moore new_object = acpi_ut_create_package_object(length); 47247e11d54SBob Moore if (!new_object) { 47347e11d54SBob Moore return (AE_NO_MEMORY); 47447e11d54SBob Moore } 47547e11d54SBob Moore 47647e11d54SBob Moore /* Convert each buffer byte to an integer package element */ 47747e11d54SBob Moore 47847e11d54SBob Moore elements = new_object->package.elements; 47947e11d54SBob Moore buffer = original_object->buffer.pointer; 48047e11d54SBob Moore 48147e11d54SBob Moore while (length--) { 482ea7c5ec1SBob Moore *elements = 483ea7c5ec1SBob Moore acpi_ut_create_integer_object((u64) *buffer); 48447e11d54SBob Moore if (!*elements) { 48547e11d54SBob Moore acpi_ut_remove_reference(new_object); 48647e11d54SBob Moore return (AE_NO_MEMORY); 48747e11d54SBob Moore } 48847e11d54SBob Moore elements++; 48947e11d54SBob Moore buffer++; 49047e11d54SBob Moore } 49147e11d54SBob Moore break; 49247e11d54SBob Moore 49347e11d54SBob Moore default: 49447e11d54SBob Moore return (AE_AML_OPERAND_TYPE); 49547e11d54SBob Moore } 49647e11d54SBob Moore 49747e11d54SBob Moore *return_object = new_object; 49847e11d54SBob Moore return (AE_OK); 49947e11d54SBob Moore } 50047e11d54SBob Moore 50147e11d54SBob Moore /******************************************************************************* 50247e11d54SBob Moore * 503e5f69d6eSBob Moore * FUNCTION: acpi_ns_repair_package_list 504e5f69d6eSBob Moore * 505e5f69d6eSBob Moore * PARAMETERS: Data - Pointer to validation data structure 506e5f69d6eSBob Moore * obj_desc_ptr - Pointer to the object to repair. The new 507e5f69d6eSBob Moore * package object is returned here, 508e5f69d6eSBob Moore * overwriting the old object. 509e5f69d6eSBob Moore * 510e5f69d6eSBob Moore * RETURN: Status, new object in *obj_desc_ptr 511e5f69d6eSBob Moore * 512e5f69d6eSBob Moore * DESCRIPTION: Repair a common problem with objects that are defined to return 513e5f69d6eSBob Moore * a variable-length Package of Packages. If the variable-length 514e5f69d6eSBob Moore * is one, some BIOS code mistakenly simply declares a single 515e5f69d6eSBob Moore * Package instead of a Package with one sub-Package. This 516e5f69d6eSBob Moore * function attempts to repair this error by wrapping a Package 517e5f69d6eSBob Moore * object around the original Package, creating the correct 518e5f69d6eSBob Moore * Package with one sub-Package. 519e5f69d6eSBob Moore * 520e5f69d6eSBob Moore * Names that can be repaired in this manner include: 521e5f69d6eSBob Moore * _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS 522e5f69d6eSBob Moore * 523e5f69d6eSBob Moore ******************************************************************************/ 524e5f69d6eSBob Moore 525e5f69d6eSBob Moore acpi_status 526e5f69d6eSBob Moore acpi_ns_repair_package_list(struct acpi_predefined_data *data, 527e5f69d6eSBob Moore union acpi_operand_object **obj_desc_ptr) 528e5f69d6eSBob Moore { 529e5f69d6eSBob Moore union acpi_operand_object *pkg_obj_desc; 530e5f69d6eSBob Moore 531e5f69d6eSBob Moore /* 532e5f69d6eSBob Moore * Create the new outer package and populate it. The new package will 533e5f69d6eSBob Moore * have a single element, the lone subpackage. 534e5f69d6eSBob Moore */ 535e5f69d6eSBob Moore pkg_obj_desc = acpi_ut_create_package_object(1); 536e5f69d6eSBob Moore if (!pkg_obj_desc) { 537e5f69d6eSBob Moore return (AE_NO_MEMORY); 538e5f69d6eSBob Moore } 539e5f69d6eSBob Moore 540e5f69d6eSBob Moore pkg_obj_desc->package.elements[0] = *obj_desc_ptr; 541e5f69d6eSBob Moore 542e5f69d6eSBob Moore /* Return the new object in the object pointer */ 543e5f69d6eSBob Moore 544e5f69d6eSBob Moore *obj_desc_ptr = pkg_obj_desc; 545e5f69d6eSBob Moore data->flags |= ACPI_OBJECT_REPAIRED; 546e5f69d6eSBob Moore 5477df200cdSBob Moore ACPI_INFO_PREDEFINED((AE_INFO, data->pathname, data->node_flags, 5487df200cdSBob Moore "Repaired Incorrectly formed Package")); 549e5f69d6eSBob Moore 550e5f69d6eSBob Moore return (AE_OK); 551e5f69d6eSBob Moore } 552