📄 evregion.c
字号:
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); } /* * 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 * (e.g., _REG method for this region) */ AcpiExExitInterpreter (); Status = RegionSetup (RegionObj, ACPI_REGION_ACTIVATE, HandlerDesc->AddressSpace.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 { /* * Save the returned context for use in all accesses to * this particular region */ RegionObj2->Extra.RegionContext = RegionContext; } } } /* We have everything we need, we can invoke the address space handler */ Handler = HandlerDesc->AddressSpace.Handler; ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", &RegionObj->Region.Handler->AddressSpace, Handler, ACPI_FORMAT_NATIVE_UINT (Address), AcpiUtGetRegionName (RegionObj->Region.SpaceId))); if (!(HandlerDesc->AddressSpace.HandlerFlags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* * For handlers other than the default (supplied) handlers, we must * exit the interpreter because the handler *might* block -- we don't * know what it will do, so we can't hold the lock on the intepreter. */ AcpiExExitInterpreter(); } /* Call the handler */ Status = Handler (Function, Address, BitWidth, Value, HandlerDesc->AddressSpace.Context, RegionObj2->Extra.RegionContext); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "Returned by Handler for [%s]", AcpiUtGetRegionName (RegionObj->Region.SpaceId))); } if (!(HandlerDesc->AddressSpace.HandlerFlags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* * We just returned from a non-default handler, we must re-enter the * interpreter */ AcpiExEnterInterpreter (); } return_ACPI_STATUS (Status);}/******************************************************************************* * * FUNCTION: AcpiEvDetachRegion * * PARAMETERS: RegionObj - Region Object * AcpiNsIsLocked - Namespace Region Already Locked? * * RETURN: None * * DESCRIPTION: Break the association between the handler and the region * this is a two way association. * ******************************************************************************/voidAcpiEvDetachRegion( ACPI_OPERAND_OBJECT *RegionObj, BOOLEAN AcpiNsIsLocked){ ACPI_OPERAND_OBJECT *HandlerObj; ACPI_OPERAND_OBJECT *ObjDesc; ACPI_OPERAND_OBJECT **LastObjPtr; ACPI_ADR_SPACE_SETUP RegionSetup; void **RegionContext; ACPI_OPERAND_OBJECT *RegionObj2; ACPI_STATUS Status; ACPI_FUNCTION_TRACE (EvDetachRegion); RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); if (!RegionObj2) { return_VOID; } RegionContext = &RegionObj2->Extra.RegionContext; /* Get the address handler from the region object */ HandlerObj = RegionObj->Region.Handler; if (!HandlerObj) { /* This region has no handler, all done */ return_VOID; } /* Find this region in the handler's list */ ObjDesc = HandlerObj->AddressSpace.RegionList; LastObjPtr = &HandlerObj->AddressSpace.RegionList; while (ObjDesc) { /* Is this the correct Region? */ if (ObjDesc == RegionObj) { ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Removing Region %p from address handler %p\n", RegionObj, HandlerObj)); /* This is it, remove it from the handler's list */ *LastObjPtr = ObjDesc->Region.Next; ObjDesc->Region.Next = NULL; /* Must clear field */ if (AcpiNsIsLocked) { Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (Status)) { return_VOID; } } /* Now stop region accesses by executing the _REG method */ Status = AcpiEvExecuteRegMethod (RegionObj, 0); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "from region _REG, [%s]", AcpiUtGetRegionName (RegionObj->Region.SpaceId))); } if (AcpiNsIsLocked) { Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (Status)) { return_VOID; } } /* * If the region has been activated, call the setup handler * with the deactivate notification */ if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE) { RegionSetup = HandlerObj->AddressSpace.Setup; Status = RegionSetup (RegionObj, ACPI_REGION_DEACTIVATE, HandlerObj->AddressSpace.Context, RegionContext); /* Init routine may fail, Just ignore errors */ if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "from region handler - deactivate, [%s]", AcpiUtGetRegionName (RegionObj->Region.SpaceId))); } RegionObj->Region.Flags &= ~(AOPOBJ_SETUP_COMPLETE); } /* * Remove handler reference in the region * * NOTE: this doesn't mean that the region goes away, the region * is just inaccessible as indicated to the _REG method * * If the region is on the handler's list, this must be the * region's handler */ RegionObj->Region.Handler = NULL; AcpiUtRemoveReference (HandlerObj); return_VOID; } /* Walk the linked list of handlers */ LastObjPtr = &ObjDesc->Region.Next; ObjDesc = ObjDesc->Region.Next; } /* If we get here, the region was not in the handler's region list */ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Cannot remove region %p from address handler %p\n", RegionObj, HandlerObj)); return_VOID;}/******************************************************************************* * * FUNCTION: AcpiEvAttachRegion * * PARAMETERS: HandlerObj - Handler Object * RegionObj - Region Object * AcpiNsIsLocked - Namespace Region Already Locked? * * RETURN: None * * DESCRIPTION: Create the association between the handler and the region * this is a two way association. * ******************************************************************************/ACPI_STATUSAcpiEvAttachRegion ( ACPI_OPERAND_OBJECT *HandlerObj, ACPI_OPERAND_OBJECT *RegionObj, BOOLEAN AcpiNsIsLocked){ ACPI_FUNCTION_TRACE (EvAttachRegion); ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Adding Region [%4.4s] %p to address handler %p [%s]\n", AcpiUtGetNodeName (RegionObj->Region.Node), RegionObj, HandlerObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId))); /* Link this region to the front of the handler's list */ RegionObj->Region.Next = HandlerObj->AddressSpace.RegionList; HandlerObj->AddressSpace.RegionList = RegionObj; /* Install the region's handler */ if (RegionObj->Region.Handler) { return_ACPI_STATUS (AE_ALREADY_EXISTS); } RegionObj->Region.Handler = HandlerObj; AcpiUtAddReference (HandlerObj); return_ACPI_STATUS (AE_OK);}/******************************************************************************* * * FUNCTION: AcpiEvInstallHandler * * PARAMETERS: WalkNamespace callback * * DESCRIPTION: This routine installs an address handler into objects that are * of type Region or Device. * * If the Object is a Device, and the device has a handler of * the same type then the search is terminated in that branch. * * This is because the existing handler is closer in proximity * to any more regions than the one we are trying to install. * ******************************************************************************/static ACPI_STATUSAcpiEvInstallHandler ( ACPI_HANDLE ObjHandle, UINT32 Level, void *Context, void **ReturnValue){ ACPI_OPERAND_OBJECT *HandlerObj; ACPI_OPERAND_OBJECT *NextHandlerObj; ACPI_OPERAND_OBJECT *ObjDesc; ACPI_NAMESPACE_NODE *Node; ACPI_STATUS Status; ACPI_FUNCTION_NAME (EvInstallHandler); HandlerObj = (ACPI_OPERAND_OBJECT *) Context; /* Parameter validation */ if (!HandlerObj) { return (AE_OK); } /* Convert and validate the device handle */ Node = AcpiNsMapHandleToNode (ObjHandle); if (!Node) { return (AE_BAD_PARAMETER); } /* * We only care about regions.and objects * that are allowed to have address space handlers */ if ((Node->Type != ACPI_TYPE_DEVICE) && (Node->Type != ACPI_TYPE_REGION) && (Node != AcpiGbl_RootNode)) { return (AE_OK); } /* Check for an existing internal object */ ObjDesc = AcpiNsGetAttachedObject (Node); if (!ObjDesc) { /* No object, just exit */ return (AE_OK); } /* Devices are handled different than regions */ if (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_DEVICE) { /* Check if this Device already has a handler for this address space */ NextHandlerObj = ObjDesc->Device.Handler;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -