⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 evgpeblk.c

📁 acpi tools for linux include acpiexec and acpixtract
💻 C
📖 第 1 页 / 共 3 页
字号:
    ACPI_HANDLE             ObjHandle,    UINT32                  Level,    void                    *Info,    void                    **ReturnValue){    ACPI_GPE_WALK_INFO      *GpeInfo = (void *) Info;    ACPI_NAMESPACE_NODE     *GpeDevice;    ACPI_GPE_BLOCK_INFO     *GpeBlock;    ACPI_NAMESPACE_NODE     *TargetGpeDevice;    ACPI_GPE_EVENT_INFO     *GpeEventInfo;    ACPI_OPERAND_OBJECT     *PkgDesc;    ACPI_OPERAND_OBJECT     *ObjDesc;    UINT32                  GpeNumber;    ACPI_STATUS             Status;    ACPI_FUNCTION_TRACE (EvMatchPrwAndGpe);    /* Check for a _PRW method under this device */    Status = AcpiUtEvaluateObject (ObjHandle, METHOD_NAME__PRW,                ACPI_BTYPE_PACKAGE, &PkgDesc);    if (ACPI_FAILURE (Status))    {        /* Ignore all errors from _PRW, we don't want to abort the subsystem */        return_ACPI_STATUS (AE_OK);    }    /* The returned _PRW package must have at least two elements */    if (PkgDesc->Package.Count < 2)    {        goto Cleanup;    }    /* Extract pointers from the input context */    GpeDevice = GpeInfo->GpeDevice;    GpeBlock = GpeInfo->GpeBlock;    /*     * The _PRW object must return a package, we are only interested     * in the first element     */    ObjDesc = PkgDesc->Package.Elements[0];    if (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_INTEGER)    {        /* Use FADT-defined GPE device (from definition of _PRW) */        TargetGpeDevice = AcpiGbl_FadtGpeDevice;        /* Integer is the GPE number in the FADT described GPE blocks */        GpeNumber = (UINT32) ObjDesc->Integer.Value;    }    else if (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_PACKAGE)    {        /* Package contains a GPE reference and GPE number within a GPE block */        if ((ObjDesc->Package.Count < 2) ||            (ACPI_GET_OBJECT_TYPE (ObjDesc->Package.Elements[0]) != ACPI_TYPE_LOCAL_REFERENCE) ||            (ACPI_GET_OBJECT_TYPE (ObjDesc->Package.Elements[1]) != ACPI_TYPE_INTEGER))        {            goto Cleanup;        }        /* Get GPE block reference and decode */        TargetGpeDevice = ObjDesc->Package.Elements[0]->Reference.Node;        GpeNumber = (UINT32) ObjDesc->Package.Elements[1]->Integer.Value;    }    else    {        /* Unknown type, just ignore it */        goto Cleanup;    }    /*     * Is this GPE within this block?     *     * TRUE iff these conditions are true:     *     1) The GPE devices match.     *     2) The GPE index(number) is within the range of the Gpe Block     *          associated with the GPE device.     */    if ((GpeDevice == TargetGpeDevice) &&        (GpeNumber >= GpeBlock->BlockBaseNumber) &&        (GpeNumber < GpeBlock->BlockBaseNumber + (GpeBlock->RegisterCount * 8)))    {        GpeEventInfo = &GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber];        /* Mark GPE for WAKE-ONLY but WAKE_DISABLED */        GpeEventInfo->Flags &= ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED);        Status = AcpiEvSetGpeType (GpeEventInfo, ACPI_GPE_TYPE_WAKE);        if (ACPI_FAILURE (Status))        {            goto Cleanup;        }        Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_DISABLE);    }Cleanup:    AcpiUtRemoveReference (PkgDesc);    return_ACPI_STATUS (AE_OK);}/******************************************************************************* * * FUNCTION:    AcpiEvGetGpeXruptBlock * * PARAMETERS:  InterruptNumber      - Interrupt for a GPE block * * RETURN:      A GPE interrupt block * * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt *              block per unique interrupt level used for GPEs. *              Should be called only when the GPE lists are semaphore locked *              and not subject to change. * ******************************************************************************/static ACPI_GPE_XRUPT_INFO *AcpiEvGetGpeXruptBlock (    UINT32                  InterruptNumber){    ACPI_GPE_XRUPT_INFO     *NextGpeXrupt;    ACPI_GPE_XRUPT_INFO     *GpeXrupt;    ACPI_STATUS             Status;    ACPI_CPU_FLAGS          Flags;    ACPI_FUNCTION_TRACE (EvGetGpeXruptBlock);    /* No need for lock since we are not changing any list elements here */    NextGpeXrupt = AcpiGbl_GpeXruptListHead;    while (NextGpeXrupt)    {        if (NextGpeXrupt->InterruptNumber == InterruptNumber)        {            return_PTR (NextGpeXrupt);        }        NextGpeXrupt = NextGpeXrupt->Next;    }    /* Not found, must allocate a new xrupt descriptor */    GpeXrupt = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_XRUPT_INFO));    if (!GpeXrupt)    {        return_PTR (NULL);    }    GpeXrupt->InterruptNumber = InterruptNumber;    /* Install new interrupt descriptor with spin lock */    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);    if (AcpiGbl_GpeXruptListHead)    {        NextGpeXrupt = AcpiGbl_GpeXruptListHead;        while (NextGpeXrupt->Next)        {            NextGpeXrupt = NextGpeXrupt->Next;        }        NextGpeXrupt->Next = GpeXrupt;        GpeXrupt->Previous = NextGpeXrupt;    }    else    {        AcpiGbl_GpeXruptListHead = GpeXrupt;    }    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);    /* Install new interrupt handler if not SCI_INT */    if (InterruptNumber != AcpiGbl_FADT.SciInterrupt)    {        Status = AcpiOsInstallInterruptHandler (InterruptNumber,                    AcpiEvGpeXruptHandler, GpeXrupt);        if (ACPI_FAILURE (Status))        {            ACPI_ERROR ((AE_INFO,                "Could not install GPE interrupt handler at level 0x%X",                InterruptNumber));            return_PTR (NULL);        }    }    return_PTR (GpeXrupt);}/******************************************************************************* * * FUNCTION:    AcpiEvDeleteGpeXrupt * * PARAMETERS:  GpeXrupt        - A GPE interrupt info block * * RETURN:      Status * * DESCRIPTION: Remove and free a GpeXrupt block. Remove an associated *              interrupt handler if not the SCI interrupt. * ******************************************************************************/static ACPI_STATUSAcpiEvDeleteGpeXrupt (    ACPI_GPE_XRUPT_INFO     *GpeXrupt){    ACPI_STATUS             Status;    ACPI_CPU_FLAGS          Flags;    ACPI_FUNCTION_TRACE (EvDeleteGpeXrupt);    /* We never want to remove the SCI interrupt handler */    if (GpeXrupt->InterruptNumber == AcpiGbl_FADT.SciInterrupt)    {        GpeXrupt->GpeBlockListHead = NULL;        return_ACPI_STATUS (AE_OK);    }    /* Disable this interrupt */    Status = AcpiOsRemoveInterruptHandler (                GpeXrupt->InterruptNumber, AcpiEvGpeXruptHandler);    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    /* Unlink the interrupt block with lock */    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);    if (GpeXrupt->Previous)    {        GpeXrupt->Previous->Next = GpeXrupt->Next;    }    else    {        /* No previous, update list head */        AcpiGbl_GpeXruptListHead = GpeXrupt->Next;    }    if (GpeXrupt->Next)    {        GpeXrupt->Next->Previous = GpeXrupt->Previous;    }    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);    /* Free the block */    ACPI_FREE (GpeXrupt);    return_ACPI_STATUS (AE_OK);}/******************************************************************************* * * FUNCTION:    AcpiEvInstallGpeBlock * * PARAMETERS:  GpeBlock        - New GPE block *              InterruptNumber - Xrupt to be associated with this GPE block * * RETURN:      Status * * DESCRIPTION: Install new GPE block with mutex support * ******************************************************************************/static ACPI_STATUSAcpiEvInstallGpeBlock (    ACPI_GPE_BLOCK_INFO     *GpeBlock,    UINT32                  InterruptNumber){    ACPI_GPE_BLOCK_INFO     *NextGpeBlock;    ACPI_GPE_XRUPT_INFO     *GpeXruptBlock;    ACPI_STATUS             Status;    ACPI_CPU_FLAGS          Flags;    ACPI_FUNCTION_TRACE (EvInstallGpeBlock);    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    GpeXruptBlock = AcpiEvGetGpeXruptBlock (InterruptNumber);    if (!GpeXruptBlock)    {        Status = AE_NO_MEMORY;        goto UnlockAndExit;    }    /* Install the new block at the end of the list with lock */    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);    if (GpeXruptBlock->GpeBlockListHead)    {        NextGpeBlock = GpeXruptBlock->GpeBlockListHead;        while (NextGpeBlock->Next)        {            NextGpeBlock = NextGpeBlock->Next;        }        NextGpeBlock->Next = GpeBlock;        GpeBlock->Previous = NextGpeBlock;    }    else    {        GpeXruptBlock->GpeBlockListHead = GpeBlock;    }    GpeBlock->XruptBlock = GpeXruptBlock;    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);UnlockAndExit:    Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS);    return_ACPI_STATUS (Status);}/******************************************************************************* * * FUNCTION:    AcpiEvDeleteGpeBlock * * PARAMETERS:  GpeBlock        - Existing GPE block * * RETURN:      Status * * DESCRIPTION: Remove a GPE block * ******************************************************************************/ACPI_STATUSAcpiEvDeleteGpeBlock (    ACPI_GPE_BLOCK_INFO     *GpeBlock){    ACPI_STATUS             Status;    ACPI_CPU_FLAGS          Flags;    ACPI_FUNCTION_TRACE (EvInstallGpeBlock);    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    /* Disable all GPEs in this block */    Status = AcpiHwDisableGpeBlock (GpeBlock->XruptBlock, GpeBlock);    if (!GpeBlock->Previous && !GpeBlock->Next)    {        /* This is the last GpeBlock on this interrupt */        Status = AcpiEvDeleteGpeXrupt (GpeBlock->XruptBlock);        if (ACPI_FAILURE (Status))        {            goto UnlockAndExit;        }    }    else    {        /* Remove the block on this interrupt with lock */        Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);        if (GpeBlock->Previous)        {            GpeBlock->Previous->Next = GpeBlock->Next;        }        else        {            GpeBlock->XruptBlock->GpeBlockListHead = GpeBlock->Next;        }        if (GpeBlock->Next)        {            GpeBlock->Next->Previous = GpeBlock->Previous;        }        AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);    }    /* Free the GpeBlock */    ACPI_FREE (GpeBlock->RegisterInfo);    ACPI_FREE (GpeBlock->EventInfo);    ACPI_FREE (GpeBlock);UnlockAndExit:    Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS);    return_ACPI_STATUS (Status);}/******************************************************************************* * * FUNCTION:    AcpiEvCreateGpeInfoBlocks * * PARAMETERS:  GpeBlock    - New GPE block * * RETURN:      Status * * DESCRIPTION: Create the RegisterInfo and EventInfo blocks for this GPE block * ******************************************************************************/static ACPI_STATUSAcpiEvCreateGpeInfoBlocks (    ACPI_GPE_BLOCK_INFO     *GpeBlock){    ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo = NULL;    ACPI_GPE_EVENT_INFO     *GpeEventInfo = NULL;    ACPI_GPE_EVENT_INFO     *ThisEvent;    ACPI_GPE_REGISTER_INFO  *ThisRegister;    ACPI_NATIVE_UINT        i;    ACPI_NATIVE_UINT        j;    ACPI_STATUS             Status;    ACPI_FUNCTION_TRACE (EvCreateGpeInfoBlocks);    /* Allocate the GPE register information block */    GpeRegisterInfo = ACPI_ALLOCATE_ZEROED (                            (ACPI_SIZE) GpeBlock->RegisterCount *                            sizeof (ACPI_GPE_REGISTER_INFO));    if (!GpeRegisterInfo)    {        ACPI_ERROR ((AE_INFO,            "Could not allocate the GpeRegisterInfo table"));        return_ACPI_STATUS (AE_NO_MEMORY);    }    /*     * Allocate the GPE EventInfo block. There are eight distinct GPEs     * per register. Initialization to zeros is sufficient.     */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -