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

📄 intr.c

📁 YLP270的Windows CE5.0 bsp源码。
💻 C
📖 第 1 页 / 共 4 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:

    intr.c

Abstract:

    This file implements the PCMCIA model device driver interrupt threads and
    apis.  This is provided as a sample to platform writers and is
    expected to be able to be used without modification on most (if not
    all) hardware platforms.

Functions:

    CardRequestIRQ()
    CardReleaseIRQ()
    ClearFCSRInterrupt()
    CallClientISR()
    CallClientISRs()
    IREQThread()
    DisplayBatteryMsg()
    BatteryCheck()
    StatusChangeThread()

Notes:


--*/


#include <windows.h>
#include <types.h>
#include <excpt.h>
#include <cardserv.h>    // ddk\inc
#include <sockserv.h>    // oak\inc
#include <pcmres.h>
#include <pcmcia.h>
#include <nkintr.h>
#include <windev.h>
#include <extern.h>
#include <celog.h>

#define REQUIRED_INTR_EVENTS    (EVENT_MASK_CARD_DETECT)
#define POLL_TIMEOUT        1000
#define INTR_POLL_TIMEOUT1       0x0100
#define INTR_POLL_TIMEOUT2       0x0300

HANDLE v_hGwesEvent;
UINT16 v_fPrevEvents[MAX_SOCKETS];
UINT16 v_fChangedEvents[MAX_SOCKETS];
BOOL v_fBattery[MAX_SOCKETS];
DWORD v_hBatteryThread[MAX_SOCKETS];
BOOL v_bSharedIntr = FALSE;
CRITICAL_SECTION v_BatteryCrit;
extern HINSTANCE g_hPcmDll;    // init.c

//
// CardRequestIRQ
//
// @doc DRIVERS
//
// @func    STATUS | CardRequestIRQ | Request interrupt notification for the specified socket/function
// @rdesc   Returns one of CERR_SUCCESS, CERR_BAD_ARGS, CERR_BAD_HANDLE, CERR_BAD_SOCKET
//          or CERR_IN_USE.
//
// @comm    This function sets up the interrupt callback exclusively for the requesting client.
//          Interrupts will not be signalled until the PC card is configured for the I/O interface
//          via the <f CardRequestConfiguration> API.
//
STATUS
CardRequestIRQ(
    CARD_CLIENT_HANDLE hCardClient, // @parm Client handle from <f CardRegisterClient>
    CARD_SOCKET_HANDLE hSocket,     // @parm Socket/function identifier (logical socket)
    CARD_ISR ISRFunction,           // @parm Pointer to the interrupt callback function
    UINT32 uISRContextData          // @parm Context that will be passed to the ISRFunction
    )
{
    PCLIENT_DRIVER pClient;
    PLOG_SOCKET pLsock;
    PIREQ_OBJ pIREQ;
    STATUS status = CERR_SUCCESS;
    BOOL bSignalInt = FALSE;

    DEBUGMSG(ZONE_FUNCTION|ZONE_IREQ,
        (TEXT("PCMCIA:CardRequestIRQ entered\r\n")));

    //
    // Perform some parameter checks first
    //
    if (ISRFunction == NULL) {
        status = CERR_BAD_ARGS;
        goto req_irq_exit;
    }

    if ((pClient = FindClient(hCardClient, TRUE, TRUE)) == NULL) {
        status = CERR_BAD_HANDLE;
        goto req_irq_exit;
    }

    //
    // The socket must already exist.
    //
    pLsock = I_FindSocket(hSocket);
    if (pLsock == NULL) {
        status = CERR_BAD_SOCKET;
        goto req_irq_exit;
    }

    if ((pLsock->hOwner != 0) &&
        (pLsock->hOwner != pClient) &&
        (pLsock->fFlags & OWNER_FLAG_EXCLUSIVE)) {
        DEBUGMSG(ZONE_WARNING,
            (TEXT("PCMCIA:CardRequestIRQ: Exclusive owner is %x, caller is %x\r\n"),
                 pLsock->hOwner, hCardClient));
        status = CERR_IN_USE;
        goto req_irq_exit;
    }

    pIREQ = LocalAlloc(LPTR, sizeof(IREQ_OBJ));
    if (pIREQ == NULL) {
        status = CERR_OUT_OF_RESOURCE;
        goto req_irq_exit;
    }

    pLsock->fFlags |= OWNER_FLAG_INTERRUPT;
    if (pLsock->hOwner == 0) {
        pLsock->hOwner = pClient;
    }

    //
    // Enable the interrupt if this is the first interrupt owner for this card
    // and the card is in I/O mode.
    //
    if ((pLsock->IREQList == NULL) && (pLsock->fFlags & OWNER_FLAG_CONFIG)) {
        bSignalInt = TRUE;
    }

    pIREQ->Next = NULL;
    pIREQ->hOwner = pClient;
    pIREQ->ISRFn = ISRFunction;
    pIREQ->uISRContext = uISRContextData;
    EnterCriticalSection(&v_SocketCrit);
    pIREQ->Next = pLsock->IREQList;
    pLsock->IREQList = pIREQ;
    LeaveCriticalSection(&v_SocketCrit);

    if (bSignalInt) {
        DEBUGMSG(ZONE_IREQ, (TEXT("PCMCIA:CardRequestIRQ:Signalling IREQThread\r\n")));
        SetEvent(v_IREQEvent);
    }

req_irq_exit:
#ifdef DEBUG
    if (status) {
        DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR|ZONE_IREQ,
            (TEXT("PCMCIA:CardRequestIRQ failed %d\r\n"), status));
    } else {
        DEBUGMSG(ZONE_FUNCTION|ZONE_IREQ,
            (TEXT("PCMCIA:CardRequestIRQ succeeded\r\n")));
    }
#endif
    return status;
}   // CardRequestIRQ


//
// CardReleaseIRQ
//
// @func    STATUS | CardReleaseIRQ | Releases ownership of the interrupt for the specified
//                                    socket/function
// @rdesc   Returns one of CERR_SUCCESS, CERR_BAD_HANDLE, CERR_BAD_SOCKET,
//          CERR_CONFIGURATION_LOCKED or CERR_IN_USE.
//
// @comm    The PC card must first be configured for the memory-only interface via the
//          <f CardReleaseConfiguration> API.
//
STATUS
CardReleaseIRQ(
    CARD_CLIENT_HANDLE hCardClient, // @parm Client handle from <f CardRegisterClient>
    CARD_SOCKET_HANDLE hSocket      // @parm Socket/function identifier (logical socket)
    )
{
    PCLIENT_DRIVER pClient;
    PLOG_SOCKET pLsock;
    PDCARD_SOCKET_STATE State;
    PIREQ_OBJ pPrev;
    PIREQ_OBJ pCurr;
    STATUS status = CERR_SUCCESS;

    DEBUGMSG(ZONE_FUNCTION|ZONE_IREQ,
        (TEXT("PCMCIA:CardReleaseIRQ entered\r\n")));

    //
    // Perform some parameter checks first
    //
    if ((pClient = FindClient(hCardClient, TRUE, TRUE)) == NULL) {
        status = CERR_BAD_HANDLE;
        goto rel_irq_exit;
    }

    //
    // Find the socket
    //
    pLsock = I_FindSocket(hSocket);
    if (pLsock == NULL) {
        status = CERR_BAD_SOCKET;
        goto rel_irq_exit;
    }

    //
    // See if the caller is in our list.
    //
    if (pLsock->IREQList == NULL) {
        status = CERR_BAD_ARGS;
        goto rel_irq_exit;
    }

    EnterCriticalSection(&v_SocketCrit);
    pPrev = pCurr = pLsock->IREQList;
    while (pCurr) {
        if (pCurr->hOwner == pClient) {
            break;
        }
        pPrev = pCurr;
        pCurr = pCurr->Next;
    }
    if (pCurr == NULL) {
        status = CERR_BAD_ARGS;
        LeaveCriticalSection(&v_SocketCrit);
        goto rel_irq_exit;
    }

    //
    // Unlink this interrupt object
    //
    if (pCurr == pLsock->IREQList) {
        pLsock->IREQList = pCurr->Next;
    } else {
        pPrev->Next = pCurr->Next;
    }
    LeaveCriticalSection(&v_SocketCrit);
    LocalFree(pCurr);

    //
    // Turn off the IREQ interrupt on this socket if there are no more
    // interrupt requesters.
    //
    if (pLsock->IREQList == NULL) {
        pLsock->fFlags &= ~OWNER_FLAG_INTERRUPT;
        if (status = PDCardGetSocket(hSocket.uSocket, &State)) {
            goto rel_irq_exit;
        }

        State.fIREQRouting &= ~SOCK_IREQ_ENABLE;
        PDCardSetSocket(hSocket.uSocket, &State);
    }

    if (pLsock->hOwner == pClient) {
        if (pLsock->fFlags == 0) {
            pLsock->hOwner = NULL;
        } else if (pLsock->IREQList) {
            pLsock->hOwner = pLsock->IREQList->hOwner;
        }
    }

rel_irq_exit:
#ifdef DEBUG
    if (status) {
        DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR|ZONE_IREQ,
            (TEXT("PCMCIA:CardReleaseIRQ failed %d\r\n"), status));
    } else {
        DEBUGMSG(ZONE_FUNCTION|ZONE_IREQ,
            (TEXT("PCMCIA:CardReleaseIRQ succeeded\r\n")));
    }
#endif
    return status;
}   // CardReleaseIRQ


//
// Clear the INTR bit in the FCSR (function configuration and status register)
// to indicate that software has processed the interrupt.
//
void
ClearFCSRInterrupt(
    PLOG_SOCKET pLsock
    )
{
    UINT8 uFSCR;

    if (pLsock->fRegisters & CFG_REGISTER_STATUS) {
        CardReadAttrByte(

⌨️ 快捷键说明

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