Merge ACPICA 20091214.

This commit is contained in:
Jung-uk Kim 2009-12-14 22:24:04 +00:00
commit 572c8255e6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=200553
31 changed files with 892 additions and 363 deletions

View File

@ -1,3 +1,70 @@
----------------------------------------
14 December 2009. Summary of changes for version 20091214:
This release is available at www.acpica.org/downloads
1) ACPI CA Core Subsystem:
Enhanced automatic data type conversions for predefined name repairs. This
change expands the automatic repairs/conversions for predefined name return
values to make Integers, Strings, and Buffers fully interchangeable. Also, a
Buffer can be converted to a Package of Integers if necessary. The nsrepair.c
module was completely restructured. Lin Ming, Bob Moore.
Implemented automatic removal of null package elements during predefined name
repairs. This change will automatically remove embedded and trailing NULL
package elements from returned package objects that are defined to contain a
variable number of sub-packages. The driver is then presented with a package
with no null elements to deal with. ACPICA BZ 819.
Implemented a repair for the predefined _FDE and _GTM names. The expected
return value for both names is a Buffer of 5 DWORDs. This repair fixes two
possible problems (both seen in the field), where a package of integers is
returned, or a buffer of BYTEs is returned. With assistance from Jung-uk Kim.
Implemented additional module-level code support. This change will properly
execute module-level code that is not at the root of the namespace (under a
Device object, etc.). Now executes the code within the current scope instead
of the root. ACPICA BZ 762. Lin Ming.
Fixed possible mutex acquisition errors when running _REG methods. Fixes a
problem where mutex errors can occur when running a _REG method that is in
the same scope as a method-defined operation region or an operation region
under a module-level IF block. This type of code is rare, so the problem has
not been seen before. ACPICA BZ 826. Lin Ming, Bob Moore.
Fixed a possible memory leak during module-level code execution. An object
could be leaked for each block of executed module-level code if the
interpreter slack mode is enabled This change deletes any implicitly returned
object from the module-level code block. Lin Ming.
Removed messages for successful predefined repair(s). The repair mechanism
was considered too wordy. Now, messages are only unconditionally emitted if
the return object cannot be repaired. Existing messages for successful
repairs were converted to ACPI_DEBUG_PRINT messages for now. ACPICA BZ 827.
Example Code and Data Size: These are the sizes for the OS-independent
acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
debug version of the code includes the debug output trace mechanism and has a
much larger code and data size.
Previous Release:
Non-Debug Version: 86.6K Code, 18.2K Data, 104.8K Total
Debug Version: 162.7K Code, 50.8K Data, 213.5K Total
Current Release:
Non-Debug Version: 87.0K Code, 18.0K Data, 105.0K Total
Debug Version: 163.4K Code, 50.8K Data, 214.2K Total
2) iASL Compiler/Disassembler and Tools:
iASL: Fixed a regression introduced in 20091112 where intermediate .SRC files
were no longer automatically removed at the termination of the compile.
acpiexec: Implemented the -f option to specify default region fill value.
This option specifies the value used to initialize buffers that simulate
operation regions. Default value is zero. Useful for debugging problems that
depend on a specific initial value for a region or field.
----------------------------------------
12 November 2009. Summary of changes for version 20091112:

View File

@ -895,20 +895,6 @@ CmCleanupAndExit (
10) / Gbl_NsLookupCount);
}
/*
* TBD: SourceOutput should be .TMP, then rename if we want to keep it?
*/
if (!Gbl_SourceOutputFlag)
{
remove (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
}
/* Delete AML file if there are errors */
if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors))
{
remove (Gbl_Files[ASL_FILE_AML_OUTPUT].Filename);
}
if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
{
@ -923,6 +909,27 @@ CmCleanupAndExit (
{
FlCloseFile (i);
}
/* Delete AML file if there are errors */
if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors))
{
remove (Gbl_Files[ASL_FILE_AML_OUTPUT].Filename);
}
/*
* Delete intermediate ("combined") source file (if -ls flag not set)
*
* TBD: SourceOutput should be .TMP, then rename if we want to keep it?
*/
if (!Gbl_SourceOutputFlag)
{
if (remove (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename))
{
printf ("Could not remove SRC file, %s\n",
Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
}
}
}

View File

@ -275,6 +275,10 @@ AcpiDbDumpExternalObject (
AcpiOsPrintf ("[Buffer] Length %.2X = ", ObjDesc->Buffer.Length);
if (ObjDesc->Buffer.Length)
{
if (ObjDesc->Buffer.Length > 16)
{
AcpiOsPrintf ("\n");
}
AcpiUtDumpBuffer (ACPI_CAST_PTR (UINT8, ObjDesc->Buffer.Pointer),
ObjDesc->Buffer.Length, DB_DWORD_DISPLAY, _COMPONENT);
}

View File

@ -160,7 +160,6 @@ AcpiDmBlockType (
ACPI_PARSE_OBJECT *Op);
/*******************************************************************************
*
* FUNCTION: AcpiDmDisassemble

View File

@ -519,7 +519,7 @@ AcpiDsCallControlMethod (
if (ObjDesc->Method.MethodFlags & AML_METHOD_INTERNAL_ONLY)
{
Status = ObjDesc->Method.Implementation (NextWalkState);
Status = ObjDesc->Method.Extra.Implementation (NextWalkState);
if (Status == AE_OK)
{
Status = AE_CTRL_TERMINATE;

View File

@ -296,18 +296,19 @@ AcpiDsLoad1BeginOp (
case ACPI_TYPE_BUFFER:
/*
* These types we will allow, but we will change the type. This
* enables some existing code of the form:
* These types we will allow, but we will change the type.
* This enables some existing code of the form:
*
* Name (DEB, 0)
* Scope (DEB) { ... }
*
* Note: silently change the type here. On the second pass, we will report
* a warning
* Note: silently change the type here. On the second pass,
* we will report a warning
*/
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n",
Path, AcpiUtGetTypeName (Node->Type)));
"Type override - [%4.4s] had invalid type (%s) "
"for Scope operator, changed to type ANY\n",
AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type)));
Node->Type = ACPI_TYPE_ANY;
WalkState->ScopeInfo->Common.Value = ACPI_TYPE_ANY;
@ -318,8 +319,9 @@ AcpiDsLoad1BeginOp (
/* All other types are an error */
ACPI_ERROR ((AE_INFO,
"Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)",
AcpiUtGetTypeName (Node->Type), Path));
"Invalid type (%s) for target of "
"Scope operator [%4.4s] (Cannot override)",
AcpiUtGetTypeName (Node->Type), AcpiUtGetNodeName (Node)));
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
}
@ -794,15 +796,16 @@ AcpiDsLoad2BeginOp (
case ACPI_TYPE_BUFFER:
/*
* These types we will allow, but we will change the type. This
* enables some existing code of the form:
* These types we will allow, but we will change the type.
* This enables some existing code of the form:
*
* Name (DEB, 0)
* Scope (DEB) { ... }
*/
ACPI_WARNING ((AE_INFO,
"Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)",
BufferPtr, AcpiUtGetTypeName (Node->Type)));
"Type override - [%4.4s] had invalid type (%s) "
"for Scope operator, changed to type ANY\n",
AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type)));
Node->Type = ACPI_TYPE_ANY;
WalkState->ScopeInfo->Common.Value = ACPI_TYPE_ANY;
@ -813,8 +816,9 @@ AcpiDsLoad2BeginOp (
/* All other types are an error */
ACPI_ERROR ((AE_INFO,
"Invalid type (%s) for target of Scope operator [%4.4s]",
AcpiUtGetTypeName (Node->Type), BufferPtr));
"Invalid type (%s) for target of "
"Scope operator [%4.4s] (Cannot override)",
AcpiUtGetTypeName (Node->Type), AcpiUtGetNodeName (Node)));
return (AE_AML_OPERAND_TYPE);
}
@ -1154,33 +1158,40 @@ AcpiDsLoad2EndOp (
}
/*
* If we are executing a method, initialize the region
* The OpRegion is not fully parsed at this time. The only valid
* argument is the SpaceId. (We must save the address of the
* AML of the address and length operands)
*
* If we have a valid region, initialize it. The namespace is
* unlocked at this point.
*
* Need to unlock interpreter if it is locked (if we are running
* a control method), in order to allow _REG methods to be run
* during AcpiEvInitializeRegion.
*/
if (WalkState->MethodNode)
{
/*
* Executing a method: initialize the region and unlock
* the interpreter
*/
Status = AcpiExCreateRegion (Op->Named.Data, Op->Named.Length,
RegionSpace, WalkState);
if (ACPI_FAILURE (Status))
{
return (Status);
}
AcpiExExitInterpreter ();
}
/*
* The OpRegion is not fully parsed at this time. Only valid
* argument is the SpaceId. (We must save the address of the
* AML of the address and length operands)
*/
/*
* If we have a valid region, initialize it
* Namespace is NOT locked at this point.
*
* TBD: need to unlock interpreter if it is locked, in order
* to allow _REG methods to be run.
*/
Status = AcpiEvInitializeRegion (AcpiNsGetAttachedObject (Node),
FALSE);
if (WalkState->MethodNode)
{
AcpiExEnterInterpreter ();
}
if (ACPI_FAILURE (Status))
{
/*

View File

@ -845,7 +845,7 @@ AcpiEvInstallHandler (
/* Convert and validate the device handle */
Node = AcpiNsMapHandleToNode (ObjHandle);
Node = AcpiNsValidateHandle (ObjHandle);
if (!Node)
{
return (AE_BAD_PARAMETER);
@ -1243,7 +1243,7 @@ AcpiEvRegRun (
/* Convert and validate the device handle */
Node = AcpiNsMapHandleToNode (ObjHandle);
Node = AcpiNsValidateHandle (ObjHandle);
if (!Node)
{
return (AE_BAD_PARAMETER);

View File

@ -716,6 +716,20 @@ AcpiEvInitializeRegion (
HandlerObj = ObjDesc->ThermalZone.Handler;
break;
case ACPI_TYPE_METHOD:
/*
* If we are executing module level code, the original
* Node's object was replaced by this Method object and we
* saved the handler in the method object.
*
* See AcpiNsExecModuleCode
*/
if (ObjDesc->Method.Flags & AOPOBJ_MODULE_LEVEL)
{
HandlerObj = ObjDesc->Method.Extra.Handler;
}
break;
default:
/* Ignore other objects */
break;

View File

@ -368,7 +368,7 @@ AcpiInstallNotifyHandler (
/* Convert and validate the device handle */
Node = AcpiNsMapHandleToNode (Device);
Node = AcpiNsValidateHandle (Device);
if (!Node)
{
Status = AE_BAD_PARAMETER;
@ -555,7 +555,7 @@ AcpiRemoveNotifyHandler (
/* Convert and validate the device handle */
Node = AcpiNsMapHandleToNode (Device);
Node = AcpiNsValidateHandle (Device);
if (!Node)
{
Status = AE_BAD_PARAMETER;

View File

@ -805,7 +805,7 @@ AcpiInstallGpeBlock (
return (Status);
}
Node = AcpiNsMapHandleToNode (GpeDevice);
Node = AcpiNsValidateHandle (GpeDevice);
if (!Node)
{
Status = AE_BAD_PARAMETER;
@ -905,7 +905,7 @@ AcpiRemoveGpeBlock (
return (Status);
}
Node = AcpiNsMapHandleToNode (GpeDevice);
Node = AcpiNsValidateHandle (GpeDevice);
if (!Node)
{
Status = AE_BAD_PARAMETER;

View File

@ -171,7 +171,7 @@ AcpiInstallAddressSpaceHandler (
/* Convert and validate the device handle */
Node = AcpiNsMapHandleToNode (Device);
Node = AcpiNsValidateHandle (Device);
if (!Node)
{
Status = AE_BAD_PARAMETER;
@ -244,7 +244,7 @@ AcpiRemoveAddressSpaceHandler (
/* Convert and validate the device handle */
Node = AcpiNsMapHandleToNode (Device);
Node = AcpiNsValidateHandle (Device);
if (!Node ||
((Node->Type != ACPI_TYPE_DEVICE) &&
(Node->Type != ACPI_TYPE_PROCESSOR) &&

View File

@ -490,6 +490,15 @@ AcpiExReleaseMutex (
return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED);
}
/* Must have a valid thread ID */
if (!WalkState->Thread)
{
ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], null thread info",
AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
/*
* The Mutex is owned, but this thread must be the owner.
* Special case for Global Lock, any thread can release
@ -505,15 +514,6 @@ AcpiExReleaseMutex (
return_ACPI_STATUS (AE_AML_NOT_OWNER);
}
/* Must have a valid thread ID */
if (!WalkState->Thread)
{
ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], null thread info",
AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
/*
* The sync level of the mutex must be equal to the current sync level. In
* other words, the current level means that at least one mutex at that

View File

@ -456,6 +456,11 @@ AcpiNsComplexRepairs (
ACPI_STATUS ValidateStatus,
ACPI_OPERAND_OBJECT **ReturnObjectPtr);
void
AcpiNsRemoveNullElements (
ACPI_PREDEFINED_DATA *Data,
UINT8 PackageType,
ACPI_OPERAND_OBJECT *ObjDesc);
/*
* nssearch - Namespace searching and entry
@ -542,13 +547,9 @@ AcpiNsExternalizeName (
char **ConvertedName);
ACPI_NAMESPACE_NODE *
AcpiNsMapHandleToNode (
AcpiNsValidateHandle (
ACPI_HANDLE Handle);
ACPI_HANDLE
AcpiNsConvertEntryToHandle(
ACPI_NAMESPACE_NODE *Node);
void
AcpiNsTerminate (
void);

View File

@ -288,7 +288,12 @@ typedef struct acpi_object_method
UINT8 SyncLevel;
union acpi_operand_object *Mutex;
UINT8 *AmlStart;
ACPI_INTERNAL_METHOD Implementation;
union
{
ACPI_INTERNAL_METHOD Implementation;
union acpi_operand_object *Handler;
} Extra;
UINT32 AmlLength;
UINT8 ThreadCount;
ACPI_OWNER_ID OwnerId;

View File

@ -158,7 +158,8 @@
#define ACPI_LV_INIT 0x00000001
#define ACPI_LV_DEBUG_OBJECT 0x00000002
#define ACPI_LV_INFO 0x00000004
#define ACPI_LV_ALL_EXCEPTIONS 0x00000007
#define ACPI_LV_REPAIR 0x00000008
#define ACPI_LV_ALL_EXCEPTIONS 0x0000000F
/* Trace verbosity level 1 [Standard Trace Level] */
@ -217,6 +218,7 @@
#define ACPI_DB_INIT ACPI_DEBUG_LEVEL (ACPI_LV_INIT)
#define ACPI_DB_DEBUG_OBJECT ACPI_DEBUG_LEVEL (ACPI_LV_DEBUG_OBJECT)
#define ACPI_DB_INFO ACPI_DEBUG_LEVEL (ACPI_LV_INFO)
#define ACPI_DB_REPAIR ACPI_DEBUG_LEVEL (ACPI_LV_REPAIR)
#define ACPI_DB_ALL_EXCEPTIONS ACPI_DEBUG_LEVEL (ACPI_LV_ALL_EXCEPTIONS)
/* Trace level -- also used in the global "DebugLevel" */
@ -248,8 +250,8 @@
/* Defaults for DebugLevel, debug and normal */
#define ACPI_DEBUG_DEFAULT (ACPI_LV_INIT | ACPI_LV_DEBUG_OBJECT)
#define ACPI_NORMAL_DEFAULT (ACPI_LV_INIT | ACPI_LV_DEBUG_OBJECT)
#define ACPI_DEBUG_DEFAULT (ACPI_LV_INIT | ACPI_LV_DEBUG_OBJECT | ACPI_LV_REPAIR)
#define ACPI_NORMAL_DEFAULT (ACPI_LV_INIT | ACPI_LV_DEBUG_OBJECT | ACPI_LV_REPAIR)
#define ACPI_DEBUG_ALL (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL)

View File

@ -120,7 +120,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
#define ACPI_CA_VERSION 0x20091112
#define ACPI_CA_VERSION 0x20091214
#include <contrib/dev/acpica/include/actypes.h>
#include <contrib/dev/acpica/include/actbl.h>

View File

@ -251,7 +251,7 @@ AcpiNsRootInitialize (
/* Mark this as a very SPECIAL method */
ObjDesc->Method.MethodFlags = AML_METHOD_INTERNAL_ONLY;
ObjDesc->Method.Implementation = AcpiUtOsiImplementation;
ObjDesc->Method.Extra.Implementation = AcpiUtOsiImplementation;
#endif
break;

View File

@ -286,7 +286,7 @@ AcpiNsDumpOneObject (
return (AE_OK);
}
ThisNode = AcpiNsMapHandleToNode (ObjHandle);
ThisNode = AcpiNsValidateHandle (ObjHandle);
if (!ThisNode)
{
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Invalid object handle %p\n",

View File

@ -477,6 +477,19 @@ AcpiNsExecModuleCode (
MethodObj->Method.NextObject);
Type = AcpiNsGetType (ParentNode);
/*
* Get the region handler and save it in the method object. We may need
* this if an operation region declaration causes a _REG method to be run.
*
* We can't do this in AcpiPsLinkModuleCode because
* AcpiGbl_RootNode->Object is NULL at PASS1.
*/
if ((Type == ACPI_TYPE_DEVICE) && ParentNode->Object)
{
MethodObj->Method.Extra.Handler =
ParentNode->Object->Device.Handler;
}
/* Must clear NextObject (AcpiNsAttachObject needs the field) */
MethodObj->Method.NextObject = NULL;
@ -513,6 +526,13 @@ AcpiNsExecModuleCode (
ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Executed module-level code at %p\n",
MethodObj->Method.AmlStart));
/* Delete a possible implicit return value (in slack mode) */
if (Info->ReturnObject)
{
AcpiUtRemoveReference (Info->ReturnObject);
}
/* Detach the temporary method object */
AcpiNsDetachObject (ParentNode);

View File

@ -337,7 +337,7 @@ AcpiNsHandleToPathname (
ACPI_FUNCTION_TRACE_PTR (NsHandleToPathname, TargetHandle);
Node = AcpiNsMapHandleToNode (TargetHandle);
Node = AcpiNsValidateHandle (TargetHandle);
if (!Node)
{
return_ACPI_STATUS (AE_BAD_PARAMETER);

View File

@ -313,31 +313,40 @@ AcpiNsCheckPredefinedNames (
Data->Pathname = Pathname;
/*
* Check that the type of the return object is what is expected for
* this predefined name
* Check that the type of the main return object is what is expected
* for this predefined name
*/
Status = AcpiNsCheckObjectType (Data, ReturnObjectPtr,
Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE_ELEMENT);
if (ACPI_FAILURE (Status))
{
goto CheckValidationStatus;
}
/* For returned Package objects, check the type of all sub-objects */
if (ReturnObject->Common.Type == ACPI_TYPE_PACKAGE)
{
Status = AcpiNsCheckPackage (Data, ReturnObjectPtr);
goto Exit;
}
/*
* Perform additional, more complicated repairs on a per-name
* basis.
* For returned Package objects, check the type of all sub-objects.
* Note: Package may have been newly created by call above.
*/
if ((*ReturnObjectPtr)->Common.Type == ACPI_TYPE_PACKAGE)
{
Status = AcpiNsCheckPackage (Data, ReturnObjectPtr);
if (ACPI_FAILURE (Status))
{
goto Exit;
}
}
/*
* The return object was OK, or it was successfully repaired above.
* Now make some additional checks such as verifying that package
* objects are sorted correctly (if required) or buffer objects have
* the correct data width (bytes vs. dwords). These repairs are
* performed on a per-name basis, i.e., the code is specific to
* particular predefined names.
*/
Status = AcpiNsComplexRepairs (Data, Node, Status, ReturnObjectPtr);
CheckValidationStatus:
Exit:
/*
* If the object validation failed or if we successfully repaired one
* or more objects, mark the parent node to suppress further warning
@ -349,7 +358,6 @@ AcpiNsCheckPredefinedNames (
}
ACPI_FREE (Data);
Cleanup:
ACPI_FREE (Pathname);
return (Status);
@ -544,6 +552,12 @@ AcpiNsCheckPackage (
"%s Validating return Package of Type %X, Count %X\n",
Data->Pathname, Package->RetInfo.Type, ReturnObject->Package.Count));
/*
* For variable-length Packages, we can safely remove all embedded
* and trailing NULL package elements
*/
AcpiNsRemoveNullElements (Data, Package->RetInfo.Type, ReturnObject);
/* Extract package count and elements array */
Elements = ReturnObject->Package.Elements;
@ -582,9 +596,10 @@ AcpiNsCheckPackage (
}
else if (Count > ExpectedCount)
{
ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
"Return Package is larger than needed - "
"found %u, expected %u", Count, ExpectedCount));
ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
"%s: Return Package is larger than needed - "
"found %u, expected %u\n",
Data->Pathname, Count, ExpectedCount));
}
/* Validate all elements of the returned package */
@ -800,56 +815,20 @@ AcpiNsCheckPackageList (
ACPI_OPERAND_OBJECT *SubPackage;
ACPI_OPERAND_OBJECT **SubElements;
ACPI_STATUS Status;
BOOLEAN NonTrailingNull = FALSE;
UINT32 ExpectedCount;
UINT32 i;
UINT32 j;
/* Validate each sub-Package in the parent Package */
/*
* Validate each sub-Package in the parent Package
*
* NOTE: assumes list of sub-packages contains no NULL elements.
* Any NULL elements should have been removed by earlier call
* to AcpiNsRemoveNullElements.
*/
for (i = 0; i < Count; i++)
{
/*
* Handling for NULL package elements. For now, we will simply allow
* a parent package with trailing NULL elements. This can happen if
* the package was defined to be longer than the initializer list.
* This is legal as per the ACPI specification. It is often used
* to allow for dynamic initialization of a Package.
*
* A future enhancement may be to simply truncate the package to
* remove the trailing NULL elements.
*/
if (!(*Elements))
{
if (!NonTrailingNull)
{
/* Ensure the remaining elements are all NULL */
for (j = 1; j < (Count - i + 1); j++)
{
if (Elements[j])
{
NonTrailingNull = TRUE;
}
}
if (!NonTrailingNull)
{
/* Ignore the trailing NULL elements */
return (AE_OK);
}
}
/* There are trailing non-null elements, issue warning */
ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
"Found NULL element at package index %u", i));
Elements++;
continue;
}
SubPackage = *Elements;
SubElements = SubPackage->Package.Elements;

View File

@ -119,12 +119,59 @@
#include <contrib/dev/acpica/include/accommon.h>
#include <contrib/dev/acpica/include/acnamesp.h>
#include <contrib/dev/acpica/include/acinterp.h>
#include <contrib/dev/acpica/include/acpredef.h>
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME ("nsrepair")
/*******************************************************************************
*
* 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
*
******************************************************************************/
/* Local prototypes */
static ACPI_STATUS
AcpiNsConvertToInteger (
ACPI_OPERAND_OBJECT *OriginalObject,
ACPI_OPERAND_OBJECT **ReturnObject);
static ACPI_STATUS
AcpiNsConvertToString (
ACPI_OPERAND_OBJECT *OriginalObject,
ACPI_OPERAND_OBJECT **ReturnObject);
static ACPI_STATUS
AcpiNsConvertToBuffer (
ACPI_OPERAND_OBJECT *OriginalObject,
ACPI_OPERAND_OBJECT **ReturnObject);
static ACPI_STATUS
AcpiNsConvertToPackage (
ACPI_OPERAND_OBJECT *OriginalObject,
ACPI_OPERAND_OBJECT **ReturnObject);
/*******************************************************************************
*
* FUNCTION: AcpiNsRepairObject
@ -153,110 +200,57 @@ AcpiNsRepairObject (
{
ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
ACPI_OPERAND_OBJECT *NewObject;
ACPI_SIZE Length;
ACPI_STATUS Status;
ACPI_FUNCTION_NAME (NsRepairObject);
/*
* 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
* repair the object. Only a limited number of repairs are possible.
* repair the object by converting it to one of the expected object
* types for this predefined name.
*/
switch (ReturnObject->Common.Type)
if (ExpectedBtypes & ACPI_RTYPE_INTEGER)
{
case ACPI_TYPE_BUFFER:
/* Does the method/object legally return a string? */
if (!(ExpectedBtypes & ACPI_RTYPE_STRING))
Status = AcpiNsConvertToInteger (ReturnObject, &NewObject);
if (ACPI_SUCCESS (Status))
{
return (AE_AML_OPERAND_TYPE);
goto ObjectRepaired;
}
/*
* Have a Buffer, expected a String, convert. 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 < ReturnObject->Buffer.Length) &&
(ReturnObject->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,
ReturnObject->Buffer.Pointer, Length);
break;
case ACPI_TYPE_INTEGER:
/* 1) Does the method/object legally return a buffer? */
if (ExpectedBtypes & ACPI_RTYPE_BUFFER)
{
/*
* Convert the Integer to a packed-byte buffer. _MAT needs
* 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 (ReturnObject, &NewObject);
if (ACPI_FAILURE (Status))
{
return (Status);
}
}
/* 2) Does the method/object legally return a string? */
else if (ExpectedBtypes & ACPI_RTYPE_STRING)
{
/*
* The only supported Integer-to-String conversion is to convert
* an integer of value 0 to a NULL string. The last element of
* _BIF and _BIX packages occasionally need this fix.
*/
if (ReturnObject->Integer.Value != 0)
{
return (AE_AML_OPERAND_TYPE);
}
/* Allocate a new NULL string object */
NewObject = AcpiUtCreateStringObject (0);
if (!NewObject)
{
return (AE_NO_MEMORY);
}
}
else
{
return (AE_AML_OPERAND_TYPE);
}
break;
default:
/* We cannot repair this object */
return (AE_AML_OPERAND_TYPE);
}
if (ExpectedBtypes & ACPI_RTYPE_STRING)
{
Status = AcpiNsConvertToString (ReturnObject, &NewObject);
if (ACPI_SUCCESS (Status))
{
goto ObjectRepaired;
}
}
if (ExpectedBtypes & ACPI_RTYPE_BUFFER)
{
Status = AcpiNsConvertToBuffer (ReturnObject, &NewObject);
if (ACPI_SUCCESS (Status))
{
goto ObjectRepaired;
}
}
if (ExpectedBtypes & ACPI_RTYPE_PACKAGE)
{
Status = AcpiNsConvertToPackage (ReturnObject, &NewObject);
if (ACPI_SUCCESS (Status))
{
goto ObjectRepaired;
}
}
/* We cannot repair this object */
return (AE_AML_OPERAND_TYPE);
ObjectRepaired:
/* Object was successfully repaired */
@ -276,16 +270,16 @@ AcpiNsRepairObject (
ReturnObject->Common.ReferenceCount--;
}
ACPI_INFO_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
"Converted %s to expected %s at index %u",
AcpiUtGetObjectTypeName (ReturnObject),
ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
"%s: Converted %s to expected %s at index %u\n",
Data->Pathname, AcpiUtGetObjectTypeName (ReturnObject),
AcpiUtGetObjectTypeName (NewObject), PackageIndex));
}
else
{
ACPI_INFO_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
"Converted %s to expected %s",
AcpiUtGetObjectTypeName (ReturnObject),
ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
"%s: Converted %s to expected %s\n",
Data->Pathname, AcpiUtGetObjectTypeName (ReturnObject),
AcpiUtGetObjectTypeName (NewObject)));
}
@ -298,6 +292,341 @@ AcpiNsRepairObject (
}
/*******************************************************************************
*
* 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
*
* 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.
*
******************************************************************************/
static 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.
*
******************************************************************************/
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;
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: AcpiNsConvertToPackage
*
* 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 Buffer object to a Package. Each byte of
* the buffer is converted to a single integer package element.
*
******************************************************************************/
static ACPI_STATUS
AcpiNsConvertToPackage (
ACPI_OPERAND_OBJECT *OriginalObject,
ACPI_OPERAND_OBJECT **ReturnObject)
{
ACPI_OPERAND_OBJECT *NewObject;
ACPI_OPERAND_OBJECT **Elements;
UINT32 Length;
UINT8 *Buffer;
switch (OriginalObject->Common.Type)
{
case ACPI_TYPE_BUFFER:
/* Buffer-to-Package conversion */
Length = OriginalObject->Buffer.Length;
NewObject = AcpiUtCreatePackageObject (Length);
if (!NewObject)
{
return (AE_NO_MEMORY);
}
/* Convert each buffer byte to an integer package element */
Elements = NewObject->Package.Elements;
Buffer = OriginalObject->Buffer.Pointer;
while (Length--)
{
*Elements = AcpiUtCreateIntegerObject ((UINT64) *Buffer);
if (!*Elements)
{
AcpiUtRemoveReference (NewObject);
return (AE_NO_MEMORY);
}
Elements++;
Buffer++;
}
break;
default:
return (AE_AML_OPERAND_TYPE);
}
*ReturnObject = NewObject;
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: AcpiNsRepairPackageList
@ -330,6 +659,9 @@ AcpiNsRepairPackageList (
ACPI_OPERAND_OBJECT *PkgObjDesc;
ACPI_FUNCTION_NAME (NsRepairPackageList);
/*
* Create the new outer package and populate it. The new package will
* have a single element, the lone subpackage.
@ -347,8 +679,8 @@ AcpiNsRepairPackageList (
*ObjDescPtr = PkgObjDesc;
Data->Flags |= ACPI_OBJECT_REPAIRED;
ACPI_INFO_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
"Repaired Incorrectly formed Package"));
ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
"%s: Repaired incorrectly formed Package\n", Data->Pathname));
return (AE_OK);
}

View File

@ -119,6 +119,7 @@
#include <contrib/dev/acpica/include/acpi.h>
#include <contrib/dev/acpica/include/accommon.h>
#include <contrib/dev/acpica/include/acnamesp.h>
#include <contrib/dev/acpica/include/acpredef.h>
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME ("nsrepair2")
@ -152,6 +153,11 @@ AcpiNsRepair_ALR (
ACPI_PREDEFINED_DATA *Data,
ACPI_OPERAND_OBJECT **ReturnObjectPtr);
static ACPI_STATUS
AcpiNsRepair_FDE (
ACPI_PREDEFINED_DATA *Data,
ACPI_OPERAND_OBJECT **ReturnObjectPtr);
static ACPI_STATUS
AcpiNsRepair_PSS (
ACPI_PREDEFINED_DATA *Data,
@ -171,10 +177,6 @@ AcpiNsCheckSortedList (
UINT8 SortDirection,
char *SortKeyName);
static ACPI_STATUS
AcpiNsRemoveNullElements (
ACPI_OPERAND_OBJECT *Package);
static ACPI_STATUS
AcpiNsSortList (
ACPI_OPERAND_OBJECT **Elements,
@ -192,19 +194,30 @@ AcpiNsSortList (
* This table contains the names of the predefined methods for which we can
* perform more complex repairs.
*
* _ALR: Sort the list ascending by AmbientIlluminance if necessary
* _PSS: Sort the list descending by Power if necessary
* _TSS: Sort the list descending by Power if necessary
* As necessary:
*
* _ALR: Sort the list ascending by AmbientIlluminance
* _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs
* _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs
* _PSS: Sort the list descending by Power
* _TSS: Sort the list descending by Power
*/
static const ACPI_REPAIR_INFO AcpiNsRepairableNames[] =
{
{"_ALR", AcpiNsRepair_ALR},
{"_FDE", AcpiNsRepair_FDE},
{"_GTM", AcpiNsRepair_FDE}, /* _GTM has same repair as _FDE */
{"_PSS", AcpiNsRepair_PSS},
{"_TSS", AcpiNsRepair_TSS},
{{0,0,0,0}, NULL} /* Table terminator */
{{0,0,0,0}, NULL} /* Table terminator */
};
#define ACPI_FDE_FIELD_COUNT 5
#define ACPI_FDE_BYTE_BUFFER_SIZE 5
#define ACPI_FDE_DWORD_BUFFER_SIZE (ACPI_FDE_FIELD_COUNT * sizeof (UINT32))
/******************************************************************************
*
* FUNCTION: AcpiNsComplexRepairs
@ -215,7 +228,7 @@ static const ACPI_REPAIR_INFO AcpiNsRepairableNames[] =
* ReturnObjectPtr - Pointer to the object returned from the
* evaluation of a method or object
*
* RETURN: Status. AE_OK if repair was successful. If name is not
* RETURN: Status. AE_OK if repair was successful. If name is not
* matched, ValidateStatus is returned.
*
* DESCRIPTION: Attempt to repair/convert a return object of a type that was
@ -313,6 +326,99 @@ AcpiNsRepair_ALR (
}
/******************************************************************************
*
* FUNCTION: AcpiNsRepair_FDE
*
* PARAMETERS: Data - Pointer to validation data structure
* ReturnObjectPtr - Pointer to the object returned from the
* evaluation of a method or object
*
* RETURN: Status. AE_OK if object is OK or was repaired successfully
*
* DESCRIPTION: Repair for the _FDE and _GTM objects. The expected return
* value is a Buffer of 5 DWORDs. This function repairs a common
* problem where the return value is a Buffer of BYTEs, not
* DWORDs.
*
*****************************************************************************/
static ACPI_STATUS
AcpiNsRepair_FDE (
ACPI_PREDEFINED_DATA *Data,
ACPI_OPERAND_OBJECT **ReturnObjectPtr)
{
ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
ACPI_OPERAND_OBJECT *BufferObject;
UINT8 *ByteBuffer;
UINT32 *DwordBuffer;
UINT32 i;
ACPI_FUNCTION_NAME (NsRepair_FDE);
switch (ReturnObject->Common.Type)
{
case ACPI_TYPE_BUFFER:
/* This is the expected type. Length should be (at least) 5 DWORDs */
if (ReturnObject->Buffer.Length >= ACPI_FDE_DWORD_BUFFER_SIZE)
{
return (AE_OK);
}
/* We can only repair if we have exactly 5 BYTEs */
if (ReturnObject->Buffer.Length != ACPI_FDE_BYTE_BUFFER_SIZE)
{
ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
"Incorrect return buffer length %u, expected %u",
ReturnObject->Buffer.Length, ACPI_FDE_DWORD_BUFFER_SIZE));
return (AE_AML_OPERAND_TYPE);
}
/* Create the new (larger) buffer object */
BufferObject = AcpiUtCreateBufferObject (ACPI_FDE_DWORD_BUFFER_SIZE);
if (!BufferObject)
{
return (AE_NO_MEMORY);
}
/* Expand each byte to a DWORD */
ByteBuffer = ReturnObject->Buffer.Pointer;
DwordBuffer = ACPI_CAST_PTR (UINT32, BufferObject->Buffer.Pointer);
for (i = 0; i < ACPI_FDE_FIELD_COUNT; i++)
{
*DwordBuffer = (UINT32) *ByteBuffer;
DwordBuffer++;
ByteBuffer++;
}
ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
"%s Expanded Byte Buffer to expected DWord Buffer\n",
Data->Pathname));
break;
default:
return (AE_AML_OPERAND_TYPE);
}
/* Delete the original return object, return the new buffer object */
AcpiUtRemoveReference (ReturnObject);
*ReturnObjectPtr = BufferObject;
Data->Flags |= ACPI_OBJECT_REPAIRED;
return (AE_OK);
}
/******************************************************************************
*
* FUNCTION: AcpiNsRepair_TSS
@ -454,6 +560,9 @@ AcpiNsCheckSortedList (
ACPI_STATUS Status;
ACPI_FUNCTION_NAME (NsCheckSortedList);
/* The top-level object must be a package */
if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
@ -462,26 +571,10 @@ AcpiNsCheckSortedList (
}
/*
* Detect any NULL package elements and remove them from the
* package.
*
* TBD: We may want to do this for all predefined names that
* return a variable-length package of packages.
* NOTE: assumes list of sub-packages contains no NULL elements.
* Any NULL elements should have been removed by earlier call
* to AcpiNsRemoveNullElements.
*/
Status = AcpiNsRemoveNullElements (ReturnObject);
if (Status == AE_NULL_ENTRY)
{
ACPI_INFO_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
"NULL elements removed from package"));
/* Exit if package is now zero length */
if (!ReturnObject->Package.Count)
{
return (AE_NULL_ENTRY);
}
}
OuterElements = ReturnObject->Package.Elements;
OuterElementCount = ReturnObject->Package.Count;
if (!OuterElementCount)
@ -539,8 +632,9 @@ AcpiNsCheckSortedList (
Data->Flags |= ACPI_OBJECT_REPAIRED;
ACPI_INFO_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
"Repaired unsorted list - now sorted by %s", SortKeyName));
ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
"%s: Repaired unsorted list - now sorted by %s\n",
Data->Pathname, SortKeyName));
return (AE_OK);
}
@ -556,40 +650,69 @@ AcpiNsCheckSortedList (
*
* FUNCTION: AcpiNsRemoveNullElements
*
* PARAMETERS: ObjDesc - A Package object
* PARAMETERS: Data - Pointer to validation data structure
* PackageType - An AcpiReturnPackageTypes value
* ObjDesc - A Package object
*
* RETURN: Status. AE_NULL_ENTRY means that one or more elements were
* removed.
* RETURN: None.
*
* DESCRIPTION: Remove all NULL package elements and update the package count.
* DESCRIPTION: Remove all NULL package elements from packages that contain
* a variable number of sub-packages.
*
*****************************************************************************/
static ACPI_STATUS
void
AcpiNsRemoveNullElements (
ACPI_PREDEFINED_DATA *Data,
UINT8 PackageType,
ACPI_OPERAND_OBJECT *ObjDesc)
{
ACPI_OPERAND_OBJECT **Source;
ACPI_OPERAND_OBJECT **Dest;
ACPI_STATUS Status = AE_OK;
UINT32 Count;
UINT32 NewCount;
UINT32 i;
ACPI_FUNCTION_NAME (NsRemoveNullElements);
/*
* 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 (PackageType)
{
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 = ObjDesc->Package.Count;
NewCount = Count;
Source = ObjDesc->Package.Elements;
Dest = Source;
/* Examine all elements of the package object */
/* Examine all elements of the package object, remove nulls */
for (i = 0; i < Count; i++)
{
if (!*Source)
{
Status = AE_NULL_ENTRY;
NewCount--;
}
else
@ -600,15 +723,19 @@ AcpiNsRemoveNullElements (
Source++;
}
if (Status == AE_NULL_ENTRY)
/* Update parent package if any null elements were removed */
if (NewCount < Count)
{
ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
"%s: Found and removed %u NULL elements\n",
Data->Pathname, (Count - NewCount)));
/* NULL terminate list and update the package count */
*Dest = NULL;
ObjDesc->Package.Count = NewCount;
}
return (Status);
}

View File

@ -857,25 +857,26 @@ AcpiNsExternalizeName (
/*******************************************************************************
*
* FUNCTION: AcpiNsMapHandleToNode
* FUNCTION: AcpiNsValidateHandle
*
* PARAMETERS: Handle - Handle to be converted to an Node
* PARAMETERS: Handle - Handle to be validated and typecast to a
* namespace node.
*
* RETURN: A Name table entry pointer
* RETURN: A pointer to a namespace node
*
* DESCRIPTION: Convert a namespace handle to a real Node
* DESCRIPTION: Convert a namespace handle to a namespace node. Handles special
* cases for the root node.
*
* Note: Real integer handles would allow for more verification
* NOTE: Real integer handles would allow for more verification
* and keep all pointers within this subsystem - however this introduces
* more (and perhaps unnecessary) overhead.
*
* The current implemenation is basically a placeholder until such time comes
* that it is needed.
* more overhead and has not been necessary to this point. Drivers
* holding handles are typically notified before a node becomes invalid
* due to a table unload.
*
******************************************************************************/
ACPI_NAMESPACE_NODE *
AcpiNsMapHandleToNode (
AcpiNsValidateHandle (
ACPI_HANDLE Handle)
{
@ -900,48 +901,6 @@ AcpiNsMapHandleToNode (
}
/*******************************************************************************
*
* FUNCTION: AcpiNsConvertEntryToHandle
*
* PARAMETERS: Node - Node to be converted to a Handle
*
* RETURN: A user handle
*
* DESCRIPTION: Convert a real Node to a namespace handle
*
******************************************************************************/
ACPI_HANDLE
AcpiNsConvertEntryToHandle (
ACPI_NAMESPACE_NODE *Node)
{
/*
* Simple implementation for now;
*/
return ((ACPI_HANDLE) Node);
/* Example future implementation ---------------------
if (!Node)
{
return (NULL);
}
if (Node == AcpiGbl_RootNode)
{
return (ACPI_ROOT_OBJECT);
}
return ((ACPI_HANDLE) Node);
------------------------------------------------------*/
}
/*******************************************************************************
*
* FUNCTION: AcpiNsTerminate

View File

@ -281,7 +281,7 @@ AcpiEvaluateObject (
/* Convert and validate the device handle */
Info->PrefixNode = AcpiNsMapHandleToNode (Handle);
Info->PrefixNode = AcpiNsValidateHandle (Handle);
if (!Info->PrefixNode)
{
Status = AE_BAD_PARAMETER;
@ -676,7 +676,7 @@ AcpiNsGetDeviceCallback (
return (Status);
}
Node = AcpiNsMapHandleToNode (ObjHandle);
Node = AcpiNsValidateHandle (ObjHandle);
Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (Status))
{
@ -888,7 +888,7 @@ AcpiAttachData (
/* Convert and validate the handle */
Node = AcpiNsMapHandleToNode (ObjHandle);
Node = AcpiNsValidateHandle (ObjHandle);
if (!Node)
{
Status = AE_BAD_PARAMETER;
@ -943,7 +943,7 @@ AcpiDetachData (
/* Convert and validate the handle */
Node = AcpiNsMapHandleToNode (ObjHandle);
Node = AcpiNsValidateHandle (ObjHandle);
if (!Node)
{
Status = AE_BAD_PARAMETER;
@ -1001,7 +1001,7 @@ AcpiGetData (
/* Convert and validate the handle */
Node = AcpiNsMapHandleToNode (ObjHandle);
Node = AcpiNsValidateHandle (ObjHandle);
if (!Node)
{
Status = AE_BAD_PARAMETER;

View File

@ -178,7 +178,7 @@ AcpiGetHandle (
if (Parent)
{
PrefixNode = AcpiNsMapHandleToNode (Parent);
PrefixNode = AcpiNsValidateHandle (Parent);
if (!PrefixNode)
{
return (AE_BAD_PARAMETER);
@ -200,7 +200,7 @@ AcpiGetHandle (
if (!ACPI_STRCMP (Pathname, ACPI_NS_ROOT_PATH))
{
*RetHandle = AcpiNsConvertEntryToHandle (AcpiGbl_RootNode);
*RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, AcpiGbl_RootNode);
return (AE_OK);
}
}
@ -216,7 +216,7 @@ AcpiGetHandle (
Status = AcpiNsGetNode (PrefixNode, Pathname, ACPI_NS_NO_UPSEARCH, &Node);
if (ACPI_SUCCESS (Status))
{
*RetHandle = AcpiNsConvertEntryToHandle (Node);
*RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
}
return (Status);
@ -282,7 +282,7 @@ AcpiGetName (
return (Status);
}
Node = AcpiNsMapHandleToNode (Handle);
Node = AcpiNsValidateHandle (Handle);
if (!Node)
{
Status = AE_BAD_PARAMETER;
@ -399,7 +399,7 @@ AcpiGetObjectInfo (
goto Cleanup;
}
Node = AcpiNsMapHandleToNode (Handle);
Node = AcpiNsValidateHandle (Handle);
if (!Node)
{
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);

View File

@ -172,7 +172,7 @@ AcpiGetType (
/* Convert and validate the handle */
Node = AcpiNsMapHandleToNode (Handle);
Node = AcpiNsValidateHandle (Handle);
if (!Node)
{
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
@ -233,7 +233,7 @@ AcpiGetParent (
/* Convert and validate the handle */
Node = AcpiNsMapHandleToNode (Handle);
Node = AcpiNsValidateHandle (Handle);
if (!Node)
{
Status = AE_BAD_PARAMETER;
@ -243,7 +243,7 @@ AcpiGetParent (
/* Get the parent entry */
ParentNode = AcpiNsGetParentNode (Node);
*RetHandle = AcpiNsConvertEntryToHandle (ParentNode);
*RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, ParentNode);
/* Return exception if parent is null */
@ -312,7 +312,7 @@ AcpiGetNextObject (
{
/* Start search at the beginning of the specified scope */
ParentNode = AcpiNsMapHandleToNode (Parent);
ParentNode = AcpiNsValidateHandle (Parent);
if (!ParentNode)
{
Status = AE_BAD_PARAMETER;
@ -324,7 +324,7 @@ AcpiGetNextObject (
/* Non-null handle, ignore the parent */
/* Convert and validate the handle */
ChildNode = AcpiNsMapHandleToNode (Child);
ChildNode = AcpiNsValidateHandle (Child);
if (!ChildNode)
{
Status = AE_BAD_PARAMETER;
@ -343,7 +343,7 @@ AcpiGetNextObject (
if (RetHandle)
{
*RetHandle = AcpiNsConvertEntryToHandle (Node);
*RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
}

View File

@ -403,7 +403,7 @@ AcpiPsExecuteMethod (
if (Info->ObjDesc->Method.MethodFlags & AML_METHOD_INTERNAL_ONLY)
{
Status = Info->ObjDesc->Method.Implementation (WalkState);
Status = Info->ObjDesc->Method.Extra.Implementation (WalkState);
Info->ReturnObject = WalkState->ReturnDesc;
/* Cleanup states */

View File

@ -191,7 +191,7 @@ AcpiRsValidateParameters (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
Node = AcpiNsMapHandleToNode (DeviceHandle);
Node = AcpiNsValidateHandle (DeviceHandle);
if (!Node)
{
return_ACPI_STATUS (AE_BAD_PARAMETER);

View File

@ -135,8 +135,9 @@
#include <contrib/dev/acpica/include/acinterp.h>
#include <contrib/dev/acpica/include/acapps.h>
extern FILE *AcpiGbl_DebugFile;
extern BOOLEAN AcpiGbl_IgnoreErrors;
extern FILE *AcpiGbl_DebugFile;
extern BOOLEAN AcpiGbl_IgnoreErrors;
extern UINT8 AcpiGbl_RegionFillValue;
typedef struct ae_table_desc

View File

@ -422,11 +422,11 @@ AcpiUtCopyIelementToEelement (
* RETURN: Status
*
* DESCRIPTION: This function is called to place a package object in a user
* buffer. A package object by definition contains other objects.
* buffer. A package object by definition contains other objects.
*
* The buffer is assumed to have sufficient space for the object.
* The caller must have verified the buffer length needed using the
* AcpiUtGetObjectSize function before calling this function.
* The caller must have verified the buffer length needed using
* the AcpiUtGetObjectSize function before calling this function.
*
******************************************************************************/
@ -485,12 +485,12 @@ AcpiUtCopyIpackageToEpackage (
* FUNCTION: AcpiUtCopyIobjectToEobject
*
* PARAMETERS: InternalObject - The internal object to be converted
* BufferPtr - Where the object is returned
* RetBuffer - Where the object is returned
*
* RETURN: Status
*
* DESCRIPTION: This function is called to build an API object to be returned to
* the caller.
* DESCRIPTION: This function is called to build an API object to be returned
* to the caller.
*
******************************************************************************/
@ -742,7 +742,7 @@ AcpiUtCopyEpackageToIpackage (
* PARAMETERS: ExternalObject - The external object to be converted
* InternalObject - Where the internal object is returned
*
* RETURN: Status - the status of the call
* RETURN: Status
*
* DESCRIPTION: Converts an external object to an internal object.
*
@ -784,7 +784,7 @@ AcpiUtCopyEobjectToIobject (
*
* RETURN: Status
*
* DESCRIPTION: Simple copy of one internal object to another. Reference count
* DESCRIPTION: Simple copy of one internal object to another. Reference count
* of the destination object is preserved.
*
******************************************************************************/
@ -1034,10 +1034,11 @@ AcpiUtCopyIelementToIelement (
*
* FUNCTION: AcpiUtCopyIpackageToIpackage
*
* PARAMETERS: *SourceObj - Pointer to the source package object
* *DestObj - Where the internal object is returned
* PARAMETERS: SourceObj - Pointer to the source package object
* DestObj - Where the internal object is returned
* WalkState - Current Walk state descriptor
*
* RETURN: Status - the status of the call
* RETURN: Status
*
* DESCRIPTION: This function is called to copy an internal package object
* into another internal package object.
@ -1093,9 +1094,9 @@ AcpiUtCopyIpackageToIpackage (
*
* FUNCTION: AcpiUtCopyIobjectToIobject
*
* PARAMETERS: WalkState - Current walk state
* SourceDesc - The internal object to be copied
* PARAMETERS: SourceDesc - The internal object to be copied
* DestDesc - Where the copied object is returned
* WalkState - Current walk state
*
* RETURN: Status
*