svn commit: r206117 - in head/sys: contrib/dev/acpica
contrib/dev/acpica/common contrib/dev/acpica/compiler
contrib/dev/acpica/debugger contrib/dev/acpica/events
contrib/dev/acpica/executer contrib...
Jung-uk Kim
jkim at FreeBSD.org
Fri Apr 2 23:04:32 UTC 2010
Author: jkim
Date: Fri Apr 2 23:04:31 2010
New Revision: 206117
URL: http://svn.freebsd.org/changeset/base/206117
Log:
Merge ACPICA 20100331 (and four additional upstream patches).
Modified:
head/sys/contrib/dev/acpica/changes.txt
head/sys/contrib/dev/acpica/common/dmextern.c
head/sys/contrib/dev/acpica/compiler/aslanalyze.c
head/sys/contrib/dev/acpica/compiler/aslcompiler.h
head/sys/contrib/dev/acpica/compiler/aslpredef.c
head/sys/contrib/dev/acpica/compiler/aslstubs.c
head/sys/contrib/dev/acpica/compiler/asltypes.h
head/sys/contrib/dev/acpica/debugger/dbdisply.c
head/sys/contrib/dev/acpica/events/evgpe.c
head/sys/contrib/dev/acpica/events/evgpeblk.c
head/sys/contrib/dev/acpica/events/evxface.c
head/sys/contrib/dev/acpica/events/evxfevnt.c
head/sys/contrib/dev/acpica/executer/exdebug.c
head/sys/contrib/dev/acpica/executer/exmutex.c
head/sys/contrib/dev/acpica/executer/exoparg2.c
head/sys/contrib/dev/acpica/executer/exregion.c
head/sys/contrib/dev/acpica/include/acevents.h
head/sys/contrib/dev/acpica/include/acexcep.h
head/sys/contrib/dev/acpica/include/acglobal.h
head/sys/contrib/dev/acpica/include/aclocal.h
head/sys/contrib/dev/acpica/include/acpixf.h
head/sys/contrib/dev/acpica/include/actables.h
head/sys/contrib/dev/acpica/include/actypes.h
head/sys/contrib/dev/acpica/include/platform/acfreebsd.h
head/sys/contrib/dev/acpica/parser/psxface.c
head/sys/contrib/dev/acpica/tables/tbutils.c
head/sys/contrib/dev/acpica/tables/tbxface.c
head/sys/contrib/dev/acpica/utilities/utglobal.c
head/sys/dev/acpica/acpi.c
head/sys/dev/acpica/acpi_button.c
head/sys/dev/acpica/acpi_ec.c
head/sys/dev/acpica/acpi_lid.c
head/sys/dev/acpica/acpivar.h
Directory Properties:
head/sys/contrib/dev/acpica/ (props changed)
Modified: head/sys/contrib/dev/acpica/changes.txt
==============================================================================
--- head/sys/contrib/dev/acpica/changes.txt Fri Apr 2 21:48:27 2010 (r206116)
+++ head/sys/contrib/dev/acpica/changes.txt Fri Apr 2 23:04:31 2010 (r206117)
@@ -1,4 +1,79 @@
----------------------------------------
+31 March 2010. Summary of changes for version 20100331:
+
+1) ACPI CA Core Subsystem:
+
+Completed a major update for the GPE support in order to improve support for
+shared GPEs and to simplify both host OS and ACPICA code. Added a reference
+count mechanism to support shared GPEs that require multiple device drivers.
+Several external interfaces have changed. One external interface has been
+removed. One new external interface was added. Most of the GPE external
+interfaces now use the GPE spinlock instead of the events mutex (and the
+Flags parameter for many GPE interfaces has been removed.) See the updated
+ACPICA Programmer Reference for details. Matthew Garrett, Bob Moore, Rafael
+Wysocki. ACPICA BZ 831.
+
+Changed:
+ AcpiEnableGpe, AcpiDisableGpe, AcpiClearGpe, AcpiGetGpeStatus
+Removed:
+ AcpiSetGpeType
+New:
+ AcpiSetGpe
+
+Implemented write support for DataTable operation regions. These regions are
+defined via the DataTableRegion() operator. Previously, only read support was
+implemented. The ACPI specification allows DataTableRegions to be read/write,
+however.
+
+Implemented a new subsystem option to force a copy of the DSDT to local
+memory. Optionally copy the entire DSDT to local memory (instead of simply
+mapping it.) There are some (albeit very rare) BIOSs that corrupt or replace
+the original DSDT, creating the need for this option. Default is FALSE, do
+not copy the DSDT.
+
+Implemented detection of a corrupted or replaced DSDT. This change adds
+support to detect a DSDT that has been corrupted and/or replaced from outside
+the OS (by firmware). This is typically catastrophic for the system, but has
+been seen on some machines. Once this problem has been detected, the DSDT
+copy option can be enabled via system configuration. Lin Ming, Bob Moore.
+
+Fixed two problems with AcpiReallocateRootTable during the root table copy.
+When copying the root table to the new allocation, the length used was
+incorrect. The new size was used instead of the current table size, meaning
+too much data was copied. Also, the count of available slots for ACPI tables
+was not set correctly. Alexey Starikovskiy, Bob Moore.
+
+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: 87.5K Code, 18.4K Data, 105.9K Total
+ Debug Version: 163.4K Code, 51.1K Data, 214.5K Total
+ Current Release:
+ Non-Debug Version: 87.9K Code, 18.6K Data, 106.5K Total
+ Debug Version: 163.5K Code, 51.3K Data, 214.8K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Implement limited typechecking for values returned from predefined
+control methods. The type of any returned static (unnamed) object is now
+validated. For example, Return(1). ACPICA BZ 786.
+
+iASL: Fixed a predefined name object verification regression. Fixes a problem
+introduced in version 20100304. An error is incorrectly generated if a
+predefined name is declared as a static named object with a value defined
+using the keywords "Zero", "One", or "Ones". Lin Ming.
+
+iASL: Added Windows 7 support for the -g option (get local ACPI tables) by
+reducing the requested registry access rights. ACPICA BZ 842.
+
+Disassembler: fixed a possible fault when generating External() statements.
+Introduced in commit ae7d6fd: Properly handle externals with parent-prefix
+(carat). Fixes a string length allocation calculation. Lin Ming.
+
+----------------------------------------
04 March 2010. Summary of changes for version 20100304:
1) ACPI CA Core Subsystem:
Modified: head/sys/contrib/dev/acpica/common/dmextern.c
==============================================================================
--- head/sys/contrib/dev/acpica/common/dmextern.c Fri Apr 2 21:48:27 2010 (r206116)
+++ head/sys/contrib/dev/acpica/common/dmextern.c Fri Apr 2 23:04:31 2010 (r206117)
@@ -270,6 +270,15 @@ AcpiDmNormalizeParentPrefix (
}
Length = (ACPI_STRLEN (ParentPath) + ACPI_STRLEN (Path) + 1);
+ if (ParentPath[1])
+ {
+ /*
+ * If ParentPath is not just a simple '\', increment the length
+ * for the required dot separator (ParentPath.Path)
+ */
+ Length++;
+ }
+
Fullpath = ACPI_ALLOCATE_ZEROED (Length);
if (!Fullpath)
{
Modified: head/sys/contrib/dev/acpica/compiler/aslanalyze.c
==============================================================================
--- head/sys/contrib/dev/acpica/compiler/aslanalyze.c Fri Apr 2 21:48:27 2010 (r206116)
+++ head/sys/contrib/dev/acpica/compiler/aslanalyze.c Fri Apr 2 23:04:31 2010 (r206117)
@@ -1157,6 +1157,12 @@ AnMethodAnalysisWalkEnd (
case PARSEOP_RETURN:
/*
+ * If the parent is a predefined method name, attempt to typecheck
+ * the return value. Only static types can be validated.
+ */
+ ApCheckPredefinedReturnValue (Op, MethodInfo);
+
+ /*
* The parent block does not "exit" and continue execution -- the
* method is terminated here with the Return() statement.
*/
Modified: head/sys/contrib/dev/acpica/compiler/aslcompiler.h
==============================================================================
--- head/sys/contrib/dev/acpica/compiler/aslcompiler.h Fri Apr 2 21:48:27 2010 (r206116)
+++ head/sys/contrib/dev/acpica/compiler/aslcompiler.h Fri Apr 2 23:04:31 2010 (r206117)
@@ -461,6 +461,11 @@ ApCheckForPredefinedMethod (
ACPI_PARSE_OBJECT *Op,
ASL_METHOD_INFO *MethodInfo);
+void
+ApCheckPredefinedReturnValue (
+ ACPI_PARSE_OBJECT *Op,
+ ASL_METHOD_INFO *MethodInfo);
+
UINT32
ApCheckForPredefinedName (
ACPI_PARSE_OBJECT *Op,
Modified: head/sys/contrib/dev/acpica/compiler/aslpredef.c
==============================================================================
--- head/sys/contrib/dev/acpica/compiler/aslpredef.c Fri Apr 2 21:48:27 2010 (r206116)
+++ head/sys/contrib/dev/acpica/compiler/aslpredef.c Fri Apr 2 23:04:31 2010 (r206117)
@@ -296,7 +296,11 @@ ApCheckForPredefinedMethod (
if (MethodInfo->NumReturnNoValue &&
PredefinedNames[Index].Info.ExpectedBtypes)
{
- sprintf (MsgBuffer, "%4.4s", PredefinedNames[Index].Info.Name);
+ ApGetExpectedTypes (StringBuffer,
+ PredefinedNames[Index].Info.ExpectedBtypes);
+
+ sprintf (MsgBuffer, "%s required for %4.4s",
+ StringBuffer, PredefinedNames[Index].Info.Name);
AslError (ASL_WARNING, ASL_MSG_RESERVED_RETURN_VALUE, Op,
MsgBuffer);
@@ -308,6 +312,90 @@ ApCheckForPredefinedMethod (
/*******************************************************************************
*
+ * FUNCTION: ApCheckPredefinedReturnValue
+ *
+ * PARAMETERS: Op - A parse node of type "RETURN".
+ * MethodInfo - Saved info about this method
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: If method is a predefined name, attempt to validate the return
+ * value. Only "static" types can be validated - a simple return
+ * of an integer/string/buffer/package or a named reference to
+ * a static object. Values such as a Localx or Argx or a control
+ * method invocation are not checked.
+ *
+ ******************************************************************************/
+
+void
+ApCheckPredefinedReturnValue (
+ ACPI_PARSE_OBJECT *Op,
+ ASL_METHOD_INFO *MethodInfo)
+{
+ UINT32 Index;
+ ACPI_PARSE_OBJECT *ReturnValueOp;
+
+
+ /* Check parent method for a match against the predefined name list */
+
+ Index = ApCheckForPredefinedName (MethodInfo->Op,
+ MethodInfo->Op->Asl.NameSeg);
+
+ switch (Index)
+ {
+ case ACPI_NOT_RESERVED_NAME: /* No underscore or _Txx or _xxx name not matched */
+ case ACPI_PREDEFINED_NAME: /* Resource Name or reserved scope name */
+ case ACPI_COMPILER_RESERVED_NAME: /* A _Txx that was not emitted by compiler */
+ case ACPI_EVENT_RESERVED_NAME: /* _Lxx, _Exx, and _Qxx methods */
+
+ /* Just return, nothing to do */
+ return;
+
+ default: /* a real predefined ACPI name */
+
+ /* Exit if no return value expected */
+
+ if (!PredefinedNames[Index].Info.ExpectedBtypes)
+ {
+ return;
+ }
+
+ /* Get the object returned, it is the next argument */
+
+ ReturnValueOp = Op->Asl.Child;
+ switch (ReturnValueOp->Asl.ParseOpcode)
+ {
+ case PARSEOP_ZERO:
+ case PARSEOP_ONE:
+ case PARSEOP_ONES:
+ case PARSEOP_INTEGER:
+ case PARSEOP_STRING_LITERAL:
+ case PARSEOP_BUFFER:
+ case PARSEOP_PACKAGE:
+
+ /* Static data return object - check against expected type */
+
+ ApCheckObjectType (ReturnValueOp,
+ PredefinedNames[Index].Info.ExpectedBtypes);
+ break;
+
+ default:
+
+ /*
+ * All other ops are very difficult or impossible to typecheck at
+ * compile time. These include all Localx, Argx, and method
+ * invocations. Also, NAMESEG and NAMESTRING because the type of
+ * any named object can be changed at runtime (for example,
+ * CopyObject will change the type of the target object.)
+ */
+ break;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: ApCheckForPredefinedObject
*
* PARAMETERS: Op - A parse node
@@ -441,7 +529,7 @@ ApCheckForPredefinedName (
*
* RETURN: None
*
- * DESCRIPTION: Check for the "special" predefined names -
+ * DESCRIPTION: Check for the "special" predefined names -
* _Lxx, _Exx, _Qxx, and _T_x
*
******************************************************************************/
@@ -512,7 +600,7 @@ ApCheckForSpecialName (
*
* FUNCTION: ApCheckObjectType
*
- * PARAMETERS: Op - A parse node
+ * PARAMETERS: Op - Current parse node
* ExpectedBtypes - Bitmap of expected return type(s)
*
* RETURN: None
@@ -529,11 +617,13 @@ ApCheckObjectType (
UINT32 ExpectedBtypes)
{
UINT32 ReturnBtype;
- char TypeBuffer[48]; /* Room for 5 types */
switch (Op->Asl.ParseOpcode)
{
+ case PARSEOP_ZERO:
+ case PARSEOP_ONE:
+ case PARSEOP_ONES:
case PARSEOP_INTEGER:
ReturnBtype = ACPI_RTYPE_INTEGER;
break;
@@ -552,11 +642,11 @@ ApCheckObjectType (
default:
/* Not one of the supported object types */
-
+
goto TypeErrorExit;
}
- /* Is the object one of the expected types? */
+ /* Exit if the object is one of the expected types */
if (ReturnBtype & ExpectedBtypes)
{
@@ -568,10 +658,13 @@ TypeErrorExit:
/* Format the expected types and emit an error message */
- ApGetExpectedTypes (TypeBuffer, ExpectedBtypes);
+ ApGetExpectedTypes (StringBuffer, ExpectedBtypes);
+
+ sprintf (MsgBuffer, "found %s, requires %s",
+ UtGetOpName (Op->Asl.ParseOpcode), StringBuffer);
AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Op,
- TypeBuffer);
+ MsgBuffer);
}
Modified: head/sys/contrib/dev/acpica/compiler/aslstubs.c
==============================================================================
--- head/sys/contrib/dev/acpica/compiler/aslstubs.c Fri Apr 2 21:48:27 2010 (r206116)
+++ head/sys/contrib/dev/acpica/compiler/aslstubs.c Fri Apr 2 23:04:31 2010 (r206117)
@@ -243,13 +243,6 @@ AcpiEvInitializeRegion (
return (AE_OK);
}
-ACPI_STATUS
-AcpiEvCheckForWakeOnlyGpe (
- ACPI_GPE_EVENT_INFO *GpeEventInfo)
-{
- return (AE_OK);
-}
-
void
AcpiExDoDebugObject (
ACPI_OPERAND_OBJECT *SourceDesc,
Modified: head/sys/contrib/dev/acpica/compiler/asltypes.h
==============================================================================
--- head/sys/contrib/dev/acpica/compiler/asltypes.h Fri Apr 2 21:48:27 2010 (r206116)
+++ head/sys/contrib/dev/acpica/compiler/asltypes.h Fri Apr 2 23:04:31 2010 (r206117)
@@ -507,7 +507,7 @@ char *AslMessages
/* ASL_MSG_RESERVED_ARG_COUNT_HI */ "Reserved method has too many arguments",
/* ASL_MSG_RESERVED_ARG_COUNT_LO */ "Reserved method has too few arguments",
/* ASL_MSG_RESERVED_METHOD */ "Reserved name must be a control method",
-/* ASL_MSG_RESERVED_OPERAND_TYPE */ "Invalid object type for reserved name, must be",
+/* ASL_MSG_RESERVED_OPERAND_TYPE */ "Invalid object type for reserved name",
/* ASL_MSG_RESERVED_RETURN_VALUE */ "Reserved method must return a value",
/* ASL_MSG_RESERVED_USE */ "Invalid use of reserved name",
/* ASL_MSG_RESERVED_WORD */ "Use of reserved name",
Modified: head/sys/contrib/dev/acpica/debugger/dbdisply.c
==============================================================================
--- head/sys/contrib/dev/acpica/debugger/dbdisply.c Fri Apr 2 21:48:27 2010 (r206116)
+++ head/sys/contrib/dev/acpica/debugger/dbdisply.c Fri Apr 2 23:04:31 2010 (r206117)
@@ -848,13 +848,12 @@ AcpiDbDisplayGpes (
Block, GpeBlock, GpeBlock->Node, Buffer);
AcpiOsPrintf (" Registers: %u (%u GPEs)\n",
- GpeBlock->RegisterCount,
- ACPI_MUL_8 (GpeBlock->RegisterCount));
+ GpeBlock->RegisterCount, GpeBlock->GpeCount);
- AcpiOsPrintf (" GPE range: 0x%X to 0x%X\n",
+ AcpiOsPrintf (" GPE range: 0x%X to 0x%X on interrupt %u\n",
GpeBlock->BlockBaseNumber,
- GpeBlock->BlockBaseNumber +
- (GpeBlock->RegisterCount * 8) -1);
+ GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1),
+ GpeXruptInfo->InterruptNumber);
AcpiOsPrintf (
" RegisterInfo: %p Status %8.8X%8.8X Enable %8.8X%8.8X\n",
@@ -871,9 +870,12 @@ AcpiDbDisplayGpes (
GpeRegisterInfo = &GpeBlock->RegisterInfo[i];
AcpiOsPrintf (
- " Reg %u: WakeEnable %2.2X, RunEnable %2.2X Status %8.8X%8.8X Enable %8.8X%8.8X\n",
- i, GpeRegisterInfo->EnableForWake,
+ " Reg %u: (GPE %.2X-%.2X) RunEnable %2.2X WakeEnable %2.2X"
+ " Status %8.8X%8.8X Enable %8.8X%8.8X\n",
+ i, GpeRegisterInfo->BaseGpeNumber,
+ GpeRegisterInfo->BaseGpeNumber + (ACPI_GPE_REGISTER_WIDTH - 1),
GpeRegisterInfo->EnableForRun,
+ GpeRegisterInfo->EnableForWake,
ACPI_FORMAT_UINT64 (GpeRegisterInfo->StatusAddress.Address),
ACPI_FORMAT_UINT64 (GpeRegisterInfo->EnableAddress.Address));
@@ -886,17 +888,19 @@ AcpiDbDisplayGpes (
if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK))
{
- /* This GPE is not used (no method or handler) */
+ /* This GPE is not used (no method or handler), ignore it */
continue;
}
AcpiOsPrintf (
- " GPE %.3X: %p Flags %2.2X: ",
- GpeBlock->BlockBaseNumber + GpeIndex,
- GpeEventInfo,
+ " GPE %.2X: %p RunRefs %2.2X WakeRefs %2.2X Flags %2.2X (",
+ GpeBlock->BlockBaseNumber + GpeIndex, GpeEventInfo,
+ GpeEventInfo->RuntimeCount, GpeEventInfo->WakeupCount,
GpeEventInfo->Flags);
+ /* Decode the flags byte */
+
if (GpeEventInfo->Flags & ACPI_GPE_LEVEL_TRIGGERED)
{
AcpiOsPrintf ("Level, ");
@@ -906,38 +910,13 @@ AcpiDbDisplayGpes (
AcpiOsPrintf ("Edge, ");
}
- switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK)
- {
- case ACPI_GPE_TYPE_WAKE:
- AcpiOsPrintf ("WakeOnly: ");
- break;
- case ACPI_GPE_TYPE_RUNTIME:
- AcpiOsPrintf (" RunOnly: ");
- break;
- case ACPI_GPE_TYPE_WAKE_RUN:
- AcpiOsPrintf (" WakeRun: ");
- break;
- default:
- AcpiOsPrintf (" NotUsed: ");
- break;
- }
-
- if (GpeEventInfo->Flags & ACPI_GPE_WAKE_ENABLED)
- {
- AcpiOsPrintf ("[Wake 1 ");
- }
- else
- {
- AcpiOsPrintf ("[Wake 0 ");
- }
-
- if (GpeEventInfo->Flags & ACPI_GPE_RUN_ENABLED)
+ if (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)
{
- AcpiOsPrintf ("Run 1], ");
+ AcpiOsPrintf ("CanWake, ");
}
else
{
- AcpiOsPrintf ("Run 0], ");
+ AcpiOsPrintf ("RunOnly, ");
}
switch (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)
@@ -957,7 +936,7 @@ AcpiDbDisplayGpes (
break;
}
- AcpiOsPrintf ("\n");
+ AcpiOsPrintf (")\n");
}
}
Block++;
Modified: head/sys/contrib/dev/acpica/events/evgpe.c
==============================================================================
--- head/sys/contrib/dev/acpica/events/evgpe.c Fri Apr 2 21:48:27 2010 (r206116)
+++ head/sys/contrib/dev/acpica/events/evgpe.c Fri Apr 2 23:04:31 2010 (r206117)
@@ -134,71 +134,20 @@ AcpiEvAsynchEnableGpe (
/*******************************************************************************
*
- * FUNCTION: AcpiEvSetGpeType
- *
- * PARAMETERS: GpeEventInfo - GPE to set
- * Type - New type
- *
- * RETURN: Status
- *
- * DESCRIPTION: Sets the new type for the GPE (wake, run, or wake/run)
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiEvSetGpeType (
- ACPI_GPE_EVENT_INFO *GpeEventInfo,
- UINT8 Type)
-{
- ACPI_STATUS Status;
-
-
- ACPI_FUNCTION_TRACE (EvSetGpeType);
-
-
- /* Validate type and update register enable masks */
-
- switch (Type)
- {
- case ACPI_GPE_TYPE_WAKE:
- case ACPI_GPE_TYPE_RUNTIME:
- case ACPI_GPE_TYPE_WAKE_RUN:
- break;
-
- default:
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
-
- /* Disable the GPE if currently enabled */
-
- Status = AcpiEvDisableGpe (GpeEventInfo);
-
- /* Clear the type bits and insert the new Type */
-
- GpeEventInfo->Flags &= ~ACPI_GPE_TYPE_MASK;
- GpeEventInfo->Flags |= Type;
- return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
* FUNCTION: AcpiEvUpdateGpeEnableMasks
*
* PARAMETERS: GpeEventInfo - GPE to update
- * Type - What to do: ACPI_GPE_DISABLE or
- * ACPI_GPE_ENABLE
*
* RETURN: Status
*
- * DESCRIPTION: Updates GPE register enable masks based on the GPE type
+ * DESCRIPTION: Updates GPE register enable masks based upon whether there are
+ * references (either wake or run) to this GPE
*
******************************************************************************/
ACPI_STATUS
AcpiEvUpdateGpeEnableMasks (
- ACPI_GPE_EVENT_INFO *GpeEventInfo,
- UINT8 Type)
+ ACPI_GPE_EVENT_INFO *GpeEventInfo)
{
ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
UINT8 RegisterBit;
@@ -216,36 +165,21 @@ AcpiEvUpdateGpeEnableMasks (
RegisterBit = (UINT8)
(1 << (GpeEventInfo->GpeNumber - GpeRegisterInfo->BaseGpeNumber));
- /* 1) Disable case. Simply clear all enable bits */
+ /* Clear the wake/run bits up front */
- if (Type == ACPI_GPE_DISABLE)
- {
- ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
- ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
- return_ACPI_STATUS (AE_OK);
- }
+ ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
+ ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
- /* 2) Enable case. Set/Clear the appropriate enable bits */
+ /* Set the mask bits only if there are references to this GPE */
- switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK)
+ if (GpeEventInfo->RuntimeCount)
{
- case ACPI_GPE_TYPE_WAKE:
- ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
- ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
- break;
-
- case ACPI_GPE_TYPE_RUNTIME:
- ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
- ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
- break;
-
- case ACPI_GPE_TYPE_WAKE_RUN:
- ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
- ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
- break;
+ ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
+ }
- default:
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ if (GpeEventInfo->WakeupCount)
+ {
+ ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
}
return_ACPI_STATUS (AE_OK);
@@ -257,19 +191,19 @@ AcpiEvUpdateGpeEnableMasks (
* FUNCTION: AcpiEvEnableGpe
*
* PARAMETERS: GpeEventInfo - GPE to enable
- * WriteToHardware - Enable now, or just mark data structs
- * (WAKE GPEs should be deferred)
*
* RETURN: Status
*
- * DESCRIPTION: Enable a GPE based on the GPE type
+ * DESCRIPTION: Hardware-enable a GPE. Always enables the GPE, regardless
+ * of type or number of references.
+ *
+ * Note: The GPE lock should be already acquired when this function is called.
*
******************************************************************************/
ACPI_STATUS
AcpiEvEnableGpe (
- ACPI_GPE_EVENT_INFO *GpeEventInfo,
- BOOLEAN WriteToHardware)
+ ACPI_GPE_EVENT_INFO *GpeEventInfo)
{
ACPI_STATUS Status;
@@ -277,54 +211,37 @@ AcpiEvEnableGpe (
ACPI_FUNCTION_TRACE (EvEnableGpe);
- /* Make sure HW enable masks are updated */
+ /*
+ * We will only allow a GPE to be enabled if it has either an
+ * associated method (_Lxx/_Exx) or a handler. Otherwise, the
+ * GPE will be immediately disabled by AcpiEvGpeDispatch the
+ * first time it fires.
+ */
+ if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK))
+ {
+ return_ACPI_STATUS (AE_NO_HANDLER);
+ }
+
+ /* Ensure the HW enable masks are current */
- Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_ENABLE);
+ Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
- /* Mark wake-enabled or HW enable, or both */
+ /* Clear the GPE (of stale events) */
- switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK)
+ Status = AcpiHwClearGpe (GpeEventInfo);
+ if (ACPI_FAILURE (Status))
{
- case ACPI_GPE_TYPE_WAKE:
-
- ACPI_SET_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED);
- break;
-
- case ACPI_GPE_TYPE_WAKE_RUN:
-
- ACPI_SET_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED);
-
- /*lint -fallthrough */
-
- case ACPI_GPE_TYPE_RUNTIME:
-
- ACPI_SET_BIT (GpeEventInfo->Flags, ACPI_GPE_RUN_ENABLED);
-
- if (WriteToHardware)
- {
- /* Clear the GPE (of stale events), then enable it */
-
- Status = AcpiHwClearGpe (GpeEventInfo);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
-
- /* Enable the requested runtime GPE */
-
- Status = AcpiHwWriteGpeEnableReg (GpeEventInfo);
- }
- break;
-
- default:
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ return_ACPI_STATUS (Status);
}
- return_ACPI_STATUS (AE_OK);
+ /* Enable the requested GPE */
+
+ Status = AcpiHwWriteGpeEnableReg (GpeEventInfo);
+ return_ACPI_STATUS (Status);
}
@@ -336,7 +253,10 @@ AcpiEvEnableGpe (
*
* RETURN: Status
*
- * DESCRIPTION: Disable a GPE based on the GPE type
+ * DESCRIPTION: Hardware-disable a GPE. Always disables the requested GPE,
+ * regardless of the type or number of references.
+ *
+ * Note: The GPE lock should be already acquired when this function is called.
*
******************************************************************************/
@@ -356,40 +276,14 @@ AcpiEvDisableGpe (
* the GPE behind our back.
*/
- /* Make sure HW enable masks are updated */
+ /* Ensure the HW enable masks are current */
- Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_DISABLE);
+ Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
- /* Clear the appropriate enabled flags for this GPE */
-
- switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK)
- {
- case ACPI_GPE_TYPE_WAKE:
-
- ACPI_CLEAR_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED);
- break;
-
- case ACPI_GPE_TYPE_WAKE_RUN:
-
- ACPI_CLEAR_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED);
-
- /*lint -fallthrough */
-
- case ACPI_GPE_TYPE_RUNTIME:
-
- /* Disable the requested runtime GPE */
-
- ACPI_CLEAR_BIT (GpeEventInfo->Flags, ACPI_GPE_RUN_ENABLED);
- break;
-
- default:
- break;
- }
-
/*
* Always H/W disable this GPE, even if we don't know the GPE type.
* Simply clear the enable bit for this particular GPE, but do not
@@ -405,6 +299,49 @@ AcpiEvDisableGpe (
/*******************************************************************************
*
+ * FUNCTION: AcpiEvLowGetGpeInfo
+ *
+ * PARAMETERS: GpeNumber - Raw GPE number
+ * GpeBlock - A GPE info block
+ *
+ * RETURN: A GPE EventInfo struct. NULL if not a valid GPE (The GpeNumber
+ * is not within the specified GPE block)
+ *
+ * DESCRIPTION: Returns the EventInfo struct associated with this GPE. This is
+ * the low-level implementation of EvGetGpeEventInfo.
+ *
+ ******************************************************************************/
+
+ACPI_GPE_EVENT_INFO *
+AcpiEvLowGetGpeInfo (
+ UINT32 GpeNumber,
+ ACPI_GPE_BLOCK_INFO *GpeBlock)
+{
+ UINT32 GpeIndex;
+
+
+ /*
+ * Validate that the GpeNumber is within the specified GpeBlock.
+ * (Two steps)
+ */
+ if (!GpeBlock ||
+ (GpeNumber < GpeBlock->BlockBaseNumber))
+ {
+ return (NULL);
+ }
+
+ GpeIndex = GpeNumber - GpeBlock->BlockBaseNumber;
+ if (GpeIndex >= GpeBlock->GpeCount)
+ {
+ return (NULL);
+ }
+
+ return (&GpeBlock->EventInfo[GpeIndex]);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: AcpiEvGetGpeEventInfo
*
* PARAMETERS: GpeDevice - Device node. NULL for GPE0/GPE1
@@ -426,7 +363,7 @@ AcpiEvGetGpeEventInfo (
UINT32 GpeNumber)
{
ACPI_OPERAND_OBJECT *ObjDesc;
- ACPI_GPE_BLOCK_INFO *GpeBlock;
+ ACPI_GPE_EVENT_INFO *GpeInfo;
UINT32 i;
@@ -441,16 +378,11 @@ AcpiEvGetGpeEventInfo (
for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++)
{
- GpeBlock = AcpiGbl_GpeFadtBlocks[i];
- if (GpeBlock)
+ GpeInfo = AcpiEvLowGetGpeInfo (GpeNumber,
+ AcpiGbl_GpeFadtBlocks[i]);
+ if (GpeInfo)
{
- if ((GpeNumber >= GpeBlock->BlockBaseNumber) &&
- (GpeNumber < GpeBlock->BlockBaseNumber +
- (GpeBlock->RegisterCount * 8)))
- {
- return (&GpeBlock->EventInfo[GpeNumber -
- GpeBlock->BlockBaseNumber]);
- }
+ return (GpeInfo);
}
}
@@ -468,15 +400,7 @@ AcpiEvGetGpeEventInfo (
return (NULL);
}
- GpeBlock = ObjDesc->Device.GpeBlock;
-
- if ((GpeNumber >= GpeBlock->BlockBaseNumber) &&
- (GpeNumber < GpeBlock->BlockBaseNumber + (GpeBlock->RegisterCount * 8)))
- {
- return (&GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber]);
- }
-
- return (NULL);
+ return (AcpiEvLowGetGpeInfo (GpeNumber, ObjDesc->Device.GpeBlock));
}
@@ -654,9 +578,9 @@ AcpiEvAsynchExecuteGpeMethod (
return_VOID;
}
- /* Set the GPE flags for return to enabled state */
+ /* Update the GPE register masks for return to enabled state */
- (void) AcpiEvEnableGpe (GpeEventInfo, FALSE);
+ (void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
/*
* Take a snapshot of the GPE info for this level - we copy the info to
@@ -872,15 +796,18 @@ AcpiEvGpeDispatch (
default:
- /* No handler or method to run! */
-
+ /*
+ * No handler or method to run!
+ * 03/2010: This case should no longer be possible. We will not allow
+ * a GPE to be enabled if it has no handler or method.
+ */
ACPI_ERROR ((AE_INFO,
"No handler or method for GPE[0x%2X], disabling event",
GpeNumber));
/*
- * Disable the GPE. The GPE will remain disabled until the ACPICA
- * Core Subsystem is restarted, or a handler is installed.
+ * Disable the GPE. The GPE will remain disabled a handler
+ * is installed or ACPICA is restarted.
*/
Status = AcpiEvDisableGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
Modified: head/sys/contrib/dev/acpica/events/evgpeblk.c
==============================================================================
--- head/sys/contrib/dev/acpica/events/evgpeblk.c Fri Apr 2 21:48:27 2010 (r206116)
+++ head/sys/contrib/dev/acpica/events/evgpeblk.c Fri Apr 2 23:04:31 2010 (r206117)
@@ -124,7 +124,7 @@
/* Local prototypes */
static ACPI_STATUS
-AcpiEvSaveMethodInfo (
+AcpiEvMatchGpeMethod (
ACPI_HANDLE ObjHandle,
UINT32 Level,
void *ObjDesc,
@@ -194,8 +194,7 @@ AcpiEvValidGpeEvent (
while (GpeBlock)
{
if ((&GpeBlock->EventInfo[0] <= GpeEventInfo) &&
- (&GpeBlock->EventInfo[((ACPI_SIZE)
- GpeBlock->RegisterCount) * 8] > GpeEventInfo))
+ (&GpeBlock->EventInfo[GpeBlock->GpeCount] > GpeEventInfo))
{
return (TRUE);
}
@@ -328,7 +327,7 @@ AcpiEvDeleteGpeHandlers (
/*******************************************************************************
*
- * FUNCTION: AcpiEvSaveMethodInfo
+ * FUNCTION: AcpiEvMatchGpeMethod
*
* PARAMETERS: Callback from WalkNamespace
*
@@ -340,8 +339,7 @@ AcpiEvDeleteGpeHandlers (
* information for quick lookup during GPE dispatch
*
* The name of each GPE control method is of the form:
- * "_Lxx" or "_Exx"
- * Where:
+ * "_Lxx" or "_Exx", where:
* L - means that the GPE is level triggered
* E - means that the GPE is edge triggered
* xx - is the GPE number [in HEX]
@@ -349,38 +347,44 @@ AcpiEvDeleteGpeHandlers (
******************************************************************************/
static ACPI_STATUS
-AcpiEvSaveMethodInfo (
+AcpiEvMatchGpeMethod (
ACPI_HANDLE ObjHandle,
UINT32 Level,
void *ObjDesc,
void **ReturnValue)
{
+ ACPI_NAMESPACE_NODE *MethodNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
ACPI_GPE_BLOCK_INFO *GpeBlock = (void *) ObjDesc;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
UINT32 GpeNumber;
char Name[ACPI_NAME_SIZE + 1];
UINT8 Type;
- ACPI_STATUS Status;
- ACPI_FUNCTION_TRACE (EvSaveMethodInfo);
+ ACPI_FUNCTION_TRACE (EvMatchGpeMethod);
/*
- * _Lxx and _Exx GPE method support
+ * Match and decode the _Lxx and _Exx GPE method names
*
- * 1) Extract the name from the object and convert to a string
+ * 1) Extract the method name and null terminate it
*/
- ACPI_MOVE_32_TO_32 (
- Name, &((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Integer);
+ ACPI_MOVE_32_TO_32 (Name, &MethodNode->Name.Integer);
Name[ACPI_NAME_SIZE] = 0;
+ /* 2) Name must begin with an underscore */
+
+ if (Name[0] != '_')
+ {
+ return_ACPI_STATUS (AE_OK); /* Ignore this method */
+ }
+
/*
- * 2) Edge/Level determination is based on the 2nd character
+ * 3) Edge/Level determination is based on the 2nd character
* of the method name
*
- * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE
- * if a _PRW object is found that points to this GPE.
+ * NOTE: Default GPE type is RUNTIME only. Later, if a _PRW object is
+ * found that points to this GPE, the ACPI_GPE_CAN_WAKE flag is set.
*/
switch (Name[1])
{
@@ -393,16 +397,15 @@ AcpiEvSaveMethodInfo (
break;
default:
- /* Unknown method type, just ignore it! */
+ /* Unknown method type, just ignore it */
ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
"Ignoring unknown GPE method type: %s "
- "(name not of form _Lxx or _Exx)",
- Name));
+ "(name not of form _Lxx or _Exx)", Name));
return_ACPI_STATUS (AE_OK);
}
- /* Convert the last two characters of the name to the GPE Number */
+ /* 4) The last two characters of the name are the hex GPE Number */
GpeNumber = ACPI_STRTOUL (&Name[2], NULL, 16);
if (GpeNumber == ACPI_UINT32_MAX)
@@ -411,45 +414,34 @@ AcpiEvSaveMethodInfo (
ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
"Could not extract GPE number from name: %s "
- "(name is not of form _Lxx or _Exx)",
- Name));
+ "(name is not of form _Lxx or _Exx)", Name));
return_ACPI_STATUS (AE_OK);
}
/* Ensure that we have a valid GPE number for this GPE block */
- if ((GpeNumber < GpeBlock->BlockBaseNumber) ||
- (GpeNumber >= (GpeBlock->BlockBaseNumber +
- (GpeBlock->RegisterCount * 8))))
+ GpeEventInfo = AcpiEvLowGetGpeInfo (GpeNumber, GpeBlock);
+ if (!GpeEventInfo)
{
/*
- * Not valid for this GPE block, just ignore it. However, it may be
- * valid for a different GPE block, since GPE0 and GPE1 methods both
- * appear under \_GPE.
+ * This GpeNumber is not valid for this GPE block, just ignore it.
+ * However, it may be valid for a different GPE block, since GPE0
+ * and GPE1 methods both appear under \_GPE.
*/
return_ACPI_STATUS (AE_OK);
}
/*
- * Now we can add this information to the GpeEventInfo block for use
- * during dispatch of this GPE. Default type is RUNTIME, although this may
- * change when the _PRW methods are executed later.
+ * Add the GPE information from above to the GpeEventInfo block for
+ * use during dispatch of this GPE.
*/
- GpeEventInfo = &GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber];
-
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list