📄 pcmciasock.cpp
字号:
/*
*
* Copyright (C) 2003-2004, MOTOROLA, INC. All Rights Reserved
* THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
* BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
* MOTOROLA, INC.
*
* Copyright (C) 2004-2006, Freescale Semiconductor, Inc. All Rights Reserved.
* THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
* AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
*
*/
#define __PCMCIASOCK_CPP__
#include "pcmciasock.h"
#define SOCKET_DELAY_MULTIPLIER 1000
#define SOCKETDelay(delayTime) \
{ \
volatile UINT32 delay = delayTime * SOCKET_DELAY_MULTIPLIER; \
while(delay--); \
}
CPcmciaSocket::CPcmciaSocket( CPcmciaBusBridge* pBridge ) : CPCMCIASocketBase<CPcmciaMemWindows, CPcmciaIoWindows, CStaticWindowBridgeContainer<CPcmciaBusBridge>, CPcmciaBusBridge>( pBridge )
{
DEBUGMSG( ZONE_PDD, ( TEXT( "+CPcmciaSocket::CPcmciaSocket\r\n" ) ) );
m_dwSocketIndex = 0;
while( m_dwSocketIndex == 0 )
{
m_dwSocketIndex = ( DWORD )
InterlockedIncrement( ( LONG * ) &ms_dwSocketLastIndex );
//Make it if it does not exist.
CPcmciaSocket* pSocket = GetSocket( ( HANDLE ) m_dwSocketIndex );
if( pSocket != NULL )
{
// Duplicated , Retry.
m_dwSocketIndex = 0;
pSocket->DeRef();
}
}
DEBUGCHK( m_pBridge );
while( m_pBridge->LockOwner( 1000 ) != TRUE )
{
DEBUGCHK( FALSE );
}
m_SocketState = ms_SocketInitState;
m_SocketInfo = ms_SocketInitInfo;
if( pBridge->GetClientIrq() == -1 )
{
m_SocketInfo.dwSocketCaps |= SOCK_CAP_ONLY_SYSINTR;
}
for( DWORD dwIndex = 0; dwIndex < IRQ_ROUTINGTABLE_SIZE; dwIndex++ )
{
if( m_SocketInfo.dwSocketCaps & SOCK_CAP_ONLY_SYSINTR )
m_SocketInfo.bArrayIrqRouting[dwIndex] = ( BYTE )pBridge->GetClientSysInt();
else
m_SocketInfo.bArrayIrqRouting[dwIndex] = ( BYTE )pBridge->GetClientIrq();
}
m_SocketInfo.dwNumOfPowerEntry = NUM_POWER_ENTRIES;
m_SocketInfo.dwNumOfWindows = pBridge->GetMemWindowCount() +
pBridge->GetIoWindowCount();
m_SocketInfo.dwBusNumber = 0;
DEBUGMSG( ZONE_PDD, ( TEXT( "-CPcmciaSocket::CPcmciaSocket m_dwSocketIndex=%d\r\n" ), m_dwSocketIndex ) );
}
CPcmciaSocket::~CPcmciaSocket()
{
DEBUGMSG( ZONE_PDD, ( TEXT( "+++CPcmciaSocket::~CPcmciaSocket m_dwSocketIndex=%d\n" ), m_dwSocketIndex) );
Lock();
BOOL bInitWindow = CardDeInitWindow();
DEBUGCHK( bInitWindow );
Unlock();
DEBUGMSG( ZONE_PDD, ( TEXT( "---CPcmciaSocket::~CPcmciaSocket\n" ) ) );
m_pBridge->ReleaseOwner();
}
STATUS CPcmciaSocket::GetPowerEntry( PDWORD pdwNumOfEnery,
PSS_POWER_ENTRY pPowerEntry )
{
STATUS status = CERR_BAD_ARGS;
if( pdwNumOfEnery != NULL && pPowerEntry != NULL )
{
DWORD dwNumOfCopied = min( *pdwNumOfEnery, NUM_POWER_ENTRIES );
if( dwNumOfCopied != 0 )
{
memcpy( pPowerEntry,
m_rgPowerEntries,
dwNumOfCopied * sizeof( SS_POWER_ENTRY ) );
*pdwNumOfEnery = dwNumOfCopied;
status = CERR_SUCCESS;
}
}
return status;
}
STATUS CPcmciaSocket::CardInquireSocket( PSS_SOCKET_INFO pSocketInfo )
{
if( pSocketInfo )
{
*pSocketInfo = m_SocketInfo;
return CERR_SUCCESS;
}
else
{
return CERR_BAD_ARGS;
}
}
//
// GetSocket - return Socket state
// [In/Out] pBuf - pointer to SS_SOCKET_STATE struct
// [In/Out] pnBuf - pointer to size of struct pointed to by pBuf
// return CERR_SUCCESS on success, CERR_UNSUPPORTED_SERVICE if size is anomolous
//
STATUS CPcmciaSocket::CardGetSocket( PSS_SOCKET_STATE pState )
{
Lock();
if( pState )
{
DWORD dwStatusChange, dwStatus, dwErrStatus;
DEBUGMSG( ZONE_PDD,
( TEXT( "==>CPcmciaSocket::CardGetSocket: eventchanged=0x%x eventstatus=0x%x,dwEventMask=0x%x \r\n \t PSCR=0x%X PIPR=0x%X\r\n" ),
pState->dwEventChanged,
pState->dwEventStatus,
pState->dwEventMask,
GET_CARD_STATUS_CHANGE(),
GET_CARD_STATUS()) );
// Clear Event State
m_SocketState.dwEventStatus = 0;
m_SocketState.dwEventChanged = 0;
// Check PCMCIA Status Change Register (PSCR)
dwStatusChange = GET_CARD_STATUS_CHANGE();
DEBUGMSG(ZONE_PDD,(TEXT("\t\r\n==Card Status Change:\t\n")));
// CDC1 CDC2: Card Detect1/2 Changed
if(IS_CARDDETEC_CHANGE(dwStatusChange)){
DEBUGMSG(ZONE_PDD,(TEXT("\tSOCK_EVENT_CD\t\n")));
m_SocketState.dwEventChanged |= SOCK_EVENT_CD;
}
// BVDC2: Batt Voltage Detect 2 / Speaker-In Changed
if(IS_BVD2_CHANGE(dwStatusChange)){
DEBUGMSG(ZONE_PDD, (TEXT("\tSOCK_EVENT_BVD2\r\n")));
m_SocketState.dwEventChanged |= SOCK_EVENT_BVD2;
}
// BVDC2: Batt Voltage Detect 1 / STSCHG Changed
if(IS_BVD1_CHANGE(dwStatusChange)){
DEBUGMSG(ZONE_PDD, (TEXT("\tSOCK_EVENT_BVD1\r\n")));
m_SocketState.dwEventChanged |= SOCK_EVENT_BVD1;
}
// WPC: Write Protect Changed
if(IS_WP_CHANGE(dwStatusChange)){
DEBUGMSG(ZONE_PDD, (TEXT("\tSOCK_EVENT_WP\r\n")));
m_SocketState.dwEventChanged |= SOCK_EVENT_WP;
}
// RDYH: Ready Low
// if(IS_READY_IREQ_CHANGE(dwStatusChange)){
// DEBUGMSG(ZONE_PDD, (TEXT("\tSOCK_EVENT_READY\r\n")));
// m_SocketState.dwEventChanged |= SOCK_EVENT_READY;
// }
// PowerOn
if(IS_POWERON_CHANGE(dwStatusChange)){
DEBUGMSG(ZONE_PDD, (TEXT("\tSOCK_EVENT_PWRCYCLE\r\n")));
m_SocketState.dwEventChanged |= SOCK_EVENT_PWRCYCLE;
}
// Clear PSCR by writing 1s
CLEAR_CARD_STATUS_CHANGE(dwStatusChange);
// PCMCIA General Status Register (PGSR)
// Check for any errors, then write 1 to clear the bit
dwErrStatus = GET_CARD_ERROR_STATUS();
CLEAR_CARD_ERROR_STATUS(dwErrStatus);
if(dwErrStatus != 0) {
DEBUGMSG(ZONE_PDD|ZONE_ERROR,(TEXT("\tError PGSR value: 0x%X\n\r"), dwErrStatus));
}
// Check PCMCIA Input Pin Register (PIPR)
dwStatus = GET_CARD_STATUS();
DEBUGMSG(ZONE_PDD,(TEXT("\t\r\n==Card Status:\t\n")));
// Check card existence
if (IS_CARD_INSERTED(dwStatus)) {
DEBUGMSG(ZONE_PDD,(TEXT("\tCard Detect\t\n")));
m_SocketState.dwEventStatus|= SOCK_EVENT_CD;
}
else
{
DEBUGMSG(ZONE_PDD,(TEXT("\tCard no longer exist\n\r")));
m_SocketState.dwEventStatus|= SOCK_EVENT_CD;
goto pcgs_exit;
}
if (IS_BVD1_SET(dwStatus)) {
m_SocketState.dwEventStatus|= SOCK_EVENT_BVD1;
DEBUGMSG(ZONE_PDD, (TEXT("\tSOCK_EVENT_BVD1\r\n")));
}
if (IS_BVD2_SET(dwStatus)) {
m_SocketState.dwEventStatus|= SOCK_EVENT_BVD2;
DEBUGMSG(ZONE_PDD, (TEXT("\tSOCK_EVENT_BVD2\r\n")));
}
if (IS_WP_SET(dwStatus)) {
m_SocketState.dwEventStatus|= SOCK_EVENT_WP;
DEBUGMSG(ZONE_PDD, (TEXT("\tSOCK_EVENT_WP\r\n")));
}
// if (IS_READY_IREQ_SET(dwStatus)) {
// m_SocketState.dwEventStatus|= SOCK_EVENT_READY;
// DEBUGMSG(ZONE_PDD, (TEXT("\tSOCK_EVENT_READY\r\n")));
// }
// PowerOn
if(IS_POWERON_SET(dwStatus)){
m_SocketState.dwEventStatus |= SOCK_EVENT_PWRCYCLE;
DEBUGMSG(ZONE_PDD, (TEXT("\tSOCK_EVENT_PWRCYCLE\r\n")));
}
// add sleep here otherwise LogoTest-PcmciaSocket TestID:16002 failed
//SOCKETDelay(1);
Sleep(10);
pcgs_exit:
*pState = m_SocketState;
pState->dwEventChanged &= pState->dwEventMask;
DEBUGMSG( ZONE_PDD,
( TEXT( "<==CPcmciaSocket::CardGetSocket: m_SocketState.eventchanged=0x%X returned eventchanged=0x%x eventstatus=0x%x,dwEventMask=0x%x\r\n" ),
m_SocketState.dwEventChanged,
pState->dwEventChanged,
pState->dwEventStatus,
pState->dwEventMask ) );
}
Unlock();
return CERR_SUCCESS;
}
//
// PDCardSetSocket
//
// @func STATUS | PDCardSetSocket | Set the socket state of the specified socket.
// @rdesc Returns one of the CERR_* return codes in cardserv.h.
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -