📄 window.c
字号:
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 + -