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

📄 intr.c

📁 YLP270的Windows CE5.0 bsp源码。
💻 C
📖 第 1 页 / 共 4 页
字号:
            pLsock->pRegWin,
            FCR_OFFSET_FCSR,
            &uFSCR);
        uFSCR &= ~FCR_FCSR_INTR;
        uFSCR |= FCR_FCSR_INTR_ACK;
        CardWriteAttrByte(pLsock->pRegWin,FCR_OFFSET_FCSR, uFSCR);
    }
}   // ClearFCSRInterrupt


//
// Call client driver's "ISR" in a protected manner.
//
// Return TRUE if client serviced the interrupt without problems.
//
BOOL
CallClientISR(
    CARD_ISR ISRFn,
    UINT32 uISRContext
    )
{
    BOOL ret = FALSE;

    if (ISRFn) {
        try {
            (ISRFn)(uISRContext);
            ret = TRUE;
            DEBUGMSG(ZONE_IREQ,
                (TEXT("PCMCIA:CallClientISR - returned from Client ISR\r\n")));
        } except (GetExceptionCode() == STATUS_ACCESS_VIOLATION ?
                EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
            DEBUGMSG(ZONE_IREQ,
                (TEXT("PCMCIA:CallClientISR - Client ISR caused an exception\r\n")));
        }
    }
    return ret;
}   // CallClientISR

//
// Function to notify all the interrupt owners of a logical socket.
//
// Return TRUE if at least one of the clients serviced the interrupt.
//
BOOL
CallClientISRs(
    PLOG_SOCKET pLsock
    )
{
    PIREQ_OBJ pIREQ;
    BOOL ret;

    //
    // If there are no interrupt owners, then bail.
    //
    if (!(pLsock->fFlags & OWNER_FLAG_INTERRUPT)) {
        return FALSE;
    }

    ret = FALSE;

    EnterCriticalSection(&v_SocketCrit);
    pIREQ = pLsock->IREQList;

    while (pIREQ) {
        if (CallClientISR(pIREQ->ISRFn, pIREQ->uISRContext)) {
            ret = TRUE;
        }
        pIREQ = pIREQ->Next;
    }
    LeaveCriticalSection(&v_SocketCrit);
    return ret;
}   // CallClientISRs

//
// Function to process PCMCIA "data" interrupts (IREQ).  When the the IREQ event
// gets signaled, this function will determine which socket and function caused
// the interrupt and will call the associated client's "ISR" (registered with
// CardRequestIRQ).
//
UINT IREQThread(UINT Nothing)
{
    PDCARD_SOCKET_STATE State;
    UINT8 uFSCR;
    UINT  uSocket;
    PLOG_SOCKET pLsock;
    PPHYS_SOCKET pPsock;
    BOOL bKeepIntEnabled;
    BOOL stat;
    BOOL bLoop;

    while (1) {
        stat = WaitForSingleObject(v_IREQEvent, INFINITE);
        if (v_bSharedIntr) SetEvent(v_StatusChangeEvent);
        do {
            bLoop = FALSE;
            for (uSocket = 0, pPsock = v_Sockets;
                 uSocket < (UINT8)v_cSockets;
                 uSocket++, pPsock++) {

                bKeepIntEnabled = FALSE;
                if (PDCardGetSocket(uSocket, &State) != CERR_SUCCESS) {
                    DEBUGMSG(ZONE_IREQ|ZONE_WARNING,
                     (TEXT("PCMCIA:IREQInt - Unable to get status of socket %d\r\n"),
                     uSocket));
                    continue;
                }

                //
                // If sharing interrupts, check for missed card insertion/removal
                //
                if (v_bSharedIntr &&
                    (State.fNotifyEvents & EVENT_MASK_CARD_DETECT) != (v_fPrevEvents[uSocket] & EVENT_MASK_CARD_DETECT)) {
                    DEBUGMSG(ZONE_IREQ,
                         (TEXT("PCMCIA:IREQInt Current CD does not match v_fPrevEvents CD\r\n")));
                    SetEvent(v_StatusChangeEvent);
                }

                //
                // Ignore if there is no card inserted.
                //
                if (!(State.fNotifyEvents & EVENT_MASK_CARD_DETECT) ||
                    v_Sockets[uSocket].PowerState == POWER_OFF ||
                    v_Sockets[uSocket].PowerState == POWER_RESET) {
                    if (State.fIREQRouting & SOCK_IREQ_ENABLE) {
                        DEBUGMSG(ZONE_IREQ,
                          (TEXT("PCMCIA:IREQInt clearing SOCK_IREQ_ENABLE for socket %d\r\n"),
                          uSocket));
                        State.fIREQRouting &= ~SOCK_IREQ_ENABLE;
                        PDCardSetSocket(uSocket, &State);
                    }
                    continue;
                }

                pLsock = pPsock->pLsock;
                if (pLsock == NULL) {
                    if (State.fIREQRouting & SOCK_IREQ_ENABLE) {
                        RETAILMSG(1,
                            (TEXT("PCMCIA:IREQInt: Got interrupt, but no IREQ owner!!!\r\n")));
                        State.fIREQRouting &= ~SOCK_IREQ_ENABLE;
                        PDCardSetSocket(uSocket, &State);
                    }
                    continue;
                }

                //
                // Turn on IREQ interrupt due to CardRequestIRQ or CardRequestConfiguration
                //
                if (!(State.fIREQRouting & SOCK_IREQ_ENABLE)) {
                    //
                    // Check each function for an interrupt owner
                    //
                    while (pLsock) {
                        if ((pLsock->fFlags & OWNER_FLAG_INTERRUPT) &&
                            (pLsock->fFlags & OWNER_FLAG_CONFIG)) {
                            break;  // found an owner, so enable interrupts
                        }
                        pLsock = pLsock->Next;
                    }
                    if (pLsock == NULL) {
                        continue;
                    }
                    DEBUGMSG(ZONE_IREQ,
                     (TEXT("PCMCIA:IREQInt setting SOCK_IREQ_ENABLE for socket %d\r\n"),
                      uSocket));
                    State.fIREQRouting |= SOCK_IREQ_ENABLE;
                    PDCardSetSocket(uSocket, &State);
                }

                //
                // Check each function to see if it interrupted
                //
                pLsock = pPsock->pLsock;
                while (pLsock) {
                    if (!(pLsock->FCSR_val & FCR_FCSR_PWR_DOWN)) {
                        if (!(pLsock->fFlags & LOG_SOCK_FLAG_NO_INTR_ACK) &&
                            pLsock->fRegisters & (1 << FCR_OFFSET_FCSR)) {                   
                            CardReadAttrByte(
                                pLsock->pRegWin,
                                FCR_OFFSET_FCSR,
                                &uFSCR);
                            if (!(uFSCR & FCR_FCSR_INTR)) {
                                pLsock = pLsock->Next;
                                bKeepIntEnabled |= TRUE;
                                continue;
                            }
                            ClearFCSRInterrupt(pLsock);
                            bKeepIntEnabled |= CallClientISRs(pLsock);
                            bLoop = TRUE;
                        } else {
                            bKeepIntEnabled |= CallClientISRs(pLsock);
                        }
                    }
                    pLsock = pLsock->Next;
                }
    
                //
                // If no clients are interested in interrupts for this socket, then disable them
                //
                if (bKeepIntEnabled == FALSE) {
                    DEBUGMSG(ZONE_IREQ, (TEXT("PCMCIA:IREQInt clearing SOCK_IREQ_ENABLE for socket %d\r\n"), uSocket));
                    State.fIREQRouting &= ~SOCK_IREQ_ENABLE;
                    PDCardSetSocket(uSocket, &State);
                }
            }   // for all sockets
        } while (bLoop);

        InterruptDone(gIntrPcmciaLevel);

    }
    return 0;
//    return bKeepIntEnabled;
}   // IREQThread


//
// Function to display the "using a PC card on battery power" message.
//
// Return TRUE if the user wants to use the PC card on battery power
//
DWORD WINAPI
DisplayBatteryMsg(
    LPVOID lpvarg
    )
{
#define MAX_TITLE 100
    BOOL bCallback = FALSE;
    CARD_SOCKET_HANDLE hSock;
    UINT uSocket = (int)lpvarg;
    LPCTSTR NewCardTitle;
    TCHAR TitleOut[MAX_TITLE] = TEXT("");
    LPCTSTR NewCardMsg;

    //
    // If gwes.exe is not running yet, then can't call its API functions
    //
    if (v_hGwesEvent == NULL) {
        v_Sockets[uSocket].fFlags |= PHYS_SOCK_FLAG_POWER_ON;
        return TRUE;
    }
    WaitForSingleObject(v_hGwesEvent, INFINITE);

    if ((v_pfnLoadStringW == NULL) || (v_pfnMessageBoxW == NULL)) {
        DEBUGMSG(ZONE_POWER|ZONE_STSCHG,
            (TEXT("PCMCIA:Can't find LoadString or MessageBox\r\n")));
        EnterCriticalSection(&v_BatteryCrit);
        if (GetCurrentThreadId() == v_hBatteryThread[uSocket]) {
            v_hBatteryThread[uSocket] = 0;
            v_fBattery[uSocket] = TRUE;
            bCallback = TRUE;
                        v_Sockets[uSocket].fFlags |= PHYS_SOCK_FLAG_POWER_ON;
        } else
                DEBUGMSG(ZONE_POWER|ZONE_WARNING,
                     (TEXT("PCMCIA:BatteryCheck: Thread already replaced\r\n")));
        LeaveCriticalSection(&v_BatteryCrit);
        if (bCallback) {
            hSock.uSocket = uSocket;
            hSock.uFunction = 0;
            CallbackOne(CE_CARDSERV_LOAD, 0, NULL, hSock);
        }
        return TRUE;
    }

    NewCardTitle = (LPCTSTR) v_pfnLoadStringW(g_hPcmDll,
                                IDS_PCMCIA_NEW_CARD_TITLE, NULL, 0);
    if (NewCardTitle == 0) {
        EnterCriticalSection(&v_BatteryCrit);
        if (GetCurrentThreadId() == v_hBatteryThread[uSocket]) {
            v_hBatteryThread[uSocket] = 0;
            v_fBattery[uSocket] = FALSE;
                        v_Sockets[uSocket].fFlags &= ~PHYS_SOCK_FLAG_POWER_ON;
        } else
                DEBUGMSG(ZONE_POWER|ZONE_WARNING,
                     (TEXT("PCMCIA:BatteryCheck: Thread already replaced\r\n")));
        LeaveCriticalSection(&v_BatteryCrit);
        return FALSE;
    }

    NewCardMsg = (LPCTSTR) v_pfnLoadStringW(g_hPcmDll,
                                IDS_PCMCIA_NEW_CARD_MSG, NULL, 0);
    if (NewCardMsg == 0) {
        EnterCriticalSection(&v_BatteryCrit);
        if (GetCurrentThreadId() == v_hBatteryThread[uSocket]) {
            v_hBatteryThread[uSocket] = 0;
            v_fBattery[uSocket] = FALSE;
                        v_Sockets[uSocket].fFlags &= ~PHYS_SOCK_FLAG_POWER_ON;
        } else
                DEBUGMSG(ZONE_POWER|ZONE_WARNING,
                     (TEXT("PCMCIA:BatteryCheck: Thread already replaced\r\n")));
        LeaveCriticalSection(&v_BatteryCrit);
        return FALSE;
    }

    if (_tcslen(NewCardTitle) < MAX_TITLE) {
        //
        // There's enough room to copy the formatted title, else use empty string.
        //
        wsprintf(TitleOut, NewCardTitle, uSocket+1);
    } else {
        DEBUGMSG(1, (TEXT("PCMCIA:Title string too long! (%a @ %d)\r\n"), __FILE__, __LINE__));
    }
    if (v_pfnMessageBoxW(NULL, NewCardMsg, TitleOut,
            MB_YESNO|MB_SETFOREGROUND|MB_TOPMOST|MB_DEFBUTTON2) != IDYES) {
        EnterCriticalSection(&v_BatteryCrit);
        if (GetCurrentThreadId() == v_hBatteryThread[uSocket]) {
            v_hBatteryThread[uSocket] = 0;
            v_fBattery[uSocket] = FALSE;
                        v_Sockets[uSocket].fFlags &= ~PHYS_SOCK_FLAG_POWER_ON;

⌨️ 快捷键说明

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