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

📄 utils.c

📁 YLP270的Windows CE5.0 bsp源码。
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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:

    utils.c

Abstract:

    This file implements the PCMCIA model device driver internal functions.
    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:

    I_FindSocket()
    I_FindClientSocket()
    I_AttachClientSocket()
    I_RemoveClientSocket()
    I_GetClientSocket()
    I_LinkLogicalWindow()
    I_UnlinkLogicalWindow()
    I_CreateLogicalWindow()
    I_DeleteLogicalWindow()
    I_MapWindow()
    IsCardInserted()
    IsValidClient()
    FindClient()
    CreateFunction()
    CreateFunctions()
    DeleteFunctions()
    RemoveCallbacks()

Notes:


--*/


#include <windows.h>
#include <types.h>
#include <tchar.h>
#include <cardserv.h>
#include <sockserv.h>
#include <linklist.h>
#include <pcmcia.h>
#include <tuple.h>
#include <extern.h>

#ifdef INSTRUM_DEV
#include <instrumd.h>
#endif

// Calculates start address of page containing address X
#define PAGE_START(X) (((UINT)(X) / v_PageSize) * v_PageSize)

//
// Return a pointer to the PLOG_SOCKET structure that represents the
// specified socket/function pair.  Return NULL if none found.
//
PLOG_SOCKET I_FindSocket(CARD_SOCKET_HANDLE hSock)
{
    PLOG_SOCKET pSock;

    if (hSock.uSocket >= v_cSockets) {
        return NULL;
    }

    EnterCriticalSection(&v_SocketCrit);
    pSock = v_Sockets[hSock.uSocket].pLsock;

    while (pSock) {
        if (pSock->hSock.uFunction == hSock.uFunction) {
            LeaveCriticalSection(&v_SocketCrit);
            return pSock;
        }
        pSock = pSock->Next;
    }
    LeaveCriticalSection(&v_SocketCrit);
    return NULL;
}


//
// Return a pointer to the PCLIENT_SOCKET structure that represents the
// specified logical socket/client pair.  Return NULL if none found.
//
PCLIENT_SOCKET
I_FindClientSocket(
    CARD_SOCKET_HANDLE hSock,
    PCLIENT_DRIVER pClient
    )
{
    PCLIENT_SOCKET pCsock;

    pCsock = pClient->pCsock;

    while (pCsock) {
        if ((pCsock->pLsock->hSock.uSocket == hSock.uSocket) &&
            (pCsock->pLsock->hSock.uFunction == hSock.uFunction)) {
            return pCsock;
        }
        pCsock = pCsock->Next;
    }
    return NULL;
}


//
// Link the PCLIENT_SOCKET structure to the client's list.
//
VOID
I_AttachClientSocket(
    PCLIENT_SOCKET pCsock,
    PCLIENT_DRIVER pClient
    )
{
    PCLIENT_SOCKET pCsockP;

    //
    // Link this socket to the client
    //
    if (pClient->pCsock == NULL) {
        pClient->pCsock = pCsock;
    } else {
        //
        // Link it at the end of the list.
        //
        pCsockP = pClient->pCsock;
        while (pCsockP->Next) {
            pCsockP = pCsockP->Next;
        }
        pCsockP->Next = pCsock;
    }
}


//
// Unlink the PCLIENT_SOCKET structure from the client's list and free it.
//
VOID
I_RemoveClientSocket(
    PCLIENT_SOCKET pCsock,
    PCLIENT_DRIVER pClient
    )
{
    PCLIENT_SOCKET pCsockP;

    if (pClient->pCsock == pCsock) {
        pClient->pCsock = pCsock->Next;     // unlink it
        goto freeit;
    } else {
        pCsockP = pClient->pCsock;
        while (pCsockP->Next) {
            if (pCsockP->Next == pCsock) {
                pCsockP->Next = pCsock->Next;   // unlink it
                goto freeit;
            }
            pCsockP = pCsockP->Next;
        }
    }
    DEBUGMSG(ZONE_WARNING, (TEXT("I_RemoveClientSocket: Something's wrong!\r\n")));
    return;

freeit:
    free(pCsock);
    return;
}   // I_RemoveClientSocket


//
// Either find the specified CLIENT_SOCKET or allocate one and link it in.
//
PCLIENT_SOCKET
I_GetClientSocket(
    PLOG_SOCKET pLsock,
    PCLIENT_DRIVER pClient
    )
{
    PCLIENT_SOCKET pCsock;

    pCsock = I_FindClientSocket(pLsock->hSock, pClient);
    if (pCsock == NULL) {
        pCsock = alloc(sizeof(CLIENT_SOCKET));
        if (pCsock == NULL) {
            return NULL;
        }
        pCsock->pLsock = pLsock;
        I_AttachClientSocket(pCsock, pClient);
    }
    return pCsock;
}   // I_GetClientSocket


//
// Attach a logical window structure to the specified physical window's list
//
VOID
I_LinkLogicalWindow(
    PPHYS_WINDOW pPhys,
    PLOG_WINDOW pWin
    )
{
    //
    // Link this new logical window to the physical window.
    //
    EnterCriticalSection(&v_WindowCrit);
    pWin->pPhys = pPhys;
    pWin->Next = pPhys->pLog;
    pPhys->pLog = pWin;
    LeaveCriticalSection(&v_WindowCrit);
}   // I_LinkLogicalWindow


//
// Unlink a logical window structure from the associated physical window
//
VOID
I_UnlinkLogicalWindow(
    PLOG_WINDOW pWin
    )
{
    PLOG_WINDOW pTmp;

    //
    // Unlink from list.
    //
    EnterCriticalSection(&v_WindowCrit);
    if (pWin->pPhys->pLog == pWin) {
        pWin->pPhys->pLog = pWin->Next;
    } else {
        pTmp = pWin->pPhys->pLog;
        while (pTmp) {
            if (pTmp->Next == pWin) {
                pTmp->Next = pWin->Next;
                pWin->Next = NULL;
                pWin->pPhys = NULL;
                break;
            }
            pTmp = pTmp->Next;
        }
    }
    LeaveCriticalSection(&v_WindowCrit);
}   // I_UnlinkLogicalWindow

//
// Create a logical window and link it to the physical window.
//
// Return NULL on failure or valid PLOG_WINDOW on success.
//
PLOG_WINDOW
I_CreateLogicalWindow(
    PPHYS_WINDOW pPhys
    )
{
    PLOG_WINDOW pWin;

    pWin = alloc(sizeof(LOG_WINDOW));

    if (pWin) {
        pWin->Next = NULL;
        pWin->hOwner = 0;
        pWin->pVirtMem = NULL;

        I_LinkLogicalWindow(pPhys, pWin);
    }

    return pWin;
}   // I_CreateLogicalWindow

//
// Unlink a logical window from the physical window and free its memory and
// the mapped memory.
//
VOID
I_DeleteLogicalWindow(
    PLOG_WINDOW pWin
    )
{

    //
    // Free the mapped memory.
    //
    if (pWin->pVirtMem) {
       DEBUGMSG(ZONE_MEM,
            (TEXT("I_DeleteLogicalWindow calling VirtualFree(0x%x).\r\n"),
            pWin->pVirtMem));
       if (VirtualFree( pWin->pVirtMem, 0, MEM_RELEASE) == FALSE) {
            DEBUGMSG(ZONE_MEM|ZONE_ERROR,
                (TEXT("I_DeleteLogicalWindow: VirtualFree failed %d\r\n"),
                GetLastError()));
        }
#ifdef INSTRUM_DEV
        ics_deleteCardRange(pWin->pVirtMem);
#endif

    }

    I_UnlinkLogicalWindow(pWin);
    free(pWin);

}   // I_DeleteLogicalWindow

//
// Map a physical memory window to a virtual/logical window
//
// Returns NULL on failure.
//
// On exit, pCardAddress points to the virtual address of the requested region.
//
PLOG_WINDOW
I_MapWindow(
    PPHYS_WINDOW pPhys,
    PUINT pCardAddress,
    UINT uSize,
    BOOL bAttribute
    )
{
    PLOG_WINDOW pWin;
    PDCARD_WINDOW_STATE WinState;
    UINT32 uStart;
    UINT32 uEnd;
    UINT32 uVirtSize;
    UINT32 uPhysAddr;
    UINT32 uWinOffset;

    pWin = I_CreateLogicalWindow(pPhys);
    if (pWin == NULL) {
        DEBUGMSG(ZONE_WARNING,
            (TEXT("I_MapWindow: I_CreateLogicalWindow failed\r\n")));
        return NULL;
    }

    //
    // Compute beginning and ending addresses of the mapping region (must be on page boundaries)
    //
    uStart = PAGE_START(*pCardAddress);
    uEnd = (((*pCardAddress + uSize) + v_PageSize - 1) / v_PageSize) * v_PageSize;
    uVirtSize = uEnd - uStart;

    DEBUGMSG(ZONE_MEM,
        (TEXT("I_MapWindow: pCardAddress = 0x%x, v_PageSize = 0x%x\n"),
         *pCardAddress, v_PageSize));

    pWin->uReqOffset = *pCardAddress;
    pWin->uReqSize = uSize;
    pWin->pVirtMem = VirtualAlloc(
                          0,
                          uVirtSize,
                          MEM_RESERVE,
                          PAGE_NOACCESS);
    if (pWin->pVirtMem == NULL) {
        DEBUGMSG(ZONE_WARNING,
            (TEXT("I_MapWindow: VirtualAlloc failed %d\r\n"), GetLastError()));
        I_DeleteLogicalWindow(pWin);
        return NULL;
    }

    // Map the memory.
#ifdef DEBUG
    if (pPhys->uBase & 0xE0000000) {
        DEBUGMSG(ZONE_WARNING|ZONE_ERROR|ZONE_MEM,
          (TEXT("PCMCIA:I_MapWindow MAKE SURE THIS PLATFORM'S PCMCIA MEMORY AREAS ARE SPECIFIED AS ACTUAL PHYSICAL ADDRESSES\r\n")));
    }
#endif

    // If window has programmable base address in hardware (PCIC), find out
    // the base of the memory window on the PC Card size (uWinOffset).  For
    // memory-mapped PCMCIA space, there is no mapping from uBase to uWinOffset,
    // so set it to 0.
    if (pWin->pPhys->fOtherCaps & MEM_CAP_PRG_BASE)
    {
        PDCardGetWindow(pPhys->uWindow, &WinState);
        uWinOffset = WinState.uOffset;
    }
    else
    {
        uWinOffset = 0;
    }

    // Physical address to be used is the base of the memory window (from host side) plus
    // the difference of the start of the page the CardAddress is in (uStart) and the
    // base of the memory window on the PC Card side.  The resulting address is page
    // adjusted.
    uPhysAddr = pPhys->uBase + uStart - uWinOffset;

    DEBUGMSG(ZONE_MEM,
        (TEXT("I_MapWindow: uBase = 0x%x, uStart = 0x%x, uWinOffset= 0x%x, uPhysAddr = 0x%x\n"),
         pPhys->uBase, uStart, uWinOffset, uPhysAddr));

    uPhysAddr >>= 8;
    if (!VirtualCopy(
             pWin->pVirtMem,
             (PVOID)uPhysAddr,
             uVirtSize,
             PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL)) {
        DEBUGMSG(ZONE_WARNING,
            (TEXT("I_MapWindow: VirtualCopy failed %d\r\n"), GetLastError()));
        I_DeleteLogicalWindow(pWin);
        return NULL;
    }

#ifdef SH4
    //
    // On SH4 we need to set some extra page table bits associated with PCMCIA
    // (the SH4 PCMCIA controller is integrated with the CPU's paging mechanism)
    //
    if (!VirtualSetPageFlags(
             pWin->pVirtMem,
             uVirtSize,
             (bAttribute ? VSPF_ATTRIBUTE : VSPF_COMMON) | (isSh4Area6(pPhys->uWindow)?VSPF_TC:0),
             NULL)) {
        DEBUGMSG(ZONE_WARNING,
            (TEXT("I_MapWindow: VirtualSetPageFlags failed %d\r\n"),
            GetLastError()));
        I_DeleteLogicalWindow(pWin);
        return NULL;
    }
#endif

#ifdef INSTRUM_DEV
    ics_addCardRange(0, pWin->pVirtMem, (PVOID)(pPhys->uBase+uStart), uVirtSize, 0);
#endif

    DEBUGMSG(ZONE_MEM,
        (TEXT("I_MapWindow: Window %d @ %x (phys = %x), size = %d\r\n"),
        pPhys->uWindow, pWin->pVirtMem, uPhysAddr << 8, pWin->uReqSize));

    pWin->hOwner = CARDSERV_CLIENT_HANDLE;
    *pCardAddress = (UINT)pWin->pVirtMem + *pCardAddress - uStart;

    return pWin;
}   // I_MapWindow


//
// Detect whether a card is inserted in the specified socket.
//
//    Return: TRUE => card is inserted
//            FALSE => card not inserted
//
BOOL
IsCardInserted(
    UINT uSocket
    )
{
     PDCARD_SOCKET_STATE State;

    if (PDCardGetSocket(uSocket, &State) != CERR_SUCCESS) {
        return FALSE;
    }

    if (State.fNotifyEvents & EVENT_MASK_CARD_DETECT) {
        return TRUE;
    }
    return FALSE;
}


//
// Determine whether the specified CARD_CLIENT_HANDLE is valid
// Caller must aquire the controlling critical section (v_ClientCrit)
//
// Return: TRUE => valid client handle
//            FALSE => not valid
//
BOOL
IsValidClient(
    PCLIENT_DRIVER pClient
    )
{
    PCLIENT_DRIVER pClient1;
    BOOL found = FALSE;
#ifdef DEBUG
    int i = 0;
#endif

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

    //
    // Validate handle
    //
    while (pClient1 != (PCLIENT_DRIVER)&v_ClientList) {
        if (pClient1 == pClient) {
            found = TRUE;
            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;
        }

⌨️ 快捷键说明

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