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

📄 config.c

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

    config.c

Abstract:

    This file implements the PCMCIA model device driver socket configuration
    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:

    FindPowerEntry()
    CardRequestConfiguration()
    CardReleaseConfiguration()
    PowerUp()
    PowerDown()
    PcmciaPowerOn()
    PcmciaPowerOff()
    CardAccessConfigurationRegister()

Notes:


--*/

#include <windows.h>
#include <types.h>
#include <cardserv.h>
#include <sockserv.h>
#include <pcmcia.h>
#include <nkintr.h>
#include <extern.h>

#define BAD_VOLTAGE_INDEX 0xff
#define NUM_REGISTERS 5     // number of function configuration registers
#define NUM_EXT_REGISTERS 4 // number of additional function configuration registers

DWORD v_SysIntrWake = 0;    // SysIntr for wake on CD changes
DWORD v_FuncSysIntrWake = 0;// SysIntr for wake on functional interrupt

//
// Find the power entry index that matches the voltage and supply specified.
//
UINT8
FindPowerEntry(
    UINT fSupply,
    UINT8 uVoltage
    )
{
    UINT8 i;
    PPDCARD_POWER_ENTRY pPwr = (PPDCARD_POWER_ENTRY)(((PCHAR)v_pAdapterInfo) +
                                sizeof(PDCARD_ADAPTER_INFO));
    for (i = 0; i < v_pAdapterInfo->uPowerEntries; i++, pPwr++) {
        if ((pPwr->uPowerLevel == uVoltage) && (pPwr->fSupply & fSupply)) {
            return i;
        }
    }

    return BAD_VOLTAGE_INDEX;
}

// Use the stored information in the PHYS_WINDOW struct to restore the window state of a socket
STATUS
RestoreWindowState(
    UINT uSocket
    )
{
    STATUS status = CERR_SUCCESS;
    PPHYS_WINDOW pPhys;
    PDCARD_WINDOW_STATE WinState;

    for (pPhys = v_pWinList; pPhys != NULL; pPhys = pPhys->Next) {
        if (pPhys->uSock != uSocket) continue;
        if ((status = PDCardGetWindow(pPhys->uWindow, &WinState)) != CERR_SUCCESS)
            break;

        WinState.uSize = pPhys->uSize;
        WinState.uOffset = pPhys->uOffset;
        if (pPhys->fFlags & PHYS_WIN_FLAG_ENABLED) {
            WinState.fState |= WIN_STATE_ENABLED;
        } else {
            WinState.fState &= ~WIN_STATE_ENABLED;
        }
        if (pPhys->fFlags & PHYS_WIN_FLAG_ATTR_MODE) {
            WinState.fState |= WIN_STATE_ATTRIBUTE;
        } else {
            WinState.fState &= ~WIN_STATE_ATTRIBUTE;
        }
#ifndef SH4
        if (pPhys->fFlags & PHYS_WIN_FLAG_16BIT_MODE) {
            WinState.fState |= WIN_STATE_16BIT;
        } else {
            WinState.fState &= ~WIN_STATE_16BIT;
        }
#endif
        if ((status = PDCardSetWindow(pPhys->uWindow, &WinState)) != CERR_SUCCESS)
            break;
    }

    return status;
}

//
// Configure the logical socket
//
STATUS
ConfigureLogSock(
    PLOG_SOCKET pLsock
    )
{
    PDCARD_SOCKET_STATE State;
    STATUS status;
    PUINT8 pRegVal;
    UINT i;
    PLOG_SOCKET pTmp;
    BOOL bIRQ, bPwr;

    status = PDCardGetSocket(pLsock->hSock.uSocket, &State);
    if (status) {
        DEBUGMSG(ZONE_WARNING,
         (TEXT("PCMCIA:ConfigureLogSock PDCardGetSocket failed %d\r\n"),
         status));
        return status;
    }

    // Socket is non-powered
    if (pLsock->FCSR_val & FCR_FCSR_PWR_DOWN)
        return CERR_SUCCESS;

    bIRQ = bPwr = FALSE;
    EnterCriticalSection(&v_SocketCrit);
    for (pTmp = v_Sockets[pLsock->hSock.uSocket].pLsock; pTmp != NULL; pTmp = pTmp->Next) {
        if (pTmp->fFlags & LOG_SOCK_FLAG_KEEP_POWERED) {
            bPwr = TRUE;
            State.fSocketCaps |= SOCK_CAP_KEEP_POWERED;
        }

        if (pTmp->fFlags & LOG_SOCK_FLAG_IRQ_WAKEUP) {
            bIRQ = TRUE;
            State.fIREQRouting |= SOCK_IREQ_WAKEUP;
        }
    }
    LeaveCriticalSection(&v_SocketCrit);

    if (!bIRQ) State.fSocketCaps &= ~SOCK_CAP_KEEP_POWERED;
    if (!bPwr) State.fIREQRouting &= ~SOCK_IREQ_WAKEUP;

    State.fVcc = pLsock->fVcc;
    State.uVpp1 = pLsock->uVpp1;
    State.uVpp2 = pLsock->uVpp2;
    State.fInterfaceType = pLsock->fInterfaceType;
    State.fControlCaps |= pLsock->fControlCaps;

    status = PDCardSetSocket(pLsock->hSock.uSocket, &State);
    if (status) {
        DEBUGMSG(ZONE_WARNING,
         (TEXT("PCMCIA:CardRequestConfiguration PDCardSetSocket failed %d\r\n"),
          status));
        return status;
    }

    // Don't want to reset the socket
    pLsock->COR_val &= ~FCR_COR_SRESET;

    if (pLsock->pRegWin != NULL) {
        pRegVal = &(pLsock->COR_val);
        for (i = 0; i < (NUM_REGISTERS + NUM_EXT_REGISTERS); i++) {
            if (pLsock->fCfgRegisters & (1 << i)) {
                CardWriteAttrByte(pLsock->pRegWin, i, *pRegVal);
            }
            pRegVal++;
        }
    }

    return status;
}

void DisableCSCWake()
{
    int i;
    PLOG_SOCKET pLsock;

    // check if CSC is not a wake source
    if (v_SysIntrWake == 0) return;
    for (i = 0; i < v_cSockets; i++) {
        if (!(v_Sockets[i].fFlags & PHYS_SOCK_FLAG_NOT_USER_ACCESS)) {
            EnterCriticalSection(&v_SocketCrit);
            // Check for:
            // log sockets that don't want to unload on resume
            // non-powered down log sockets that want IRQ wakeup
            for (pLsock = v_Sockets[i].pLsock; pLsock != NULL; pLsock = pLsock->Next) {
                if ((pLsock->fFlags & LOG_SOCK_FLAG_NO_SUSPEND_UNLOAD) ||
                    ((pLsock->fFlags & LOG_SOCK_FLAG_IRQ_WAKEUP) &&
                     !(pLsock->FCSR_val & FCR_FCSR_PWR_DOWN)))
                    break;
            }
            LeaveCriticalSection(&v_SocketCrit);
            if (pLsock != NULL) break;
        }
    }

    // If no accessible sockets want NO_SUSPEND_UNLOAD or IRQ_WAKEUP
    // we can sleep on card insertion/removal
    if (i == v_cSockets) {
        if (v_SysIntrWake == v_FuncSysIntrWake ||
            KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &v_SysIntrWake, sizeof(v_SysIntrWake), NULL, 0, NULL)) {
            v_SysIntrWake = 0;
        }
    }
}

void DisableIRQWake()
{
    int i;
    PLOG_SOCKET pLsock;

    // check if CSC is not a wake source
    if (v_FuncSysIntrWake == 0) return;
    EnterCriticalSection(&v_SocketCrit);
    for (i = 0; i < v_cSockets; i++) {
        // Check for non-powered down log socks that want IRQ wakeup
        for (pLsock = v_Sockets[i].pLsock; pLsock != NULL; pLsock = pLsock->Next) {
            if ((pLsock->fFlags & LOG_SOCK_FLAG_IRQ_WAKEUP) &&
                !(pLsock->FCSR_val & FCR_FCSR_PWR_DOWN))
                break;
        }
        if (pLsock != NULL) break;
    }
    LeaveCriticalSection(&v_SocketCrit);

    // If no sockets want IRQ_WAKEUP, we can sleep on functional interrupts
    if (i == v_cSockets) {
        if (v_SysIntrWake == v_FuncSysIntrWake ||
            KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &v_FuncSysIntrWake, sizeof(v_FuncSysIntrWake), NULL, 0, NULL)) {
            v_FuncSysIntrWake = 0;
        }
    }
}

BOOL EnableCSCWake(UINT uSocket)
{
    if (v_SysIntrWake == 0 &&
        !(v_Sockets[uSocket].fFlags & PHYS_SOCK_FLAG_NOT_USER_ACCESS)) {
        if (gIntrPcmciaState != 0 && 
            KernelIoControl(IOCTL_HAL_ENABLE_WAKE, &gIntrPcmciaState, sizeof(gIntrPcmciaState), NULL, 0, NULL)) {
            v_SysIntrWake = gIntrPcmciaState;
        } else {
            return FALSE;
        }
    }
    return TRUE;
}

BOOL EnableIRQWake()
{
    if (v_FuncSysIntrWake == 0) {
        if (KernelIoControl(IOCTL_HAL_ENABLE_WAKE, &gIntrPcmciaLevel, sizeof(gIntrPcmciaLevel), NULL, 0, NULL)) {
            v_FuncSysIntrWake = gIntrPcmciaLevel;
        }
    }
    return (v_SysIntrWake != 0);
}

//
// CardModifyConfiguration
//
// @doc DRIVERS
//
// @func    STATUS | CardModifyConfiguration | Configure socket and PC card interface type and voltage.
// @rdesc   Returns one of CERR_SUCCESS, CERR_BAD_HANDLE, CERR_BAD_SOCKET, CERR_IN_USE, CERR_BAD_ARGS
//
// @comm    Change the fAttributes bits on an already existing configuration
//          Currently can only change CFG_ATTR_IRQ_WAKEUP, CFG_ATTR_KEEP_POWERED, and
//          CFG_ATTR_NO_SUSPEND_UNLOAD
// @xref    <f CardRequestConfiguration> <f CardReleaseConfiguration>
//
STATUS
CardModifyConfiguration(
    CARD_CLIENT_HANDLE hCardClient, // @parm Handle from <f CardRegisterClient>
    CARD_SOCKET_HANDLE hSock,       // @parm Socket/function identifier
    PUINT16 fAttributes
    )
{
    PLOG_SOCKET pLsock, pTmp;
    STATUS status = CERR_SUCCESS;
    PCLIENT_DRIVER pClient;
    BOOL bCSC = FALSE, bIRQ = FALSE;
    PDCARD_SOCKET_STATE State;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("PCMCIA:CardModifyConfiguration entered\r\n")));

    pLsock = I_FindSocket(hSock);
    if (pLsock == NULL || !(pLsock->fFlags & OWNER_FLAG_CONFIG)) {
        status = CERR_BAD_SOCKET;
        goto mod_cfg_err_exit;
    }

    if (hCardClient == NULL ||
        (pClient = FindClient(hCardClient, TRUE, TRUE)) == NULL) {
        status = CERR_BAD_HANDLE;
        goto mod_cfg_err_exit;
    } else if (pLsock->hOwner != pClient) {
        status = CERR_IN_USE;
        goto mod_cfg_err_exit;
    }

    if (fAttributes == NULL) {
        status = CERR_BAD_ARGS;
        goto mod_cfg_err_exit;
    }

    //
    // Attempt to set functional interrupts as a wake source
    //
    if (*fAttributes & CFG_ATTR_IRQ_WAKEUP) {
        if (!(pLsock->fFlags & LOG_SOCK_FLAG_IRQ_WAKEUP)) {
            pLsock->fFlags |= LOG_SOCK_FLAG_IRQ_WAKEUP;

            // Try to make insertion/removal a wake source if it isn't already,
            bCSC = FALSE;
            if (!EnableCSCWake(hSock.uSocket)) {
                pLsock->fFlags &= ~LOG_SOCK_FLAG_IRQ_WAKEUP;
                *fAttributes &= ~CFG_ATTR_IRQ_WAKEUP;
                goto mod_cfg_irqw1;
            }

            // Try to make IRQs a wake source if it isn't already,
            if (!EnableIRQWake()) {
                pLsock->fFlags &= ~LOG_SOCK_FLAG_IRQ_WAKEUP;
                *fAttributes &= ~CFG_ATTR_IRQ_WAKEUP;
                bCSC = TRUE;
                goto mod_cfg_irqw1;
            }

⌨️ 快捷键说明

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