diff options
Diffstat (limited to 'source/components/namespace')
-rw-r--r-- | source/components/namespace/nsconvert.c | 481 | ||||
-rw-r--r-- | source/components/namespace/nspredef.c | 154 | ||||
-rw-r--r-- | source/components/namespace/nsprepkg.c | 11 | ||||
-rw-r--r-- | source/components/namespace/nsrepair.c | 392 | ||||
-rw-r--r-- | source/components/namespace/nsrepair2.c | 8 | ||||
-rw-r--r-- | source/components/namespace/nsutils.c | 8 |
6 files changed, 702 insertions, 352 deletions
diff --git a/source/components/namespace/nsconvert.c b/source/components/namespace/nsconvert.c new file mode 100644 index 000000000000..e3ff375f2536 --- /dev/null +++ b/source/components/namespace/nsconvert.c @@ -0,0 +1,481 @@ +/****************************************************************************** + * + * Module Name: nsconvert - Object conversions for objects returned by + * predefined methods + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2013, Intel Corp. + * 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. + */ + +#define __NSCONVERT_C__ + +#include "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: AcpiNsConvertToInteger + * + * PARAMETERS: OriginalObject - Object to be converted + * ReturnObject - 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 +AcpiNsConvertToInteger ( + ACPI_OPERAND_OBJECT *OriginalObject, + ACPI_OPERAND_OBJECT **ReturnObject) +{ + ACPI_OPERAND_OBJECT *NewObject; + ACPI_STATUS Status; + UINT64 Value = 0; + UINT32 i; + + + switch (OriginalObject->Common.Type) + { + case ACPI_TYPE_STRING: + + /* String-to-Integer conversion */ + + Status = AcpiUtStrtoul64 (OriginalObject->String.Pointer, + ACPI_ANY_BASE, &Value); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + break; + + case ACPI_TYPE_BUFFER: + + /* Buffer-to-Integer conversion. Max buffer size is 64 bits. */ + + if (OriginalObject->Buffer.Length > 8) + { + return (AE_AML_OPERAND_TYPE); + } + + /* Extract each buffer byte to create the integer */ + + for (i = 0; i < OriginalObject->Buffer.Length; i++) + { + Value |= ((UINT64) OriginalObject->Buffer.Pointer[i] << (i * 8)); + } + break; + + default: + return (AE_AML_OPERAND_TYPE); + } + + NewObject = AcpiUtCreateIntegerObject (Value); + if (!NewObject) + { + return (AE_NO_MEMORY); + } + + *ReturnObject = NewObject; + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiNsConvertToString + * + * PARAMETERS: OriginalObject - Object to be converted + * ReturnObject - 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 +AcpiNsConvertToString ( + ACPI_OPERAND_OBJECT *OriginalObject, + ACPI_OPERAND_OBJECT **ReturnObject) +{ + ACPI_OPERAND_OBJECT *NewObject; + ACPI_SIZE Length; + ACPI_STATUS Status; + + + switch (OriginalObject->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 (OriginalObject->Integer.Value == 0) + { + /* Allocate a new NULL string object */ + + NewObject = AcpiUtCreateStringObject (0); + if (!NewObject) + { + return (AE_NO_MEMORY); + } + } + else + { + Status = AcpiExConvertToString (OriginalObject, &NewObject, + ACPI_IMPLICIT_CONVERT_HEX); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + } + break; + + case ACPI_TYPE_BUFFER: + /* + * Buffer-to-String conversion. Use a ToString + * 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 < OriginalObject->Buffer.Length) && + (OriginalObject->Buffer.Pointer[Length])) + { + Length++; + } + + /* Allocate a new string object */ + + NewObject = AcpiUtCreateStringObject (Length); + if (!NewObject) + { + return (AE_NO_MEMORY); + } + + /* + * Copy the raw buffer data with no transform. String is already NULL + * terminated at Length+1. + */ + ACPI_MEMCPY (NewObject->String.Pointer, + OriginalObject->Buffer.Pointer, Length); + break; + + default: + return (AE_AML_OPERAND_TYPE); + } + + *ReturnObject = NewObject; + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiNsConvertToBuffer + * + * PARAMETERS: OriginalObject - Object to be converted + * ReturnObject - 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 +AcpiNsConvertToBuffer ( + ACPI_OPERAND_OBJECT *OriginalObject, + ACPI_OPERAND_OBJECT **ReturnObject) +{ + ACPI_OPERAND_OBJECT *NewObject; + ACPI_STATUS Status; + ACPI_OPERAND_OBJECT **Elements; + UINT32 *DwordBuffer; + UINT32 Count; + UINT32 i; + + + switch (OriginalObject->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 = AcpiExConvertToBuffer (OriginalObject, &NewObject); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + break; + + case ACPI_TYPE_STRING: + + /* String-to-Buffer conversion. Simple data copy */ + + NewObject = AcpiUtCreateBufferObject (OriginalObject->String.Length); + if (!NewObject) + { + return (AE_NO_MEMORY); + } + + ACPI_MEMCPY (NewObject->Buffer.Pointer, + OriginalObject->String.Pointer, OriginalObject->String.Length); + 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 = OriginalObject->Package.Elements; + Count = OriginalObject->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 */ + + NewObject = AcpiUtCreateBufferObject (ACPI_MUL_4 (Count)); + if (!NewObject) + { + return (AE_NO_MEMORY); + } + + /* Copy the package elements (integers) to the buffer as DWORDs */ + + Elements = OriginalObject->Package.Elements; + DwordBuffer = ACPI_CAST_PTR (UINT32, NewObject->Buffer.Pointer); + + for (i = 0; i < Count; i++) + { + *DwordBuffer = (UINT32) (*Elements)->Integer.Value; + DwordBuffer++; + Elements++; + } + break; + + default: + return (AE_AML_OPERAND_TYPE); + } + + *ReturnObject = NewObject; + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiNsConvertToUnicode + * + * PARAMETERS: OriginalObject - ASCII String Object to be converted + * ReturnObject - 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 +AcpiNsConvertToUnicode ( + ACPI_OPERAND_OBJECT *OriginalObject, + ACPI_OPERAND_OBJECT **ReturnObject) +{ + ACPI_OPERAND_OBJECT *NewObject; + char *AsciiString; + UINT16 *UnicodeBuffer; + UINT32 UnicodeLength; + UINT32 i; + + + if (!OriginalObject) + { + return (AE_OK); + } + + /* If a Buffer was returned, it must be at least two bytes long */ + + if (OriginalObject->Common.Type == ACPI_TYPE_BUFFER) + { + if (OriginalObject->Buffer.Length < 2) + { + return (AE_AML_OPERAND_VALUE); + } + + *ReturnObject = NULL; + return (AE_OK); + } + + /* + * The original object is an ASCII string. Convert this string to + * a unicode buffer. + */ + AsciiString = OriginalObject->String.Pointer; + UnicodeLength = (OriginalObject->String.Length * 2) + 2; + + /* Create a new buffer object for the Unicode data */ + + NewObject = AcpiUtCreateBufferObject (UnicodeLength); + if (!NewObject) + { + return (AE_NO_MEMORY); + } + + UnicodeBuffer = ACPI_CAST_PTR (UINT16, NewObject->Buffer.Pointer); + + /* Convert ASCII to Unicode */ + + for (i = 0; i < OriginalObject->String.Length; i++) + { + UnicodeBuffer[i] = (UINT16) AsciiString[i]; + } + + *ReturnObject = NewObject; + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiNsConvertToResource + * + * PARAMETERS: OriginalObject - Object to be converted + * ReturnObject - Where the new converted object is returned + * + * RETURN: Status. AE_OK if conversion was successful + * + * DESCRIPTION: Attempt to convert a Integer object to a ResourceTemplate + * Buffer. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiNsConvertToResource ( + ACPI_OPERAND_OBJECT *OriginalObject, + ACPI_OPERAND_OBJECT **ReturnObject) +{ + ACPI_OPERAND_OBJECT *NewObject; + UINT8 *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 EndTag + * resource descriptor. + */ + if (OriginalObject) + { + switch (OriginalObject->Common.Type) + { + case ACPI_TYPE_INTEGER: + + /* We can only repair an Integer==0 */ + + if (OriginalObject->Integer.Value) + { + return (AE_AML_OPERAND_TYPE); + } + break; + + case ACPI_TYPE_BUFFER: + + if (OriginalObject->Buffer.Length) + { + /* Additional checks can be added in the future */ + + *ReturnObject = NULL; + return (AE_OK); + } + break; + + case ACPI_TYPE_STRING: + default: + + return (AE_AML_OPERAND_TYPE); + } + } + + /* Create the new buffer object for the resource descriptor */ + + NewObject = AcpiUtCreateBufferObject (2); + if (!NewObject) + { + return (AE_NO_MEMORY); + } + + Buffer = ACPI_CAST_PTR (UINT8, NewObject->Buffer.Pointer); + + /* Initialize the Buffer with a single EndTag descriptor */ + + Buffer[0] = (ACPI_RESOURCE_NAME_END_TAG | ASL_RDESC_END_TAG_SIZE); + Buffer[1] = 0x00; + + *ReturnObject = NewObject; + return (AE_OK); +} diff --git a/source/components/namespace/nspredef.c b/source/components/namespace/nspredef.c index b588bb638fd8..f12bc155ac06 100644 --- a/source/components/namespace/nspredef.c +++ b/source/components/namespace/nspredef.c @@ -87,6 +87,11 @@ AcpiNsGetExpectedTypes ( char *Buffer, UINT32 ExpectedBtypes); +static UINT32 +AcpiNsGetBitmappedType ( + ACPI_OPERAND_OBJECT *ReturnObject); + + /* * Names for the types that can be returned by the predefined objects. * Used for warning messages. Must be in the same order as the ACPI_RTYPEs @@ -124,7 +129,6 @@ AcpiNsCheckPredefinedNames ( ACPI_STATUS ReturnStatus, ACPI_OPERAND_OBJECT **ReturnObjectPtr) { - ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; ACPI_STATUS Status = AE_OK; const ACPI_PREDEFINED_INFO *Predefined; char *Pathname; @@ -167,26 +171,6 @@ AcpiNsCheckPredefinedNames ( } /* - * If there is no return value, check if we require a return value for - * this predefined name. Either one return value is expected, or none, - * for both methods and other objects. - * - * Exit now if there is no return object. Warning if one was expected. - */ - if (!ReturnObject) - { - if ((Predefined->Info.ExpectedBtypes) && - (!(Predefined->Info.ExpectedBtypes & ACPI_RTYPE_NONE))) - { - ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, - "Missing expected return value")); - - Status = AE_AML_NO_RETURN_VALUE; - } - goto Cleanup; - } - - /* * Return value validation and possible repair. * * 1) Don't perform return value validation/repair if this feature @@ -447,30 +431,13 @@ AcpiNsCheckObjectType ( { ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; ACPI_STATUS Status = AE_OK; - UINT32 ReturnBtype; char TypeBuffer[48]; /* Room for 5 types */ - /* - * If we get a NULL ReturnObject here, it is a NULL package element. - * Since all extraneous NULL package elements were removed earlier by a - * call to AcpiNsRemoveNullElements, this is an unexpected NULL element. - * We will attempt to repair it. - */ - if (!ReturnObject) - { - Status = AcpiNsRepairNullElement (Data, ExpectedBtypes, - PackageIndex, ReturnObjectPtr); - if (ACPI_SUCCESS (Status)) - { - return (AE_OK); /* Repair was successful */ - } - goto TypeErrorExit; - } - /* A Namespace node should not get here, but make sure */ - if (ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED) + if (ReturnObject && + ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED) { ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, "Invalid return type - Found a Namespace node [%4.4s] type %s", @@ -487,56 +454,26 @@ AcpiNsCheckObjectType ( * from all of the predefined names (including elements of returned * packages) */ - switch (ReturnObject->Common.Type) + Data->ReturnBtype = AcpiNsGetBitmappedType (ReturnObject); + if (Data->ReturnBtype == ACPI_RTYPE_ANY) { - case ACPI_TYPE_INTEGER: - ReturnBtype = ACPI_RTYPE_INTEGER; - break; - - case ACPI_TYPE_BUFFER: - ReturnBtype = ACPI_RTYPE_BUFFER; - break; - - case ACPI_TYPE_STRING: - ReturnBtype = ACPI_RTYPE_STRING; - break; - - case ACPI_TYPE_PACKAGE: - ReturnBtype = ACPI_RTYPE_PACKAGE; - break; - - case ACPI_TYPE_LOCAL_REFERENCE: - ReturnBtype = ACPI_RTYPE_REFERENCE; - break; - - default: /* Not one of the supported objects, must be incorrect */ - goto TypeErrorExit; } - /* Is the object one of the expected types? */ + /* For reference objects, check that the reference type is correct */ - if (ReturnBtype & ExpectedBtypes) + if ((Data->ReturnBtype & ExpectedBtypes) == ACPI_RTYPE_REFERENCE) { - /* For reference objects, check that the reference type is correct */ - - if (ReturnObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) - { - Status = AcpiNsCheckReference (Data, ReturnObject); - } - + Status = AcpiNsCheckReference (Data, ReturnObject); return (Status); } - /* Type mismatch -- attempt repair of the returned object */ + /* Attempt simple repair of the returned object if necessary */ - Status = AcpiNsRepairObject (Data, ExpectedBtypes, + Status = AcpiNsSimpleRepair (Data, ExpectedBtypes, PackageIndex, ReturnObjectPtr); - if (ACPI_SUCCESS (Status)) - { - return (AE_OK); /* Repair was successful */ - } + return (Status); TypeErrorExit: @@ -606,6 +543,67 @@ AcpiNsCheckReference ( /******************************************************************************* * + * FUNCTION: AcpiNsGetBitmappedType + * + * PARAMETERS: ReturnObject - Object returned from method/obj evaluation + * + * RETURN: Object return type. ACPI_RTYPE_ANY indicates that the object + * type is not supported. ACPI_RTYPE_NONE indicates that no + * object was returned (ReturnObject is NULL). + * + * DESCRIPTION: Convert object type into a bitmapped object return type. + * + ******************************************************************************/ + +static UINT32 +AcpiNsGetBitmappedType ( + ACPI_OPERAND_OBJECT *ReturnObject) +{ + UINT32 ReturnBtype; + + + if (!ReturnObject) + { + return (ACPI_RTYPE_NONE); + } + + /* Map ACPI_OBJECT_TYPE to internal bitmapped type */ + + switch (ReturnObject->Common.Type) + { + case ACPI_TYPE_INTEGER: + ReturnBtype = ACPI_RTYPE_INTEGER; + break; + + case ACPI_TYPE_BUFFER: + ReturnBtype = ACPI_RTYPE_BUFFER; + break; + + case ACPI_TYPE_STRING: + ReturnBtype = ACPI_RTYPE_STRING; + break; + + case ACPI_TYPE_PACKAGE: + ReturnBtype = ACPI_RTYPE_PACKAGE; + break; + + case ACPI_TYPE_LOCAL_REFERENCE: + ReturnBtype = ACPI_RTYPE_REFERENCE; + break; + + default: + /* Not one of the supported objects, must be incorrect */ + + ReturnBtype = ACPI_RTYPE_ANY; + break; + } + + return (ReturnBtype); +} + + +/******************************************************************************* + * * FUNCTION: AcpiNsGetExpectedTypes * * PARAMETERS: Buffer - Pointer to where the string is returned diff --git a/source/components/namespace/nsprepkg.c b/source/components/namespace/nsprepkg.c index 9b10a4076f57..d18205c83fd7 100644 --- a/source/components/namespace/nsprepkg.c +++ b/source/components/namespace/nsprepkg.c @@ -122,10 +122,17 @@ AcpiNsCheckPackage ( Elements = ReturnObject->Package.Elements; Count = ReturnObject->Package.Count; - /* The package must have at least one element, else invalid */ - + /* + * Most packages must have at least one element. The only exception + * is the variable-length package (ACPI_PTYPE1_VAR). + */ if (!Count) { + if (Package->RetInfo.Type == ACPI_PTYPE1_VAR) + { + return (AE_OK); + } + ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, "Return Package has no elements (empty)")); diff --git a/source/components/namespace/nsrepair.c b/source/components/namespace/nsrepair.c index 7b170d0b8264..e06502811d33 100644 --- a/source/components/namespace/nsrepair.c +++ b/source/components/namespace/nsrepair.c @@ -48,6 +48,7 @@ #include "acnamesp.h" #include "acinterp.h" #include "acpredef.h" +#include "amlresrc.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME ("nsrepair") @@ -74,6 +75,11 @@ * Buffer -> String * Buffer -> Package of Integers * Package -> Package of one Package + * + * Additional conversions that are available: + * Convert a null return or zero return value to an EndTag descriptor + * Convert an ASCII string to a Unicode buffer + * * An incorrect standalone object is wrapped with required outer package * * Additional possible repairs: @@ -84,25 +90,46 @@ /* Local prototypes */ -static ACPI_STATUS -AcpiNsConvertToInteger ( - ACPI_OPERAND_OBJECT *OriginalObject, - ACPI_OPERAND_OBJECT **ReturnObject); +static const ACPI_SIMPLE_REPAIR_INFO * +AcpiNsMatchSimpleRepair ( + ACPI_NAMESPACE_NODE *Node, + UINT32 ReturnBtype, + UINT32 PackageIndex); -static ACPI_STATUS -AcpiNsConvertToString ( - ACPI_OPERAND_OBJECT *OriginalObject, - ACPI_OPERAND_OBJECT **ReturnObject); -static ACPI_STATUS -AcpiNsConvertToBuffer ( - ACPI_OPERAND_OBJECT *OriginalObject, - ACPI_OPERAND_OBJECT **ReturnObject); +/* + * Special but simple repairs for some names. + * + * 2nd argument: Unexpected types that can be repaired + */ +static const ACPI_SIMPLE_REPAIR_INFO AcpiObjectRepairInfo[] = +{ + /* Resource descriptor conversions */ + + { "_CRS", ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | ACPI_RTYPE_NONE, + ACPI_NOT_PACKAGE_ELEMENT, + AcpiNsConvertToResource }, + { "_DMA", ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | ACPI_RTYPE_NONE, + ACPI_NOT_PACKAGE_ELEMENT, + AcpiNsConvertToResource }, + { "_PRS", ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | ACPI_RTYPE_NONE, + ACPI_NOT_PACKAGE_ELEMENT, + AcpiNsConvertToResource }, + + /* Unicode conversions */ + + { "_MLS", ACPI_RTYPE_STRING, 1, + AcpiNsConvertToUnicode }, + { "_STR", ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER, + ACPI_NOT_PACKAGE_ELEMENT, + AcpiNsConvertToUnicode }, + { {0,0,0,0}, 0, 0, NULL } /* Table terminator */ +}; /******************************************************************************* * - * FUNCTION: AcpiNsRepairObject + * FUNCTION: AcpiNsSimpleRepair * * PARAMETERS: Data - Pointer to validation data structure * ExpectedBtypes - Object types expected @@ -120,19 +147,58 @@ AcpiNsConvertToBuffer ( ******************************************************************************/ ACPI_STATUS -AcpiNsRepairObject ( +AcpiNsSimpleRepair ( ACPI_PREDEFINED_DATA *Data, UINT32 ExpectedBtypes, UINT32 PackageIndex, ACPI_OPERAND_OBJECT **ReturnObjectPtr) { ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; - ACPI_OPERAND_OBJECT *NewObject; + ACPI_OPERAND_OBJECT *NewObject = NULL; ACPI_STATUS Status; + const ACPI_SIMPLE_REPAIR_INFO *Predefined; + + + ACPI_FUNCTION_NAME (NsSimpleRepair); - ACPI_FUNCTION_NAME (NsRepairObject); + /* + * Special repairs for certain names that are in the repair table. + * Check if this name is in the list of repairable names. + */ + Predefined = AcpiNsMatchSimpleRepair (Data->Node, + Data->ReturnBtype, PackageIndex); + if (Predefined) + { + if (!ReturnObject) + { + ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, + ACPI_WARN_ALWAYS, "Missing expected return value")); + } + + Status = Predefined->ObjectConverter (ReturnObject, &NewObject); + if (ACPI_FAILURE (Status)) + { + /* A fatal error occurred during a conversion */ + + ACPI_EXCEPTION ((AE_INFO, Status, + "During return object analysis")); + return (Status); + } + if (NewObject) + { + goto ObjectRepaired; + } + } + /* + * Do not perform simple object repair unless the return type is not + * expected. + */ + if (Data->ReturnBtype & ExpectedBtypes) + { + return (AE_OK); + } /* * At this point, we know that the type of the returned object was not @@ -140,6 +206,25 @@ AcpiNsRepairObject ( * repair the object by converting it to one of the expected object * types for this predefined name. */ + + /* + * If there is no return value, check if we require a return value for + * this predefined name. Either one return value is expected, or none, + * for both methods and other objects. + * + * Exit now if there is no return object. Warning if one was expected. + */ + if (!ReturnObject) + { + if (ExpectedBtypes && (!(ExpectedBtypes & ACPI_RTYPE_NONE))) + { + ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, + ACPI_WARN_ALWAYS, "Missing expected return value")); + + return (AE_AML_NO_RETURN_VALUE); + } + } + if (ExpectedBtypes & ACPI_RTYPE_INTEGER) { Status = AcpiNsConvertToInteger (ReturnObject, &NewObject); @@ -240,273 +325,52 @@ ObjectRepaired: } -/******************************************************************************* - * - * FUNCTION: AcpiNsConvertToInteger - * - * PARAMETERS: OriginalObject - Object to be converted - * ReturnObject - 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 -AcpiNsConvertToInteger ( - ACPI_OPERAND_OBJECT *OriginalObject, - ACPI_OPERAND_OBJECT **ReturnObject) -{ - ACPI_OPERAND_OBJECT *NewObject; - ACPI_STATUS Status; - UINT64 Value = 0; - UINT32 i; - - - switch (OriginalObject->Common.Type) - { - case ACPI_TYPE_STRING: - - /* String-to-Integer conversion */ - - Status = AcpiUtStrtoul64 (OriginalObject->String.Pointer, - ACPI_ANY_BASE, &Value); - if (ACPI_FAILURE (Status)) - { - return (Status); - } - break; - - case ACPI_TYPE_BUFFER: - - /* Buffer-to-Integer conversion. Max buffer size is 64 bits. */ - - if (OriginalObject->Buffer.Length > 8) - { - return (AE_AML_OPERAND_TYPE); - } - - /* Extract each buffer byte to create the integer */ - - for (i = 0; i < OriginalObject->Buffer.Length; i++) - { - Value |= ((UINT64) OriginalObject->Buffer.Pointer[i] << (i * 8)); - } - break; - - default: - return (AE_AML_OPERAND_TYPE); - } - - NewObject = AcpiUtCreateIntegerObject (Value); - if (!NewObject) - { - return (AE_NO_MEMORY); - } - - *ReturnObject = NewObject; - return (AE_OK); -} - - -/******************************************************************************* +/****************************************************************************** * - * FUNCTION: AcpiNsConvertToString + * FUNCTION: AcpiNsMatchSimpleRepair * - * PARAMETERS: OriginalObject - Object to be converted - * ReturnObject - Where the new converted object is returned + * PARAMETERS: Node - Namespace node for the method/object + * ReturnBtype - Object type that was returned + * PackageIndex - Index of object within parent package (if + * applicable - ACPI_NOT_PACKAGE_ELEMENT + * otherwise) * - * RETURN: Status. AE_OK if conversion was successful. + * RETURN: Pointer to entry in repair table. NULL indicates not found. * - * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String. + * DESCRIPTION: Check an object name against the repairable object list. * - ******************************************************************************/ + *****************************************************************************/ -static ACPI_STATUS -AcpiNsConvertToString ( - ACPI_OPERAND_OBJECT *OriginalObject, - ACPI_OPERAND_OBJECT **ReturnObject) +static const ACPI_SIMPLE_REPAIR_INFO * +AcpiNsMatchSimpleRepair ( + ACPI_NAMESPACE_NODE *Node, + UINT32 ReturnBtype, + UINT32 PackageIndex) { - ACPI_OPERAND_OBJECT *NewObject; - ACPI_SIZE Length; - ACPI_STATUS Status; - - - switch (OriginalObject->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 (OriginalObject->Integer.Value == 0) - { - /* Allocate a new NULL string object */ - - NewObject = AcpiUtCreateStringObject (0); - if (!NewObject) - { - return (AE_NO_MEMORY); - } - } - else - { - Status = AcpiExConvertToString (OriginalObject, &NewObject, - ACPI_IMPLICIT_CONVERT_HEX); - if (ACPI_FAILURE (Status)) - { - return (Status); - } - } - break; - - case ACPI_TYPE_BUFFER: - /* - * Buffer-to-String conversion. Use a ToString - * 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 < OriginalObject->Buffer.Length) && - (OriginalObject->Buffer.Pointer[Length])) - { - Length++; - } - - /* Allocate a new string object */ - - NewObject = AcpiUtCreateStringObject (Length); - if (!NewObject) - { - return (AE_NO_MEMORY); - } - - /* - * Copy the raw buffer data with no transform. String is already NULL - * terminated at Length+1. - */ - ACPI_MEMCPY (NewObject->String.Pointer, - OriginalObject->Buffer.Pointer, Length); - break; - - default: - return (AE_AML_OPERAND_TYPE); - } - - *ReturnObject = NewObject; - return (AE_OK); -} - + const ACPI_SIMPLE_REPAIR_INFO *ThisName; -/******************************************************************************* - * - * FUNCTION: AcpiNsConvertToBuffer - * - * PARAMETERS: OriginalObject - Object to be converted - * ReturnObject - 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. - * - ******************************************************************************/ - -static ACPI_STATUS -AcpiNsConvertToBuffer ( - ACPI_OPERAND_OBJECT *OriginalObject, - ACPI_OPERAND_OBJECT **ReturnObject) -{ - ACPI_OPERAND_OBJECT *NewObject; - ACPI_STATUS Status; - ACPI_OPERAND_OBJECT **Elements; - UINT32 *DwordBuffer; - UINT32 Count; - UINT32 i; + /* Search info table for a repairable predefined method/object name */ - switch (OriginalObject->Common.Type) + ThisName = AcpiObjectRepairInfo; + while (ThisName->ObjectConverter) { - 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 = AcpiExConvertToBuffer (OriginalObject, &NewObject); - if (ACPI_FAILURE (Status)) - { - return (Status); - } - break; - - case ACPI_TYPE_STRING: - - /* String-to-Buffer conversion. Simple data copy */ - - NewObject = AcpiUtCreateBufferObject (OriginalObject->String.Length); - if (!NewObject) + if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Name)) { - return (AE_NO_MEMORY); - } - - ACPI_MEMCPY (NewObject->Buffer.Pointer, - OriginalObject->String.Pointer, OriginalObject->String.Length); - 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 = OriginalObject->Package.Elements; - Count = OriginalObject->Package.Count; + /* Check if we can actually repair this name/type combination */ - for (i = 0; i < Count; i++) - { - if ((!*Elements) || - ((*Elements)->Common.Type != ACPI_TYPE_INTEGER)) + if ((ReturnBtype & ThisName->UnexpectedBtypes) && + (PackageIndex == ThisName->PackageIndex)) { - return (AE_AML_OPERAND_TYPE); + return (ThisName); } - Elements++; - } - - /* Create the new buffer object to replace the Package */ - NewObject = AcpiUtCreateBufferObject (ACPI_MUL_4 (Count)); - if (!NewObject) - { - return (AE_NO_MEMORY); - } - - /* Copy the package elements (integers) to the buffer as DWORDs */ - - Elements = OriginalObject->Package.Elements; - DwordBuffer = ACPI_CAST_PTR (UINT32, NewObject->Buffer.Pointer); - - for (i = 0; i < Count; i++) - { - *DwordBuffer = (UINT32) (*Elements)->Integer.Value; - DwordBuffer++; - Elements++; + return (NULL); } - break; - - default: - return (AE_AML_OPERAND_TYPE); + ThisName++; } - *ReturnObject = NewObject; - return (AE_OK); + return (NULL); /* Name was not found in the repair table */ } diff --git a/source/components/namespace/nsrepair2.c b/source/components/namespace/nsrepair2.c index 5650e338746e..b81c0dd0d52e 100644 --- a/source/components/namespace/nsrepair2.c +++ b/source/components/namespace/nsrepair2.c @@ -72,7 +72,7 @@ typedef struct acpi_repair_info /* Local prototypes */ static const ACPI_REPAIR_INFO * -AcpiNsMatchRepairableName ( +AcpiNsMatchComplexRepair ( ACPI_NAMESPACE_NODE *Node); static ACPI_STATUS @@ -197,7 +197,7 @@ AcpiNsComplexRepairs ( /* Check if this name is in the list of repairable names */ - Predefined = AcpiNsMatchRepairableName (Node); + Predefined = AcpiNsMatchComplexRepair (Node); if (!Predefined) { return (ValidateStatus); @@ -210,7 +210,7 @@ AcpiNsComplexRepairs ( /****************************************************************************** * - * FUNCTION: AcpiNsMatchRepairableName + * FUNCTION: AcpiNsMatchComplexRepair * * PARAMETERS: Node - Namespace node for the method/object * @@ -221,7 +221,7 @@ AcpiNsComplexRepairs ( *****************************************************************************/ static const ACPI_REPAIR_INFO * -AcpiNsMatchRepairableName ( +AcpiNsMatchComplexRepair ( ACPI_NAMESPACE_NODE *Node) { const ACPI_REPAIR_INFO *ThisName; diff --git a/source/components/namespace/nsutils.c b/source/components/namespace/nsutils.c index 7002200e3188..16a6bdb96444 100644 --- a/source/components/namespace/nsutils.c +++ b/source/components/namespace/nsutils.c @@ -128,10 +128,10 @@ AcpiNsGetType ( if (!Node) { ACPI_WARNING ((AE_INFO, "Null Node parameter")); - return_VALUE (ACPI_TYPE_ANY); + return_UINT8 (ACPI_TYPE_ANY); } - return_VALUE (Node->Type); + return_UINT8 (Node->Type); } @@ -160,10 +160,10 @@ AcpiNsLocal ( /* Type code out of range */ ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type)); - return_VALUE (ACPI_NS_NORMAL); + return_UINT32 (ACPI_NS_NORMAL); } - return_VALUE (AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL); + return_UINT32 (AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL); } |