static ACPI_STATUS
AcpiDsInitOneObject (
ACPI_HANDLE ObjHandle,
UINT32 Level,
void *Context,
void **ReturnValue)
{
ACPI_INIT_WALK_INFO *Info = (ACPI_INIT_WALK_INFO *) Context;
ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
ACPI_STATUS Status;
ACPI_OPERAND_OBJECT *ObjDesc;
ACPI_FUNCTION_ENTRY ();
/*
* We are only interested in NS nodes owned by the table that
* was just loaded
*/
if (Node->OwnerId != Info->OwnerId)
{
return (AE_OK);
}
Info->ObjectCount++;
/* And even then, we are only interested in a few object types */
switch (AcpiNsGetType (ObjHandle))
{
case ACPI_TYPE_REGION:
Status = AcpiDsInitializeRegion (ObjHandle);
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
"During Region initialization %p [%4.4s]",
ObjHandle, AcpiUtGetNodeName (ObjHandle)));
}
Info->OpRegionCount++;
break;
case ACPI_TYPE_METHOD:
/*
* Auto-serialization support. We will examine each method that is
* NotSerialized to determine if it creates any Named objects. If
* it does, it will be marked serialized to prevent problems if
* the method is entered by two or more threads and an attempt is
* made to create the same named object twice -- which results in
* an AE_ALREADY_EXISTS exception and method abort.
*/
Info->MethodCount++;
ObjDesc = AcpiNsGetAttachedObject (Node);
if (!ObjDesc)
{
break;
}
/* Ignore if already serialized */
if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED)
{
Info->SerialMethodCount++;
break;
}
if (AcpiGbl_AutoSerializeMethods)
{
/* Parse/scan method and serialize it if necessary */
AcpiDsAutoSerializeMethod (Node, ObjDesc);
if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED)
{
/* Method was just converted to Serialized */
Info->SerialMethodCount++;
Info->SerializedMethodCount++;
break;
}
}
Info->NonSerialMethodCount++;
break;
case ACPI_TYPE_DEVICE:
Info->DeviceCount++;
break;
default:
break;
}
/*
* We ignore errors from above, and always return OK, since
* we don't want to abort the walk on a single error.
*/
//.........这里部分代码省略.........
//.........这里部分代码省略.........
/*
* Check to make sure that the target is
* one of the opcodes that actually opens a scope
*/
switch (Node->Type)
{
case ACPI_TYPE_ANY:
case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
case ACPI_TYPE_DEVICE:
case ACPI_TYPE_POWER:
case ACPI_TYPE_PROCESSOR:
case ACPI_TYPE_THERMAL:
/* These are acceptable types */
break;
case ACPI_TYPE_INTEGER:
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
/*
* These types we will allow, but we will change the type.
* This enables some existing code of the form:
*
* Name (DEB, 0)
* Scope (DEB) { ... }
*
* Note: silently change the type here. On the second pass,
* we will report a warning
*/
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Type override - [%4.4s] had invalid type (%s) "
"for Scope operator, changed to type ANY\n",
AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type)));
Node->Type = ACPI_TYPE_ANY;
WalkState->ScopeInfo->Common.Value = ACPI_TYPE_ANY;
break;
case ACPI_TYPE_METHOD:
/*
* Allow scope change to root during execution of module-level
* code. Root is typed METHOD during this time.
*/
if ((Node == AcpiGbl_RootNode) &&
(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
{
break;
}
/*lint -fallthrough */
default:
/* All other types are an error */
ACPI_ERROR ((AE_INFO,
"Invalid type (%s) for target of "
"Scope operator [%4.4s] (Cannot override)",
AcpiUtGetTypeName (Node->Type), AcpiUtGetNodeName (Node)));
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
}
break;
default:
开发者ID:ModeenF,项目名称:haiku,代码行数:67,代码来源:dswload.c
示例3: AcpiNsAttachObject
ACPI_STATUS
AcpiNsAttachObject (
ACPI_NAMESPACE_NODE *Node,
ACPI_OPERAND_OBJECT *Object,
ACPI_OBJECT_TYPE Type)
{
ACPI_OPERAND_OBJECT *ObjDesc;
ACPI_OPERAND_OBJECT *LastObjDesc;
ACPI_OBJECT_TYPE ObjectType = ACPI_TYPE_ANY;
ACPI_FUNCTION_TRACE (NsAttachObject);
/*
* Parameter validation
*/
if (!Node)
{
/* Invalid handle */
ACPI_ERROR ((AE_INFO, "Null NamedObj handle"));
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
if (!Object && (ACPI_TYPE_ANY != Type))
{
/* Null object */
ACPI_ERROR ((AE_INFO,
"Null object, but type not ACPI_TYPE_ANY"));
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
{
/* Not a name handle */
ACPI_ERROR ((AE_INFO, "Invalid handle %p [%s]",
Node, AcpiUtGetDescriptorName (Node)));
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/* Check if this object is already attached */
if (Node->Object == Object)
{
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
"Obj %p already installed in NameObj %p\n",
Object, Node));
return_ACPI_STATUS (AE_OK);
}
/* If null object, we will just install it */
if (!Object)
{
ObjDesc = NULL;
ObjectType = ACPI_TYPE_ANY;
}
/*
* If the source object is a namespace Node with an attached object,
* we will use that (attached) object
*/
else if ((ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED) &&
((ACPI_NAMESPACE_NODE *) Object)->Object)
{
/*
* Value passed is a name handle and that name has a
* non-null value. Use that name's value and type.
*/
ObjDesc = ((ACPI_NAMESPACE_NODE *) Object)->Object;
ObjectType = ((ACPI_NAMESPACE_NODE *) Object)->Type;
}
/*
* Otherwise, we will use the parameter object, but we must type
* it first
*/
else
{
ObjDesc = (ACPI_OPERAND_OBJECT *) Object;
/* Use the given type */
ObjectType = Type;
}
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n",
ObjDesc, Node, AcpiUtGetNodeName (Node)));
/* Detach an existing attached object if present */
if (Node->Object)
{
AcpiNsDetachObject (Node);
}
//.........这里部分代码省略.........
ACPI_STATUS
AcpiDsBeginMethodExecution (
ACPI_NAMESPACE_NODE *MethodNode,
ACPI_OPERAND_OBJECT *ObjDesc,
ACPI_WALK_STATE *WalkState)
{
ACPI_STATUS Status = AE_OK;
ACPI_FUNCTION_TRACE_PTR (DsBeginMethodExecution, MethodNode);
if (!MethodNode)
{
return_ACPI_STATUS (AE_NULL_ENTRY);
}
AcpiExStartTraceMethod (MethodNode, ObjDesc, WalkState);
/* Prevent wraparound of thread count */
if (ObjDesc->Method.ThreadCount == ACPI_UINT8_MAX)
{
ACPI_ERROR ((AE_INFO,
"Method reached maximum reentrancy limit (255)"));
return_ACPI_STATUS (AE_AML_METHOD_LIMIT);
}
/*
* If this method is serialized, we need to acquire the method mutex.
*/
if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED)
{
/*
* Create a mutex for the method if it is defined to be Serialized
* and a mutex has not already been created. We defer the mutex creation
* until a method is actually executed, to minimize the object count
*/
if (!ObjDesc->Method.Mutex)
{
Status = AcpiDsCreateMethodMutex (ObjDesc);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
}
/*
* The CurrentSyncLevel (per-thread) must be less than or equal to
* the sync level of the method. This mechanism provides some
* deadlock prevention.
*
* If the method was auto-serialized, we just ignore the sync level
* mechanism, because auto-serialization of methods can interfere
* with ASL code that actually uses sync levels.
*
* Top-level method invocation has no walk state at this point
*/
if (WalkState &&
(!(ObjDesc->Method.InfoFlags & ACPI_METHOD_IGNORE_SYNC_LEVEL)) &&
(WalkState->Thread->CurrentSyncLevel >
ObjDesc->Method.Mutex->Mutex.SyncLevel))
{
ACPI_ERROR ((AE_INFO,
"Cannot acquire Mutex for method [%4.4s]"
", current SyncLevel is too large (%u)",
AcpiUtGetNodeName (MethodNode),
WalkState->Thread->CurrentSyncLevel));
return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
}
/*
* Obtain the method mutex if necessary. Do not acquire mutex for a
* recursive call.
*/
if (!WalkState ||
!ObjDesc->Method.Mutex->Mutex.ThreadId ||
(WalkState->Thread->ThreadId !=
ObjDesc->Method.Mutex->Mutex.ThreadId))
{
/*
* Acquire the method mutex. This releases the interpreter if we
* block (and reacquires it before it returns)
*/
Status = AcpiExSystemWaitMutex (
ObjDesc->Method.Mutex->Mutex.OsMutex, ACPI_WAIT_FOREVER);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
/* Update the mutex and walk info and save the original SyncLevel */
if (WalkState)
{
ObjDesc->Method.Mutex->Mutex.OriginalSyncLevel =
WalkState->Thread->CurrentSyncLevel;
ObjDesc->Method.Mutex->Mutex.ThreadId =
//.........这里部分代码省略.........
ACPI_STATUS
AcpiUtEvaluateObject (
ACPI_NAMESPACE_NODE *PrefixNode,
char *Path,
UINT32 ExpectedReturnBtypes,
ACPI_OPERAND_OBJECT **ReturnDesc)
{
ACPI_EVALUATE_INFO *Info;
ACPI_STATUS Status;
UINT32 ReturnBtype;
ACPI_FUNCTION_TRACE (UtEvaluateObject);
/* Allocate the evaluation information block */
Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
if (!Info)
{
return_ACPI_STATUS (AE_NO_MEMORY);
}
Info->PrefixNode = PrefixNode;
Info->Pathname = Path;
/* Evaluate the object/method */
Status = AcpiNsEvaluate (Info);
if (ACPI_FAILURE (Status))
{
if (Status == AE_NOT_FOUND)
{
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n",
AcpiUtGetNodeName (PrefixNode), Path));
}
else
{
ACPI_ERROR_METHOD ("Method execution failed",
PrefixNode, Path, Status);
}
goto Cleanup;
}
/* Did we get a return object? */
if (!Info->ReturnObject)
{
if (ExpectedReturnBtypes)
{
ACPI_ERROR_METHOD ("No object was returned from",
PrefixNode, Path, AE_NOT_EXIST);
Status = AE_NOT_EXIST;
}
goto Cleanup;
}
/* Map the return object type to the bitmapped type */
switch ((Info->ReturnObject)->Common.Type)
{
case ACPI_TYPE_INTEGER:
ReturnBtype = ACPI_BTYPE_INTEGER;
break;
case ACPI_TYPE_BUFFER:
ReturnBtype = ACPI_BTYPE_BUFFER;
break;
case ACPI_TYPE_STRING:
ReturnBtype = ACPI_BTYPE_STRING;
break;
case ACPI_TYPE_PACKAGE:
ReturnBtype = ACPI_BTYPE_PACKAGE;
break;
default:
ReturnBtype = 0;
break;
}
if ((AcpiGbl_EnableInterpreterSlack) &&
(!ExpectedReturnBtypes))
{
/*
* We received a return object, but one was not expected. This can
* happen frequently if the "implicit return" feature is enabled.
* Just delete the return object and return AE_OK.
*/
AcpiUtRemoveReference (Info->ReturnObject);
goto Cleanup;
}
/* Is the return object one of the expected types? */
if (!(ExpectedReturnBtypes & ReturnBtype))
//.........这里部分代码省略.........
//.........这里部分代码省略.........
}
Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
if (ACPI_FAILURE (Status))
{
return_VOID;
}
/* Must revalidate the GpeNumber/GpeBlock */
if (!AcpiEvValidGpeEvent (GpeEventInfo))
{
Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
return_VOID;
}
/*
* Take a snapshot of the GPE info for this level - we copy the info to
* prevent a race condition with RemoveHandler/RemoveBlock.
*/
ACPI_MEMCPY (LocalGpeEventInfo, GpeEventInfo,
sizeof (ACPI_GPE_EVENT_INFO));
Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
if (ACPI_FAILURE (Status))
{
return_VOID;
}
/* Do the correct dispatch - normal method or implicit notify */
switch (LocalGpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)
{
case ACPI_GPE_DISPATCH_NOTIFY:
/*
* Implicit notify.
* Dispatch a DEVICE_WAKE notify to the appropriate handler.
* NOTE: the request is queued for execution after this method
* completes. The notify handlers are NOT invoked synchronously
* from this thread -- because handlers may in turn run other
* control methods.
*
* June 2012: Expand implicit notify mechanism to support
* notifies on multiple device objects.
*/
Notify = LocalGpeEventInfo->Dispatch.NotifyList;
while (ACPI_SUCCESS (Status) && Notify)
{
Status = AcpiEvQueueNotifyRequest (Notify->DeviceNode,
ACPI_NOTIFY_DEVICE_WAKE);
Notify = Notify->Next;
}
break;
case ACPI_GPE_DISPATCH_METHOD:
/* Allocate the evaluation information block */
Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
if (!Info)
{
Status = AE_NO_MEMORY;
}
else
{
/*
* Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the
* _Lxx/_Exx control method that corresponds to this GPE
*/
Info->PrefixNode = LocalGpeEventInfo->Dispatch.MethodNode;
Info->Flags = ACPI_IGNORE_RETURN_VALUE;
Status = AcpiNsEvaluate (Info);
ACPI_FREE (Info);
}
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
"while evaluating GPE method [%4.4s]",
AcpiUtGetNodeName (LocalGpeEventInfo->Dispatch.MethodNode)));
}
break;
default:
return_VOID; /* Should never happen */
}
/* Defer enabling of GPE until all notify handlers are done */
Status = AcpiOsExecute (OSL_NOTIFY_HANDLER,
AcpiEvAsynchEnableGpe, LocalGpeEventInfo);
if (ACPI_FAILURE (Status))
{
ACPI_FREE (LocalGpeEventInfo);
}
return_VOID;
}
开发者ID:DonCN,项目名称:haiku,代码行数:101,代码来源:evgpe.c
示例7: AcpiExAcquireMutex
ACPI_STATUS
AcpiExAcquireMutex (
ACPI_OPERAND_OBJECT *TimeDesc,
ACPI_OPERAND_OBJECT *ObjDesc,
ACPI_WALK_STATE *WalkState)
{
ACPI_STATUS Status;
ACPI_FUNCTION_TRACE_PTR (ExAcquireMutex, ObjDesc);
if (!ObjDesc)
{
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/* Sanity check: we must have a valid thread ID */
if (!WalkState->Thread)
{
ACPI_ERROR ((AE_INFO, "Cannot acquire Mutex [%4.4s], null thread info",
AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
/*
* Current Sync must be less than or equal to the sync level of the
* mutex. This mechanism provides some deadlock prevention
*/
if (WalkState->Thread->CurrentSyncLevel > ObjDesc->Mutex.SyncLevel)
{
ACPI_ERROR ((AE_INFO,
"Cannot acquire Mutex [%4.4s], current SyncLevel is too large (%d)",
AcpiUtGetNodeName (ObjDesc->Mutex.Node),
WalkState->Thread->CurrentSyncLevel));
return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
}
/* Support for multiple acquires by the owning thread */
if (ObjDesc->Mutex.OwnerThread)
{
if (ObjDesc->Mutex.OwnerThread->ThreadId ==
WalkState->Thread->ThreadId)
{
/*
* 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. Special case for Global Lock */
if (ObjDesc->Mutex.OsMutex == AcpiGbl_GlobalLockMutex)
{
Status = AcpiEvAcquireGlobalLock ((UINT16) TimeDesc->Integer.Value);
}
else
{
Status = AcpiExSystemWaitMutex (ObjDesc->Mutex.OsMutex,
(UINT16) TimeDesc->Integer.Value);
}
if (ACPI_FAILURE (Status))
{
/* Includes failure from a timeout on TimeDesc */
return_ACPI_STATUS (Status);
}
/* Have the mutex: update mutex and walk info and save the SyncLevel */
ObjDesc->Mutex.OwnerThread = WalkState->Thread;
ObjDesc->Mutex.AcquisitionDepth = 1;
ObjDesc->Mutex.OriginalSyncLevel = WalkState->Thread->CurrentSyncLevel;
WalkState->Thread->CurrentSyncLevel = ObjDesc->Mutex.SyncLevel;
/* Link the mutex to the current thread for force-unlock at method exit */
AcpiExLinkMutex (ObjDesc, WalkState->Thread);
return_ACPI_STATUS (AE_OK);
}
开发者ID:andreiw,项目名称:polaris,代码行数:87,代码来源:exmutex.c
示例8: AcpiExReleaseMutex
ACPI_STATUS
AcpiExReleaseMutex (
ACPI_OPERAND_OBJECT *ObjDesc,
ACPI_WALK_STATE *WalkState)
{
ACPI_STATUS Status = AE_OK;
ACPI_FUNCTION_TRACE (ExReleaseMutex);
if (!ObjDesc)
{
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/* The mutex must have been previously acquired in order to release it */
if (!ObjDesc->Mutex.OwnerThread)
{
ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], not acquired",
AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED);
}
/* Sanity check: we must have a valid thread ID */
if (!WalkState->Thread)
{
ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], null thread info",
AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
/*
* The Mutex is owned, but this thread must be the owner.
* Special case for Global Lock, any thread can release
*/
if ((ObjDesc->Mutex.OwnerThread->ThreadId != WalkState->Thread->ThreadId) &&
(ObjDesc->Mutex.OsMutex != AcpiGbl_GlobalLockMutex))
{
ACPI_ERROR ((AE_INFO,
"Thread %X cannot release Mutex [%4.4s] acquired by thread %X",
WalkState->Thread->ThreadId,
AcpiUtGetNodeName (ObjDesc->Mutex.Node),
ObjDesc->Mutex.OwnerThread->ThreadId));
return_ACPI_STATUS (AE_AML_NOT_OWNER);
}
/*
* The sync level of the mutex must be less than or equal to the current
* sync level
*/
if (ObjDesc->Mutex.SyncLevel > WalkState->Thread->CurrentSyncLevel)
{
ACPI_ERROR ((AE_INFO,
"Cannot release Mutex [%4.4s], incorrect SyncLevel",
AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
}
/* Match multiple Acquires with multiple Releases */
ObjDesc->Mutex.AcquisitionDepth--;
if (ObjDesc->Mutex.AcquisitionDepth != 0)
{
/* Just decrement the depth and return */
return_ACPI_STATUS (AE_OK);
}
/* Unlink the mutex from the owner's list */
AcpiExUnlinkMutex (ObjDesc);
/* Release the mutex, special case for Global Lock */
if (ObjDesc->Mutex.OsMutex == AcpiGbl_GlobalLockMutex)
{
Status = AcpiEvReleaseGlobalLock ();
}
else
{
AcpiOsReleaseMutex (ObjDesc->Mutex.OsMutex);
}
/* Update the mutex and restore SyncLevel */
ObjDesc->Mutex.OwnerThread = NULL;
WalkState->Thread->CurrentSyncLevel = ObjDesc->Mutex.OriginalSyncLevel;
return_ACPI_STATUS (Status);
}
开发者ID:andreiw,项目名称:polaris,代码行数:93,代码来源:exmutex.c
示例9: AcpiNsInstallNode
void
AcpiNsInstallNode (
ACPI_WALK_STATE *WalkState,
ACPI_NAMESPACE_NODE *ParentNode, /* Parent */
ACPI_NAMESPACE_NODE *Node, /* New Child*/
ACPI_OBJECT_TYPE Type)
{
ACPI_OWNER_ID OwnerId = 0;
ACPI_NAMESPACE_NODE *ChildNode;
ACPI_FUNCTION_TRACE (NsInstallNode);
if (WalkState)
{
/*
* Get the owner ID from the Walk state. The owner ID is used to
* track table deletion and deletion of objects created by methods.
*/
OwnerId = WalkState->OwnerId;
if ((WalkState->MethodDesc) &&
(ParentNode != WalkState->MethodNode))
{
/*
* A method is creating a new node that is not a child of the
* method (it is non-local). Mark the executing method as having
* modified the namespace. This is used for cleanup when the
* method exits.
*/
WalkState->MethodDesc->Method.InfoFlags |=
ACPI_METHOD_MODIFIED_NAMESPACE;
}
}
/* Link the new entry into the parent and existing children */
Node->Peer = NULL;
Node->Parent = ParentNode;
ChildNode = ParentNode->Child;
if (!ChildNode)
{
ParentNode->Child = Node;
}
else
{
/* Add node to the end of the peer list */
while (ChildNode->Peer)
{
ChildNode = ChildNode->Peer;
}
ChildNode->Peer = Node;
}
/* Init the new entry */
Node->OwnerId = OwnerId;
Node->Type = (UINT8) Type;
ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
"%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n",
AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type), Node, OwnerId,
AcpiUtGetNodeName (ParentNode), AcpiUtGetTypeName (ParentNode->Type),
ParentNode));
return_VOID;
}
开发者ID:9elements,项目名称:fwts,代码行数:71,代码来源:nsalloc.c
示例10: AcpiEvQueueNotifyRequest
ACPI_STATUS
AcpiEvQueueNotifyRequest (
ACPI_NAMESPACE_NODE *Node,
UINT32 NotifyValue)
{
ACPI_OPERAND_OBJECT *ObjDesc;
ACPI_OPERAND_OBJECT *HandlerListHead = NULL;
ACPI_GENERIC_STATE *Info;
UINT8 HandlerListId = 0;
ACPI_STATUS Status = AE_OK;
ACPI_FUNCTION_NAME (EvQueueNotifyRequest);
/* Are Notifies allowed on this object? */
if (!AcpiEvIsNotifyObject (Node))
{
return (AE_TYPE);
}
/* Get the correct notify list type (System or Device) */
if (NotifyValue <= ACPI_MAX_SYS_NOTIFY)
{
HandlerListId = ACPI_SYSTEM_HANDLER_LIST;
}
else
{
HandlerListId = ACPI_DEVICE_HANDLER_LIST;
}
/* Get the notify object attached to the namespace Node */
ObjDesc = AcpiNsGetAttachedObject (Node);
if (ObjDesc)
{
/* We have an attached object, Get the correct handler list */
HandlerListHead = ObjDesc->CommonNotify.NotifyList[HandlerListId];
}
/*
* If there is no notify handler (Global or Local)
* for this object, just ignore the notify
*/
if (!AcpiGbl_GlobalNotify[HandlerListId].Handler && !HandlerListHead)
{
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"No notify handler for Notify, ignoring (%4.4s, %X) node %p\n",
AcpiUtGetNodeName (Node), NotifyValue, Node));
return (AE_OK);
}
/* Setup notify info and schedule the notify dispatcher */
Info = AcpiUtCreateGenericState ();
if (!Info)
{
return (AE_NO_MEMORY);
}
Info->Common.DescriptorType = ACPI_DESC_TYPE_STATE_NOTIFY;
Info->Notify.Node = Node;
Info->Notify.Value = (UINT16) NotifyValue;
Info->Notify.HandlerListId = HandlerListId;
Info->Notify.HandlerListHead = HandlerListHead;
Info->Notify.Global = &AcpiGbl_GlobalNotify[HandlerListId];
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n",
AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type),
NotifyValue, AcpiUtGetNotifyName (NotifyValue), Node));
Status = AcpiOsExecute (OSL_NOTIFY_HANDLER, AcpiEvNotifyDispatch,
Info);
if (ACPI_FAILURE (Status))
{
AcpiUtDeleteGenericState (Info);
}
return (Status);
}
//.........这里部分代码省略.........
AcpiUtAddReference (ObjDesc->BankField.RegionObj);
AcpiUtAddReference (ObjDesc->BankField.BankObj);
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Bank Field: BitOff %X, Off %X, Gran %X, Region %p, BankReg %p\n",
ObjDesc->BankField.StartFieldBitOffset,
ObjDesc->BankField.BaseByteOffset,
ObjDesc->Field.AccessByteWidth,
ObjDesc->BankField.RegionObj,
ObjDesc->BankField.BankObj));
/*
* Remember location in AML stream of the field unit
* opcode and operands -- since the BankValue
* operands must be evaluated.
*/
SecondDesc = ObjDesc->Common.NextObject;
SecondDesc->Extra.AmlStart = ACPI_CAST_PTR (ACPI_PARSE_OBJECT,
Info->DataRegisterNode)->Named.Data;
SecondDesc->Extra.AmlLength = ACPI_CAST_PTR (ACPI_PARSE_OBJECT,
Info->DataRegisterNode)->Named.Length;
break;
case ACPI_TYPE_LOCAL_INDEX_FIELD:
/* Get the Index and Data registers */
ObjDesc->IndexField.IndexObj =
AcpiNsGetAttachedObject (Info->RegisterNode);
ObjDesc->IndexField.DataObj =
AcpiNsGetAttachedObject (Info->DataRegisterNode);
if (!ObjDesc->IndexField.DataObj || !ObjDesc->IndexField.IndexObj)
{
ACPI_ERROR ((AE_INFO, "Null Index Object during field prep"));
AcpiUtDeleteObjectDesc (ObjDesc);
return_ACPI_STATUS (AE_AML_INTERNAL);
}
/* An additional reference for the attached objects */
AcpiUtAddReference (ObjDesc->IndexField.DataObj);
AcpiUtAddReference (ObjDesc->IndexField.IndexObj);
/*
* April 2006: Changed to match MS behavior
*
* The value written to the Index register is the byte offset of the
* target field in units of the granularity of the IndexField
*
* Previously, the value was calculated as an index in terms of the
* width of the Data register, as below:
*
* ObjDesc->IndexField.Value = (UINT32)
* (Info->FieldBitPosition / ACPI_MUL_8 (
* ObjDesc->Field.AccessByteWidth));
*
* February 2006: Tried value as a byte offset:
* ObjDesc->IndexField.Value = (UINT32)
* ACPI_DIV_8 (Info->FieldBitPosition);
*/
ObjDesc->IndexField.Value = (UINT32) ACPI_ROUND_DOWN (
ACPI_DIV_8 (Info->FieldBitPosition),
ObjDesc->IndexField.AccessByteWidth);
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"IndexField: BitOff %X, Off %X, Value %X, "
"Gran %X, Index %p, Data %p\n",
ObjDesc->IndexField.StartFieldBitOffset,
ObjDesc->IndexField.BaseByteOffset,
ObjDesc->IndexField.Value,
ObjDesc->Field.AccessByteWidth,
ObjDesc->IndexField.IndexObj,
ObjDesc->IndexField.DataObj));
break;
default:
/* No other types should get here */
break;
}
/*
* Store the constructed descriptor (ObjDesc) into the parent Node,
* preserving the current type of that NamedObj.
*/
Status = AcpiNsAttachObject (
Info->FieldNode, ObjDesc, AcpiNsGetType (Info->FieldNode));
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Set NamedObj %p [%4.4s], ObjDesc %p\n",
Info->FieldNode, AcpiUtGetNodeName (Info->FieldNode), ObjDesc));
/* Remove local reference to the object */
AcpiUtRemoveReference (ObjDesc);
return_ACPI_STATUS (Status);
}
开发者ID:Strongc,项目名称:reactos,代码行数:101,代码来源:exprep.c
示例13: AcpiNsDetachObject
void
AcpiNsDetachObject (
ACPI_NAMESPACE_NODE *Node)
{
ACPI_OPERAND_OBJECT *ObjDesc;
ACPI_FUNCTION_TRACE (NsDetachObject);
ObjDesc = Node->Object;
if (!ObjDesc ||
(ObjDesc->Common.Type == ACPI_TYPE_LOCAL_DATA))
{
return_VOID;
}
if (Node->Flags & ANOBJ_ALLOCATED_BUFFER)
{
/* Free the dynamic aml buffer */
if (ObjDesc->Common.Type == ACPI_TYPE_METHOD)
{
ACPI_FREE (ObjDesc->Method.AmlStart);
}
}
/* Clear the Node entry in all cases */
Node->Object = NULL;
if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND)
{
/* Unlink object from front of possible object list */
Node->Object = ObjDesc->Common.NextObject;
/* Handle possible 2-descriptor object */
if (Node->Object &&
(Node->Object->Common.Type != ACPI_TYPE_LOCAL_DATA))
{
Node->Object = Node->Object->Common.NextObject;
}
/*
* Detach the object from any data objects (which are still held by
* the namespace node)
*/
if (ObjDesc->Common.NextObject &&
((ObjDesc->Common.NextObject)->Common.Type == ACPI_TYPE_LOCAL_DATA))
{
ObjDesc->Common.NextObject = NULL;
}
}
/* Reset the node type to untyped */
Node->Type = ACPI_TYPE_ANY;
ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Node %p [%4.4s] Object %p\n",
Node, AcpiUtGetNodeName (Node), ObjDesc));
/* Remove one reference on the object (and all subobjects) */
AcpiUtRemoveReference (ObjDesc);
return_VOID;
}
ACPI_STATUS
AcpiEvAddressSpaceDispatch (
ACPI_OPERAND_OBJECT *RegionObj,
ACPI_OPERAND_OBJECT *FieldObj,
UINT32 Function,
UINT32 RegionOffset,
UINT32 BitWidth,
UINT64 *Value)
{
ACPI_STATUS Status;
ACPI_ADR_SPACE_HANDLER Handler;
ACPI_ADR_SPACE_SETUP RegionSetup;
ACPI_OPERAND_OBJECT *HandlerDesc;
ACPI_OPERAND_OBJECT *RegionObj2;
void *RegionContext = NULL;
ACPI_CONNECTION_INFO *Context;
ACPI_FUNCTION_TRACE (EvAddressSpaceDispatch);
RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
if (!RegionObj2)
{
return_ACPI_STATUS (AE_NOT_EXIST);
}
/* Ensure that there is a handler associated with this region */
HandlerDesc = RegionObj->Region.Handler;
if (!HandlerDesc)
{
ACPI_ERROR ((AE_INFO,
"No handler for Region [%4.4s] (%p) [%s]",
AcpiUtGetNodeName (RegionObj->Region.Node),
RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
return_ACPI_STATUS (AE_NOT_EXIST);
}
Context = HandlerDesc->AddressSpace.Context;
/*
* It may be the case that the region has never been initialized.
* Some types of regions require special init code
*/
if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE))
{
/* This region has not been initialized yet, do it */
RegionSetup = HandlerDesc->AddressSpace.Setup;
if (!RegionSetup)
{
/* No initialization routine, exit with error */
ACPI_ERROR ((AE_INFO,
"No init routine for region(%p) [%s]",
RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
return_ACPI_STATUS (AE_NOT_EXIST);
}
/*
* We must exit the interpreter because the region setup will
* potentially execute control methods (for example, the _REG method
* for this region)
*/
AcpiExExitInterpreter ();
Status = RegionSetup (RegionObj, ACPI_REGION_ACTIVATE,
Context, &RegionContext);
/* Re-enter the interpreter */
AcpiExEnterInterpreter ();
/* Check for failure of the Region Setup */
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
"During region initialization: [%s]",
AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
return_ACPI_STATUS (Status);
}
/* Region initialization may have been completed by RegionSetup */
if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE))
{
RegionObj->Region.Flags |= AOPOBJ_SETUP_COMPLETE;
if (RegionObj2->Extra.RegionContext)
{
/* The handler for this region was already installed */
ACPI_FREE (RegionContext);
}
else
{
/*
//.........这里部分代码省略.........
//.........这里部分代码省略.........
Info->OpRegionCount++;
break;
case ACPI_TYPE_BUFFER_FIELD:
Info->FieldCount++;
break;
case ACPI_TYPE_LOCAL_BANK_FIELD:
Info->FieldCount++;
break;
case ACPI_TYPE_BUFFER:
Info->BufferCount++;
break;
case ACPI_TYPE_PACKAGE:
Info->PackageCount++;
break;
default:
/* No init required, just exit now */
return (AE_OK);
}
/* If the object is already initialized, nothing else to do */
if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
{
return (AE_OK);
}
/* Must lock the interpreter before executing AML code */
AcpiExEnterInterpreter ();
/*
* Each of these types can contain executable AML code within the
* declaration.
*/
switch (Type)
{
case ACPI_TYPE_REGION:
Info->OpRegionInit++;
Status = AcpiDsGetRegionArguments (ObjDesc);
break;
case ACPI_TYPE_BUFFER_FIELD:
Info->FieldInit++;
Status = AcpiDsGetBufferFieldArguments (ObjDesc);
break;
case ACPI_TYPE_LOCAL_BANK_FIELD:
Info->FieldInit++;
Status = AcpiDsGetBankFieldArguments (ObjDesc);
break;
case ACPI_TYPE_BUFFER:
Info->BufferInit++;
Status = AcpiDsGetBufferArguments (ObjDesc);
break;
case ACPI_TYPE_PACKAGE:
Info->PackageInit++;
Status = AcpiDsGetPackageArguments (ObjDesc);
break;
default:
/* No other types can get here */
break;
}
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
"Could not execute arguments for [%4.4s] (%s)",
AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Type)));
}
/*
* Print a dot for each object unless we are going to print the entire
* pathname
*/
if (!(AcpiDbgLevel & ACPI_LV_INIT_NAMES))
{
ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "."));
}
/*
* We ignore errors from above, and always return OK, since we don't want
* to abort the walk on any single error.
*/
AcpiExExitInterpreter ();
return (AE_OK);
}
请发表评论