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 1213a58176eSBob Moore ACPI_FUNCTION_NAME(ns_repair_object); 1223a58176eSBob Moore 12327526993SBob Moore /* 12427526993SBob Moore * At this point, we know that the type of the returned object was not 12527526993SBob Moore * one of the expected types for this predefined name. Attempt to 12647e11d54SBob Moore * repair the object by converting it to one of the expected object 12747e11d54SBob Moore * types for this predefined name. 12827526993SBob Moore */ 12947e11d54SBob Moore if (expected_btypes & ACPI_RTYPE_INTEGER) { 13047e11d54SBob Moore status = acpi_ns_convert_to_integer(return_object, &new_object); 13147e11d54SBob Moore if (ACPI_SUCCESS(status)) { 13247e11d54SBob Moore goto object_repaired; 133b2deadd5SBob Moore } 134b2deadd5SBob Moore } 13547e11d54SBob Moore if (expected_btypes & ACPI_RTYPE_STRING) { 13647e11d54SBob Moore status = acpi_ns_convert_to_string(return_object, &new_object); 13747e11d54SBob Moore if (ACPI_SUCCESS(status)) { 13847e11d54SBob Moore goto object_repaired; 139b2deadd5SBob Moore } 14047e11d54SBob Moore } 1410240d7b4SLin Ming if (expected_btypes & ACPI_RTYPE_BUFFER) { 14247e11d54SBob Moore status = acpi_ns_convert_to_buffer(return_object, &new_object); 14347e11d54SBob Moore if (ACPI_SUCCESS(status)) { 14447e11d54SBob Moore goto object_repaired; 1450240d7b4SLin Ming } 1460240d7b4SLin Ming } 14747e11d54SBob Moore if (expected_btypes & ACPI_RTYPE_PACKAGE) { 14847e11d54SBob Moore status = acpi_ns_convert_to_package(return_object, &new_object); 14947e11d54SBob Moore if (ACPI_SUCCESS(status)) { 15047e11d54SBob Moore goto object_repaired; 15127526993SBob Moore } 15227526993SBob Moore } 15327526993SBob Moore 15427526993SBob Moore /* We cannot repair this object */ 15527526993SBob Moore 15627526993SBob Moore return (AE_AML_OPERAND_TYPE); 15747e11d54SBob Moore 15847e11d54SBob Moore object_repaired: 15927526993SBob Moore 16027526993SBob Moore /* Object was successfully repaired */ 161b2deadd5SBob Moore 162b2deadd5SBob Moore /* 163b2deadd5SBob Moore * If the original object is a package element, we need to: 164b2deadd5SBob Moore * 1. Set the reference count of the new object to match the 165b2deadd5SBob Moore * reference count of the old object. 166b2deadd5SBob Moore * 2. Decrement the reference count of the original object. 167b2deadd5SBob Moore */ 168b2deadd5SBob Moore if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { 169b2deadd5SBob Moore new_object->common.reference_count = 170b2deadd5SBob Moore return_object->common.reference_count; 171b2deadd5SBob Moore 172b2deadd5SBob Moore if (return_object->common.reference_count > 1) { 173b2deadd5SBob Moore return_object->common.reference_count--; 174b2deadd5SBob Moore } 175b2deadd5SBob Moore 1763a58176eSBob Moore ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 1773a58176eSBob Moore "%s: Converted %s to expected %s at index %u\n", 1783a58176eSBob Moore data->pathname, 1793a58176eSBob Moore acpi_ut_get_object_type_name(return_object), 18027526993SBob Moore acpi_ut_get_object_type_name(new_object), 181b2deadd5SBob Moore package_index)); 182b2deadd5SBob Moore } else { 1833a58176eSBob Moore ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 1843a58176eSBob Moore "%s: Converted %s to expected %s\n", 1853a58176eSBob Moore data->pathname, 1863a58176eSBob Moore acpi_ut_get_object_type_name(return_object), 1873a58176eSBob Moore acpi_ut_get_object_type_name(new_object))); 188b2deadd5SBob Moore } 189b2deadd5SBob Moore 190b2deadd5SBob Moore /* Delete old object, install the new return object */ 191b2deadd5SBob Moore 192b2deadd5SBob Moore acpi_ut_remove_reference(return_object); 193b2deadd5SBob Moore *return_object_ptr = new_object; 194b2deadd5SBob Moore data->flags |= ACPI_OBJECT_REPAIRED; 195b2deadd5SBob Moore return (AE_OK); 196b2deadd5SBob Moore } 197e5f69d6eSBob Moore 198e5f69d6eSBob Moore /******************************************************************************* 199e5f69d6eSBob Moore * 20047e11d54SBob Moore * FUNCTION: acpi_ns_convert_to_integer 20147e11d54SBob Moore * 20247e11d54SBob Moore * PARAMETERS: original_object - Object to be converted 20347e11d54SBob Moore * return_object - Where the new converted object is returned 20447e11d54SBob Moore * 20547e11d54SBob Moore * RETURN: Status. AE_OK if conversion was successful. 20647e11d54SBob Moore * 20747e11d54SBob Moore * DESCRIPTION: Attempt to convert a String/Buffer object to an Integer. 20847e11d54SBob Moore * 20947e11d54SBob Moore ******************************************************************************/ 21047e11d54SBob Moore 21147e11d54SBob Moore static acpi_status 21247e11d54SBob Moore acpi_ns_convert_to_integer(union acpi_operand_object *original_object, 21347e11d54SBob Moore union acpi_operand_object **return_object) 21447e11d54SBob Moore { 21547e11d54SBob Moore union acpi_operand_object *new_object; 21647e11d54SBob Moore acpi_status status; 21747e11d54SBob Moore u64 value = 0; 21847e11d54SBob Moore u32 i; 21947e11d54SBob Moore 22047e11d54SBob Moore switch (original_object->common.type) { 22147e11d54SBob Moore case ACPI_TYPE_STRING: 22247e11d54SBob Moore 22347e11d54SBob Moore /* String-to-Integer conversion */ 22447e11d54SBob Moore 22547e11d54SBob Moore status = acpi_ut_strtoul64(original_object->string.pointer, 22647e11d54SBob Moore ACPI_ANY_BASE, &value); 22747e11d54SBob Moore if (ACPI_FAILURE(status)) { 22847e11d54SBob Moore return (status); 22947e11d54SBob Moore } 23047e11d54SBob Moore break; 23147e11d54SBob Moore 23247e11d54SBob Moore case ACPI_TYPE_BUFFER: 23347e11d54SBob Moore 23447e11d54SBob Moore /* Buffer-to-Integer conversion. Max buffer size is 64 bits. */ 23547e11d54SBob Moore 23647e11d54SBob Moore if (original_object->buffer.length > 8) { 23747e11d54SBob Moore return (AE_AML_OPERAND_TYPE); 23847e11d54SBob Moore } 23947e11d54SBob Moore 24047e11d54SBob Moore /* Extract each buffer byte to create the integer */ 24147e11d54SBob Moore 24247e11d54SBob Moore for (i = 0; i < original_object->buffer.length; i++) { 24347e11d54SBob Moore value |= 24447e11d54SBob Moore ((u64) original_object->buffer. 24547e11d54SBob Moore pointer[i] << (i * 8)); 24647e11d54SBob Moore } 24747e11d54SBob Moore break; 24847e11d54SBob Moore 24947e11d54SBob Moore default: 25047e11d54SBob Moore return (AE_AML_OPERAND_TYPE); 25147e11d54SBob Moore } 25247e11d54SBob Moore 25347e11d54SBob Moore new_object = acpi_ut_create_integer_object(value); 25447e11d54SBob Moore if (!new_object) { 25547e11d54SBob Moore return (AE_NO_MEMORY); 25647e11d54SBob Moore } 25747e11d54SBob Moore 25847e11d54SBob Moore *return_object = new_object; 25947e11d54SBob Moore return (AE_OK); 26047e11d54SBob Moore } 26147e11d54SBob Moore 26247e11d54SBob Moore /******************************************************************************* 26347e11d54SBob Moore * 26447e11d54SBob Moore * FUNCTION: acpi_ns_convert_to_string 26547e11d54SBob Moore * 26647e11d54SBob Moore * PARAMETERS: original_object - Object to be converted 26747e11d54SBob Moore * return_object - Where the new converted object is returned 26847e11d54SBob Moore * 26947e11d54SBob Moore * RETURN: Status. AE_OK if conversion was successful. 27047e11d54SBob Moore * 27147e11d54SBob Moore * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String. 27247e11d54SBob Moore * 27347e11d54SBob Moore ******************************************************************************/ 27447e11d54SBob Moore 27547e11d54SBob Moore static acpi_status 27647e11d54SBob Moore acpi_ns_convert_to_string(union acpi_operand_object *original_object, 27747e11d54SBob Moore union acpi_operand_object **return_object) 27847e11d54SBob Moore { 27947e11d54SBob Moore union acpi_operand_object *new_object; 28047e11d54SBob Moore acpi_size length; 28147e11d54SBob Moore acpi_status status; 28247e11d54SBob Moore 28347e11d54SBob Moore switch (original_object->common.type) { 28447e11d54SBob Moore case ACPI_TYPE_INTEGER: 28547e11d54SBob Moore /* 28647e11d54SBob Moore * Integer-to-String conversion. Commonly, convert 28747e11d54SBob Moore * an integer of value 0 to a NULL string. The last element of 28847e11d54SBob Moore * _BIF and _BIX packages occasionally need this fix. 28947e11d54SBob Moore */ 29047e11d54SBob Moore if (original_object->integer.value == 0) { 29147e11d54SBob Moore 29247e11d54SBob Moore /* Allocate a new NULL string object */ 29347e11d54SBob Moore 29447e11d54SBob Moore new_object = acpi_ut_create_string_object(0); 29547e11d54SBob Moore if (!new_object) { 29647e11d54SBob Moore return (AE_NO_MEMORY); 29747e11d54SBob Moore } 29847e11d54SBob Moore } else { 29947e11d54SBob Moore status = 30047e11d54SBob Moore acpi_ex_convert_to_string(original_object, 30147e11d54SBob Moore &new_object, 30247e11d54SBob Moore ACPI_IMPLICIT_CONVERT_HEX); 30347e11d54SBob Moore if (ACPI_FAILURE(status)) { 30447e11d54SBob Moore return (status); 30547e11d54SBob Moore } 30647e11d54SBob Moore } 30747e11d54SBob Moore break; 30847e11d54SBob Moore 30947e11d54SBob Moore case ACPI_TYPE_BUFFER: 31047e11d54SBob Moore /* 31147e11d54SBob Moore * Buffer-to-String conversion. Use a to_string 31247e11d54SBob Moore * conversion, no transform performed on the buffer data. The best 31347e11d54SBob Moore * example of this is the _BIF method, where the string data from 31447e11d54SBob Moore * the battery is often (incorrectly) returned as buffer object(s). 31547e11d54SBob Moore */ 31647e11d54SBob Moore length = 0; 31747e11d54SBob Moore while ((length < original_object->buffer.length) && 31847e11d54SBob Moore (original_object->buffer.pointer[length])) { 31947e11d54SBob Moore length++; 32047e11d54SBob Moore } 32147e11d54SBob Moore 32247e11d54SBob Moore /* Allocate a new string object */ 32347e11d54SBob Moore 32447e11d54SBob Moore new_object = acpi_ut_create_string_object(length); 32547e11d54SBob Moore if (!new_object) { 32647e11d54SBob Moore return (AE_NO_MEMORY); 32747e11d54SBob Moore } 32847e11d54SBob Moore 32947e11d54SBob Moore /* 33047e11d54SBob Moore * Copy the raw buffer data with no transform. String is already NULL 33147e11d54SBob Moore * terminated at Length+1. 33247e11d54SBob Moore */ 33347e11d54SBob Moore ACPI_MEMCPY(new_object->string.pointer, 33447e11d54SBob Moore original_object->buffer.pointer, length); 33547e11d54SBob Moore break; 33647e11d54SBob Moore 33747e11d54SBob Moore default: 33847e11d54SBob Moore return (AE_AML_OPERAND_TYPE); 33947e11d54SBob Moore } 34047e11d54SBob Moore 34147e11d54SBob Moore *return_object = new_object; 34247e11d54SBob Moore return (AE_OK); 34347e11d54SBob Moore } 34447e11d54SBob Moore 34547e11d54SBob Moore /******************************************************************************* 34647e11d54SBob Moore * 34747e11d54SBob Moore * FUNCTION: acpi_ns_convert_to_buffer 34847e11d54SBob Moore * 34947e11d54SBob Moore * PARAMETERS: original_object - Object to be converted 35047e11d54SBob Moore * return_object - Where the new converted object is returned 35147e11d54SBob Moore * 35247e11d54SBob Moore * RETURN: Status. AE_OK if conversion was successful. 35347e11d54SBob Moore * 354ea7c5ec1SBob Moore * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer. 35547e11d54SBob Moore * 35647e11d54SBob Moore ******************************************************************************/ 35747e11d54SBob Moore 35847e11d54SBob Moore static acpi_status 35947e11d54SBob Moore acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, 36047e11d54SBob Moore union acpi_operand_object **return_object) 36147e11d54SBob Moore { 36247e11d54SBob Moore union acpi_operand_object *new_object; 36347e11d54SBob Moore acpi_status status; 364ea7c5ec1SBob Moore union acpi_operand_object **elements; 365ea7c5ec1SBob Moore u32 *dword_buffer; 366ea7c5ec1SBob Moore u32 count; 367ea7c5ec1SBob Moore u32 i; 36847e11d54SBob Moore 36947e11d54SBob Moore switch (original_object->common.type) { 37047e11d54SBob Moore case ACPI_TYPE_INTEGER: 37147e11d54SBob Moore /* 37247e11d54SBob Moore * Integer-to-Buffer conversion. 37347e11d54SBob Moore * Convert the Integer to a packed-byte buffer. _MAT and other 37447e11d54SBob Moore * objects need this sometimes, if a read has been performed on a 37547e11d54SBob Moore * Field object that is less than or equal to the global integer 37647e11d54SBob Moore * size (32 or 64 bits). 37747e11d54SBob Moore */ 37847e11d54SBob Moore status = 37947e11d54SBob Moore acpi_ex_convert_to_buffer(original_object, &new_object); 38047e11d54SBob Moore if (ACPI_FAILURE(status)) { 38147e11d54SBob Moore return (status); 38247e11d54SBob Moore } 38347e11d54SBob Moore break; 38447e11d54SBob Moore 38547e11d54SBob Moore case ACPI_TYPE_STRING: 38647e11d54SBob Moore 38747e11d54SBob Moore /* String-to-Buffer conversion. Simple data copy */ 38847e11d54SBob Moore 38947e11d54SBob Moore new_object = 39047e11d54SBob Moore acpi_ut_create_buffer_object(original_object->string. 39147e11d54SBob Moore length); 39247e11d54SBob Moore if (!new_object) { 39347e11d54SBob Moore return (AE_NO_MEMORY); 39447e11d54SBob Moore } 39547e11d54SBob Moore 39647e11d54SBob Moore ACPI_MEMCPY(new_object->buffer.pointer, 39747e11d54SBob Moore original_object->string.pointer, 39847e11d54SBob Moore original_object->string.length); 39947e11d54SBob Moore break; 40047e11d54SBob Moore 401ea7c5ec1SBob Moore case ACPI_TYPE_PACKAGE: 40243420bbbSBob Moore /* 40343420bbbSBob Moore * This case is often seen for predefined names that must return a 40443420bbbSBob Moore * Buffer object with multiple DWORD integers within. For example, 40543420bbbSBob Moore * _FDE and _GTM. The Package can be converted to a Buffer. 40643420bbbSBob Moore */ 407ea7c5ec1SBob Moore 408ea7c5ec1SBob Moore /* All elements of the Package must be integers */ 409ea7c5ec1SBob Moore 410ea7c5ec1SBob Moore elements = original_object->package.elements; 411ea7c5ec1SBob Moore count = original_object->package.count; 412ea7c5ec1SBob Moore 413ea7c5ec1SBob Moore for (i = 0; i < count; i++) { 414ea7c5ec1SBob Moore if ((!*elements) || 415ea7c5ec1SBob Moore ((*elements)->common.type != ACPI_TYPE_INTEGER)) { 416ea7c5ec1SBob Moore return (AE_AML_OPERAND_TYPE); 417ea7c5ec1SBob Moore } 418ea7c5ec1SBob Moore elements++; 419ea7c5ec1SBob Moore } 420ea7c5ec1SBob Moore 421ea7c5ec1SBob Moore /* Create the new buffer object to replace the Package */ 422ea7c5ec1SBob Moore 423ea7c5ec1SBob Moore new_object = acpi_ut_create_buffer_object(ACPI_MUL_4(count)); 424ea7c5ec1SBob Moore if (!new_object) { 425ea7c5ec1SBob Moore return (AE_NO_MEMORY); 426ea7c5ec1SBob Moore } 427ea7c5ec1SBob Moore 428ea7c5ec1SBob Moore /* Copy the package elements (integers) to the buffer as DWORDs */ 429ea7c5ec1SBob Moore 430ea7c5ec1SBob Moore elements = original_object->package.elements; 431ea7c5ec1SBob Moore dword_buffer = ACPI_CAST_PTR(u32, new_object->buffer.pointer); 432ea7c5ec1SBob Moore 433ea7c5ec1SBob Moore for (i = 0; i < count; i++) { 434ea7c5ec1SBob Moore *dword_buffer = (u32) (*elements)->integer.value; 435ea7c5ec1SBob Moore dword_buffer++; 436ea7c5ec1SBob Moore elements++; 437ea7c5ec1SBob Moore } 438ea7c5ec1SBob Moore break; 439ea7c5ec1SBob Moore 44047e11d54SBob Moore default: 44147e11d54SBob Moore return (AE_AML_OPERAND_TYPE); 44247e11d54SBob Moore } 44347e11d54SBob Moore 44447e11d54SBob Moore *return_object = new_object; 44547e11d54SBob Moore return (AE_OK); 44647e11d54SBob Moore } 44747e11d54SBob Moore 44847e11d54SBob Moore /******************************************************************************* 44947e11d54SBob Moore * 45047e11d54SBob Moore * FUNCTION: acpi_ns_convert_to_package 45147e11d54SBob Moore * 45247e11d54SBob Moore * PARAMETERS: original_object - Object to be converted 45347e11d54SBob Moore * return_object - Where the new converted object is returned 45447e11d54SBob Moore * 45547e11d54SBob Moore * RETURN: Status. AE_OK if conversion was successful. 45647e11d54SBob Moore * 45747e11d54SBob Moore * DESCRIPTION: Attempt to convert a Buffer object to a Package. Each byte of 45847e11d54SBob Moore * the buffer is converted to a single integer package element. 45947e11d54SBob Moore * 46047e11d54SBob Moore ******************************************************************************/ 46147e11d54SBob Moore 46247e11d54SBob Moore static acpi_status 46347e11d54SBob Moore acpi_ns_convert_to_package(union acpi_operand_object *original_object, 46447e11d54SBob Moore union acpi_operand_object **return_object) 46547e11d54SBob Moore { 46647e11d54SBob Moore union acpi_operand_object *new_object; 46747e11d54SBob Moore union acpi_operand_object **elements; 46847e11d54SBob Moore u32 length; 46947e11d54SBob Moore u8 *buffer; 47047e11d54SBob Moore 47147e11d54SBob Moore switch (original_object->common.type) { 47247e11d54SBob Moore case ACPI_TYPE_BUFFER: 47347e11d54SBob Moore 47447e11d54SBob Moore /* Buffer-to-Package conversion */ 47547e11d54SBob Moore 47647e11d54SBob Moore length = original_object->buffer.length; 47747e11d54SBob Moore new_object = acpi_ut_create_package_object(length); 47847e11d54SBob Moore if (!new_object) { 47947e11d54SBob Moore return (AE_NO_MEMORY); 48047e11d54SBob Moore } 48147e11d54SBob Moore 48247e11d54SBob Moore /* Convert each buffer byte to an integer package element */ 48347e11d54SBob Moore 48447e11d54SBob Moore elements = new_object->package.elements; 48547e11d54SBob Moore buffer = original_object->buffer.pointer; 48647e11d54SBob Moore 48747e11d54SBob Moore while (length--) { 488ea7c5ec1SBob Moore *elements = 489ea7c5ec1SBob Moore acpi_ut_create_integer_object((u64) *buffer); 49047e11d54SBob Moore if (!*elements) { 49147e11d54SBob Moore acpi_ut_remove_reference(new_object); 49247e11d54SBob Moore return (AE_NO_MEMORY); 49347e11d54SBob Moore } 49447e11d54SBob Moore elements++; 49547e11d54SBob Moore buffer++; 49647e11d54SBob Moore } 49747e11d54SBob Moore break; 49847e11d54SBob Moore 49947e11d54SBob Moore default: 50047e11d54SBob Moore return (AE_AML_OPERAND_TYPE); 50147e11d54SBob Moore } 50247e11d54SBob Moore 50347e11d54SBob Moore *return_object = new_object; 50447e11d54SBob Moore return (AE_OK); 50547e11d54SBob Moore } 50647e11d54SBob Moore 50747e11d54SBob Moore /******************************************************************************* 50847e11d54SBob Moore * 509e5f69d6eSBob Moore * FUNCTION: acpi_ns_repair_package_list 510e5f69d6eSBob Moore * 511e5f69d6eSBob Moore * PARAMETERS: Data - Pointer to validation data structure 512e5f69d6eSBob Moore * obj_desc_ptr - Pointer to the object to repair. The new 513e5f69d6eSBob Moore * package object is returned here, 514e5f69d6eSBob Moore * overwriting the old object. 515e5f69d6eSBob Moore * 516e5f69d6eSBob Moore * RETURN: Status, new object in *obj_desc_ptr 517e5f69d6eSBob Moore * 518e5f69d6eSBob Moore * DESCRIPTION: Repair a common problem with objects that are defined to return 519e5f69d6eSBob Moore * a variable-length Package of Packages. If the variable-length 520e5f69d6eSBob Moore * is one, some BIOS code mistakenly simply declares a single 521e5f69d6eSBob Moore * Package instead of a Package with one sub-Package. This 522e5f69d6eSBob Moore * function attempts to repair this error by wrapping a Package 523e5f69d6eSBob Moore * object around the original Package, creating the correct 524e5f69d6eSBob Moore * Package with one sub-Package. 525e5f69d6eSBob Moore * 526e5f69d6eSBob Moore * Names that can be repaired in this manner include: 527e5f69d6eSBob Moore * _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS 528e5f69d6eSBob Moore * 529e5f69d6eSBob Moore ******************************************************************************/ 530e5f69d6eSBob Moore 531e5f69d6eSBob Moore acpi_status 532e5f69d6eSBob Moore acpi_ns_repair_package_list(struct acpi_predefined_data *data, 533e5f69d6eSBob Moore union acpi_operand_object **obj_desc_ptr) 534e5f69d6eSBob Moore { 535e5f69d6eSBob Moore union acpi_operand_object *pkg_obj_desc; 536e5f69d6eSBob Moore 5373a58176eSBob Moore ACPI_FUNCTION_NAME(ns_repair_package_list); 5383a58176eSBob Moore 539e5f69d6eSBob Moore /* 540e5f69d6eSBob Moore * Create the new outer package and populate it. The new package will 541e5f69d6eSBob Moore * have a single element, the lone subpackage. 542e5f69d6eSBob Moore */ 543e5f69d6eSBob Moore pkg_obj_desc = acpi_ut_create_package_object(1); 544e5f69d6eSBob Moore if (!pkg_obj_desc) { 545e5f69d6eSBob Moore return (AE_NO_MEMORY); 546e5f69d6eSBob Moore } 547e5f69d6eSBob Moore 548e5f69d6eSBob Moore pkg_obj_desc->package.elements[0] = *obj_desc_ptr; 549e5f69d6eSBob Moore 550e5f69d6eSBob Moore /* Return the new object in the object pointer */ 551e5f69d6eSBob Moore 552e5f69d6eSBob Moore *obj_desc_ptr = pkg_obj_desc; 553e5f69d6eSBob Moore data->flags |= ACPI_OBJECT_REPAIRED; 554e5f69d6eSBob Moore 5553a58176eSBob Moore ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 5563a58176eSBob Moore "%s: Repaired incorrectly formed Package\n", 5573a58176eSBob Moore data->pathname)); 558e5f69d6eSBob Moore 559e5f69d6eSBob Moore return (AE_OK); 560e5f69d6eSBob Moore } 561