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

📄 intr.c

📁 YLP270的Windows CE5.0 bsp源码。
💻 C
📖 第 1 页 / 共 4 页
字号:
        } else
                DEBUGMSG(ZONE_POWER|ZONE_WARNING,
                     (TEXT("PCMCIA:BatteryCheck: Thread already replaced\r\n")));
        LeaveCriticalSection(&v_BatteryCrit);
        return FALSE;
    }
    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;
}


//
// Function to query the user about using a PC card while on battery power.
//
// Return TRUE if the user wants to use the PC card on battery power or if the
// system is running on AC power.
//
BOOL
BatteryCheck(
    UINT8 uSocket
    )
{
    SYSTEM_POWER_STATUS_EX PowerStatus;
    DWORD   dwLen;
    DWORD   dwValue;

    dwValue = FALSE;    // Set default
    dwLen = sizeof(dwValue);
    RegQueryValueEx(HKEY_LOCAL_MACHINE, L"NoBatteryCheck",
                    (LPDWORD) L"Drivers\\Pcmcia", NULL,
                    (LPBYTE) &dwValue, &dwLen);

    if (dwValue) {
        DEBUGMSG (1, (TEXT("Ignoring battery check\r\n")));
                v_Sockets[uSocket].fFlags |= PHYS_SOCK_FLAG_POWER_ON;
        return TRUE;
    }

    //
    // If we are on battery power, prompt the user to see if he wants his
    // battery drained (PC cards are typically very power hungry).  Remember his
    // response in the physical socket structure so we don't have to re-prompt
    // everytime we come back from standby.  The user will have to remove and
    // reinsert the card with power on in order to get prompted again.
    //
    DEBUGMSG(ZONE_POWER, (TEXT("Before Battery Check fFlags for socket %d = %x\r\n"),uSocket,v_Sockets[uSocket].fFlags));
    if (v_Sockets[uSocket].fFlags & PHYS_SOCK_FLAG_FROM_STANDBY) {
        DEBUGMSG(ZONE_POWER|ZONE_STSCHG,
            (TEXT("PCMCIA:BatteryCheck returning %s.\r\n"),
            (v_Sockets[uSocket].fFlags & PHYS_SOCK_FLAG_POWER_ON) ?
                 TEXT("TRUE") : TEXT("FALSE")));
        return (v_Sockets[uSocket].fFlags & PHYS_SOCK_FLAG_POWER_ON) ? TRUE:FALSE;
    }

    if (NULL == v_pfnGetSystemPowerStatusEx) {
        DEBUGMSG(ZONE_POWER|ZONE_STSCHG,
            (TEXT("PCMCIA:Couldn't getprocaddr of GetSystemPowerStatusEx\r\n")));
        goto BatteryCheckExit;
    }

    if (v_pfnGetSystemPowerStatusEx(&PowerStatus, TRUE)) {
        DEBUGMSG(ZONE_POWER|ZONE_STSCHG,
            (TEXT("PCMCIA:BatteryCheck:ACLineStatus = %d\r\n"), PowerStatus.ACLineStatus));
        if (PowerStatus.ACLineStatus != AC_LINE_ONLINE && !v_fBattery[uSocket]) {
            HANDLE hThd;
            DWORD dSocket;

            if (v_hBatteryThread[uSocket] != 0) {
                DEBUGMSG(ZONE_POWER|ZONE_WARNING,
                     (TEXT("PCMCIA:BatteryCheck: Warning!  Battery Thread not NULL!\r\n")));
                v_Sockets[uSocket].fFlags &= ~PHYS_SOCK_FLAG_POWER_ON;
                return FALSE;
            }

            EnterCriticalSection(&v_BatteryCrit);

            dSocket = uSocket;
            hThd = CreateThread(NULL, 0,
                        (LPTHREAD_START_ROUTINE)DisplayBatteryMsg,
                        (LPVOID)dSocket,
                        0,
                        &v_hBatteryThread[uSocket]);
            if (hThd) {
                CloseHandle(hThd);
            } else {
                DEBUGMSG(ZONE_POWER,
                    (TEXT("PCMCIA:BatteryCheck: CreateThread failed %d\r\n"),
                    GetLastError()));
            }
            LeaveCriticalSection(&v_BatteryCrit);
            v_Sockets[uSocket].fFlags &= ~PHYS_SOCK_FLAG_POWER_ON;
            return FALSE;
/*
            if (DisplayBatteryMsg(uSocket) == FALSE) {
                v_Sockets[uSocket].fFlags &= ~PHYS_SOCK_FLAG_POWER_ON;
                DEBUGMSG(ZONE_POWER|ZONE_STSCHG,
                    (TEXT("PCMCIA:BatteryCheck returning FALSE\r\n")));
                return FALSE;
            }
*/
        }
    } else {
        DEBUGMSG(ZONE_POWER|ZONE_STSCHG,
            (TEXT("PCMCIA:BatteryCheck:GetSystemPowerStatusEx failed %d\r\n"),
            GetLastError()));
    }

BatteryCheckExit:
    v_Sockets[uSocket].fFlags |= PHYS_SOCK_FLAG_POWER_ON;
    DEBUGMSG(ZONE_POWER|ZONE_STSCHG, (TEXT("PCMCIA:BatteryCheck TRUE-fFlag for Socket %d is %x\r\n"),uSocket,v_Sockets[uSocket].fFlags));
    return TRUE;
}   // BatteryCheck


//
// Function to process PCMCIA status change interrupts.  When the status change
// event gets signaled, this thread will determine what caused the interrupt
// and then perform appropriate callbacks to the client drivers.
//
UINT
StatusChangeThread(
    UINT Nothing
    )
{
    UINT16 fChanged;
    UINT16 fChangeBack;
//    UINT16 fPRROn;
    UINT16 fCurr;
    UINT   uSocket;
    UINT   uFunction;
    UINT   ret;
    UINT   uTimeOut = INFINITE;
    PDCARD_SOCKET_STATE State;
    CARD_SOCKET_HANDLE hSock;
    CARD_EVENT EventCode;
//    UINT CallbackFlags;
    UINT8  fEvents[MAX_FUNCTIONS];
    UINT   bChanged;

    PPHYS_SOCKET pPsock;
    PLOG_SOCKET pLsock;
    UINT8 uPRR;
#ifdef DEBUG
    TCHAR OutBuf[128];
#endif
    //
    // Check if we need to poll card status
    //
    for (uSocket = 0; uSocket < (UINT8)v_cSockets; uSocket++) {
        v_fPrevEvents[uSocket] = 0;
        //
        // See if we need to poll for card detect and other events
        // (The interrupt events are in the low byte of the fFlags field)
        //
        if (!(v_Sockets[uSocket].fFlags & REQUIRED_INTR_EVENTS)) {
//            uTimeOut = POLL_TIMEOUT;
        }
    }

    //
    // We'll need to poll for status change if we were unable to get an interrupt
    //
    if (v_StatusChangeEvent == NULL) {
        v_StatusChangeEvent = CreateEvent(NULL, FALSE, FALSE , NULL);
        uTimeOut = POLL_TIMEOUT;
    }

#ifdef DEBUG
    if (uTimeOut == POLL_TIMEOUT) {
        DEBUGMSG(ZONE_INIT|ZONE_STSCHG|ZONE_WARNING,
            (TEXT("PCMCIA:StatusChangeThread - PCMCIA driver is resorting to polling for Status Change.\r\n")));
    }
#endif

    //
    // Wait for PCMCIA interrupts and process them
    //
    while (1) {
        ret = WaitForSingleObject(v_StatusChangeEvent, uTimeOut);
        DEBUGMSG(ZONE_STSCHG, (TEXT("PCMCIA:StatusChangeInt signalled\r\n")));

        for (uSocket = 0, pPsock = v_Sockets; uSocket < (UINT8)v_cSockets; uSocket++, pPsock++) {

            if (PDCardGetSocket(uSocket, &State) != CERR_SUCCESS) {
                DEBUGMSG(ZONE_STSCHG|ZONE_WARNING,
                 (TEXT("PCMCIA:StatusChangeInt - Unable to get status of socket %d\r\n"),
                  uSocket));
                continue;
            }
            hSock.uFunction = 0;

            DEBUGMSG(ZONE_STSCHG, (TEXT("PCMCIA:StatusChangeInt socket %d events = %x\r\n"),uSocket,State.fNotifyEvents));
            hSock.uSocket = uSocket;

            for (uFunction = 0; uFunction < MAX_FUNCTIONS; uFunction++)
                fEvents[uFunction] = 0;
            bChanged = FALSE;
//          fPRROn = 0;

            //
            // Check for events which may have been caused by STSCHG -- the PDD may report
            // these as battery low events, since the STSCHG pin is mapped to BVD1 in IO mode.
            //
            if ((State.fNotifyEvents & EVENT_MASK_CARD_DETECT) &&
                (State.fNotifyEvents &
                (EVENT_MASK_STATUS_CHANGE | EVENT_MASK_BATTERY_DEAD | EVENT_MASK_BATTERY_LOW))) {
                //
                // If card is in I/O mode, and supports a pin replacement
                // register, read status from PRR. Note -- won't work for multi function cards.
                //
                pLsock = pPsock->pLsock;
                if (pLsock == NULL) {
                    DEBUGMSG(ZONE_STSCHG|ZONE_WARNING,
                             (TEXT("PCMCIA:StatusChangeInt - Unable to get logical socket %d\r\n"),
                              uSocket));
                } else if (v_Sockets[uSocket].PowerState != POWER_OFF &&
                           v_Sockets[uSocket].PowerState != POWER_KEPT &&
                           v_Sockets[uSocket].PowerState != POWER_RESET) {
                    for (; pLsock != NULL; pLsock = pLsock->Next) {
                        uFunction = pLsock->hSock.uFunction;
                        if (uFunction < 0 || uFunction >= MAX_FUNCTIONS) {
                            DEBUGMSG((ZONE_STSCHG|ZONE_WARNING),
                                (TEXT("PCMCIA:StatusChangeThread: invalid function %d\n\r"),
                                    uFunction));
                            continue;
                        }
                         if ((!(pLsock->FCSR_val & FCR_FCSR_PWR_DOWN)) &&  // Not powered down
                             (pLsock->fFlags & OWNER_FLAG_CONFIG) &&       // IO mode
                             (pLsock->fRegisters & CFG_REGISTER_PIN)) {
                             // Using Pin Replacement Register, clear existing event mask
                            if (!bChanged)
                                State.fNotifyEvents &= ~(EVENT_MASK_STATUS_CHANGE |
                                                         EVENT_MASK_BATTERY_DEAD  |
                                                         EVENT_MASK_BATTERY_LOW);
                            bChanged = TRUE;
                            CardReadAttrByte(pLsock->pRegWin,FCR_OFFSET_PRR,&uPRR);
                            DEBUGMSG(ZONE_STSCHG,
                                (TEXT("PCMCIA:StatusChangeInt: Read value 0x%X from PRR on socket %d %d\n\r"),
                                uPRR, uSocket, uFunction));
                            if (uPRR & FCR_PRR_CBVD1) {
                                if (!(uPRR & FCR_PRR_RBVD1)) {
                                    fEvents[uFunction] |= (EVENT_MASK_BATTERY_DEAD & State.fInterruptEvents);
//                                    fPRROn |= EVENT_MASK_BATTERY_DEAD;
                                }
                                uPRR &= ~FCR_PRR_CBVD1;
                            }
                            if (uPRR & FCR_PRR_CBVD2) {
                                if (!(uPRR & FCR_PRR_RBVD2)) {
                                    fEvents[uFunction] |= (EVENT_MASK_BATTERY_LOW & State.fInterruptEvents);
//                                    fPRROn |= EVENT_MASK_BATTERY_LOW;
                                }
                                uPRR &= ~FCR_PRR_CBVD2;
                            }
                            if (uPRR & FCR_PRR_CRDY) {
                                if (uPRR & FCR_PRR_RREADY) {
                                     fEvents[uFunction] |= (EVENT_MASK_CARD_READY & State.fInterruptEvents);
//                                     fPRROn |= EVENT_MASK_CARD_READY;
                                }
                                uPRR &= ~FCR_PRR_CRDY;
                            }
                            if (uPRR & FCR_PRR_CWP) {
                                if (uPRR & FCR_PRR_RWP) {
                                    fEvents[uFunction] |= (EVENT_MASK_WRITE_PROTECT & State.fInterruptEvents);
//                                    fPRROn |= EVENT_MASK_WRITE_PROTECT;
                                }
                                uPRR &= ~FCR_PRR_CWP;
                            }
                            // Clear the PRR
                            CardWriteAttrByte(pLsock->pRegWin,FCR_OFFSET_PRR, uPRR);
                        } else {
                            if (!(pLsock->fRegisters & CFG_REGISTER_PIN)) {
                                DEBUGMSG(ZONE_WARNING,
                                    (TEXT("PCMCIA:Card doesn't support PRR (0x%X)\n\r"),
                                    pLsock->fRegisters));
                            } else {
                                DEBUGMSG(ZONE_WARNING,
                                    (TEXT("PCMCIA:Card not in I/O mode (fl 0x%X)\n\r"),
                                    pLsock->fFlags));
                            }
                        }
                    }
                }
            }

            //
            // Determine what changed.  The below XOR computes the
            // bits that have changed.  Then that result is ANDed with
            // the bitmask of what the socket is capable of reporting.
            //
            fChanged = (State.fInterruptEvents|EVENT_MASK_CARD_DETECT) &
                        (v_fPrevEvents[uSocket] ^ State.fNotifyEvents);
            fCurr = State.fNotifyEvents;
            v_fChangedEvents[uSocket] = fChanged;

⌨️ 快捷键说明

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