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

📄 utils.c

📁 YLP270的Windows CE5.0 bsp源码。
💻 C
📖 第 1 页 / 共 2 页
字号:
#endif
    }

    LeaveCriticalSection(&v_ClientCrit);

    return found;
}   // IsValidClient

PCLIENT_DRIVER
FindClient(
    CARD_CLIENT_HANDLE pClient,
    BOOL fCritSec,
    BOOL fCCH
    )
{
    PCLIENT_DRIVER pClient1;
#ifdef DEBUG
    int i = 0;
#endif

    if (fCCH && pClient == (PCLIENT_DRIVER)CARDSERV_CLIENT_HANDLE)
        return CARDSERV_CLIENT_HANDLE;

    if (fCritSec)
        EnterCriticalSection(&v_ClientCrit);
    pClient1 = (PCLIENT_DRIVER)v_ClientList.Flink;

    //
    // Validate handle
    //
    while (pClient1 != (PCLIENT_DRIVER)&v_ClientList) {
        if (pClient1->hClient == pClient)
            break;
        pClient1 = (PCLIENT_DRIVER)pClient1->List.Flink;

#ifdef DEBUG
        i++;
        if (i > 500) {
            DEBUGMSG(ZONE_WARNING, (TEXT("PCMCIA.DLL: Problem in IsValidClient()!!!\r\n")));
            break;
        }
#endif
    }

    if (pClient1 == (PCLIENT_DRIVER)&v_ClientList)
        pClient1 = NULL;

    if (fCritSec)
        LeaveCriticalSection(&v_ClientCrit);

    return pClient1;
}   // FindClient


//
// Create a LOG_SOCKET structure for the specified function of a newly inserted
// card, remember stuff about it and link it to the socket structure.
//
PLOG_SOCKET
CreateFunction(
    CARD_SOCKET_HANDLE hSock
    )
{
    PLOG_SOCKET pLsock;
    PARSED_CONFIG Cfg;
    UINT BufLen;
    STATUS status;
    UCHAR buf[1024];
    PPARSED_CFTABLE pCfTable = (PPARSED_CFTABLE) buf;
    UINT i;
    PPHYS_WINDOW pPhys;
    PDCARD_WINDOW_STATE WinState;
    UINT32 CardAddress;

    pLsock = alloc(sizeof(LOG_SOCKET));
    if (pLsock == NULL) {
        DEBUGMSG(ZONE_CALLBACK|ZONE_WARNING,
            (TEXT("CreateFunction: Couldn't allocate a logical socket for %d:%d!\r\n"),
            hSock.uSocket, hSock.uFunction));
        return NULL;
    }

    pLsock->Next = NULL;
    pLsock->hSock = hSock;
    pLsock->hOwner = 0;
    pLsock->IREQList = 0;
    pLsock->pRegWin = NULL;
    pLsock->fPrevEvents = 0;
    pLsock->fChangedEvents = 0;
    pLsock->hQueryDriver = 0;

    //
    // Link it to the socket structure
    //
    EnterCriticalSection(&v_SocketCrit);
    if (v_Sockets[hSock.uSocket].pLsock != NULL) {
        pLsock->Next = v_Sockets[hSock.uSocket].pLsock;
    }
    v_Sockets[hSock.uSocket].pLsock = pLsock;
    LeaveCriticalSection(&v_SocketCrit);

#ifdef FORCE_MODEM
    pLsock->fRegisters = 0xf;
    Cfg.ConfigBase = 0x100;
    Cfg.RegMask = 0xf;
#else
    //
    // Get the CISTPL_CONFIG tuple and remember the config reg address
    // and the register presence mask.
    //
    BufLen = 1;
    status = CardGetParsedTuple(
                hSock,
                CISTPL_CONFIG,
                &Cfg,
                &BufLen);
    if (status == CERR_SUCCESS) {
        pLsock->fRegisters = Cfg.RegMask;
    } else {
        DEBUGMSG(ZONE_CALLBACK|ZONE_WARNING,
            (TEXT("CreateFunction: CardGetParsedTuple(CISTPL_CONFIG) returned %d for %d:%d\r\n"),
            status, hSock.uSocket, hSock.uFunction));
        Cfg.ConfigBase = 0;
        Cfg.RegMask = 0;
    }
#endif

#ifndef FORCE_MODEM
    if ((Cfg.ConfigBase != 0) && (Cfg.RegMask != 0)) {
        //
        // Get the CISTPL_CFTABLE_ENTRY information to determine the card's interface type.
        // If it's an I/O card, then we need to map a window to attribute memory to
        // access the config registers.
        //
        BufLen = sizeof(buf)/sizeof(PARSED_CFTABLE);
        status = CardGetParsedTuple(
                    hSock,
                    CISTPL_CFTABLE_ENTRY,
                    pCfTable,
                    &BufLen);
        if (status == CERR_SUCCESS) {
            for (i = 0; i < BufLen; i++, pCfTable++) {
                if (pCfTable->IFacePresent) {
                    if (pCfTable->IFaceType != 1) {     // 1 == I/O card
                        continue;
                    }
#endif
                    //
                    // Find a physical memory window associated with this socket.
                    //
                    EnterCriticalSection(&v_WindowCrit);
                    CardAddress = Cfg.ConfigBase;

                    // Try first to use the existing attribute window used by Tuple parser
                    pPhys = v_Sockets[hSock.uSocket].pAttrWin->pPhys;
                    if (pPhys)
                    {
                        PDCardGetWindow(pPhys->uWindow, &WinState);
                        if ((WinState.uOffset <= CardAddress) &&
                            (CardAddress + 15 <= (WinState.uOffset + WinState.uSize)))
                        {
                            // Map window into attribute space
                            pLsock->hRegWin = I_MapWindow(pPhys, &CardAddress, 15, TRUE);
                            pLsock->pRegWin = (PVOID)CardAddress;

                            DEBUGMSG(ZONE_CALLBACK|ZONE_WARNING,
                                (TEXT("CreateFunction: Re-using Tuple attribute window, Config registers @ 0x%x for %d:%d\r\n"),
                                 CardAddress, hSock.uSocket, hSock.uFunction));

                            LeaveCriticalSection(&v_WindowCrit);
                            goto cf_done;
                        }
                    }

                    // Find another window, not used by Tuple parser
                    pPhys = v_pWinList;
                    while (pPhys) {
                        if (pPhys->uSock == hSock.uSocket) {
                            if (pPhys->fWindowCaps & WIN_CAP_ATTRIBUTE) {
                                // Don't use same physical window as the Tuple parser
                                if (pPhys == v_Sockets[pPhys->uSock].pAttrWin->pPhys)
                                {
                                    pPhys = pPhys->Next;
                                    continue;
                                }

                                // Set PCMCIA offset, which is simply the start address of the page
                                // containing CardAddress (in the PC Card address space)
                                PDCardGetWindow(pPhys->uWindow, &WinState);
                                pPhys->uOffset = WinState.uOffset = PAGE_START(CardAddress);
                                PDCardSetWindow(pPhys->uWindow, &WinState);

                                // Map window into attribute space
                                pLsock->hRegWin = I_MapWindow(pPhys, &CardAddress, 15, TRUE);
                                pLsock->pRegWin = (PVOID)CardAddress;

                                DEBUGMSG(ZONE_CALLBACK|ZONE_WARNING,
                                    (TEXT("CreateFunction: Config registers @ 0x%x for %d:%d\r\n"),
                                    CardAddress, hSock.uSocket, hSock.uFunction));

                                LeaveCriticalSection(&v_WindowCrit);
                                goto cf_done;
                            }
                        }
                        pPhys = pPhys->Next;
                    }
                    LeaveCriticalSection(&v_WindowCrit);

#ifndef FORCE_MODEM
                }
            }
        } else {
            DEBUGMSG(ZONE_CALLBACK|ZONE_WARNING,
                (TEXT("CreateFunction: CardGetParsedTuple(CISTPL_CFTABLE_ENTRY) returned %d for %d:%d\r\n"),
                status, hSock.uSocket, hSock.uFunction));
        }
    }
#endif

cf_done:
    pLsock->COR_val = 0;

    return pLsock;
}


//
// Create a LOG_SOCKET structure for each function of a newly inserted card.
//
// Returns the number of functions on the newly inserted card.
//
int CreateFunctions(UINT uSocket)
{
    CARD_SOCKET_HANDLE hSock;
    UINT8 numfn;
    UINT8 fn;
    UINT Created;
    PCARD_TUPLE_PARMS pTuple;
    PCARD_DATA_PARMS pData;
    UCHAR buf[BUFFER_SIZE + sizeof(CARD_DATA_PARMS)];
    STATUS status;

    DEBUGCHK(uSocket < (UINT)v_cSockets);

    hSock.uSocket = uSocket;
    hSock.uFunction = 0;
    Created = 1;

    //
    // Function 0 must be created in order to use the tuple APIs, so create the
    // first function now.
    //
    if (CreateFunction(hSock) == NULL) {
        return 0;
    }

    //
    // Read the CISTPL_LONGLINK_MFC tuple.  If one doesn't exist, then assume
    // the card has only one function.
    //
    pTuple = (PCARD_TUPLE_PARMS)buf;
    pTuple->hSocket = hSock;
    pTuple->fAttributes = TUPLE_RETURN_LINKS;
    pTuple->uDesiredTuple = CISTPL_LONGLINK_MFC;
    status = CardGetFirstTuple(pTuple);
    if (status == CERR_SUCCESS) {
        fn = pTuple->uTupleLink;    // tuple length
        pData = (PCARD_DATA_PARMS)buf;
        pData->uTupleOffset = 0;
        pData->uBufLen = BUFFER_SIZE;
        status = CardGetTupleData(pData);
        if (status == CERR_SUCCESS) {
            //
            // The first byte of a CISTPL_LONGLINK_MFC is the number of functions
            //
            numfn = buf[sizeof(CARD_DATA_PARMS)];
            //
            // If the tuple length exactly matches what it should be for the
            // number of functions reported, then trust it.
            //
            DEBUGMSG(ZONE_CALLBACK,
                (TEXT("PCMCIA:CreateFunctions - CISTPL_LONGLINK_MFC reports %d functions\r\n"),
                numfn));
            if ((numfn * 5 + 1) >= fn) {
                if (numfn <= MAX_FUNCTIONS) {
                    for (fn = 1; fn < numfn; fn++) {
                        hSock.uFunction = fn;
                        if (CreateFunction(hSock) != NULL) {
                            Created++;
                        }
                    }
                }
            } else {
                DEBUGMSG(ZONE_CALLBACK,
                    (TEXT("PCMCIA:CreateFunctions - CISTPL_LONGLINK_MFC length=%d should be %d\r\n"),
                    fn, numfn * 5 + 1));
            }
        }
    } else {
        DEBUGMSG(ZONE_CALLBACK|ZONE_WARNING,
            (TEXT("CreateFunctions: CardGetFirstTuple(CISTPL_LONGLINK_MFC) returned %d for %d:%d\r\n"),
            status, hSock.uSocket, hSock.uFunction));
    }

    DEBUGMSG(ZONE_CALLBACK,
        (TEXT("PCMCIA:CreateFunctions - Created %d functions\r\n"),
        Created));
    v_Sockets[uSocket].cFunctions = Created;
    return Created;
}   // CreateFunctions


//
// Delete the LOG_SOCKET structures for all functions of a removed card.
//
// This function is called after the last card removal callback has returned
// so all references can be safely removed.
//
STATUS DeleteFunctions(UINT uSocket)
{
    PLOG_SOCKET pLsock;
    PCLIENT_SOCKET pCsock;
    PCLIENT_DRIVER pClient;


    //
    // Walk the list of logical sockets and remove any outstanding references.
    //
    EnterCriticalSection(&v_FindDriverCrit);
    EnterCriticalSection(&v_SocketCrit);
    while (v_Sockets[uSocket].pLsock) {
        pLsock = v_Sockets[uSocket].pLsock;

        if (pLsock->hQueryDriver != 0) {
            if (v_hGwesEvent == NULL ||
                WaitForSingleObject(v_hGwesEvent, INFINITE) != WAIT_OBJECT_0 ||
                (NULL == v_pfnPostThreadMessageW) ||
                !v_pfnPostThreadMessageW(pLsock->hQueryDriver, WM_QUIT, 0, 0)) {
                DEBUGMSG(ZONE_ERROR, (TEXT("DeleteFunctions(%d.%d): v_pfnPostThreadMessage failed(%d)\r\n"),
                    uSocket, pLsock->hSock.uFunction, GetLastError()));
            }
            pLsock->hQueryDriver = 0;
        }

        //
        // Find and remove all client references to this logical socket.
        //
        EnterCriticalSection(&v_ClientCrit);
        pClient = (PCLIENT_DRIVER)v_ClientList.Flink;
        while (pClient != (PCLIENT_DRIVER)&v_ClientList) {
            if (pClient->pCsock) {
                pCsock = I_FindClientSocket(pLsock->hSock, pClient);
                if (pCsock) {
                    I_RemoveClientSocket(pCsock, pClient);
                }
            }
            pClient = (PCLIENT_DRIVER)pClient->List.Flink;
        }
        LeaveCriticalSection(&v_ClientCrit);

        v_Sockets[uSocket].pLsock = pLsock->Next;
        if (pLsock->hRegWin) {
            I_DeleteLogicalWindow(pLsock->hRegWin);
        }
        free(pLsock);
    }

    //
    // Free the memory mappings to the card's CIS
    //
    if (v_Sockets[uSocket].pAttrWin) {
        I_DeleteLogicalWindow(v_Sockets[uSocket].pAttrWin);
        v_Sockets[uSocket].pAttrWin = NULL;
    }
    if (v_Sockets[uSocket].pCmnWin) {
        I_DeleteLogicalWindow(v_Sockets[uSocket].pCmnWin);
        v_Sockets[uSocket].pCmnWin = NULL;
    }

    //
    // Free the device id string
    //
    if (v_Sockets[uSocket].pDevId) {
        free(v_Sockets[uSocket].pDevId);
        v_Sockets[uSocket].pDevId = NULL;
    }

    v_Sockets[uSocket].cFunctions = 0;
    LeaveCriticalSection(&v_SocketCrit);
    LeaveCriticalSection(&v_FindDriverCrit);
    return CERR_SUCCESS;
}   // DeleteFunctions

//
// RemoveCallbacks - remove all callbacks for a deregistering client or
// for an aborted multi-callback event or CE_PM_RESUMEs.
//
VOID
RemoveCallbacks(
    PCLIENT_DRIVER pClient,
    CARD_SOCKET_HANDLE hSock,
    CARD_EVENT MajorEvent,
    DWORD evType
    )
{
    PCALLBACK_STRUCT pCur, pPrev, pDel;
    BOOL bRemove;
    //
    // Callback events are removed for these 3 situations:
    // 1. One of the client drivers rejected a query request.  Remove
    // all events associated with the failing one.
    //
    // 2. A client driver is deregistering.  All callbacks associated
    // with this client are removed except those that are the last in a
    // callback sequence.
    //
    // 3. Remove all CE_PM_RESUMEs on power on to in case the sequence of
    // removals and inserts got interrupted by a power off.
    //

    switch (evType) {
    case REMOVE_QUERY:
    case REMOVE_DEREGISTER:
    case REMOVE_PM_RESUME:
    case REMOVE_INIT_MFC:
        break;
    default:
        return;
    }

    EnterCriticalSection(&v_CallbackCrit);
    pCur = pPrev = v_CallbackHead;

    while (pCur) {
        bRemove = FALSE;
        switch (evType) {
        case REMOVE_QUERY:
             if ((pCur->pReqClient == pClient) &&
                 (pCur->hSock.uSocket == hSock.uSocket) &&
                 (pCur->hSock.uFunction == hSock.uFunction)&&
                 (pCur->MajorEvent == MajorEvent)) {
                 bRemove = TRUE;
             }
             break;

        case REMOVE_DEREGISTER:
             if ((!(pCur->fFlags & CALLBACK_FLAG_LAST)) &&
                 ((pCur->pReqClient == pClient) ||
                  (pCur->pDestClient == pClient))) {
                 bRemove = TRUE;
             }
             break;

        case REMOVE_PM_RESUME:
             if (pCur->MajorEvent == CE_PM_RESUME) {
                 bRemove = TRUE;
             }
             break;

        case REMOVE_INIT_MFC:
             if ((pCur->hSock.uSocket == hSock.uSocket) &&
                 (pCur->hSock.uFunction == hSock.uFunction)&&
                 (pCur->MajorEvent == CE_CARD_INSERTION)) {
                 bRemove = TRUE;
             }
             break;
         }

        if (bRemove) {
            pDel = pCur;
            if (v_CallbackTail == pCur) {
                v_CallbackTail = pPrev;
            }
            if (pPrev == pCur) {
                v_CallbackHead = pCur->Next;
                if (v_CallbackHead == NULL) {
                    v_CallbackTail = NULL;
                }
                pPrev = pCur->Next;
                pCur = pPrev;
            } else {
                pPrev->Next = pCur->Next;
                pCur = pPrev->Next;
            }
            free(pDel);
        } else {
            pPrev = pCur;
            pCur = pCur->Next;
        }
    }
#ifdef DEBUG
    if (v_CallbackHead == NULL) {
       if (v_CallbackTail != NULL) {
            DEBUGMSG(1|ZONE_ERROR|ZONE_CALLBACK,
                (TEXT("RemoveCallbacks:v_CallbackHead=0 but v_CallbackTail = 0x%x\r\n"),
                v_CallbackTail));
       }
    }
    if (v_CallbackTail == NULL) {
       if (v_CallbackHead != NULL) {
            DEBUGMSG(1|ZONE_ERROR|ZONE_CALLBACK,
                (TEXT("RemoveCallbacks:v_CallbackTail=0 but v_CallbackHead = 0x%x\r\n"),
                v_CallbackHead));
       }
    }
#endif
    LeaveCriticalSection(&v_CallbackCrit);
}   // RemoveCallbacks

⌨️ 快捷键说明

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