-#define ACPI_CA_VERSION 0x20040211
+#define ACPI_CA_VERSION 0x20040527
+
+/*
+ * OS name, used for the _OS object. The _OS object is essentially obsolete,
+ * but there is a large base of ASL/AML code in existing machines that check
+ * for the string below. The use of this string usually guarantees that
+ * the ASL will execute down the most tested code path. Also, there is some
+ * code that will not execute the _OSI method unless _OS matches the string
+ * below. Therefore, change this string at your own risk.
+ */
+#define ACPI_OS_NAME "Microsoft Windows NT"
/* Maximum objects in the various object caches */
-#define ACPI_MAX_STATE_CACHE_DEPTH 64 /* State objects for stacks */
+#define ACPI_MAX_STATE_CACHE_DEPTH 64 /* State objects */
#define ACPI_MAX_PARSE_CACHE_DEPTH 96 /* Parse tree objects */
#define ACPI_MAX_EXTPARSE_CACHE_DEPTH 64 /* Parse tree objects */
#define ACPI_MAX_OBJECT_CACHE_DEPTH 64 /* Interpreter operand objects */
@@ -225,10 +235,11 @@
/* Constants used in searching for the RSDP in low memory */
@@ -225,12 +225,8 @@
#define COMPILER_DEPENDENT_INT64 long long
#define COMPILER_DEPENDENT_UINT64 unsigned long long
-
-/* Name of host operating system (returned by the _OS_ namespace object) */
-
-#define ACPI_OS_NAME "Intel ACPI/CA Core Subsystem"
-
-/* This macro is used to tag functions as "printf-like" because
+/*
+ * This macro is used to tag functions as "printf-like" because
* some compilers can catch printf format string problems. MSVC
* doesn't, so this is proprocessed away.
*/
Index: sys/dev/acpi/acpica/Subsystem/acevents.h
===================================================================
RCS file: /cvsroot/src/sys/dev/acpi/acpica/Subsystem/acevents.h,v
retrieving revision 1.9
diff -u -r1.9 acevents.h
--- sys/dev/acpi/acpica/Subsystem/acevents.h 14 Feb 2004 16:57:24 -0000 1.9
+++ sys/dev/acpi/acpica/Subsystem/acevents.h 17 Jun 2004 04:08:34 -0000
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Name: acevents.h - Event subcomponent prototypes and defines
- * xRevision: 93 $
+ * xRevision: 95 $
*
*****************************************************************************/
/*
- * Ensure that the globals are actually defined only once.
+ * Ensure that the globals are actually defined and initialized only once.
*
- * The use of these defines allows a single list of globals (here) in order
+ * The use of these macros allows a single list of globals (here) in order
* to simplify maintenance of the code.
*/
#ifdef DEFINE_ACPI_GLOBALS
#define ACPI_EXTERN
+#define ACPI_INIT_GLOBAL(a,b) a=b
#else
#define ACPI_EXTERN extern
+#define ACPI_INIT_GLOBAL(a,b) a
#endif
+/*
+ * Keep local copies of these FADT-based registers. NOTE: These globals
+ * are first in this file for alignment reasons on 64-bit systems.
+ */
+ACPI_EXTERN ACPI_GENERIC_ADDRESS AcpiGbl_XPm1aEnable;
+ACPI_EXTERN ACPI_GENERIC_ADDRESS AcpiGbl_XPm1bEnable;
+
/*****************************************************************************
*
+ * Runtime configuration (static defaults that can be overriden at runtime)
+ *
+ ****************************************************************************/
+
+/*
+ * Create the predefined _OSI method in the namespace? Default is TRUE
+ * because ACPI CA is fully compatible with other ACPI implementations.
+ * Changing this will revert ACPI CA (and machine ASL) to pre-OSI behavior.
+ */
+ACPI_EXTERN UINT8 ACPI_INIT_GLOBAL (AcpiGbl_CreateOsiMethod, TRUE);
+
+/*
+ * Automatically serialize ALL control methods? Default is FALSE, meaning
+ * to use the Serialized/NotSerialized method flags on a per method basis.
+ * Only change this if the ASL code is poorly written and cannot handle
+ * reentrancy even though methods are marked "NotSerialized".
+ */
+ACPI_EXTERN UINT8 ACPI_INIT_GLOBAL (AcpiGbl_AllMethodsSerialized, FALSE);
+
+/*
+ * Disable wakeup GPEs during runtime? Default is TRUE because WAKE and
+ * RUNTIME GPEs should never be shared, and WAKE GPEs should typically only
+ * be enabled just before going to sleep.
+ */
+ACPI_EXTERN UINT8 ACPI_INIT_GLOBAL (AcpiGbl_LeaveWakeGpesDisabled, TRUE);
+
+
+/*****************************************************************************
+ *
* ACPI Table globals
*
****************************************************************************/
@@ -160,7 +198,6 @@
*
* These tables are single-table only; meaning that there can be at most one
* of each in the system. Each global points to the actual table.
- *
*/
ACPI_EXTERN UINT32 AcpiGbl_TableFlags;
ACPI_EXTERN UINT32 AcpiGbl_RsdtTableCount;
@@ -170,6 +207,11 @@
ACPI_EXTERN ACPI_TABLE_HEADER *AcpiGbl_DSDT;
ACPI_EXTERN FACS_DESCRIPTOR *AcpiGbl_FACS;
ACPI_EXTERN ACPI_COMMON_FACS AcpiGbl_CommonFACS;
+/*
+ * Since there may be multiple SSDTs and PSDTS, a single pointer is not
+ * sufficient; Therefore, there isn't one!
+ */
+
-/* Keep local copies of these FADT-based registers */
-
-ACPI_EXTERN ACPI_GENERIC_ADDRESS AcpiGbl_XPm1aEnable;
-ACPI_EXTERN ACPI_GENERIC_ADDRESS AcpiGbl_XPm1bEnable;
-
-/*
- * Since there may be multiple SSDTs and PSDTS, a single pointer is not
- * sufficient; Therefore, there isn't one!
- */
-
-
/*
* ACPI Table info arrays
*/
@@ -234,13 +265,16 @@
ACPI_EXTERN BOOLEAN AcpiGbl_AcpiHardwarePresent;
ACPI_EXTERN BOOLEAN AcpiGbl_GlobalLockPresent;
ACPI_EXTERN BOOLEAN AcpiGbl_EventsInitialized;
+ACPI_EXTERN BOOLEAN AcpiGbl_SystemAwakeAndRunning;
@@ -264,8 +264,6 @@
UINT8 Type; /* Type associated with this name */
UINT16 OwnerId;
ACPI_NAME_UNION Name; /* ACPI Name, always 4 chars per ACPI spec */
-
-
union acpi_operand_object *Object; /* Pointer to attached ACPI object (optional) */
struct acpi_namespace_node *Child; /* First child */
struct acpi_namespace_node *Peer; /* Next peer*/
@@ -287,10 +285,8 @@
#define ANOBJ_METHOD_LOCAL 0x10
#define ANOBJ_METHOD_NO_RETVAL 0x20
#define ANOBJ_METHOD_SOME_NO_RETVAL 0x40
-
#define ANOBJ_IS_BIT_OFFSET 0x80
-
/*
* ACPI Table Descriptor. One per ACPI table
*/
@@ -392,16 +388,33 @@
*
****************************************************************************/
-/* Information about a GPE, one per each GPE in an array */
+/* Dispatch info for each GPE -- either a method or handler, cannot be both */
-typedef struct acpi_gpe_event_info
+typedef struct acpi_handler_info
{
- ACPI_NAMESPACE_NODE *MethodNode; /* Method node for this GPE level */
- ACPI_GPE_HANDLER Handler; /* Address of handler, if any */
+ ACPI_EVENT_HANDLER Address; /* Address of handler, if any */
void *Context; /* Context to be passed to handler */
+ ACPI_NAMESPACE_NODE *MethodNode; /* Method node for this GPE level (saved) */
+
+} ACPI_HANDLER_INFO;
+
+typedef union acpi_gpe_dispatch_info
+{
+ ACPI_NAMESPACE_NODE *MethodNode; /* Method node for this GPE level */
+ struct acpi_handler_info *Handler;
+
+} ACPI_GPE_DISPATCH_INFO;
+
+/*
+ * Information about a GPE, one per each GPE in an array.
+ * NOTE: Important to keep this struct as small as possible.
+ */
+typedef struct acpi_gpe_event_info
+{
+ union acpi_gpe_dispatch_info Dispatch; /* Either Method or Handler */
struct acpi_gpe_register_info *RegisterInfo; /* Backpointer to register info */
- UINT8 Flags; /* Level or Edge */
- UINT8 BitMask; /* This GPE within the register */
+ UINT8 Flags; /* Misc info about this GPE */
+ UINT8 RegisterBit; /* This GPE bit within the register */
} ACPI_GPE_EVENT_INFO;
@@ -411,9 +424,8 @@
{
ACPI_GENERIC_ADDRESS StatusAddress; /* Address of status reg */
ACPI_GENERIC_ADDRESS EnableAddress; /* Address of enable reg */
- UINT8 Status; /* Current value of status reg */
- UINT8 Enable; /* Current value of enable reg */
- UINT8 WakeEnable; /* Mask of bits to keep enabled when sleeping */
+ UINT8 EnableForWake; /* GPEs to keep enabled when sleeping */
+ UINT8 EnableForRun; /* GPEs to keep enabled when running */
UINT8 BaseGpeNumber; /* Base GPE number for this register */
-#if 0
-/*
- * XXX this is technically correct, but will cause problems with some ASL
- * which only works if the string names a Microsoft operating system.
- */
-#define ACPI_OS_NAME "NetBSD"
-#else
-#define ACPI_OS_NAME "Microsoft Windows NT"
-#endif
-
/* NetBSD uses GCC */
@@ -142,13 +142,14 @@
typedef struct acpi_walk_state
{
UINT8 DataType; /* To differentiate various internal objs MUST BE FIRST!*/\
+ UINT8 WalkType;
ACPI_OWNER_ID OwnerId; /* Owner of objects created during the walk */
BOOLEAN LastPredicate; /* Result of last predicate */
+ UINT8 Reserved; /* For alignment */
UINT8 CurrentResult; /* */
UINT8 NextOpInfo; /* Info about NextOp */
UINT8 NumOperands; /* Stack pointer for Operands[] array */
UINT8 ReturnUsed;
- UINT8 WalkType;
UINT16 Opcode; /* Current AML opcode */
UINT8 ScopeDepth;
UINT8 Reserved1;
@@ -164,7 +165,8 @@
struct acpi_namespace_node Arguments[ACPI_METHOD_NUM_ARGS]; /* Control method arguments */
union acpi_operand_object **CallerReturnDesc;
ACPI_GENERIC_STATE *ControlState; /* List of control states (nested IFs) */
- struct acpi_namespace_node *DeferredNode; /* Used when executing deferred opcodes */
+ struct acpi_namespace_node *DeferredNode; /* Used when executing deferred opcodes */
+ struct acpi_gpe_event_info *GpeEventInfo; /* Info for GPE (_Lxx/_Exx methods only */
struct acpi_namespace_node LocalVariables[ACPI_METHOD_NUM_LOCALS]; /* Control method locals */
struct acpi_namespace_node *MethodCallNode; /* Called method Node*/
ACPI_PARSE_OBJECT *MethodCallOp; /* MethodCall Op if running a method */
@@ -279,4 +281,22 @@
} ACPI_AML_OPERANDS;
-
/*
* Table types. These values are passed to the table related APIs
*/
@@ -488,14 +486,13 @@
#define ACPI_TABLE_MAX 6
#define NUM_ACPI_TABLE_TYPES (ACPI_TABLE_MAX+1)
-
/*
* Types associated with ACPI names and objects. The first group of
* values (up to ACPI_TYPE_EXTERNAL_MAX) correspond to the definition
* of the ACPI ObjectType() operator (See the ACPI Spec). Therefore,
* only add to the first group if the spec changes.
*
- * Types must be kept in sync with the global AcpiNsProperties
+ * NOTE: Types must be kept in sync with the global AcpiNsProperties
* and AcpiNsTypeNames arrays.
*/
typedef UINT32 ACPI_OBJECT_TYPE;
@@ -532,26 +529,27 @@
#define ACPI_TYPE_LOCAL_INDEX_FIELD 0x13
#define ACPI_TYPE_LOCAL_REFERENCE 0x14 /* Arg#, Local#, Name, Debug, RefOf, Index */
#define ACPI_TYPE_LOCAL_ALIAS 0x15
-#define ACPI_TYPE_LOCAL_NOTIFY 0x16
-#define ACPI_TYPE_LOCAL_ADDRESS_HANDLER 0x17
-#define ACPI_TYPE_LOCAL_RESOURCE 0x18
-#define ACPI_TYPE_LOCAL_RESOURCE_FIELD 0x19
-#define ACPI_TYPE_LOCAL_SCOPE 0x1A /* 1 Name, multiple ObjectList Nodes */
+#define ACPI_TYPE_LOCAL_METHOD_ALIAS 0x16
+#define ACPI_TYPE_LOCAL_NOTIFY 0x17
+#define ACPI_TYPE_LOCAL_ADDRESS_HANDLER 0x18
+#define ACPI_TYPE_LOCAL_RESOURCE 0x19
+#define ACPI_TYPE_LOCAL_RESOURCE_FIELD 0x1A
+#define ACPI_TYPE_LOCAL_SCOPE 0x1B /* 1 Name, multiple ObjectList Nodes */
-#define ACPI_TYPE_NS_NODE_MAX 0x1A /* Last typecode used within a NS Node */
+#define ACPI_TYPE_NS_NODE_MAX 0x1B /* Last typecode used within a NS Node */
/*
* These are special object types that never appear in
* a Namespace node, only in an ACPI_OPERAND_OBJECT
*/
-#define ACPI_TYPE_LOCAL_EXTRA 0x1B
-#define ACPI_TYPE_LOCAL_DATA 0x1C
+#define ACPI_TYPE_LOCAL_EXTRA 0x1C
+#define ACPI_TYPE_LOCAL_DATA 0x1D
- UINT32 Valid; /* Indicates which fields are valid */
+ UINT32 Valid; /* Indicates which fields below are valid */
UINT32 CurrentStatus; /* _STA value */
ACPI_INTEGER Address; /* _ADR value if any */
ACPI_DEVICE_ID HardwareId; /* _HID value if any */
ACPI_DEVICE_ID UniqueId; /* _UID value if any */
+ UINT8 HighestDstates[4]; /* _SxD values: 0xFF indicates not valid */
ACPI_COMPATIBLE_ID_LIST CompatibilityId; /* List of _CIDs if any */
- /* 1) Parse: Create a new walk state for the preempting walk */
-
- NextWalkState = AcpiDsCreateWalkState (ObjDesc->Method.OwningId,
- Op, ObjDesc, NULL);
- if (!NextWalkState)
+ if (!(ObjDesc->Method.MethodFlags & AML_METHOD_INTERNAL_ONLY))
{
- return_ACPI_STATUS (AE_NO_MEMORY);
- }
+ /* 1) Parse: Create a new walk state for the preempting walk */
- /* Create and init a Root Node */
+ NextWalkState = AcpiDsCreateWalkState (ObjDesc->Method.OwningId,
+ Op, ObjDesc, NULL);
+ if (!NextWalkState)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
- Op = AcpiPsCreateScopeOp ();
- if (!Op)
- {
- Status = AE_NO_MEMORY;
- goto Cleanup;
- }
+ /* Create and init a Root Node */
- Status = AcpiPsParseAml (NextWalkState);
- AcpiPsDeleteParseTree (Op);
+ Status = AcpiPsParseAml (NextWalkState);
+ AcpiPsDeleteParseTree (Op);
+ }
/* 2) Execute: Create a new state for the preempting walk */
@@ -433,7 +438,6 @@
Status = AE_NO_MEMORY;
goto Cleanup;
}
-
/*
* The resolved arguments were put on the previous walk state's operand
* stack. Operands on the previous walk state stack always
@@ -442,9 +446,12 @@
*/
ThisWalkState->Operands [ThisWalkState->NumOperands] = NULL;
+ if (ObjDesc->Method.MethodFlags & AML_METHOD_INTERNAL_ONLY)
+ {
+ Status = ObjDesc->Method.Implementation (NextWalkState);
+ return_ACPI_STATUS (Status);
+ }
+
return_ACPI_STATUS (AE_OK);
/* On error, we must delete the new walk state */
Cleanup:
+ if (NextWalkState && (NextWalkState->MethodDesc))
+ {
+ /* Decrement the thread count on the method parse tree */
+
+ NextWalkState->MethodDesc->Method.ThreadCount--;
+ }
(void) AcpiDsTerminateControlMethod (NextWalkState);
AcpiDsDeleteWalkState (NextWalkState);
return_ACPI_STATUS (Status);
-
}
@@ -607,12 +625,34 @@
}
}
- /* Decrement the thread count on the method parse tree */
+ if (WalkState->MethodDesc->Method.ThreadCount)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "*** Not deleting method namespace, there are still %d threads\n",
+ WalkState->MethodDesc->Method.ThreadCount));
+ }
- WalkState->MethodDesc->Method.ThreadCount--;
if (!WalkState->MethodDesc->Method.ThreadCount)
{
/*
+ * Support to dynamically change a method from NotSerialized to
+ * Serialized if it appears that the method is written foolishly and
+ * does not support multiple thread execution. The best example of this
+ * is if such a method creates namespace objects and blocks. A second
+ * thread will fail with an AE_ALREADY_EXISTS exception
+ *
+ * This code is here because we must wait until the last thread exits
+ * before creating the synchronization semaphore.
+ */
+ if ((WalkState->MethodDesc->Method.Concurrency == 1) &&
+ (!WalkState->MethodDesc->Method.Semaphore))
+ {
+ Status = AcpiOsCreateSemaphore (1,
+ 1,
+ &WalkState->MethodDesc->Method.Semaphore);
+ }
+
+ /*
* There are no more threads executing this method. Perform
* additional cleanup.
*
Index: sys/dev/acpi/acpica/Subsystem/dsmthdat.c
===================================================================
RCS file: /cvsroot/src/sys/dev/acpi/acpica/Subsystem/dsmthdat.c,v
retrieving revision 1.11
diff -u -r1.11 dsmthdat.c
--- sys/dev/acpi/acpica/Subsystem/dsmthdat.c 14 Feb 2004 16:57:24 -0000 1.11
+++ sys/dev/acpi/acpica/Subsystem/dsmthdat.c 17 Jun 2004 04:08:40 -0000
@@ -1,7 +1,7 @@
/*******************************************************************************
*
* Module Name: dsmthdat - control method arguments and local variables
- * xRevision: 77 $
+ * xRevision: 78 $
*
******************************************************************************/
/*
- * Store this object to the Node
- * (perform the indirect store)
+ * Store this object to the Node (perform the indirect store)
+ * NOTE: No implicit conversion is performed, as per the ACPI
+ * specification rules on storing to Locals/Args.
*/
Status = AcpiExStoreObjectToNode (NewObjDesc,
- CurrentObjDesc->Reference.Object, WalkState);
+ CurrentObjDesc->Reference.Object, WalkState,
+ ACPI_NO_IMPLICIT_CONVERSION);
/* Remove local reference if we copied the object above */
Index: sys/dev/acpi/acpica/Subsystem/dsopcode.c
===================================================================
RCS file: /cvsroot/src/sys/dev/acpi/acpica/Subsystem/dsopcode.c,v
retrieving revision 1.10
diff -u -r1.10 dsopcode.c
--- sys/dev/acpi/acpica/Subsystem/dsopcode.c 14 Feb 2004 16:57:24 -0000 1.10
+++ sys/dev/acpi/acpica/Subsystem/dsopcode.c 17 Jun 2004 04:08:41 -0000
@@ -2,7 +2,7 @@
*
* Module Name: dsopcode - Dispatcher Op Region support and handling of
* "control" opcodes
- * xRevision: 93 $
+ * xRevision: 95 $
*
*****************************************************************************/
+ /* Set the GPE flags for return to enabled state */
+
+ (void) AcpiEvEnableGpe (GpeEventInfo, FALSE);
+
/*
* Take a snapshot of the GPE info for this level - we copy the
* info to prevent a race condition with RemoveHandler/RemoveBlock.
@@ -371,26 +635,36 @@
return_VOID;
}
- if (LocalGpeEventInfo.MethodNode)
+ /*
+ * Must check for control method type dispatch one more
+ * time to avoid race with EvGpeInstallHandler
+ */
+ if ((LocalGpeEventInfo.Flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD)
{
/*
- * Invoke the GPE Method (_Lxx, _Exx):
- * (Evaluate the _Lxx/_Exx control method that corresponds to this GPE.)
+ * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
+ * control method that corresponds to this GPE
*/
- Status = AcpiNsEvaluateByHandle (LocalGpeEventInfo.MethodNode, NULL, NULL);
+ Info.Node = LocalGpeEventInfo.Dispatch.MethodNode;
+ Info.Parameters = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT *, GpeEventInfo);
+ Info.ParameterType = ACPI_PARAM_GPE;
+
+ Status = AcpiNsEvaluateByHandle (&Info);
if (ACPI_FAILURE (Status))
{
- ACPI_REPORT_ERROR (("%s while evaluating method [%4.4s] for GPE[%2X]\n",
+ ACPI_REPORT_ERROR ((
+ "%s while evaluating method [%4.4s] for GPE[%2X]\n",
AcpiFormatException (Status),
- AcpiUtGetNodeName (LocalGpeEventInfo.MethodNode), GpeNumber));
+ AcpiUtGetNodeName (LocalGpeEventInfo.Dispatch.MethodNode),
+ GpeNumber));
}
}
- if (LocalGpeEventInfo.Flags & ACPI_EVENT_LEVEL_TRIGGERED)
+ if ((LocalGpeEventInfo.Flags & ACPI_GPE_XRUPT_TYPE_MASK) == ACPI_GPE_LEVEL_TRIGGERED)
{
/*
- * GPE is level-triggered, we clear the GPE status bit after handling
- * the event.
+ * GPE is level-triggered, we clear the GPE status bit after
+ * handling the event.
*/
Status = AcpiHwClearGpe (&LocalGpeEventInfo);
if (ACPI_FAILURE (Status))
@@ -401,7 +675,7 @@
@@ -437,7 +711,7 @@
* If edge-triggered, clear the GPE status bit now. Note that
* level-triggered events are cleared after the GPE is serviced.
*/
- if (GpeEventInfo->Flags & ACPI_EVENT_EDGE_TRIGGERED)
+ if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) == ACPI_GPE_EDGE_TRIGGERED)
{
Status = AcpiHwClearGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
@@ -448,6 +722,17 @@
}
}
+ /* Save current system state */
+
+ if (AcpiGbl_SystemAwakeAndRunning)
+ {
+ ACPI_SET_BIT (GpeEventInfo->Flags, ACPI_GPE_SYSTEM_RUNNING);
+ }
+ else
+ {
+ ACPI_CLEAR_BIT (GpeEventInfo->Flags, ACPI_GPE_SYSTEM_RUNNING);
+ }
+
/*
* Dispatch the GPE to either an installed handler, or the control
* method associated with this GPE (_Lxx or _Exx).
@@ -455,15 +740,20 @@
* If there is neither a handler nor a method, we disable the level to
* prevent further events from coming in here.
*/
- if (GpeEventInfo->Handler)
+ switch (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)
{
- /* Invoke the installed handler (at interrupt level) */
+ case ACPI_GPE_DISPATCH_HANDLER:
- GpeEventInfo->Handler (GpeEventInfo->Context);
+ /*
+ * Invoke the installed handler (at interrupt level)
+ * Ignore return status for now. TBD: leave GPE disabled on error?
+ */
+ (void) GpeEventInfo->Dispatch.Handler->Address (
+ GpeEventInfo->Dispatch.Handler->Context);
/* It is now safe to clear level-triggered events. */
- if (GpeEventInfo->Flags & ACPI_EVENT_LEVEL_TRIGGERED)
+ if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) == ACPI_GPE_LEVEL_TRIGGERED)
{
Status = AcpiHwClearGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
@@ -474,14 +764,15 @@
return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
}
}
- }
- else if (GpeEventInfo->MethodNode)
- {
+ break;
+
+ case ACPI_GPE_DISPATCH_METHOD:
+
/*
* Disable GPE, so it doesn't keep firing before the method has a
* chance to run.
*/
- Status = AcpiHwDisableGpe (GpeEventInfo);
+ Status = AcpiEvDisableGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
ACPI_REPORT_ERROR ((
@@ -502,9 +793,10 @@
"AcpiEvGpeDispatch: Unable to queue handler for GPE[%2X], event is disabled\n",
GpeNumber));
}
- }
- else
- {
+ break;
+
+ default:
+
/* No handler or method to run! */
ACPI_REPORT_ERROR ((
@@ -515,7 +807,7 @@
* Disable the GPE. The GPE will remain disabled until the ACPI
* Core Subsystem is restarted, or a handler is installed.
*/
- Status = AcpiHwDisableGpe (GpeEventInfo);
+ Status = AcpiEvDisableGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
ACPI_REPORT_ERROR ((
@@ -523,8 +815,62 @@
GpeNumber));
return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
}
+ break;
}
return_VALUE (ACPI_INTERRUPT_HANDLED);
}
+
+#ifdef ACPI_GPE_NOTIFY_CHECK
+
+/*******************************************************************************
+ * NOT USED, PROTOTYPE ONLY AND WILL PROBABLY BE REMOVED
+ *
+ * FUNCTION: AcpiEvCheckForWakeOnlyGpe
+ *
+ * PARAMETERS: GpeEventInfo - info for this GPE
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Determine if a a GPE is "wake-only".
+ *
+ * Called from Notify() code in interpreter when a "DeviceWake"
+ * Notify comes in.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvCheckForWakeOnlyGpe (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE ("EvCheckForWakeOnlyGpe");
+
+
+ if ((GpeEventInfo) && /* Only >0 for _Lxx/_Exx */
+ ((GpeEventInfo->Flags & ACPI_GPE_SYSTEM_MASK) == ACPI_GPE_SYSTEM_RUNNING)) /* System state at GPE time */
+ {
+ /* This must be a wake-only GPE, disable it */
+
+ Status = AcpiEvDisableGpe (GpeEventInfo);
+
+ /* Set GPE to wake-only. Do not change wake disabled/enabled status */
+
+ AcpiEvSetGpeType (GpeEventInfo, ACPI_GPE_TYPE_WAKE);
+
+ ACPI_REPORT_INFO (("GPE %p was updated from wake/run to wake-only\n",
+ GpeEventInfo));
+
+ /* This was a wake-only GPE */
+
+ return_ACPI_STATUS (AE_WAKE_ONLY_GPE);
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+#endif
+
+
Index: sys/dev/acpi/acpica/Subsystem/evgpeblk.c
===================================================================
RCS file: /cvsroot/src/sys/dev/acpi/acpica/Subsystem/evgpeblk.c,v
retrieving revision 1.7
diff -u -r1.7 evgpeblk.c
--- sys/dev/acpi/acpica/Subsystem/evgpeblk.c 14 Feb 2004 16:57:24 -0000 1.7
+++ sys/dev/acpi/acpica/Subsystem/evgpeblk.c 17 Jun 2004 04:08:43 -0000
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: evgpeblk - GPE block creation and initialization.
- * xRevision: 27 $
+ * xRevision: 36 $
*
*****************************************************************************/
@@ -129,7 +129,7 @@
*
* FUNCTION: AcpiEvValidGpeEvent
*
- * PARAMETERS: GpeEventInfo - Info for this GPE
+ * PARAMETERS: GpeEventInfo - Info for this GPE
*
* RETURN: TRUE if the GpeEvent is valid
*
@@ -236,6 +236,56 @@
}
+/******************************************************************************
+ *
+ * FUNCTION: AcpiEvDeleteGpeHandlers
+ *
+ * PARAMETERS: GpeXruptInfo - GPE Interrupt info
+ * GpeBlock - Gpe Block info
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Delete all Handler objects found in the GPE data structs.
+ * Used only prior to termination.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvDeleteGpeHandlers (
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
+ ACPI_GPE_BLOCK_INFO *GpeBlock)
+{
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_NATIVE_UINT i;
+ ACPI_NATIVE_UINT j;
+
+
+ ACPI_FUNCTION_TRACE ("EvDeleteGpeHandlers");
+
+
+ /* Examine each GPE Register within the block */
+
+ for (i = 0; i < GpeBlock->RegisterCount; i++)
+ {
+ /* Now look at the individual GPEs in this byte register */
+
+ for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
+ {
+ GpeEventInfo = &GpeBlock->EventInfo[(i * ACPI_GPE_REGISTER_WIDTH) + j];
+
+ if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER)
+ {
+ ACPI_MEM_FREE (GpeEventInfo->Dispatch.Handler);
+ GpeEventInfo->Dispatch.Handler = NULL;
+ GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK;
+ }
+ }
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
/*******************************************************************************
*
* FUNCTION: AcpiEvSaveMethodInfo
@@ -250,11 +300,11 @@
* information for quick lookup during GPE dispatch
*
* The name of each GPE control method is of the form:
- * "_Lnn" or "_Enn"
- * Where:
- * L - means that the GPE is level triggered
- * E - means that the GPE is edge triggered
- * nn - is the GPE number [in HEX]
+ * "_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]
*
******************************************************************************/
- /* Extract the name from the object and convert to a string */
-
+ /*
+ * _Lxx and _Exx GPE method support
+ *
+ * 1) Extract the name from the object and convert to a string
+ */
ACPI_MOVE_32_TO_32 (Name,
&((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Integer);
Name[ACPI_NAME_SIZE] = 0;
/*
- * Edge/Level determination is based on the 2nd character
- * of the method name
+ * 2) 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.
*/
switch (Name[1])
{
case 'L':
- Type = ACPI_EVENT_LEVEL_TRIGGERED;
+ Type = ACPI_GPE_LEVEL_TRIGGERED;
break;
case 'E':
- Type = ACPI_EVENT_EDGE_TRIGGERED;
+ Type = ACPI_GPE_EDGE_TRIGGERED;
break;
default:
/* Unknown method type, just ignore it! */
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Unknown GPE method type: %s (name not of form _Lnn or _Enn)\n",
+ "Unknown GPE method type: %s (name not of form _Lxx or _Exx)\n",
Name));
return_ACPI_STATUS (AE_OK);
}
@@ -313,7 +369,7 @@
/* Conversion failed; invalid method, just ignore it */
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not extract GPE number from name: %s (name is not of form _Lnn or _Enn)\n",
+ "Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)\n",
Name));
return_ACPI_STATUS (AE_OK);
}
@@ -333,24 +389,151 @@
/*
* Now we can add this information to the GpeEventInfo block
- * for use during dispatch of this GPE.
+ * for use during dispatch of this GPE. Default type is RUNTIME, although
+ * this may change when the _PRW methods are executed later.
*/
GpeEventInfo = &GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber];
+ /* Find all GPE methods (_Lxx, _Exx) for this block */
+
+ Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice,
+ ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, AcpiEvSaveMethodInfo,
+ GpeBlock, NULL);
+
+ /*
+ * Runtime option: Should Wake GPEs be enabled at runtime? The default
+ * is No,they should only be enabled just as the machine goes to sleep.
+ */
+ if (AcpiGbl_LeaveWakeGpesDisabled)
+ {
+ /*
+ * Differentiate RUNTIME vs WAKE GPEs, via the _PRW control methods.
+ * (Each GPE that has one or more _PRWs that reference it is by
+ * definition a WAKE GPE and will not be enabled while the machine
+ * is running.)
+ */
+ GpeInfo.GpeBlock = GpeBlock;
+ GpeInfo.GpeDevice = GpeDevice;
+
+ Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, AcpiEvMatchPrwAndGpe,
+ &GpeInfo, NULL);
+ }
+
+ /*
+ * Enable all GPEs in this block that are 1) "runtime" or "run/wake" GPEs,
+ * and 2) have a corresponding _Lxx or _Exx method. All other GPEs must
+ * be enabled via the AcpiEnableGpe() external interface.
+ */
+ WakeGpeCount = 0;
+ GpeEnabledCount = 0;
+
+ for (i = 0; i < GpeBlock->RegisterCount; i++)
+ {
+ for (j = 0; j < 8; j++)
+ {
+ /* Get the info block for this particular GPE */
+
+ GpeEventInfo = &GpeBlock->EventInfo[(i * ACPI_GPE_REGISTER_WIDTH) + j];
+
+ if (((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) &&
+ (GpeEventInfo->Flags & ACPI_GPE_TYPE_RUNTIME))
+ {
+ GpeEnabledCount++;
+ }
+
+ if (GpeEventInfo->Flags & ACPI_GPE_TYPE_WAKE)
+ {
+ WakeGpeCount++;
+ }
+ }
+ }
+
/* Dump info about this GPE block */
- ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE %02d to %02d [%4.4s] %d regs at %8.8X%8.8X on int %d\n",
- GpeBlock->BlockBaseNumber,
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+ "GPE %02X to %02X [%4.4s] %u regs at %8.8X%8.8X on int 0x%X\n",
+ (UINT32) GpeBlock->BlockBaseNumber,
(UINT32) (GpeBlock->BlockBaseNumber +
((GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH) -1)),
GpeDevice->Name.Ascii,
@@ -868,11 +1114,14 @@
ACPI_FORMAT_UINT64 (ACPI_GET_ADDRESS (GpeBlock->BlockAddress.Address)),
InterruptLevel));
- /* Find all GPE methods (_Lxx, _Exx) for this block */
- Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice,
- ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, AcpiEvSaveMethodInfo,
- GpeBlock, NULL);
+ /* Enable all valid GPEs found above */
+
+ Status = AcpiHwEnableRuntimeGpeBlock (NULL, GpeBlock);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+ "Found %u Wake, Enabled %u Runtime GPEs in this block\n",
+ WakeGpeCount, GpeEnabledCount));
- /* Get a handle to the predefined _GPE object */
-
- Status = AcpiGetHandle (NULL, "\\_GPE", &GpeDevice);
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
/*
- * Initialize the GPE Blocks defined in the FADT
+ * Initialize the GPE Block(s) defined in the FADT
*
* Why the GPE register block lengths are divided by 2: From the ACPI Spec,
* section "General-Purpose Event Registers", we have:
@@ -954,8 +1201,9 @@
- Status = AcpiEvCreateGpeBlock (GpeDevice, &AcpiGbl_FADT->XGpe1Blk,
+ Status = AcpiEvCreateGpeBlock (AcpiGbl_FadtGpeDevice, &AcpiGbl_FADT->XGpe1Blk,
RegisterCount1, AcpiGbl_FADT->Gpe1Base,
AcpiGbl_FADT->SciInt, &AcpiGbl_GpeFadtBlocks[1]);
+
if (ACPI_FAILURE (Status))
{
ACPI_REPORT_ERROR ((
@@ -1015,8 +1264,10 @@
{
/* GPEs are not required by ACPI, this is OK */
- ACPI_REPORT_INFO (("There are no GPE blocks defined in the FADT\n"));
- return_ACPI_STATUS (AE_OK);
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+ "There are no GPE blocks defined in the FADT\n"));
+ Status = AE_OK;
+ goto Cleanup;
}
/* Check for Max GPE number out-of-range */
@@ -1025,9 +1276,12 @@
{
ACPI_REPORT_ERROR (("Maximum GPE number from FADT is too large: 0x%X\n",
GpeNumberMax));
- return_ACPI_STATUS (AE_BAD_VALUE);
+ Status = AE_BAD_VALUE;
+ goto Cleanup;
}
/*
- * For value 1 (Ejection Request), some device method may need to be run.
+ * For value 3 (Ejection Request), some device method may need to be run.
* For value 2 (Device Wake) if _PRW exists, the _PS0 method may need to be run.
* For value 0x80 (Status Change) on the power button or sleep button,
* initiate soft-off or sleep operation?
@@ -197,27 +211,15 @@
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Dispatching Notify(%X) on node %p\n", NotifyValue, Node));
/*
@@ -281,8 +283,8 @@
/* There is no per-device notify handler for this device */
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "No notify handler for [%4.4s] node %p\n",
- AcpiUtGetNodeName (Node), Node));
+ "No notify handler for Notify(%4.4s, %X) node %p\n",
+ AcpiUtGetNodeName (Node), NotifyValue, Node));
}
return (Status);
@@ -663,6 +665,10 @@
}
}
+ /* Deallocate all handler objects installed within GPE info structs */
+
+ Status = AcpiEvWalkGpeList (AcpiEvDeleteGpeHandlers);
+
/* Return to original mode if necessary */
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
/*
* All address spaces (PCI Config, EC, SMBus) are scope dependent
* and registration must occur for a specific device.
@@ -178,10 +184,9 @@
* has already been installed (via AcpiInstallAddressSpaceHandler).
* Similar for AE_SAME_HANDLER.
*/
-
for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++)
{
- Status = AcpiInstallAddressSpaceHandler ((ACPI_HANDLE) AcpiGbl_RootNode,
+ Status = AcpiEvInstallSpaceHandler (AcpiGbl_RootNode,
AcpiGbl_DefaultAddressSpaces[i],
ACPI_DEFAULT_HANDLER, NULL, NULL);
switch (Status)
@@ -192,15 +197,65 @@
/*
- * _REG method has two arguments
- * Arg0: Integer: Operation region space ID
+ * The _REG method has two arguments:
+ *
+ * Arg0, Integer: Operation region space ID
* Same value as RegionObj->Region.SpaceId
- * Arg1: Integer: connection status
+ * Arg1, Integer: connection status
* 1 for connecting the handler,
* 0 for disconnecting the handler
* Passed as a parameter
@@ -269,10 +326,15 @@
Params[1]->Integer.Value = Function;
Params[2] = NULL;
+ Info.Node = RegionObj2->Extra.Method_REG;
+ Info.Parameters = Params;
+ Info.ParameterType = ACPI_PARAM_ARGS;
+
/* Execute the method, no return value */
- if (!(HandlerDesc->AddressSpace.Flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED))
+ if (!(HandlerDesc->AddressSpace.Hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED))
{
/*
* For handlers other than the default (supplied) handlers, we must
@@ -443,7 +505,7 @@
AcpiFormatException (Status)));
}
- if (!(HandlerDesc->AddressSpace.Flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED))
+ if (!(HandlerDesc->AddressSpace.Hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED))
{
/*
* We just returned from a non-default handler, we must re-enter the
@@ -793,6 +855,288 @@
return (Status);
}
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvInstallSpaceHandler
+ *
+ * PARAMETERS: Node - Namespace node for the device
+ * SpaceId - The address space ID
+ * Handler - Address of the handler
+ * Setup - Address of the setup function
+ * Context - Value passed to the handler on each access
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install a handler for all OpRegions of a given SpaceId.
+ * Assumes namespace is locked
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvInstallSpaceHandler (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_ADR_SPACE_TYPE SpaceId,
+ ACPI_ADR_SPACE_HANDLER Handler,
+ ACPI_ADR_SPACE_SETUP Setup,
+ void *Context)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *HandlerObj;
+ ACPI_STATUS Status;
+ ACPI_OBJECT_TYPE Type;
+ UINT16 Flags = 0;
+
+
+ ACPI_FUNCTION_TRACE ("EvInstallSpaceHandler");
+
+
+ /*
+ * This registration is valid for only the types below
+ * and the root. This is where the default handlers
+ * get placed.
+ */
+ if ((Node->Type != ACPI_TYPE_DEVICE) &&
+ (Node->Type != ACPI_TYPE_PROCESSOR) &&
+ (Node->Type != ACPI_TYPE_THERMAL) &&
+ (Node != AcpiGbl_RootNode))
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ if (Handler == ACPI_DEFAULT_HANDLER)
+ {
+ Flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
+
+ switch (SpaceId)
+ {
+ case ACPI_ADR_SPACE_SYSTEM_MEMORY:
+ Handler = AcpiExSystemMemorySpaceHandler;
+ Setup = AcpiEvSystemMemoryRegionSetup;
+ break;
+
+ case ACPI_ADR_SPACE_SYSTEM_IO:
+ Handler = AcpiExSystemIoSpaceHandler;
+ Setup = AcpiEvIoSpaceRegionSetup;
+ break;
+
+ case ACPI_ADR_SPACE_PCI_CONFIG:
+ Handler = AcpiExPciConfigSpaceHandler;
+ Setup = AcpiEvPciConfigRegionSetup;
+ break;
+
+ case ACPI_ADR_SPACE_CMOS:
+ Handler = AcpiExCmosSpaceHandler;
+ Setup = AcpiEvCmosRegionSetup;
+ break;
+
+ case ACPI_ADR_SPACE_PCI_BAR_TARGET:
+ Handler = AcpiExPciBarSpaceHandler;
+ Setup = AcpiEvPciBarRegionSetup;
+ break;
+
+ case ACPI_ADR_SPACE_DATA_TABLE:
+ Handler = AcpiExDataTableSpaceHandler;
+ Setup = NULL;
+ break;
+
+ default:
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+ }
+
+ /* If the caller hasn't specified a setup routine, use the default */
+
+ if (!Setup)
+ {
+ Setup = AcpiEvDefaultRegionSetup;
+ }
+
+ /* Check for an existing internal object */
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (ObjDesc)
+ {
+ /*
+ * The attached device object already exists.
+ * Make sure the handler is not already installed.
+ */
+ HandlerObj = ObjDesc->Device.Handler;
+
+ /* Walk the handler list for this device */
+
+ while (HandlerObj)
+ {
+ /* Same SpaceId indicates a handler already installed */
+
+ if (HandlerObj->AddressSpace.SpaceId == SpaceId)
+ {
+ if (HandlerObj->AddressSpace.Handler == Handler)
+ {
+ /*
+ * It is (relatively) OK to attempt to install the SAME
+ * handler twice. This can easily happen with PCI_Config space.
+ */
+ Status = AE_SAME_HANDLER;
+ goto UnlockAndExit;
+ }
+ else
+ {
+ /* A handler is already installed */
+
+ Status = AE_ALREADY_EXISTS;
+ }
+ goto UnlockAndExit;
+ }
+
+ /* Walk the linked list of handlers */
+
+ HandlerObj = HandlerObj->AddressSpace.Next;
+ }
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Creating object on Device %p while installing handler\n", Node));
+
+ /* ObjDesc does not exist, create one */
+
+ if (Node->Type == ACPI_TYPE_ANY)
+ {
+ Type = ACPI_TYPE_DEVICE;
+ }
+ else
+ {
+ Type = Node->Type;
+ }
+
+ ObjDesc = AcpiUtCreateInternalObject (Type);
+ if (!ObjDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto UnlockAndExit;
+ }
+
+ /* Init new descriptor */
+
+ ObjDesc->Common.Type = (UINT8) Type;
+
+ /* Attach the new object to the Node */
+
+ Status = AcpiNsAttachObject (Node, ObjDesc, Type);
+
+ /* Remove local reference to the object */
+
+ AcpiUtRemoveReference (ObjDesc);
+
+ if (ACPI_FAILURE (Status))
+ {
+ goto UnlockAndExit;
+ }
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
+ AcpiUtGetRegionName (SpaceId), SpaceId,
+ AcpiUtGetNodeName (Node), Node, ObjDesc));
+
+ /*
+ * Install the handler
+ *
+ * At this point there is no existing handler.
+ * Just allocate the object for the handler and link it
+ * into the list.
+ */
+ HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
+ if (!HandlerObj)
+ {
+ Status = AE_NO_MEMORY;
+ goto UnlockAndExit;
+ }
+
+ /* Init handler obj */
+
+ HandlerObj->AddressSpace.SpaceId = (UINT8) SpaceId;
+ HandlerObj->AddressSpace.Hflags = Flags;
+ HandlerObj->AddressSpace.RegionList = NULL;
+ HandlerObj->AddressSpace.Node = Node;
+ HandlerObj->AddressSpace.Handler = Handler;
+ HandlerObj->AddressSpace.Context = Context;
+ HandlerObj->AddressSpace.Setup = Setup;
+
+ /* Install at head of Device.AddressSpace list */
+
+ HandlerObj->AddressSpace.Next = ObjDesc->Device.Handler;
+
+ /*
+ * The Device object is the first reference on the HandlerObj.
+ * Each region that uses the handler adds a reference.
+ */
+ ObjDesc->Device.Handler = HandlerObj;
+
+ /*
+ * Walk the namespace finding all of the regions this
+ * handler will manage.
+ *
+ * Start at the device and search the branch toward
+ * the leaf nodes until either the leaf is encountered or
+ * a device is detected that has an address handler of the
+ * same type.
+ *
+ * In either case, back up and search down the remainder
+ * of the branch
+ */
+ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX,
+ ACPI_NS_WALK_UNLOCK, AcpiEvInstallHandler,
+ HandlerObj, NULL);
+
+UnlockAndExit:
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvExecuteRegMethods
+ *
+ * PARAMETERS: Node - Namespace node for the device
+ * SpaceId - The address space ID
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Run _REG methods for the Space ID;
+ * Note: assumes namespace is locked, or system init time.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvExecuteRegMethods (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_ADR_SPACE_TYPE SpaceId)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE ("EvExecuteRegMethods");
+
+
+ /*
+ * Run all _REG methods for all Operation Regions for this
+ * space ID. This is a separate walk in order to handle any
+ * interdependencies between regions and _REG methods. (i.e. handlers
+ * must be installed for all regions of this Space ID before we
+ * can run any _REG methods)
+ */
+ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX,
+ ACPI_NS_WALK_UNLOCK, AcpiEvRegRun,
+ &SpaceId, NULL);
+
+ return_ACPI_STATUS (Status);
+}
+
+
/*******************************************************************************
*
* FUNCTION: AcpiEvRegRun
@@ -810,20 +1154,13 @@
void *Context,
void **ReturnValue)
{
- ACPI_OPERAND_OBJECT *HandlerObj;
ACPI_OPERAND_OBJECT *ObjDesc;
ACPI_NAMESPACE_NODE *Node;
+ ACPI_ADR_SPACE_TYPE SpaceId;
ACPI_STATUS Status;
- if (ObjDesc->Region.SpaceId != HandlerObj->AddressSpace.SpaceId)
+ if (ObjDesc->Region.SpaceId != SpaceId)
{
/*
* This region is for a different address space
Index: sys/dev/acpi/acpica/Subsystem/evxface.c
===================================================================
RCS file: /cvsroot/src/sys/dev/acpi/acpica/Subsystem/evxface.c,v
retrieving revision 1.10
diff -u -r1.10 evxface.c
--- sys/dev/acpi/acpica/Subsystem/evxface.c 14 Feb 2004 16:57:24 -0000 1.10
+++ sys/dev/acpi/acpica/Subsystem/evxface.c 17 Jun 2004 04:08:43 -0000
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: evxface - External interfaces for ACPI events
- * xRevision: 142 $
+ * xRevision: 145 $
*
*****************************************************************************/
@@ -275,6 +275,7 @@
* HandlerType - The type of handler:
* ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
* ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
+ * ACPI_ALL_NOTIFY: both system and device
* Handler - Address of the handler
* Context - Value passed to the handler on each GPE
*
@@ -334,22 +335,23 @@
{
/* Make sure the handler is not already installed */
- if (HandlerType == ACPI_SYSTEM_NOTIFY)
+ if (HandlerType & ACPI_SYSTEM_NOTIFY)
{
ObjDesc->CommonNotify.SystemNotify = NotifyObj;
}
- else /* ACPI_DEVICE_NOTIFY */
+
+ if (HandlerType & ACPI_DEVICE_NOTIFY)
{
ObjDesc->CommonNotify.DeviceNotify = NotifyObj;
}
+
+ if (HandlerType == ACPI_ALL_NOTIFY)
+ {
+ /* Extra ref if installed in both */
+
+ AcpiUtAddReference (NotifyObj);
+ }
}
@@ -453,6 +462,7 @@
* HandlerType - The type of handler:
* ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
* ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
+ * ACPI_ALL_NOTIFY: both system and device
* Handler - Address of the handler
* RETURN: Status
*
@@ -506,22 +516,23 @@
{
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n"));
/*******************************************************************************
*
- * FUNCTION: AcpiEnableGpe
+ * FUNCTION: AcpiSetGpeType
*
* PARAMETERS: GpeDevice - Parent GPE Device
* GpeNumber - GPE level within the GPE block
- * Flags - Just enable, or also wake enable?
- * Called from ISR or not
+ * Type - New GPE type
*
* RETURN: Status
*
@@ -308,28 +307,17 @@
******************************************************************************/
- /* Use semaphore lock if not executing at interrupt level */
-
- if (Flags & ACPI_NOT_ISR)
- {
- Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
- }
/* Ensure that we have a valid GPE number */
@@ -340,85 +328,77 @@
goto UnlockAndExit;
}
- /* Enable the requested GPE number */
-
- Status = AcpiHwEnableGpe (GpeEventInfo);
- if (ACPI_FAILURE (Status))
+ if ((GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK) == Type)
{
- goto UnlockAndExit;
+ return_ACPI_STATUS (AE_OK);
}
- if (Flags & ACPI_EVENT_WAKE_ENABLE)
- {
- AcpiHwEnableGpeForWakeup (GpeEventInfo);
- }
+ /* Set the new type (will disable GPE if currently enabled) */
+
+ Status = AcpiEvSetGpeType (GpeEventInfo, Type);
- /* Decode the Fixed Event */
+ /* Use semaphore lock if not executing at interrupt level */
- if (Event > ACPI_EVENT_MAX)
+ if (Flags & ACPI_NOT_ISR)
{
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
}
- /*
- * Disable the requested fixed event (by writing a zero to the
- * enable register bit)
- */
- Status = AcpiSetRegister (AcpiGbl_FixedEventInfo[Event].EnableRegisterId,
- 0, ACPI_MTX_LOCK);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
+ /* Ensure that we have a valid GPE number */
- Status = AcpiGetRegister (AcpiGbl_FixedEventInfo[Event].EnableRegisterId,
- &Value, ACPI_MTX_LOCK);
- if (ACPI_FAILURE (Status))
+ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
+ if (!GpeEventInfo)
{
- return_ACPI_STATUS (Status);
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
}
- if (Value != 0)
+ /* Perform the enable */
+
+ Status = AcpiEvEnableGpe (GpeEventInfo, TRUE);
+
+UnlockAndExit:
+ if (Flags & ACPI_NOT_ISR)
{
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not disable %s events\n", AcpiUtGetEventName (Event)));
- return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
}
-
return_ACPI_STATUS (Status);
}
@@ -429,7 +409,7 @@
*
* PARAMETERS: GpeDevice - Parent GPE Device
* GpeNumber - GPE level within the GPE block
- * Flags - Just enable, or also wake enable?
+ * Flags - Just disable, or also wake disable?
* Called from ISR or not
*
* RETURN: Status
@@ -471,24 +451,74 @@
goto UnlockAndExit;
}
+ Status = AcpiEvDisableGpe (GpeEventInfo);
+
+UnlockAndExit:
+ if (Flags & ACPI_NOT_ISR)
+ {
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ }
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDisableEvent
+ *
+ * PARAMETERS: Event - The fixed eventto be enabled
+ * Flags - Reserved
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Disable an ACPI event (fixed)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDisableEvent (
+ UINT32 Event,
+ UINT32 Flags)
+{
+ ACPI_STATUS Status = AE_OK;
+ UINT32 Value;
+
+
+ ACPI_FUNCTION_TRACE ("AcpiDisableEvent");
+
+
+ /* Decode the Fixed Event */
+
+ if (Event > ACPI_EVENT_MAX)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
/*
- * Only disable the requested GPE number for wake if specified.
- * Otherwise, turn it totally off
+ * Disable the requested fixed event (by writing a zero to the
+ * enable register bit)
*/
- if (Flags & ACPI_EVENT_WAKE_DISABLE)
+ Status = AcpiSetRegister (AcpiGbl_FixedEventInfo[Event].EnableRegisterId,
+ 0, ACPI_MTX_LOCK);
+ if (ACPI_FAILURE (Status))
{
- AcpiHwDisableGpeForWakeup (GpeEventInfo);
+ return_ACPI_STATUS (Status);
}
- else
+
+ Status = AcpiGetRegister (AcpiGbl_FixedEventInfo[Event].EnableRegisterId,
+ &Value, ACPI_MTX_LOCK);
+ if (ACPI_FAILURE (Status))
{
- Status = AcpiHwDisableGpe (GpeEventInfo);
+ return_ACPI_STATUS (Status);
}
- /*
- * This registration is valid for only the types below
- * and the root. This is where the default handlers
- * get placed.
- */
- if ((Node->Type != ACPI_TYPE_DEVICE) &&
- (Node->Type != ACPI_TYPE_PROCESSOR) &&
- (Node->Type != ACPI_TYPE_THERMAL) &&
- (Node != AcpiGbl_RootNode))
- {
- Status = AE_BAD_PARAMETER;
- goto UnlockAndExit;
- }
-
- if (Handler == ACPI_DEFAULT_HANDLER)
- {
- Flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
-
- switch (SpaceId)
- {
- case ACPI_ADR_SPACE_SYSTEM_MEMORY:
- Handler = AcpiExSystemMemorySpaceHandler;
- Setup = AcpiEvSystemMemoryRegionSetup;
- break;
-
- case ACPI_ADR_SPACE_SYSTEM_IO:
- Handler = AcpiExSystemIoSpaceHandler;
- Setup = AcpiEvIoSpaceRegionSetup;
- break;
-
- case ACPI_ADR_SPACE_PCI_CONFIG:
- Handler = AcpiExPciConfigSpaceHandler;
- Setup = AcpiEvPciConfigRegionSetup;
- break;
-
- case ACPI_ADR_SPACE_CMOS:
- Handler = AcpiExCmosSpaceHandler;
- Setup = AcpiEvCmosRegionSetup;
- break;
-
- case ACPI_ADR_SPACE_PCI_BAR_TARGET:
- Handler = AcpiExPciBarSpaceHandler;
- Setup = AcpiEvPciBarRegionSetup;
- break;
-
- case ACPI_ADR_SPACE_DATA_TABLE:
- Handler = AcpiExDataTableSpaceHandler;
- Setup = NULL;
- break;
-
- default:
- Status = AE_BAD_PARAMETER;
- goto UnlockAndExit;
- }
- }
-
- /* If the caller hasn't specified a setup routine, use the default */
-
- if (!Setup)
- {
- Setup = AcpiEvDefaultRegionSetup;
- }
-
- /* Check for an existing internal object */
-
- ObjDesc = AcpiNsGetAttachedObject (Node);
- if (ObjDesc)
- {
- /*
- * The attached device object already exists.
- * Make sure the handler is not already installed.
- */
- HandlerObj = ObjDesc->Device.Handler;
-
- /* Walk the handler list for this device */
-
- while (HandlerObj)
- {
- /* Same SpaceId indicates a handler already installed */
-
- if(HandlerObj->AddressSpace.SpaceId == SpaceId)
- {
- if (HandlerObj->AddressSpace.Handler == Handler)
- {
- /*
- * It is (relatively) OK to attempt to install the SAME
- * handler twice. This can easily happen with PCI_Config space.
- */
- Status = AE_SAME_HANDLER;
- goto UnlockAndExit;
- }
- else
- {
- /* A handler is already installed */
-
- Status = AE_ALREADY_EXISTS;
- }
- goto UnlockAndExit;
- }
-
- /* Walk the linked list of handlers */
-
- HandlerObj = HandlerObj->AddressSpace.Next;
- }
- }
- else
- {
- ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
- "Creating object on Device %p while installing handler\n", Node));
-
- /* ObjDesc does not exist, create one */
-
- if (Node->Type == ACPI_TYPE_ANY)
- {
- Type = ACPI_TYPE_DEVICE;
- }
- else
- {
- Type = Node->Type;
- }
-
- ObjDesc = AcpiUtCreateInternalObject (Type);
- if (!ObjDesc)
- {
- Status = AE_NO_MEMORY;
- goto UnlockAndExit;
- }
-
- /* Init new descriptor */
-
- ObjDesc->Common.Type = (UINT8) Type;
-
- /* Attach the new object to the Node */
-
- Status = AcpiNsAttachObject (Node, ObjDesc, Type);
-
- /* Remove local reference to the object */
-
- AcpiUtRemoveReference (ObjDesc);
+ /* Install the handler for all Regions for this Space ID */
- if (ACPI_FAILURE (Status))
- {
- goto UnlockAndExit;
- }
- }
-
- ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
- "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
- AcpiUtGetRegionName (SpaceId), SpaceId,
- AcpiUtGetNodeName (Node), Node, ObjDesc));
-
- /*
- * Install the handler
- *
- * At this point there is no existing handler.
- * Just allocate the object for the handler and link it
- * into the list.
- */
- HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
- if (!HandlerObj)
+ Status = AcpiEvInstallSpaceHandler (Node, SpaceId, Handler, Setup, Context);
+ if (ACPI_FAILURE (Status))
{
- Status = AE_NO_MEMORY;
goto UnlockAndExit;
}
- /* Init handler obj */
+ /* Run all _REG methods for this address space */
- HandlerObj->AddressSpace.SpaceId = (UINT8) SpaceId;
- HandlerObj->AddressSpace.Hflags = Flags;
- HandlerObj->AddressSpace.RegionList = NULL;
- HandlerObj->AddressSpace.Node = Node;
- HandlerObj->AddressSpace.Handler = Handler;
- HandlerObj->AddressSpace.Context = Context;
- HandlerObj->AddressSpace.Setup = Setup;
-
- /* Install at head of Device.AddressSpace list */
-
- HandlerObj->AddressSpace.Next = ObjDesc->Device.Handler;
-
- /*
- * The Device object is the first reference on the HandlerObj.
- * Each region that uses the handler adds a reference.
- */
- ObjDesc->Device.Handler = HandlerObj;
-
- /*
- * Walk the namespace finding all of the regions this
- * handler will manage.
- *
- * Start at the device and search the branch toward
- * the leaf nodes until either the leaf is encountered or
- * a device is detected that has an address handler of the
- * same type.
- *
- * In either case, back up and search down the remainder
- * of the branch
- */
- Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Device, ACPI_UINT32_MAX,
- ACPI_NS_WALK_UNLOCK, AcpiEvInstallHandler,
- HandlerObj, NULL);
-
- /*
- * Now we can run the _REG methods for all Regions for this
- * space ID. This is a separate walk in order to handle any
- * interdependencies between regions and _REG methods. (i.e. handlers
- * must be installed for all regions of this Space ID before we
- * can run any _REG methods.
- */
- Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Device, ACPI_UINT32_MAX,
- ACPI_NS_WALK_UNLOCK, AcpiEvRegRun,
- HandlerObj, NULL);
+ Status = AcpiEvExecuteRegMethods (Node, SpaceId);
@@ -394,13 +395,30 @@
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Load from Region %p %s\n",
ObjDesc, AcpiUtGetObjectTypeName (ObjDesc)));
- /* Get the table header */
+ /*
+ * If the Region Address and Length have not been previously evaluated,
+ * evaluate them now and save the results.
+ */
+ if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
+ {
+ Status = AcpiDsGetRegionArguments (ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /* Get the base physical address of the region */
+
+ Address = ObjDesc->Region.Address;
+
+ /* Get the table length from the table header */
TableHeader.Length = 0;
- for (i = 0; i < sizeof (ACPI_TABLE_HEADER); i++)
+ for (i = 0; i < 8; i++)
{
Status = AcpiEvAddressSpaceDispatch (ObjDesc, ACPI_READ,
- (ACPI_PHYSICAL_ADDRESS) i, 8,
+ (ACPI_PHYSICAL_ADDRESS) (i + Address), 8,
((UINT8 *) &TableHeader) + i);
if (ACPI_FAILURE (Status))
{
@@ -408,6 +426,13 @@
}
}
+ /* Sanity check the table length */
+
+ if (TableHeader.Length < sizeof (ACPI_TABLE_HEADER))
+ {
+ return_ACPI_STATUS (AE_BAD_HEADER);
+ }
+
/* Allocate a buffer for the entire table */
- /* Copy the header to the buffer */
-
- ACPI_MEMCPY (TablePtr, &TableHeader, sizeof (ACPI_TABLE_HEADER));
- TableDataPtr = ACPI_PTR_ADD (UINT8, TablePtr, sizeof (ACPI_TABLE_HEADER));
-
- /* Get the table from the op region */
+ /* Get the entire table from the op region */
for (i = 0; i < TableHeader.Length; i++)
{
Status = AcpiEvAddressSpaceDispatch (ObjDesc, ACPI_READ,
- (ACPI_PHYSICAL_ADDRESS) i, 8,
- ((UINT8 *) TableDataPtr + i));
+ (ACPI_PHYSICAL_ADDRESS) (i + Address), 8,
+ ((UINT8 *) TablePtr + i));
if (ACPI_FAILURE (Status))
{
goto Cleanup;
@@ -455,6 +475,13 @@
}
- if (TargetNode->Type == ACPI_TYPE_LOCAL_ALIAS)
+ if ((TargetNode->Type == ACPI_TYPE_LOCAL_ALIAS) ||
+ (TargetNode->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
{
/*
* Dereference an existing alias so that we don't create a chain
@@ -170,7 +171,7 @@
* always exactly one level of indirection away from the
* actual aliased name.
*/
- TargetNode = (ACPI_NAMESPACE_NODE *) TargetNode->Object;
+ TargetNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, TargetNode->Object);
}
+ case ACPI_TYPE_METHOD:
+
+ /*
+ * The new alias has the type ALIAS and points to the original
+ * NS node, not the object itself. This is because for these
+ * types, the object can change dynamically via a Store.
+ */
+ AliasNode->Type = ACPI_TYPE_LOCAL_METHOD_ALIAS;
+ AliasNode->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode);
+ break;
+
default:
/* Attach the original source object to the new Alias Node */
@@ -684,29 +696,36 @@
ObjDesc->Method.AmlStart = AmlStart;
ObjDesc->Method.AmlLength = AmlLength;
- /* disassemble the method flags */
-
+ /*
+ * Disassemble the method flags. Split off the Arg Count
+ * for efficiency
+ */
MethodFlags = (UINT8) Operand[1]->Integer.Value;
case ACPI_TYPE_LOCAL_ALIAS:
+ case ACPI_TYPE_LOCAL_METHOD_ALIAS:
case ACPI_TYPE_LOCAL_EXTRA:
case ACPI_TYPE_LOCAL_DATA:
default:
Index: sys/dev/acpi/acpica/Subsystem/exfldio.c
===================================================================
RCS file: /cvsroot/src/sys/dev/acpi/acpica/Subsystem/exfldio.c,v
retrieving revision 1.11
diff -u -r1.11 exfldio.c
--- sys/dev/acpi/acpica/Subsystem/exfldio.c 14 Feb 2004 16:57:24 -0000 1.11
+++ sys/dev/acpi/acpica/Subsystem/exfldio.c 17 Jun 2004 04:08:45 -0000
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: exfldio - Aml Field I/O
- * xRevision: 103 $
+ * xRevision: 106 $
*
*****************************************************************************/
@@ -355,7 +355,7 @@
}
else if (Status == AE_NOT_EXIST)
{
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ ACPI_REPORT_ERROR ((
"Region %s(%X) has no handler\n",
AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
RgnDesc->Region.SpaceId));
@@ -868,14 +868,84 @@
/*******************************************************************************
*
+ * FUNCTION: AcpiExCommonBufferSetup
+ *
+ * PARAMETERS: ObjDesc - Field object
+ * BufferLength - Length of caller's buffer
+ * DatumCount - Where the DatumCount is returned
+ *
+ * RETURN: Status, DatumCount
+ *
+ * DESCRIPTION: Common code to validate the incoming buffer size and compute
+ * the number of field "datums" that must be read or written.
+ * A "datum" is the smallest unit that can be read or written
+ * to the field, it is either 1,2,4, or 8 bytes.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExCommonBufferSetup (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT32 BufferLength,
+ UINT32 *DatumCount)
+{
+ UINT32 ByteFieldLength;
+ UINT32 ActualByteFieldLength;
+
+
+ ACPI_FUNCTION_TRACE ("ExCommonBufferSetup");
+
+
+ /*
+ * Incoming buffer must be at least as long as the field, we do not
+ * allow "partial" field reads/writes. We do not care if the buffer is
+ * larger than the field, this typically happens when an integer is
+ * read/written to a field that is actually smaller than an integer.
+ */
+ ByteFieldLength = ACPI_ROUND_BITS_UP_TO_BYTES (
+ ObjDesc->CommonField.BitLength);
+ if (ByteFieldLength > BufferLength)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "Field size %X (bytes) is too large for buffer (%X)\n",
+ ByteFieldLength, BufferLength));
+
+ return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
+ }
+
+ /*
+ * Create "actual" field byte count (minimum number of bytes that
+ * must be read), then convert to datum count (minimum number
+ * of datum-sized units that must be read)
+ */
+ ActualByteFieldLength = ACPI_ROUND_BITS_UP_TO_BYTES (
+ ObjDesc->CommonField.StartFieldBitOffset +
+ ObjDesc->CommonField.BitLength);
+
+
+ *DatumCount = ACPI_ROUND_UP_TO (ActualByteFieldLength,
+ ObjDesc->CommonField.AccessByteWidth);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "BufferBytes %X, ActualBytes %X, Datums %X, ByteGran %X\n",
+ ByteFieldLength, ActualByteFieldLength,
+ *DatumCount, ObjDesc->CommonField.AccessByteWidth));
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: AcpiExExtractFromField
*
- * PARAMETERS: *ObjDesc - Field to be read
- * *Value - Where to store value
+ * PARAMETERS: ObjDesc - Field to be read
+ * Buffer - Where to store the field data
+ * BufferLength - Length of Buffer
*
* RETURN: Status
*
- * DESCRIPTION: Retrieve the value of the given field
+ * DESCRIPTION: Retrieve the current value of the given field
*
******************************************************************************/
- /*
- * The field must fit within the caller's buffer
- */
- ByteFieldLength = ACPI_ROUND_BITS_UP_TO_BYTES (ObjDesc->CommonField.BitLength);
- if (ByteFieldLength > BufferLength)
- {
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "Field size %X (bytes) too large for buffer (%X)\n",
- ByteFieldLength, BufferLength));
-
- return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
- }
-
- /* Convert field byte count to datum count, round up if necessary */
-
- DatumCount = ACPI_ROUND_UP_TO (ByteFieldLength,
- ObjDesc->CommonField.AccessByteWidth);
+ /* Validate buffer, compute number of datums */
- /*
- * If the field is not aligned on a datum boundary and does not
- * fit within a single datum, we must read an extra datum.
- *
- * We could just split the aligned and non-aligned cases since the
- * aligned case is so very simple, but this would require more code.
- */
- if ((ObjDesc->CommonField.EndFieldValidBits != 0) &&
- (!(ObjDesc->CommonField.Flags & AOPOBJ_SINGLE_DATUM)))
+ Status = AcpiExCommonBufferSetup (ObjDesc, BufferLength, &DatumCount);
+ if (ACPI_FAILURE (Status))
{
- DatumCount++;
+ return_ACPI_STATUS (Status);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "ByteLen %X, DatumLen %X, ByteGran %X\n",
- ByteFieldLength, DatumCount,ObjDesc->CommonField.AccessByteWidth));
-
/*
* Clear the caller's buffer (the whole buffer length as given)
* This is very important, especially in the cases where the buffer
@@ -1055,12 +1097,13 @@
*
* FUNCTION: AcpiExInsertIntoField
*
- * PARAMETERS: *ObjDesc - Field to be set
- * Buffer - Value to store
+ * PARAMETERS: ObjDesc - Field to be written
+ * Buffer - Data to be written
+ * BufferLength - Length of Buffer
*
* RETURN: Status
*
- * DESCRIPTION: Store the value into the given field
+ * DESCRIPTION: Store the Buffer contents into the given field
*
******************************************************************************/
- /*
- * Incoming buffer must be at least as long as the field, we do not
- * allow "partial" field writes. We do not care if the buffer is
- * larger than the field, this typically happens when an integer is
- * written to a field that is actually smaller than an integer.
- */
- ByteFieldLength = ACPI_ROUND_BITS_UP_TO_BYTES (
- ObjDesc->CommonField.BitLength);
- if (BufferLength < ByteFieldLength)
- {
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "Buffer length %X too small for field %X\n",
- BufferLength, ByteFieldLength));
+ /* Validate buffer, compute number of datums */
- return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
+ Status = AcpiExCommonBufferSetup (ObjDesc, BufferLength, &DatumCount);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
}
- ByteFieldLength = ACPI_ROUND_BITS_UP_TO_BYTES (
- ObjDesc->CommonField.StartFieldBitOffset +
- ObjDesc->CommonField.BitLength);
-
- /* Convert byte count to datum count, round up if necessary */
-
- DatumCount = ACPI_ROUND_UP_TO (ByteFieldLength,
- ObjDesc->CommonField.AccessByteWidth);
-
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "Bytes %X, Datums %X, ByteGran %X\n",
- ByteFieldLength, DatumCount, ObjDesc->CommonField.AccessByteWidth));
-
/*
* Break the request into up to three parts (similar to an I/O request):
* 1) non-aligned part at start
Index: sys/dev/acpi/acpica/Subsystem/exmutex.c
===================================================================
RCS file: /cvsroot/src/sys/dev/acpi/acpica/Subsystem/exmutex.c,v
retrieving revision 1.13
diff -u -r1.13 exmutex.c
--- sys/dev/acpi/acpica/Subsystem/exmutex.c 7 Apr 2004 18:19:34 -0000 1.13
+++ sys/dev/acpi/acpica/Subsystem/exmutex.c 17 Jun 2004 04:08:45 -0000
@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: exmutex - ASL Mutex Acquire/Release functions
- * xRevision: 20 $
+ * xRevision: 24 $
*
*****************************************************************************/
@@ -131,7 +131,7 @@
*
* FUNCTION: AcpiExUnlinkMutex
*
- * PARAMETERS: *ObjDesc - The mutex to be unlinked
+ * PARAMETERS: ObjDesc - The mutex to be unlinked
*
* RETURN: Status
*
@@ -151,6 +151,8 @@
return;
}
+ /* Doubly linked list */
+
if (ObjDesc->Mutex.Next)
{
(ObjDesc->Mutex.Next)->Mutex.Prev = ObjDesc->Mutex.Prev;
@@ -171,8 +173,8 @@
*
* FUNCTION: AcpiExLinkMutex
*
- * PARAMETERS: *ObjDesc - The mutex to be linked
- * *ListHead - head of the "AcquiredMutex" list
+ * PARAMETERS: ObjDesc - The mutex to be linked
+ * ListHead - head of the "AcquiredMutex" list
*
* RETURN: Status
*
@@ -212,8 +214,8 @@
*
* FUNCTION: AcpiExAcquireMutex
*
- * PARAMETERS: *TimeDesc - The 'time to delay' object descriptor
- * *ObjDesc - The object descriptor for this op
+ * PARAMETERS: TimeDesc - The 'time to delay' object descriptor
+ * ObjDesc - The object descriptor for this op
*
* RETURN: Status
*
@@ -258,19 +260,22 @@
return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
}
- /*
- * Support for multiple acquires by the owning thread
- */
+ /* Support for multiple acquires by the owning thread */
- if ((ObjDesc->Mutex.OwnerThread) &&
- (ObjDesc->Mutex.OwnerThread->ThreadId == WalkState->Thread->ThreadId))
+ if (ObjDesc->Mutex.OwnerThread)
{
- /*
- * The mutex is already owned by this thread,
- * just increment the acquisition depth
- */
- ObjDesc->Mutex.AcquisitionDepth++;
- return_ACPI_STATUS (AE_OK);
+ /* Special case for Global Lock, allow all threads */
+
+ if ((ObjDesc->Mutex.OwnerThread->ThreadId == WalkState->Thread->ThreadId) ||
+ (ObjDesc->Mutex.Semaphore == AcpiGbl_GlobalLockSemaphore))
+ {
+ /*
+ * The mutex is already owned by this thread,
+ * just increment the acquisition depth
+ */
+ ObjDesc->Mutex.AcquisitionDepth++;
+ return_ACPI_STATUS (AE_OK);
+ }
}
/* Acquire the mutex, wait if necessary */
@@ -283,12 +288,12 @@
return_ACPI_STATUS (Status);
}
- /* Have the mutex, update mutex and walk info */
+ /* Have the mutex: update mutex and walk info and save the SyncLevel */
/* Link the mutex to the current thread for force-unlock at method exit */
@@ -303,7 +308,7 @@
*
* FUNCTION: AcpiExReleaseMutex
*
- * PARAMETERS: *ObjDesc - The object descriptor for this op
+ * PARAMETERS: ObjDesc - The object descriptor for this op
*
* RETURN: Status
*
@@ -345,9 +350,12 @@
return_ACPI_STATUS (AE_AML_INTERNAL);
}
- /* The Mutex is owned, but this thread must be the owner */
-
- if (ObjDesc->Mutex.OwnerThread->ThreadId != WalkState->Thread->ThreadId)
+ /*
+ * The Mutex is owned, but this thread must be the owner.
+ * Special case for Global Lock, any thread can release
+ */
+ if ((ObjDesc->Mutex.OwnerThread->ThreadId != WalkState->Thread->ThreadId) &&
+ (ObjDesc->Mutex.Semaphore != AcpiGbl_GlobalLockSemaphore))
{
ACPI_REPORT_ERROR ((
"Thread %X cannot release Mutex [%4.4s] acquired by thread %X\n",
@@ -368,9 +376,8 @@
return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
}
- /*
- * Match multiple Acquires with multiple Releases
- */
+ /* Match multiple Acquires with multiple Releases */
+
ObjDesc->Mutex.AcquisitionDepth--;
if (ObjDesc->Mutex.AcquisitionDepth != 0)
{
@@ -387,10 +394,10 @@
Status = AcpiExSystemReleaseMutex (ObjDesc);
- /* Update the mutex and walk state */
+ /* Update the mutex and walk state, restore SyncLevel before acquire */
return_ACPI_STATUS (Status);
}
@@ -400,7 +407,7 @@
*
* FUNCTION: AcpiExReleaseAllMutexes
*
- * PARAMETERS: *MutexList - Head of the mutex list
+ * PARAMETERS: MutexList - Head of the mutex list
*
* RETURN: Status
*
@@ -420,9 +427,8 @@
ACPI_FUNCTION_ENTRY ();
- /*
- * Traverse the list of owned mutexes, releasing each one.
- */
+ /* Traverse the list of owned mutexes, releasing each one */
+
while (Next)
{
This = Next;
@@ -442,7 +448,11 @@
/* Mark mutex unowned */
- This->Mutex.OwnerThread = NULL;
+ This->Mutex.OwnerThread = NULL;
+
+ /* Update Thread SyncLevel (Last mutex is the important one) */
+
+ Thread->CurrentSyncLevel = This->Mutex.OriginalSyncLevel;
}
}
+ /* Second value is the notify value */
+
+ Value = (UINT32) Operand[1]->Integer.Value;
+
/* Notifies allowed on this object? */
if (!AcpiEvIsNotifyObject (Node))
{
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unexpected notify object type [%s]\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Unexpected notify object type [%s]\n",
AcpiUtGetTypeName (Node->Type)));
Status = AE_AML_OPERAND_TYPE;
break;
}
+#ifdef ACPI_GPE_NOTIFY_CHECK
+ /*
+ * GPE method wake/notify check. Here, we want to ensure that we
+ * don't receive any "DeviceWake" Notifies from a GPE _Lxx or _Exx
+ * GPE method during system runtime. If we do, the GPE is marked
+ * as "wake-only" and disabled.
+ *
+ * 1) Is the Notify() value == DeviceWake?
+ * 2) Is this a GPE deferred method? (An _Lxx or _Exx method)
+ * 3) Did the original GPE happen at system runtime?
+ * (versus during wake)
+ *
+ * If all three cases are true, this is a wake-only GPE that should
+ * be disabled at runtime.
+ */
+ if (Value == 2) /* DeviceWake */
+ {
+ Status = AcpiEvCheckForWakeOnlyGpe (WalkState->GpeEventInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ /* AE_WAKE_ONLY_GPE only error, means ignore this notify */
+
+ return_ACPI_STATUS (AE_OK)
+ }
+ }
+#endif
+
/*
* Dispatch the notify to the appropriate handler
* NOTE: the request is queued for execution after this method
@@ -210,8 +243,7 @@
* from this thread -- because handlers may in turn run other
* control methods.
*/
- Status = AcpiEvQueueNotifyRequest (Node,
- (UINT32) Operand[1]->Integer.Value);
+ Status = AcpiEvQueueNotifyRequest (Node, Value);
break;
- if (EntryType == ACPI_TYPE_LOCAL_ALIAS)
+ if ((EntryType == ACPI_TYPE_LOCAL_ALIAS) ||
+ (EntryType == ACPI_TYPE_LOCAL_METHOD_ALIAS))
{
/* There is always exactly one level of indirection */
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Arg/Local %X] ValueObj is %p\n",
+ StackDesc->Reference.Offset, ObjDesc));
+
/*
* Now we can delete the original Reference Object and
- * replace it with the resolve value
+ * replace it with the resolved value
*/
AcpiUtRemoveReference (StackDesc);
*StackPtr = ObjDesc;
-
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Arg/Local %d] ValueObj is %p\n",
- StackDesc->Reference.Offset, ObjDesc));
break;
/******************************************************************************
*
- * FUNCTION: AcpiHwEnableGpe
+ * FUNCTION: AcpiHwWriteGpeEnableReg
*
- * PARAMETERS: GpeNumber - The GPE
+ * PARAMETERS: GpeEventInfo - Info block for the GPE to be enabled
*
- * RETURN: None
+ * RETURN: Status
*
- * DESCRIPTION: Enable a single GPE.
+ * DESCRIPTION: Write a GPE enable register. Note: The bit for this GPE must
+ * already be cleared or set in the parent register
+ * EnableForRun mask.
*
******************************************************************************/
ACPI_STATUS
-AcpiHwEnableGpe (
- ACPI_GPE_EVENT_INFO *GpeEventInfo)
-{
- UINT32 InByte;
- ACPI_STATUS Status;
-
-
- ACPI_FUNCTION_ENTRY ();
-
-
- /*
- * Read the current value of the register, set the appropriate bit
- * to enable the GPE, and write out the new register.
- */
- Status = AcpiHwLowLevelRead (8, &InByte,
- &GpeEventInfo->RegisterInfo->EnableAddress);
- if (ACPI_FAILURE (Status))
- {
- return (Status);
- }
-
- /* Write with the new GPE bit enabled */
-
- Status = AcpiHwLowLevelWrite (8, (InByte | GpeEventInfo->BitMask),
- &GpeEventInfo->RegisterInfo->EnableAddress);
-
- return (Status);
-}
-
-
-/******************************************************************************
- *
- * FUNCTION: AcpiHwEnableGpeForWakeup
- *
- * PARAMETERS: GpeNumber - The GPE
- *
- * RETURN: None
- *
- * DESCRIPTION: Keep track of which GPEs the OS has requested not be
- * disabled when going to sleep.
- *
- ******************************************************************************/
-
-void
-AcpiHwEnableGpeForWakeup (
+AcpiHwWriteGpeEnableReg (
ACPI_GPE_EVENT_INFO *GpeEventInfo)
{
ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
-
-
- ACPI_FUNCTION_ENTRY ();
-
-
- /* Get the info block for the entire GPE register */
-
- GpeRegisterInfo = GpeEventInfo->RegisterInfo;
- if (!GpeRegisterInfo)
- {
- return;
- }
-
- /*
- * Set the bit so we will not disable this when sleeping
- */
- GpeRegisterInfo->WakeEnable |= GpeEventInfo->BitMask;
-}
-
-
-/******************************************************************************
- *
- * FUNCTION: AcpiHwDisableGpe
- *
- * PARAMETERS: GpeNumber - The GPE
- *
- * RETURN: None
- *
- * DESCRIPTION: Disable a single GPE.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiHwDisableGpe (
- ACPI_GPE_EVENT_INFO *GpeEventInfo)
-{
- UINT32 InByte;
ACPI_STATUS Status;
- ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
ACPI_FUNCTION_ENTRY ();
@@ -235,69 +155,15 @@
GpeRegisterInfo = GpeEventInfo->RegisterInfo;
if (!GpeRegisterInfo)
{
- return (AE_BAD_PARAMETER);
- }
-
- /*
- * Read the current value of the register, clear the appropriate bit,
- * and write out the new register value to disable the GPE.
- */
- Status = AcpiHwLowLevelRead (8, &InByte,
- &GpeRegisterInfo->EnableAddress);
- if (ACPI_FAILURE (Status))
- {
- return (Status);
+ return (AE_NOT_EXIST);
}
- /* Write the byte with this GPE bit cleared */
+ /* Write the entire GPE (runtime) enable register */
- Status = AcpiHwLowLevelWrite (8, (InByte & ~(GpeEventInfo->BitMask)),
+ Status = AcpiHwLowLevelWrite (8, GpeRegisterInfo->EnableForRun,
&GpeRegisterInfo->EnableAddress);
- if (ACPI_FAILURE (Status))
- {
- return (Status);
- }
-
- AcpiHwDisableGpeForWakeup (GpeEventInfo);
- return (AE_OK);
-}
-
-
-/******************************************************************************
- *
- * FUNCTION: AcpiHwDisableGpeForWakeup
- *
- * PARAMETERS: GpeNumber - The GPE
- *
- * RETURN: None
- *
- * DESCRIPTION: Keep track of which GPEs the OS has requested not be
- * disabled when going to sleep.
- *
- ******************************************************************************/
-void
-AcpiHwDisableGpeForWakeup (
- ACPI_GPE_EVENT_INFO *GpeEventInfo)
-{
- ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
-
-
- ACPI_FUNCTION_ENTRY ();
-
-
- /* Get the info block for the entire GPE register */
-
- GpeRegisterInfo = GpeEventInfo->RegisterInfo;
- if (!GpeRegisterInfo)
- {
- return;
- }
-
- /*
- * Clear the bit so we will disable this when sleeping
- */
- GpeRegisterInfo->WakeEnable &= ~(GpeEventInfo->BitMask);
+ return (Status);
}
@@ -305,11 +171,11 @@
*
* FUNCTION: AcpiHwClearGpe
*
- * PARAMETERS: GpeNumber - The GPE
+ * PARAMETERS: GpeEventInfo - Info block for the GPE to be cleared
*
- * RETURN: None
+ * RETURN: StatusStatus
*
- * DESCRIPTION: Clear a single GPE.
+ * DESCRIPTION: Clear the status bit for a single GPE.
*
******************************************************************************/
@@ -327,7 +193,7 @@
* Write a one to the appropriate bit in the status register to
* clear this GPE.
*/
- Status = AcpiHwLowLevelWrite (8, GpeEventInfo->BitMask,
+ Status = AcpiHwLowLevelWrite (8, GpeEventInfo->RegisterBit,
&GpeEventInfo->RegisterInfo->StatusAddress);
return (Status);
@@ -338,9 +204,10 @@
*
* FUNCTION: AcpiHwGetGpeStatus
*
- * PARAMETERS: GpeNumber - The GPE
+ * PARAMETERS: GpeEventInfo - Info block for the GPE to queried
+ * EventStatus - Where the GPE status is returned
*
- * RETURN: None
+ * RETURN: Status
*
* DESCRIPTION: Return the status of a single GPE.
*
@@ -352,7 +219,7 @@
ACPI_EVENT_STATUS *EventStatus)
{
UINT32 InByte;
- UINT8 BitMask;
+ UINT8 RegisterBit;
ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
ACPI_STATUS Status;
ACPI_EVENT_STATUS LocalEventStatus = 0;
@@ -372,29 +239,23 @@
- /* GPE Enabled? */
+ /* GPE currently enabled? (enabled for runtime?) */
- Status = AcpiHwLowLevelRead (8, &InByte, &GpeRegisterInfo->EnableAddress);
- if (ACPI_FAILURE (Status))
- {
- goto UnlockAndExit;
- }
-
- if (BitMask & InByte)
+ if (RegisterBit & GpeRegisterInfo->EnableForRun)
{
LocalEventStatus |= ACPI_EVENT_FLAG_ENABLED;
}
- /* GPE Enabled for wake? */
+ /* GPE enabled for wake? */
- if (BitMask & GpeRegisterInfo->WakeEnable)
+ if (RegisterBit & GpeRegisterInfo->EnableForWake)
{
LocalEventStatus |= ACPI_EVENT_FLAG_WAKE_ENABLED;
}
- /* GPE active (set)? */
+ /* GPE currently active (status bit == 1)? */
Status = AcpiHwLowLevelRead (8, &InByte, &GpeRegisterInfo->StatusAddress);
if (ACPI_FAILURE (Status))
@@ -402,7 +263,7 @@
goto UnlockAndExit;
}
- if (BitMask & InByte)
+ if (RegisterBit & InByte)
{
LocalEventStatus |= ACPI_EVENT_FLAG_SET;
}
@@ -466,7 +327,7 @@
*
* RETURN: Status
*
- * DESCRIPTION: Clear all GPEs within a GPE block
+ * DESCRIPTION: Clear status bits for all GPEs within a GPE block
*
******************************************************************************/
@@ -483,7 +344,7 @@
for (i = 0; i < GpeBlock->RegisterCount; i++)
{
- /* Clear all GPEs in this register */
+ /* Clear status on all GPEs in this register */
Status = AcpiHwLowLevelWrite (8, 0xFF,
&GpeBlock->RegisterInfo[i].StatusAddress);
@@ -499,60 +360,46 @@
/******************************************************************************
*
- * FUNCTION: AcpiHwDisableNonWakeupGpeBlock
+ * FUNCTION: AcpiHwEnableRuntimeGpeBlock
*
* PARAMETERS: GpeXruptInfo - GPE Interrupt info
* GpeBlock - Gpe Block info
*
* RETURN: Status
*
- * DESCRIPTION: Disable all GPEs except wakeup GPEs in a GPE block
+ * DESCRIPTION: Enable all "runtime" GPEs within a GPE block. (Includes
+ * combination wake/run GPEs.)
*
******************************************************************************/
- /* Get the register info for the entire GPE block */
-
- GpeRegisterInfo = GpeBlock->RegisterInfo;
+ /* NOTE: assumes that all GPEs are currently disabled */
/* Examine each GPE Register within the block */
for (i = 0; i < GpeBlock->RegisterCount; i++)
{
- /*
- * Read the enabled status of all GPEs. We
- * will be using it to restore all the GPEs later.
- */
- Status = AcpiHwLowLevelRead (8, &InValue,
- &GpeRegisterInfo->EnableAddress);
- if (ACPI_FAILURE (Status))
+ if (!GpeBlock->RegisterInfo[i].EnableForRun)
{
- return (Status);
+ continue;
}
- GpeRegisterInfo->Enable = (UINT8) InValue;
+ /* Enable all "runtime" GPEs in this register */
- /*
- * Disable all GPEs except wakeup GPEs.
- */
- Status = AcpiHwLowLevelWrite (8, GpeRegisterInfo->WakeEnable,
- &GpeRegisterInfo->EnableAddress);
+ Status = AcpiHwLowLevelWrite (8, GpeBlock->RegisterInfo[i].EnableForRun,
+ &GpeBlock->RegisterInfo[i].EnableAddress);
if (ACPI_FAILURE (Status))
{
return (Status);
}
-
- GpeRegisterInfo++;
}
return (AE_OK);
@@ -561,111 +408,128 @@
/******************************************************************************
*
- * FUNCTION: AcpiHwDisableNonWakeupGpes
+ * FUNCTION: AcpiHwEnableWakeupGpeBlock
*
- * PARAMETERS: None
+ * PARAMETERS: GpeXruptInfo - GPE Interrupt info
+ * GpeBlock - Gpe Block info
*
- * RETURN: None
+ * RETURN: Status
*
- * DESCRIPTION: Disable all non-wakeup GPEs
- * Called with interrupts disabled. The interrupt handler also
- * modifies GpeRegisterInfo->Enable, so it should not be
- * given the chance to run until after non-wake GPEs are
- * re-enabled.
+ * DESCRIPTION: Enable all "wake" GPEs within a GPE block. (Includes
+ * combination wake/run GPEs.)
*
******************************************************************************/
- /* This callback processes one entire GPE block */
+ ACPI_FUNCTION_TRACE ("HwDisableAllGpes");
- /* Get the register info for the entire GPE block */
- GpeRegisterInfo = GpeBlock->RegisterInfo;
+ Status = AcpiEvWalkGpeList (AcpiHwDisableGpeBlock);
+ Status = AcpiEvWalkGpeList (AcpiHwClearGpeBlock);
+ return_ACPI_STATUS (Status);
+}
- /* Examine each GPE register within the block */
- for (i = 0; i < GpeBlock->RegisterCount; i++)
- {
- /*
- * We previously stored the enabled status of all GPEs.
- * Blast them back in.
- */
- Status = AcpiHwLowLevelWrite (8, GpeRegisterInfo->Enable,
- &GpeRegisterInfo->EnableAddress);
- if (ACPI_FAILURE (Status))
- {
- return (Status);
- }
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwEnableAllRuntimeGpes
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enable all GPEs of the given type
+ *
+ ******************************************************************************/
ACPI_FUNCTION_TRACE ("AcpiGetSleepTypeData");
@@ -236,19 +236,20 @@
/*
* Evaluate the namespace object containing the values for this state
*/
- Status = AcpiNsEvaluateByName ((char *) AcpiGbl_DbSleepStates[SleepState],
- NULL, &ObjDesc);
+ Info.Parameters = NULL;
+ Status = AcpiNsEvaluateByName ((char *) AcpiGbl_SleepStateNames[SleepState],
+ &Info);
if (ACPI_FAILURE (Status))
{
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s while evaluating SleepState [%s]\n",
- AcpiFormatException (Status), AcpiGbl_DbSleepStates[SleepState]));
+ AcpiFormatException (Status), AcpiGbl_SleepStateNames[SleepState]));
return_ACPI_STATUS (Status);
}
/* Must have a return object */
- if (!ObjDesc)
+ if (!Info.ReturnObject)
{
ACPI_REPORT_ERROR (("Missing Sleep State object\n"));
Status = AE_NOT_EXIST;
@@ -256,7 +257,7 @@
/* It must be of type Package */
- else if (ACPI_GET_OBJECT_TYPE (ObjDesc) != ACPI_TYPE_PACKAGE)
+ else if (ACPI_GET_OBJECT_TYPE (Info.ReturnObject) != ACPI_TYPE_PACKAGE)
{
ACPI_REPORT_ERROR (("Sleep State object not a Package\n"));
Status = AE_AML_OPERAND_TYPE;
@@ -264,7 +265,7 @@
/* The package must have at least two elements */
- else if (ObjDesc->Package.Count < 2)
+ else if (Info.ReturnObject->Package.Count < 2)
{
ACPI_REPORT_ERROR (("Sleep State package does not have at least two elements\n"));
Status = AE_AML_NO_OPERAND;
@@ -272,12 +273,12 @@
/* The first two elements must both be of type Integer */
- else if ((ACPI_GET_OBJECT_TYPE (ObjDesc->Package.Elements[0]) != ACPI_TYPE_INTEGER) ||
- (ACPI_GET_OBJECT_TYPE (ObjDesc->Package.Elements[1]) != ACPI_TYPE_INTEGER))
+ else if ((ACPI_GET_OBJECT_TYPE (Info.ReturnObject->Package.Elements[0]) != ACPI_TYPE_INTEGER) ||
+ (ACPI_GET_OBJECT_TYPE (Info.ReturnObject->Package.Elements[1]) != ACPI_TYPE_INTEGER))
{
ACPI_REPORT_ERROR (("Sleep State package elements are not both Integers (%s, %s)\n",
- AcpiUtGetObjectTypeName (ObjDesc->Package.Elements[0]),
- AcpiUtGetObjectTypeName (ObjDesc->Package.Elements[1])));
+ AcpiUtGetObjectTypeName (Info.ReturnObject->Package.Elements[0]),
+ AcpiUtGetObjectTypeName (Info.ReturnObject->Package.Elements[1])));
Status = AE_AML_OPERAND_TYPE;
}
else
@@ -285,17 +286,19 @@
/*
* Valid _Sx_ package size, type, and value
*/
- *SleepTypeA = (UINT8) (ObjDesc->Package.Elements[0])->Integer.Value;
- *SleepTypeB = (UINT8) (ObjDesc->Package.Elements[1])->Integer.Value;
+ *SleepTypeA = (UINT8) (Info.ReturnObject->Package.Elements[0])->Integer.Value;
+ *SleepTypeB = (UINT8) (Info.ReturnObject->Package.Elements[1])->Integer.Value;
}
if (ACPI_FAILURE (Status))
{
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "While evaluating SleepState [%s], bad Sleep object %p type %s\n",
- AcpiGbl_DbSleepStates[SleepState], ObjDesc, AcpiUtGetObjectTypeName (ObjDesc)));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "While evaluating SleepState [%s], bad Sleep object %p type %s\n",
+ AcpiGbl_SleepStateNames[SleepState], Info.ReturnObject,
+ AcpiUtGetObjectTypeName (Info.ReturnObject)));
}
- Status = AcpiEvaluateObject (NULL, "\\_PTS", &ArgList, NULL);
+ Status = AcpiEvaluateObject (NULL, METHOD_NAME__PTS, &ArgList, NULL);
if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
{
return_ACPI_STATUS (Status);
}
- Status = AcpiEvaluateObject (NULL, "\\_GTS", &ArgList, NULL);
+ Status = AcpiEvaluateObject (NULL, METHOD_NAME__GTS, &ArgList, NULL);
if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
{
return_ACPI_STATUS (Status);
}
- /* Set the system indicators to show the desired sleep state. */
+ /* Setup the argument to _SST */
switch (SleepState)
{
case ACPI_STATE_S0:
- /* _SST 1: Working */
- Arg.Integer.Value = 1;
+ Arg.Integer.Value = ACPI_SST_WORKING;
break;
+
case ACPI_STATE_S1:
case ACPI_STATE_S2:
case ACPI_STATE_S3:
- /* _SST 3: Sleeping. Used to indicate system state S1, S2 or S3. */
- Arg.Integer.Value = 3;
+ Arg.Integer.Value = ACPI_SST_SLEEPING;
break;
+
case ACPI_STATE_S4:
- /* _SST 4: Sleeping with context saved to non-volatile storage. */
- Arg.Integer.Value = 4;
+ Arg.Integer.Value = ACPI_SST_SLEEP_CONTEXT;
break;
- case ACPI_STATE_S5:
- /* _SST 0: No system state indication. Indicator off. */
- Arg.Integer.Value = 0;
+
+ default:
+ Arg.Integer.Value = ACPI_SST_INDICATOR_OFF; /* Default is indicator off */
break;
}
- Status = AcpiEvaluateObject (NULL, "\\_SI._SST", &ArgList, NULL);
+ /* Set the system indicators to show the desired sleep state. */
+
+ Status = AcpiEvaluateObject (NULL, METHOD_NAME__SST, &ArgList, NULL);
if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
{
ACPI_REPORT_ERROR (("Method _SST failed, %s\n", AcpiFormatException (Status)));
@@ -339,22 +353,24 @@
SleepTypeRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_TYPE_A);
SleepEnableRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_ENABLE);
- if (SleepState != ACPI_STATE_S5)
+ /* Clear wake status */
+
+ Status = AcpiSetRegister (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
+ if (ACPI_FAILURE (Status))
{
- /* Clear wake status */
+ return_ACPI_STATUS (Status);
+ }
- Status = AcpiSetRegister (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
+ /* Clear all fixed and general purpose status bits */
- Status = AcpiHwClearAcpiStatus (ACPI_MTX_DO_NOT_LOCK);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
+ Status = AcpiHwClearAcpiStatus (ACPI_MTX_DO_NOT_LOCK);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
for (InitVal = AcpiGbl_PreDefinedNames; InitVal->Name; InitVal++)
{
+ /* _OSI is optional for now, will be permanent later */
+
+ if (!ACPI_STRCMP (InitVal->Name, "_OSI") && !AcpiGbl_CreateOsiMethod)
+ {
+ continue;
+ }
+
Status = AcpiNsLookup (NULL, InitVal->Name, InitVal->Type,
- ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, NULL, &NewNode);
+ ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH,
+ NULL, &NewNode);
if (ACPI_FAILURE (Status) || (!NewNode)) /* Must be on same line for code converter */
{
@@ -205,7 +213,8 @@
Status = AcpiOsPredefinedOverride (InitVal, &Val);
if (ACPI_FAILURE (Status))
{
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not override predefined %s\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Could not override predefined %s\n",
InitVal->Name));
}
-#if defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
+#if defined (_ACPI_ASL_COMPILER) || defined (_ACPI_DUMP_APP)
- /* Compiler cheats by putting parameter count in the OwnerID */
+ /* iASL Compiler cheats by putting parameter count in the OwnerID */
NewNode->OwnerId = ObjDesc->Method.ParamCount;
+#else
+ /* Mark this as a very SPECIAL method */
+
+ ObjDesc->Method.MethodFlags = AML_METHOD_INTERNAL_ONLY;
+ ObjDesc->Method.Implementation = AcpiUtOsiImplementation;
#endif
break;
@@ -305,9 +310,9 @@
* to evaluate it.
*/
ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n",
- Pathname, Node, AcpiNsGetAttachedObject (Node)));
+ Pathname, Info->Node, AcpiNsGetAttachedObject (Info->Node)));
- Status = AcpiNsEvaluateByHandle (Node, Params, ReturnObject);
+ Status = AcpiNsEvaluateByHandle (Info);
ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n",
Pathname));
@@ -334,6 +339,7 @@
* Params - List of parameters to pass to the method,
* terminated by NULL. Params itself may be
* NULL if no parameters are being passed.
+ * ParamType - Type of Parameter list
* ReturnObject - Where to put method's return value (if
* any). If NULL, no value is returned.
*
@@ -347,13 +353,9 @@
/*
+ * For a method alias, we must grab the actual method node
+ * so that proper scoping context will be established
+ * before execution.
+ */
+ if (AcpiNsGetType (Info->Node) == ACPI_TYPE_LOCAL_METHOD_ALIAS)
+ {
+ Info->Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Info->Node->Object);
+ }
+
+ /*
* Two major cases here:
* 1) The object is an actual control method -- execute it.
* 2) The object is not a method -- just return it's current
@@ -404,13 +413,12 @@
* In both cases, the namespace is unlocked by the
* AcpiNs* procedure
*/
- if (AcpiNsGetType (Node) == ACPI_TYPE_METHOD)
+ if (AcpiNsGetType (Info->Node) == ACPI_TYPE_METHOD)
{
/*
* Case 1) We have an actual control method to execute
*/
- Status = AcpiNsExecuteControlMethod (Node, Params,
- &LocalReturnObject);
+ Status = AcpiNsExecuteControlMethod (Info);
}
else
{
@@ -418,7 +426,7 @@
* Case 2) Object is NOT a method, just return its
* current value
*/
- Status = AcpiNsGetObjectValue (Node, &LocalReturnObject);
+ Status = AcpiNsGetObjectValue (Info);
}
/*
@@ -427,21 +435,6 @@
*/
if (Status == AE_CTRL_RETURN_VALUE)
{
- /*
- * If the Method returned a value and the caller
- * provided a place to store a returned value, Copy
- * the returned value to the object descriptor provided
- * by the caller.
- */
- if (ReturnObject)
- {
- /*
- * Valid return object, copy the pointer to
- * the returned object
- */
- *ReturnObject = LocalReturnObject;
- }
-
/* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */
/*
- * We will run _STA/_INI on Devices and Processors only
+ * We will run _STA/_INI on Devices, Processors and ThermalZones only
*/
- if ((Node->Type != ACPI_TYPE_DEVICE) &&
- (Node->Type != ACPI_TYPE_PROCESSOR))
+ if ((Pinfo.Node->Type != ACPI_TYPE_DEVICE) &&
+ (Pinfo.Node->Type != ACPI_TYPE_PROCESSOR) &&
+ (Pinfo.Node->Type != ACPI_TYPE_THERMAL))
{
return_ACPI_STATUS (AE_OK);
}
@@ -459,19 +463,19 @@
/*
* Run _STA to determine if we can run _INI on the device.
*/
- ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_METHOD, Node, "_STA"));
- Status = AcpiUtExecute_STA (Node, &Flags);
+ ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_METHOD, Pinfo.Node, "_STA"));
+ Status = AcpiUtExecute_STA (Pinfo.Node, &Flags);
if (ACPI_FAILURE (Status))
{
- if (Node->Type == ACPI_TYPE_DEVICE)
+ if (Pinfo.Node->Type == ACPI_TYPE_DEVICE)
{
/* Ignore error and move on to next device */
return_ACPI_STATUS (AE_OK);
}
- /* _STA is not required for Processor objects */
+ /* _STA is not required for Processor or ThermalZone objects */
}
else
{
@@ -488,8 +492,8 @@
/*
* The device is present. Run _INI.
*/
- ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_METHOD, ObjHandle, "_INI"));
- Status = AcpiNsEvaluateRelative (ObjHandle, "_INI", NULL, NULL);
+ ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_METHOD, Pinfo.Node, "_INI"));
+ Status = AcpiNsEvaluateRelative ("_INI", &Pinfo);
if (ACPI_FAILURE (Status))
{
/* No _INI (AE_NOT_FOUND) means device requires no initialization */
@@ -498,14 +502,14 @@
{
/* Ignore error and move on to next device */
#define _COMPONENT ACPI_NAMESPACE
@@ -234,11 +235,11 @@
* FUNCTION: AcpiEvaluateObject
*
* PARAMETERS: Handle - Object handle (optional)
- * *Pathname - Object pathname (optional)
- * **ExternalParams - List of parameters to pass to method,
+ * Pathname - Object pathname (optional)
+ * ExternalParams - List of parameters to pass to method,
* terminated by NULL. May be NULL
* if no parameters are being passed.
- * *ReturnBuffer - Where to put method's return value (if
+ * ReturnBuffer - Where to put method's return value (if
* any). If NULL, no value is returned.
*
* RETURN: Status
@@ -257,8 +258,8 @@
ACPI_BUFFER *ReturnBuffer)
{
ACPI_STATUS Status;
- ACPI_OPERAND_OBJECT **InternalParams = NULL;
- ACPI_OPERAND_OBJECT *InternalReturnObj = NULL;
+ ACPI_STATUS Status2;
+ ACPI_PARAMETER_INFO Info;
ACPI_SIZE BufferSpaceNeeded;
UINT32 i;
+ Info.Node = Handle;
+ Info.Parameters = NULL;
+ Info.ReturnObject = NULL;
+ Info.ParameterType = ACPI_PARAM_ARGS;
+
/*
* If there are parameters to be passed to the object
* (which must be a control method), the external objects
@@ -277,9 +283,10 @@
* Allocate a new parameter block for the internal objects
* Add 1 to count to allow for null terminated internal list
*/
- InternalParams = ACPI_MEM_CALLOCATE (((ACPI_SIZE) ExternalParams->Count + 1) *
- sizeof (void *));
- if (!InternalParams)
+ Info.Parameters = ACPI_MEM_CALLOCATE (
+ ((ACPI_SIZE) ExternalParams->Count + 1) *
+ sizeof (void *));
+ if (!Info.Parameters)
{
return_ACPI_STATUS (AE_NO_MEMORY);
}
@@ -291,16 +298,17 @@
for (i = 0; i < ExternalParams->Count; i++)
{
Status = AcpiUtCopyEobjectToIobject (&ExternalParams->Pointer[i],
- &InternalParams[i]);
+ &Info.Parameters[i]);
if (ACPI_FAILURE (Status))
{
- AcpiUtDeleteInternalObjectList (InternalParams);
+ AcpiUtDeleteInternalObjectList (Info.Parameters);
return_ACPI_STATUS (Status);
}
}
- InternalParams[ExternalParams->Count] = NULL;
+ Info.Parameters[ExternalParams->Count] = NULL;
}
+
/*
* Three major cases:
* 1) Fully qualified pathname
@@ -313,8 +321,7 @@
/*
* The path is fully qualified, just evaluate by name
*/
- Status = AcpiNsEvaluateByName (Pathname, InternalParams,
- &InternalReturnObj);
+ Status = AcpiNsEvaluateByName (Pathname, &Info);
}
else if (!Handle)
{
@@ -349,16 +356,14 @@
* The null pathname case means the handle is for
* the actual object to be evaluated
*/
- Status = AcpiNsEvaluateByHandle (Handle, InternalParams,
- &InternalReturnObj);
+ Status = AcpiNsEvaluateByHandle (&Info);
}
else
{
/*
* Both a Handle and a relative Pathname
*/
- Status = AcpiNsEvaluateRelative (Handle, Pathname, InternalParams,
- &InternalReturnObj);
+ Status = AcpiNsEvaluateRelative (Pathname, &Info);
}
}
@@ -369,13 +374,13 @@
*/
if (ReturnBuffer)
{
- if (!InternalReturnObj)
+ if (!Info.ReturnObject)
{
ReturnBuffer->Length = 0;
}
else
{
- if (ACPI_GET_DESCRIPTOR_TYPE (InternalReturnObj) == ACPI_DESC_TYPE_NAMED)
+ if (ACPI_GET_DESCRIPTOR_TYPE (Info.ReturnObject) == ACPI_DESC_TYPE_NAMED)
{
/*
* If we received a NS Node as a return object, this means that
@@ -386,7 +391,7 @@
* support for various types at a later date if necessary.
*/
Status = AE_TYPE;
- InternalReturnObj = NULL; /* No need to delete a NS Node */
+ Info.ReturnObject = NULL; /* No need to delete a NS Node */
ReturnBuffer->Length = 0;
}
@@ -396,7 +401,7 @@
* Find out how large a buffer is needed
* to contain the returned object
*/
- Status = AcpiUtGetObjectSize (InternalReturnObj,
+ Status = AcpiUtGetObjectSize (Info.ReturnObject,
&BufferSpaceNeeded);
if (ACPI_SUCCESS (Status))
{
@@ -410,14 +415,15 @@
*/
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Needed buffer size %X, %s\n",
- (UINT32) BufferSpaceNeeded, AcpiFormatException (Status)));
+ (UINT32) BufferSpaceNeeded,
+ AcpiFormatException (Status)));
}
else
{
/*
* We have enough space for the object, build it
*/
- Status = AcpiUtCopyIobjectToEobject (InternalReturnObj,
+ Status = AcpiUtCopyIobjectToEobject (Info.ReturnObject,
ReturnBuffer);
}
}
@@ -425,25 +431,32 @@
}
}
- /* Delete the return and parameter objects */
-
- if (InternalReturnObj)
+ if (Info.ReturnObject)
{
/*
- * Delete the internal return object. (Or at least
- * decrement the reference count by one)
+ * Delete the internal return object. NOTE: Interpreter
+ * must be locked to avoid race condition.
*/
- AcpiUtRemoveReference (InternalReturnObj);
+ Status2 = AcpiExEnterInterpreter ();
+ if (ACPI_SUCCESS (Status2))
+ {
+ /*
+ * Delete the internal return object. (Or at least
+ * decrement the reference count by one)
+ */
+ AcpiUtRemoveReference (Info.ReturnObject);
+ AcpiExExitInterpreter ();
+ }
}
/*
* Free the input parameter list (if we created one),
*/
- if (InternalParams)
+ if (Info.Parameters)
{
/* Free the allocated parameter block */
@@ -377,7 +377,7 @@
{
/*
* Get extra info for ACPI Devices objects only:
- * Run the Device _HID, _UID, _CID, _STA, and _ADR methods.
+ * Run the Device _HID, _UID, _CID, _STA, _ADR and _SxD methods.
*
* Note: none of these methods are required, so they may or may
* not be present for this device. The Info.Valid bitfield is used
@@ -427,6 +427,14 @@
Info.Valid |= ACPI_VALID_ADR;
}
+ /* Execute the Device._SxD methods */
+
+ Status = AcpiUtExecute_Sxds (Node, Info.HighestDstates);
+ if (ACPI_SUCCESS (Status))
+ {
+ Info.Valid |= ACPI_VALID_SXDS;
+ }
+
Status = AE_OK;
}
if (Op->Common.AmlOpcode == AML_REGION_OP)
@@ -996,6 +1007,11 @@
AcpiPsCompleteThisOp (WalkState, Op);
Op = NULL;
+ if (PreOp)
+ {
+ AcpiPsFreeOp (PreOp);
+ PreOp = NULL;
+ }
switch (Status)
{
@@ -1288,6 +1304,30 @@
{
ACPI_REPORT_METHOD_ERROR ("Method execution failed",
WalkState->MethodNode, NULL, Status);
+
+ /* Check for possible multi-thread reentrancy problem */
+
+ if ((Status == AE_ALREADY_EXISTS) &&
+ (!WalkState->MethodDesc->Method.Semaphore))
+ {
+ /*
+ * This method is marked NotSerialized, but it tried to create a named
+ * object, causing the second thread entrance to fail. We will workaround
+ * this by marking the method permanently as Serialized.
+ */
+ WalkState->MethodDesc->Method.MethodFlags |= AML_METHOD_SERIALIZED;
+ WalkState->MethodDesc->Method.Concurrency = 1;
+ }
+ }
+
+ if (WalkState->MethodDesc)
+ {
+ /* Decrement the thread count on the method parse tree */
+
+ if (WalkState->MethodDesc->Method.ThreadCount)
+ {
+ WalkState->MethodDesc->Method.ThreadCount--;
+ }
}
/* We are done with this walk, move on to the parent if any */
Index: sys/dev/acpi/acpica/Subsystem/psscope.c
===================================================================
RCS file: /cvsroot/src/sys/dev/acpi/acpica/Subsystem/psscope.c,v
retrieving revision 1.10
diff -u -r1.10 psscope.c
--- sys/dev/acpi/acpica/Subsystem/psscope.c 14 Feb 2004 16:57:25 -0000 1.10
+++ sys/dev/acpi/acpica/Subsystem/psscope.c 17 Jun 2004 04:08:50 -0000
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: psscope - Parser scope stack management routines
- * xRevision: 37 $
+ * xRevision: 38 $
*
*****************************************************************************/
@@ -134,7 +134,7 @@
*
* FUNCTION: AcpiPsxExecute
*
- * PARAMETERS: MethodNode - A method object containing both the AML
+ * PARAMETERS: Info->Node - A method object containing both the AML
* address and length.
* **Params - List of parameters to pass to method,
* terminated by NULL. Params itself may be
@@ -150,9 +150,7 @@
/* Init for new method, wait on concurrency semaphore */
- Status = AcpiDsBeginMethodExecution (MethodNode, ObjDesc, NULL);
+ Status = AcpiDsBeginMethodExecution (Info->Node, ObjDesc, NULL);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
- if (Params)
+ if ((Info->ParameterType == ACPI_PARAM_ARGS) &&
+ (Info->Parameters))
{
/*
* The caller "owns" the parameters, so give each one an extra
* reference
*/
- for (i = 0; Params[i]; i++)
+ for (i = 0; Info->Parameters[i]; i++)
{
- AcpiUtAddReference (Params[i]);
+ AcpiUtAddReference (Info->Parameters[i]);
}
}
Cleanup1:
- if (Params)
+ if ((Info->ParameterType == ACPI_PARAM_ARGS) &&
+ (Info->Parameters))
{
/* Take away the extra reference that we gave the parameters above */
- for (i = 0; Params[i]; i++)
+ for (i = 0; Info->Parameters[i]; i++)
{
/* Ignore errors, just do them all */
@@ -320,11 +321,11 @@
* If the method has returned an object, signal this to the caller with
* a control exception code
*/
- if (*ReturnObjDesc)
+ if (Info->ReturnObject)
{
ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned ObjDesc=%p\n",
- *ReturnObjDesc));
- ACPI_DUMP_STACK_ENTRY (*ReturnObjDesc);
+ Info->ReturnObject));
+ ACPI_DUMP_STACK_ENTRY (Info->ReturnObject);
@@ -489,14 +489,17 @@
* Flags - Current memory mode (logical vs.
* physical addressing)
*
- * RETURN: Status
+ * RETURN: Status, RSDP physical address
*
* DESCRIPTION: Search lower 1Mbyte of memory for the root system descriptor
* pointer structure. If it is found, set *RSDP to point to it.
*
- * NOTE: The RSDP must be either in the first 1K of the Extended
- * BIOS Data Area or between E0000 and FFFFF (ACPI 1.0 section
- * 5.2.2; assertion #421).
+ * NOTE1: The RSDP must be either in the first 1K of the Extended
+ * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.)
+ * Only a 32-bit physical address is necessary.
+ *
+ * NOTE2: This function is always available, regardless of the
+ * initialization state of the rest of ACPI.
*
******************************************************************************/
/******************************************************************************
@@ -273,26 +300,22 @@
/*
* Predefined ACPI Names (Built-in to the Interpreter)
*
- * Initial values are currently supported only for types String and Number.
- * Both are specified as strings in this table.
- *
* NOTES:
- * 1) _SB_ is defined to be a device to allow _SB_/_INI to be run
+ * 1) _SB_ is defined to be a device to allow \_SB_._INI to be run
* during the initialization sequence.
*/
-
const ACPI_PREDEFINED_NAMES AcpiGbl_PreDefinedNames[] =
{
{"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL},
{"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL},
{"_SB_", ACPI_TYPE_DEVICE, NULL},
{"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL},
- {"_TZ_", ACPI_TYPE_LOCAL_SCOPE, NULL},
+ {"_TZ_", ACPI_TYPE_THERMAL, NULL},
{"_REV", ACPI_TYPE_INTEGER, "2"},
{"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME},
{"_GL_", ACPI_TYPE_MUTEX, "0"},
-
ACPI_TABLE_SUPPORT AcpiGbl_TableData[NUM_ACPI_TABLE_TYPES] =
{
/*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Contains valid AML? */
@@ -549,9 +570,8 @@
*
* The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching; when
* stored in a table it really means that we have thus far seen no evidence to
- * indicatewhat type is actually going to be stored for this entry.
+ * indicate what type is actually going to be stored for this entry.
*/
-
static const char AcpiGbl_BadType[] = "UNDEFINED";
#define TYPE_NAME_LENGTH 12 /* Maximum length of each string */
/*
- * Initialize ACPI Event handling
+ * Install the default OpRegion handlers. These are installed unless
+ * other handlers have already been installed via the
+ * InstallAddressSpaceHandler interface.
+ */
+ if (!(Flags & ACPI_NO_ADDRESS_SPACE_INIT))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n"));
+
+ Status = AcpiEvInstallRegionHandlers ();
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /*
+ * Initialize ACPI Event handling (Fixed and General Purpose)
*
* NOTE: We must have the hardware AND events initialized before we can execute
* ANY control methods SAFELY. Any control method can require ACPI hardware
@@ -268,20 +283,20 @@
{
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI events\n"));
- Status = AcpiEvInitialize ();
+ Status = AcpiEvInitializeEvents ();
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
}
- /* Install the SCI handler, Global Lock handler, and GPE handlers */
+ /* Install the SCI handler and Global Lock handler */
- Status = AcpiEvHandlerInitialize ();
+ Status = AcpiEvInstallXruptHandlers ();
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
@@ -315,19 +330,17 @@
/*
- * Install the default OpRegion handlers. These are installed unless
- * other handlers have already been installed via the
- * InstallAddressSpaceHandler interface.
+ * Run all _REG methods
*
- * NOTE: This will cause _REG methods to be run. Any objects accessed
+ * NOTE: Any objects accessed
* by the _REG methods will be automatically initialized, even if they
* contain executable AML (see call to AcpiNsInitializeObjects below).
*/
if (!(Flags & ACPI_NO_ADDRESS_SPACE_INIT))
{
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Executing _REG OpRegion methods\n"));
- Status = AcpiEvInitAddressSpaces ();
+ Status = AcpiEvInitializeOpRegions ();
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
@@ -341,7 +354,7 @@
*/
if (!(Flags & ACPI_NO_OBJECT_INIT))
{
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Objects\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Completing Initialization of ACPI Objects\n"));
Status = AcpiNsInitializeObjects ();
if (ACPI_FAILURE (Status))