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

📄 window.c

📁 YLP270的Windows CE5.0 bsp源码。
💻 C
📖 第 1 页 / 共 3 页
字号:
    I_DeleteLogicalWindow(pWin);

rel_win_exit:
#ifdef DEBUG
    if (status) {
        DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR,
            (TEXT("CardReleaseWindow failed %d\r\n"), status));
    } else {
        DEBUGMSG(ZONE_FUNCTION,
            (TEXT("CardReleaseWindow succeeded\r\n")));
    }
#endif

    return status;
}   // CardReleaseWindow


//
// CardModifyWindow
//
// @func STATUS | CardModifyWindow | Change the attributes of the specified memory window.
// @rdesc   Returns one of CERR_SUCCESS, CERR_BAD_HANDLE, CERR_BAD_WINDOW or
//          CERR_BAD_ARGS.
//
// @comm    The window attributes that can be changed are:
//          1. Address either common or attribute space
//          2. Enable or disable window
//          3. Memory window speed
//          4. Choose 16 or 8 bit data path
// @xref    <t CARD_WINDOW_HANDLE> <f CardMapWindow>
//
STATUS
CardModifyWindow(
    CARD_WINDOW_HANDLE hWin,    // @parm Memory window handle from <f CardRequestWindow>
    UINT16 fAttributes,         // @parm Bit encoded window attributes (see cardserv.h)
    UINT8  fAccessSpeed         // @parm Bit encoded access speed (see cardserv.h)
    )
{
    PLOG_WINDOW pWin = (PLOG_WINDOW)hWin;
    PDCARD_WINDOW_STATE WinState;
    STATUS status = CERR_SUCCESS;
    unsigned int x;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("CardModifyWindow entered\r\n")));

    EnterCriticalSection(&v_WindowCrit);
    //
    // Perform some parameter checks first
    //
    if (!IsValidWindow(pWin)) {
        status = CERR_BAD_WINDOW;
        goto mod_win_exit;
    }
    if (!IsValidClient((PCLIENT_DRIVER)pWin->hOwner)) {
        status = CERR_BAD_HANDLE;
        goto mod_win_exit;
    }

    // Check if attribute flags are valid
    x = fAttributes & ~(WIN_ATTR_ATTRIBUTE | WIN_ATTR_ENABLED | WIN_ATTR_16BIT | WIN_ATTR_ACCESS_SPEED_VALID);
    if ((pWin->fAttributes & x) != x) {
        status = CERR_BAD_ARGS;
        goto mod_win_exit;
    }

    //
    // Must be only user (besides card services) of this physical window
    //
    if ((pWin->pPhys->pLog != pWin) || (pWin->Next != NULL)) {
        //
        // Check if card services is using this window and allow modification
        // if so.  Card services will be the first user of a window.
        // (note: first user means that it should be at the end!)
        //
        if ((pWin->pPhys->pLog != pWin) ||
            (pWin->Next->hOwner != CARDSERV_CLIENT_HANDLE) ||
            (pWin->Next->Next != NULL)) {
//        if ((pWin->pPhys->pLog->hOwner != CARDSERV_CLIENT_HANDLE) ||
//            (pWin->pPhys->pLog->Next != pWin) ||
//            (pWin->Next != NULL)) {
            status = CERR_IN_USE;
            goto mod_win_exit;
        }
    }

    status = PDCardGetWindow(pWin->pPhys->uWindow, &WinState);
    if (status) {
        goto mod_win_exit;
    }

    //
    // Change memory spaces (common or attribute) as appropriate
    //
    if (fAttributes & WIN_ATTR_ATTRIBUTE) {
        WinState.fState |= WIN_STATE_ATTRIBUTE;
        pWin->pPhys->fFlags |= PHYS_WIN_FLAG_ATTR_MODE;
    } else {
        WinState.fState &= ~WIN_STATE_ATTRIBUTE;
        pWin->pPhys->fFlags &= ~PHYS_WIN_FLAG_ATTR_MODE;
    }

    //
    // Enable or disable window
    //
    if (fAttributes & WIN_ATTR_ENABLED) {
        WinState.fState |= WIN_STATE_ENABLED;
        pWin->pPhys->fFlags |= PHYS_WIN_FLAG_ENABLED;
    } else {
        WinState.fState &= ~WIN_STATE_ENABLED;
        pWin->pPhys->fFlags &= ~PHYS_WIN_FLAG_ENABLED;
    }

    //
    // Change data path width
    //
    if (fAttributes & WIN_ATTR_16BIT) {
        WinState.fState |= WIN_STATE_16BIT;
        pWin->pPhys->fFlags |= PHYS_WIN_FLAG_16BIT_MODE;
    } else {
        WinState.fState &= ~WIN_STATE_16BIT;
        pWin->pPhys->fFlags &= ~PHYS_WIN_FLAG_16BIT_MODE;
    }

    //
    // See if user wants to change the window's access speed
    //
    if (fAttributes & WIN_ATTR_ACCESS_SPEED_VALID) {
        if (WinState.fSpeed != fAccessSpeed) {
            WinState.fSpeed = fAccessSpeed;
        }
    }

    pWin->fAttributes = fAttributes;
    status = PDCardSetWindow(pWin->pPhys->uWindow, &WinState);

mod_win_exit:
    LeaveCriticalSection(&v_WindowCrit);
#ifdef DEBUG
    if (status) {
        DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR,
            (TEXT("CardModifyWindow failed %d\r\n"), status));
    } else {
        DEBUGMSG(ZONE_FUNCTION,
            (TEXT("CardModifyWindow succeeded\r\n")));
    }
#endif

    return status;
}   // CardModifyWindow


//
// CardMapWindow
//
// @func PVOID | CardMapWindow | Map a memory or I/O window to virtual memory
//                                and return the pointer to virtual memory.
//
// @rdesc   Returns a PVOID pointer on success. On failure the return value is NULL and
//          GetLastError will return one of CERR_BAD_HANDLE, CERR_IN_USE,
//          CERR_OUT_OF_RESOURCE, CERR_BAD_SIZE or CERR_BAD_WINDOW.
//
// @comm    On failure, the previous virtual mapping for this window may be
//          invalid.
//
// Most of the current WinCE platforms use 3 fixed memory mapped ranges to
// access the 3 PC card address spaces (attribute, I/O and common memory).
// On these platforms, the address returned from CardMapWindow is a virtual
// address mapped to the physical address that corresponds to the caller's
// request.  Multiple clients are prevented from allocating overlapping ranges
// within each address space, though multiple allocations are allowed within
// each space.  A single client is allowed to map a range that overlaps its own
// previously allocated ranges.
// On platforms that support programmable windows via a standard socket
// controller, a combination of fixed memory mapped ranges and programmable
// ranges is used.  If the requested range cannot be mapped within one of the
// fixed regions, then one of the programmable regions may be used.  To avoid
// memory contention, the system ensures that only one mapped range exists
// within a programmable range.  The programmable ranges are not large (about
// 32k), but they can access anywhere within the 64Mb PC card address space.
//
// @xref <t CARD_WINDOW_HANDLE>
//
PVOID
CardMapWindow(
    CARD_WINDOW_HANDLE hWin,    // @parm Memory window handle from <f CardRequestWindow>
    UINT32 uCardAddress,        // @parm Starting address on the PC card to map
    UINT32 uSize,               // @parm Size of region to map to the PC card
    PUINT32 pGranularity        // @parm Memory granularity of mapped region
    )
{
    PLOG_WINDOW pWin = (PLOG_WINDOW)hWin;
    PLOG_WINDOW pTmp;
    PPHYS_WINDOW pPhys;
    UINT uStart;
    UINT uEnd;
    UINT uVirtSize;
    UINT uPhysAddr;
    UINT fAttributes;
    PDCARD_WINDOW_STATE WinState;
    STATUS status = CERR_SUCCESS;
    BOOL bSetSocket = FALSE;
    PVOID RetVal;

#ifdef x86
    ULONG  inIoSpace;
    PHYSICAL_ADDRESS ioPhysicalBase;
#endif // x86

    DEBUGMSG(ZONE_FUNCTION, (TEXT("CardMapWindow entered\r\n")));

    // handle possible NULL return value - might be possible to #ifdef x86 this
    SetLastError(CERR_SUCCESS);
    EnterCriticalSection(&v_WindowCrit);

    //
    // The granularity parameter harks back to the first Windows CE development
    // platform (Perp) which mapped the PCMCIA area such that a valid byte was
    // presented at each DWORD aligned address. One had to add 4 to the address
    // pointer to access the next byte. The granularity parameter allowed the
    // same driver to work on other platforms as well, as long as the driver
    // multiplied the desired offset by the granularity.
    //
    if (pGranularity) {
        *pGranularity = 1;
    }

    //
    // Perform some parameter checks first
    //
    if (!IsValidWindow(pWin)) {
        status = CERR_BAD_WINDOW;
        goto map_win_fail_norel;
    }
    if (!IsValidClient((PCLIENT_DRIVER)pWin->hOwner)) {
        status = CERR_BAD_HANDLE;
        goto map_win_fail_norel;
    }
    if (uSize == 0) {
        status = CERR_BAD_SIZE;
        goto map_win_fail_norel;
    }

    fAttributes = pWin->fAttributes; // remember requested window attributes.

    //
    // Check if this window can accommodate the request
    //
    if (((uCardAddress + uSize) > pWin->pPhys->uMaxSize) ||
        (pWin->pPhys->fOtherCaps & MEM_CAP_PRG_BASE)) {
        //
        // If this window's mapping is programmable and this is the only
        // logical window on this physical window, then remap it.
        //
        if ((pWin->pPhys->fOtherCaps & MEM_CAP_PRG_BASE) &&
            (pWin->pPhys->pLog == pWin) &&
            (pWin->Next == NULL)) {
            DEBUGMSG(ZONE_MEM, (TEXT("CardMapWindow need to remap.\r\n")));
        } else {
            DEBUGMSG(ZONE_MEM, (TEXT("CardMapWindow need to switch physical windows.\r\n")));
            //
            // See if there is an available physical window to support this request
            //
            pPhys = FindPhysWindow(
                            pWin->pPhys->uSock,
                            pWin->fAttributes,
                            uSize,
                            pWin->pPhys);
            if (pPhys == NULL) {
                status = CERR_OUT_OF_RESOURCE;
                goto map_win_fail_norel;
            }
            //
            // Link the caller's logical window to the available physical window
            //
            I_UnlinkLogicalWindow(pWin);
            I_LinkLogicalWindow(pPhys, pWin);
            //DisplayAllWindows();
        }
        bSetSocket = TRUE;
    }

    //
    // Make sure no existing windows collide
    //
    pTmp = pWin->pPhys->pLog;
    while (pTmp) {
        if (pTmp != pWin) {
            //
            // If someone besides card services owns this window, then see if it collides.
            // Also allow window overlap if both windows are owned by the same client.
            //
            if ((pTmp->hOwner != 0) &&
                (pTmp->hOwner != CARDSERV_CLIENT_HANDLE)) {
                if (pTmp->hOwner != pWin->hOwner) {
                    if ((uCardAddress+uSize) > pTmp->uReqOffset) {
                        if (uCardAddress < (pTmp->uReqOffset + pTmp->uReqSize)) {
                            status = CERR_IN_USE;
                            DEBUGMSG(ZONE_WARNING|ZONE_MEM,
                                (TEXT("CardMapWindow: window collision\r\n")));

                            goto map_win_fail_norel;
                        }
                    }
                }
            }
        }
        pTmp = pTmp->Next;
    }   // Window collision check

    //
    // Undo the old mapping
    //
    if (pWin->pVirtMem) {
        DEBUGMSG(ZONE_MEM, (TEXT("CardMapWindow calling VirtualFree(0x%x) for old mapping.\r\n"), pWin->pVirtMem));
        if (VirtualFree(pWin->pVirtMem, 0, MEM_RELEASE) == FALSE) {
            DEBUGMSG(ZONE_MEM|ZONE_ERROR, (TEXT("CarpMapWindow: VirtualFree(old) failed %d\r\n"), GetLastError()));
        }

#ifdef INSTRUM_DEV
        ics_deleteCardRange(pWin->pVirtMem);
#endif

        pWin->pVirtMem = NULL;
    }

    if ((pWin->pPhys->fWindowCaps & WIN_CAP_IO) && pWin->uReqSize != 0 &&
        g_IORM_ID[pWin->pPhys->uSock] != 0)
        ResourceRelease(g_IORM_ID[pWin->pPhys->uSock], pWin->uReqOffset, pWin->uReqSize);
    pWin->uReqOffset = 0;
    pWin->uReqSize = 0;
    if ((pWin->pPhys->fWindowCaps & WIN_CAP_IO) && g_IORM_ID[pWin->pPhys->uSock] != 0) {
        if (ResourceRequest(g_IORM_ID[pWin->pPhys->uSock], uCardAddress, uSize) != TRUE) {
            status = CERR_IN_USE;
            goto map_win_fail_norel;
        }
    }

    if (bSetSocket == TRUE) {
        DEBUGMSG(ZONE_MEM, (TEXT("CardMapWindow remapping window %d.\r\n"), pWin->pPhys->uWindow));
        //
        // Remap the physical window
        //
        status = PDCardGetWindow(pWin->pPhys->uWindow, &WinState);
        if (status) {
            goto map_win_fail;
        }
        WinState.uOffset = pWin->pPhys->uOffset = uCardAddress;
        WinState.uSize = pWin->pPhys->uSize = uSize;
        WinState.fState |= WIN_STATE_ENABLED;
        pWin->pPhys->fFlags |= PHYS_WIN_FLAG_ENABLED;
        if (fAttributes & WIN_ATTR_ATTRIBUTE) {
            WinState.fState |= WIN_STATE_ATTRIBUTE;
            pWin->pPhys->fFlags |= PHYS_WIN_FLAG_ATTR_MODE;
        } else {
            WinState.fState &= ~WIN_STATE_ATTRIBUTE;
            pWin->pPhys->fFlags &= ~PHYS_WIN_FLAG_ATTR_MODE;
        }
        status = PDCardSetWindow(pWin->pPhys->uWindow, &WinState);
        if (status) {

⌨️ 快捷键说明

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