socket.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 689 行 · 第 1/2 页

C
689
字号
        }

        //
        // Assert RESET
        //
        PCICIndex(uSocket, REG_INTERRUPT_AND_GENERAL_CONTROL);
        intctl = PCICDataRead();
        PCICDataWrite((UINT8)(intctl & ~ INT_CARD_NOT_RESET));

        Sleep(20);

        PCICIndex(uSocket, REG_POWER_CONTROL);

        PCICDataWrite(PWR_OUTPUT_ENABLE|PWR_AUTO_POWER|
                  PWR_VPP2_BIT0|PWR_VPP1_BIT0);
        //
        // Power the socket
        //
        PCICIndex(uSocket, REG_POWER_CONTROL);
        PCICDataWrite(PWR_OUTPUT_ENABLE|PWR_AUTO_POWER|
                      PWR_VCC_POWER|PWR_VPP2_BIT0|PWR_VPP1_BIT0);

        Sleep(20);

        //
        // Deassert RESET
        //
        PCICIndex(uSocket, REG_INTERRUPT_AND_GENERAL_CONTROL);
        intctl = PCICDataRead();
        PCICDataWrite((UINT8)(intctl | INT_CARD_NOT_RESET));

        Sleep(20);
    
        //
        // Allow the card 2 seconds to assert RDY
        //
        PCICIndex(uSocket, REG_INTERFACE_STATUS);
        for (t = 0; t < PCMCIA_MAX_RDY_WAIT_TIME; t += PCMCIA_RDY_POLL_INT) {
            tmp = PCICDataRead();
            if (tmp & STS_CARD_READY) {
                DEBUGMSG(ZONE_PDD,
                   (TEXT("PDCardSetSocket: Card in socket %d RDY after %dms\r\n"),
                    uSocket, t));
                 break;
            }
            Sleep(PCMCIA_RDY_POLL_INT);
        }

        if (t >= PCMCIA_MAX_RDY_WAIT_TIME) {
            DEBUGMSG(ZONE_PDD,
               (TEXT("PDCardSetSocket: CARD IN SOCKET %d NOT RDY AFTER %dms\r\n"),
                uSocket, t));
        }
//        Sleep(300); // necessary for CF cards?
    }

    if (pState->fIREQRouting & SOCK_IREQ_ENABLE) 
        DumpSocketRegisters(uSocket);

    *pPDDState = *pState;

pcss_exit:
#ifdef DEBUG
    DeltaSocketRegisters(uSocket);
#endif
    LeaveCriticalSection(&g_PCIC_Crit);
    return CERR_SUCCESS;

pcss_fail:
    DEBUGMSG(ZONE_PDD, (TEXT("PDCardSetSocket(%d) returning %d\r\n"),
        uSocket, ret));
    return ret;
}   // PDCardSetSocket


//
// PDCardInquireAdapter
//
// @func    STATUS | PDCardInquireAdapter | Returns the socket controller's characteristics
//                                          and capabilities.
// @rdesc   Returns one of the CERR_* return codes in cardserv.h.
//
STATUS
PDCardInquireAdapter(
    PPDCARD_ADAPTER_INFO pAdapterInfo   // @parm Pointer to PDCARD_ADAPTER_INFO structure.
    )
{
    if (pAdapterInfo->uPowerEntries < NUM_POWER_ENTRIES) {
        pAdapterInfo->uPowerEntries = NUM_POWER_ENTRIES;
        return CERR_BAD_ARG_LENGTH;
    }

    // Copy the adapter info
    memcpy(pAdapterInfo, &v_AdapterInfo, sizeof(PDCARD_ADAPTER_INFO));
    pAdapterInfo = (PPDCARD_ADAPTER_INFO)(((UINT)pAdapterInfo) + sizeof(PDCARD_ADAPTER_INFO));

    // Copy the power entries at the end
    memcpy(pAdapterInfo, &v_PowerEntries, sizeof(v_PowerEntries));
    return CERR_SUCCESS;
}

//
// Set up socket's initial window registers and interrupts
//
VOID
InitSocket(
    UINT32 uSocket
    )
{
    PDCARD_WINDOW_STATE WinState;
    PDCARD_SOCKET_STATE SockState;
    UINT32 status; 
    UINT32 i; 
    UINT32 first, last;

    //
    // Set the socket to detect status change events
    //
    SockState = v_SockState[uSocket];
    SockState.fInterruptEvents = EVENT_MASK_CARD_DETECT|
                                 EVENT_MASK_CARD_LOCK|
                                 EVENT_MASK_BATTERY_LOW|
                                 EVENT_MASK_BATTERY_DEAD|
                                 EVENT_MASK_WRITE_PROTECT;
    SockState.fInterfaceType = CFG_IFACE_MEMORY;
    SockState.fIREQRouting = 0;
    SockState.fVcc = VCC_DEFAULT_INDEX;
    PDCardSetSocket(uSocket, &SockState);

    //
    // Initially enable only the memory windows
    //
    first = (uSocket == 0) ? 0 : SOCKET1_FIRST_MEMORY_WINDOW;
    last = first + SOCKET1_FIRST_MEMORY_WINDOW;
    for (i = first; i < last; i++) {
        status = PDCardGetWindow(i, &WinState);
        if (status == CERR_SUCCESS) {
            WinState.fState |= WIN_STATE_ATTRIBUTE|WIN_STATE_ENABLED;
            PDCardSetWindow(i, &WinState);
        }
    }
}   // InitSocket

//
// PDCardResetSocket
//
// @func    STATUS | PDCardResetSocket | Resets the specified socket.
// @rdesc   Returns one of the CERR_* return codes in cardserv.h.
//
STATUS
PDCardResetSocket(
    UINT32 uSocket  // @parm Socket number (first socket is 0)
    )
{
    UINT8 tmp;
    UINT8 intctl;
    UINT32 t; 

    if (uSocket >= NUM_SOCKETS) {
        return CERR_BAD_SOCKET;
    }

    EnterCriticalSection(&g_PCIC_Crit);

    PCICIndex(uSocket, REG_INTERFACE_STATUS);
    tmp = PCICDataRead();

    //
    // Power off the socket
    //
    PCICIndex(uSocket, REG_POWER_CONTROL);
    PCICDataWrite(0);

    if ((tmp & (STS_CD1|STS_CD2)) != (STS_CD1|STS_CD2)) {
        //
        // Leave it powered off if no card in it.
        //
        InitSocketNoCard(uSocket, FALSE);
        LeaveCriticalSection(&g_PCIC_Crit);
        return CERR_NO_CARD;
    }

    //
    // Tri-state outputs for 310ms
    //
    Sleep(310);

    //
    // Assert RESET
    //
    PCICIndex(uSocket, REG_INTERRUPT_AND_GENERAL_CONTROL);
    intctl = PCICDataRead();
    PCICDataWrite(0);

    //
    // Power the socket
    //
    PCICIndex(uSocket, REG_POWER_CONTROL);
    PCICDataWrite(PWR_OUTPUT_ENABLE|PWR_AUTO_POWER|PWR_VCC_POWER);

    Sleep(20);

    //
    // Deassert RESET
    //
    PCICIndex(uSocket, REG_INTERRUPT_AND_GENERAL_CONTROL);
    PCICDataWrite(INT_CARD_NOT_RESET);

    //
    // Allow 20ms for card to assert RDY
    //
    Sleep(20);

    //
    // Allow the card 2 seconds to assert RDY
    //
    PCICIndex(uSocket, REG_INTERFACE_STATUS);
    for (t = 0; t < PCMCIA_MAX_RDY_WAIT_TIME; t += PCMCIA_RDY_POLL_INT) {
        tmp = PCICDataRead();
        if (tmp & STS_CARD_READY) {
            DEBUGMSG(ZONE_PDD,
               (TEXT("PDCardResetSocket: Card in socket %d RDY after %dms\r\n"),
               uSocket, t));
            break;
        }
        Sleep(PCMCIA_RDY_POLL_INT);
    }

    if (t >= PCMCIA_MAX_RDY_WAIT_TIME) {
        DEBUGMSG(ZONE_PDD,
           (TEXT("PDCardResetSocket: CARD IN SOCKET %d NOT RDY AFTER %dms\r\n"),
            uSocket, t));
    }

    InitSocket(uSocket);

    PCICIndex(uSocket, REG_INTERRUPT_AND_GENERAL_CONTROL);
    intctl |= INT_CARD_NOT_RESET;
    PCICDataWrite(intctl);

    LeaveCriticalSection(&g_PCIC_Crit);

    // Required by Ricoh R5C476/family (Lanner) following socket initialization.
    //
    Sleep(100);

    return CERR_SUCCESS;
}   // PDCardResetSocket


//
// PDCardGetAdapter
//
// @func    STATUS | PDCardGetAdapter | Returns power save mode status and capabilities
// @rdesc   Returns one of the CERR_* return codes in cardserv.h
//
STATUS
PDCardGetAdapter(
    UINT32 uSocket,
    PPDCARD_ADAPTER_STATE pState
    )
{
    UINT8 tmp;
    BOOL bUserMode;

    if (uSocket >= NUM_SOCKETS) {
        return CERR_BAD_SOCKET;
    }

    if (pState == NULL) {
        return CERR_BAD_ARGS;
    }

    bUserMode = (*pState & ADP_STATE_KERNEL_MODE) ? FALSE : TRUE;

    DEBUGMSG(bUserMode & ZONE_PDD, (TEXT("PDCardGetAdapter entered\r\n")));

    *pState = 0;
    if (bUserMode) {
        EnterCriticalSection(&g_PCIC_Crit);
    }
    PCICIndex(uSocket, REG_POWER_CONTROL);
    tmp = PCICDataRead();
    if (!(tmp & PWR_OUTPUT_ENABLE)) {
        *pState |= ADP_STATE_POWERDOWN;
    }

    if (bUserMode) {
        LeaveCriticalSection(&g_PCIC_Crit);
    }
    DEBUGMSG(bUserMode & ZONE_PDD, (TEXT("PDCardGetAdapter done\r\n")));
    return CERR_SUCCESS;
}


//
// PDCardSetAdapter
//
// @func    STATUS | PDCardSetAdapter | Sets power save mode status and capabilities
// @rdesc   Returns one of the CERR_* return codes in cardserv.h
//
STATUS
PDCardSetAdapter(
    UINT32 uSocket,
    PPDCARD_ADAPTER_STATE pState
    )
{
    BOOL bUserMode;

    if (uSocket >= NUM_SOCKETS) {
        return CERR_BAD_SOCKET;
    }

    if (pState == NULL) {
        return CERR_BAD_ARGS;
    }

    bUserMode = (*pState & ADP_STATE_KERNEL_MODE) ? FALSE : TRUE;
    
    DEBUGMSG(bUserMode & ZONE_PDD, (TEXT("PDCardSetAdapter entered\r\n")));

    if (bUserMode) {
        EnterCriticalSection(&g_PCIC_Crit);
    }

    //
    // The socket controller will automatically power up when a card is inserted
    //
    if (*pState & (ADP_STATE_POWERDOWN|ADP_STATE_POWEROFF)) {
        //
        // Power down the socket
        //
        InitSocketNoCard(uSocket, bUserMode);
    }

    if (bUserMode) {
        LeaveCriticalSection(&g_PCIC_Crit);
    }

    DEBUGMSG(bUserMode & ZONE_PDD, (TEXT("PDCardSetAdapter done\r\n")));

    return CERR_SUCCESS;
}

⌨️ 快捷键说明

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