📄 pdsocket.cpp
字号:
//
// Copyright(C) Renesas Technology Corp. 2005. All rights reserved.
//
// PCCARD driver for ITS-DS7
//
// FILE : pdsocket.cpp
// CREATED : 2005.02.03
// MODIFIED :
// AUTHOR : Renesas Technology Corp.
// HARDWARE : RENESAS ITS-DS7
// HISTORY :
// 2005.02.03
// - Created release code.
// (based on PCCARD driver for ASPEN for WCE5.0)
//
// 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:
PDSocket.c
Abstract:
This file implements the PCMCIA model device driver initialization 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:
Notes:
--*/
#include <windows.h>
#include <types.h>
#include <socksv2.h>
#include <memory.h>
#include <ceddk.h>
#include <nkintr.h>
#include "PDSocket.h"
//------------------------------------------------------------------------------
#define DEFAULT_PRIORITY 101
#define ZONE_SOCKET ZONE_PDD
typedef struct _PCMCIA_INIT {
ULONG reg_base;
ULONG attr_win_base;
ULONG cmn_win_base;
ULONG io_win_base;
}PCMCIA_INIT;
PCMCIA_INIT v_PcmciaInit[NUM_SLOTS] = {
{PCMCIA0_REG_BASE, FIRST_1MB_FROM_BASE0, SECOND_1MB_FROM_BASE0, THIRD_1MB_FROM_BASE0},
{PCMCIA1_REG_BASE, FIRST_1MB_FROM_BASE1, SECOND_1MB_FROM_BASE1, THIRD_1MB_FROM_BASE1}
};
//------------------------------------------------------------------------------
CPCCardBusBridge::CPCCardBusBridge( LPCTSTR RegPath ) : CPCCardBusBridgeBase( RegPath ),
CMiniThread( 0, TRUE )
{
m_dwCSCSysIntr = (DWORD)-1;
for( int nSlot = 0; nSlot < NUM_SLOTS; nSlot++ )
{
m_rgPcmciaInterruptEvents[nSlot] = PCMCIA_INTERRUPT_NONE;
m_rgdwFunctionSysIntr[nSlot] = (DWORD)-1;
m_rgpCardSocket[nSlot] = NULL;
m_rguSocketNum[nSlot] = (WORD)-1;
}
m_hISTEvent = NULL;
m_hPcCardDriver = NULL;
m_ResumeFlag = FALSE;
};
BOOL CPCCardBusBridge::Init()
{
// bind to socket services
if( !loadPcCardEntry() )
{
return FALSE;
}
// load registry settings
if( !loadRequiredRegEntry() )
{
return FALSE;
}
// map and initialize the hardware
if( !MapHardware() )
{
return FALSE;
}
// disable client interrupts
for( int nSlot = 0; nSlot < NUM_SLOTS; nSlot++ )
{
EnableClientInterrupt( nSlot, FALSE );
}
// register the sockets with socket services
for( int nSlot = 0; nSlot < NUM_SLOTS; nSlot++ )
{
if( !GetSocketNumberFromCS( nSlot, TRUE ) )
{
// unregister sockets
for( int n = 0; n < nSlot; n++ )
{
GetSocketNumberFromCS( nSlot, FALSE );
}
return FALSE;
}
}
// Configure the CSC Interrupt event
m_hISTEvent = CreateEvent( 0, FALSE, FALSE, NULL );
BOOL b = InterruptInitialize( m_dwCSCSysIntr, m_hISTEvent, 0, 0 );
// Enable CSC interrupt
EnableCSCInterrupts( TRUE );
// Set CSC tread priority.
CeSetPriority( m_uPriority );
// run the CSC thrad
bTerminated = FALSE;
ThreadStart();
return TRUE;
}
CPCCardBusBridge::~CPCCardBusBridge()
{
// Terminate the CSC thread
bTerminated = TRUE;
if( m_hISTEvent )
{
SetEvent( m_hISTEvent );
ThreadTerminated( 1000 );
InterruptDisable( m_dwCSCSysIntr );
CloseHandle( m_hISTEvent );
};
// remove the sockets
for( int nSlot = 0; nSlot < NUM_SLOTS; nSlot++ )
{
RemovePCardSocket( nSlot );
if( m_rguSocketNum[nSlot] != ( UINT16 ) - 1 )
{
GetSocketNumberFromCS( nSlot, FALSE );
m_rguSocketNum[nSlot] = ( UINT16 ) - 1;
}
}
}
DWORD CPCCardBusBridge::ThreadRun() // This is the card detect / card status change IST.
{
// If card is inserted into the socket when system boot. It doesn't generate interrupt.
// To solve this we have to set this thread first.
BOOL fFirstTime[NUM_SLOTS];
for( int n = 0; n < NUM_SLOTS; n++ )
{
fFirstTime[n] = TRUE;
}
SetEvent( m_hISTEvent );
while( !bTerminated )
{
DEBUGCHK( m_hISTEvent != NULL );
BOOL bInterrupt = ( WaitForSingleObject( m_hISTEvent, INFINITE ) !=
WAIT_TIMEOUT );
if( !bInterrupt )
{
// Time out
#ifdef DEBUG
WORD wChanged = READ_REGISTER_USHORT( m_rgPcmciaRegisters[0].pINTR );
WORD wStatus = READ_REGISTER_USHORT( m_rgPcmciaRegisters[0].pCST );
WORD wStatChangeIntEn = READ_REGISTER_USHORT( m_rgPcmciaRegisters[0].pINTC );
#endif
continue;
}
if( m_ResumeFlag )
{
for( int nSlot = 0; nSlot < NUM_SLOTS; nSlot++ )
{
Lock();
m_ResumeFlag = FALSE;
if( m_rgpCardSocket[nSlot] )
m_rgpCardSocket[nSlot]->Resuming();
Unlock();
}
}
else
{
for( int nSlot = 0; nSlot < NUM_SLOTS; nSlot++ )
{
Lock();
// read the card status change and card status registers
WORD wChanged;
if(nSlot) wChanged = m_pDriverGlobals->pcm.slot1Enable;
else wChanged = m_pDriverGlobals->pcm.slot0Enable;
WORD wStatus = READ_REGISTER_USHORT( m_rgPcmciaRegisters[nSlot].pCST );
WORD wStatChangeIntEn = READ_REGISTER_USHORT( m_rgPcmciaRegisters[nSlot].pINTC );
/*
// acknowledge the inteerupt, clear the card status change register bits
if( wChanged & ( MR_SHPC_INTR_CARD_DETECT | MR_SHPC_INTR_STSCHG ) )
{
WORD wTemp = wChanged & ( MR_SHPC_INTR_CARD_DETECT | MR_SHPC_INTR_STSCHG );
wTemp = ~wTemp;
wTemp &= ~CC_PCMCIA_CSCR_GEN_CD_INT;
wTemp |= CC_PCMCIA_CSCR_TPS2206_SEL;
WRITE_REGISTER_USHORT( m_rgPcmciaRegisters[nSlot].pCSCR, wTemp );
}
*/
if( fFirstTime[nSlot] )
{
fFirstTime[nSlot] = FALSE;
wChanged |= MR_SHPC_INTR_CARD_DETECT;
}
else
{
// now lets record which interrupts can be cleared for the HAL
if(nSlot)
{
m_pDriverGlobals->pcm.slot1Enable = wChanged;
}
else
{
m_pDriverGlobals->pcm.slot0Enable = wChanged;
}
}
PCMCIA_INTERRUPT_EVENT otherEvent = m_rgPcmciaInterruptEvents[nSlot];
m_rgPcmciaInterruptEvents[nSlot] = PCMCIA_INTERRUPT_NONE;
Unlock();
// Process CD events
if( ( wChanged & MR_SHPC_INTR_CARD_DETECT ) ||
( otherEvent == PCMCIA_INTERRUPT_FORCE_EJECT ) )
{
if( m_rgpCardSocket[nSlot] != NULL )
{
RemovePCardSocket( nSlot );
}
if( IsCardInserted( nSlot ) )
{
InsertPCardSocket( nSlot, CreatePCMCIASocket( nSlot, this ) );
if(nSlot) m_pDriverGlobals->pcm.slot1Enable &= (~MR_SHPC_INTR_CARD_DETECT);
else m_pDriverGlobals->pcm.slot0Enable &= (~MR_SHPC_INTR_CARD_DETECT);
}
}
else // process other events
{
if( IsCardInserted( nSlot ) )
{
if( m_rgpCardSocket[nSlot] && otherEvent != PCMCIA_INTERRUPT_NONE )
{
m_rgpCardSocket[nSlot]->SocketEventHandle( nSlot, wChanged, wStatus, otherEvent );
}
}
}
} // for
} // if
DEBUGMSG( ZONE_FUNCTION,
( L"PCCard: PCCard Bus Call InterruptDone\r\n" ) );
InterruptDone( m_dwCSCSysIntr );
} // while
return 0;
}
BOOL CPCCardBusBridge::SetInterruptEvent( int nSlot, PCMCIA_INTERRUPT_EVENT pcmIntrEvent )
{
Lock();
m_rgPcmciaInterruptEvents[nSlot] = pcmIntrEvent;
SetEvent( m_hISTEvent );
Unlock();
return TRUE;
}
BOOL CPCCardBusBridge::NeedPowerResuming()
{
m_ResumeFlag = TRUE;
::SetInterruptEvent( m_dwCSCSysIntr );
return TRUE;
}
void CPCCardBusBridge::PowerMgr( BOOL bPowerDown )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -