📄 pdsocket.cpp
字号:
// Copyright (c) David Vescovi. All rights reserved.
// Part of Project DrumStix
// Windows Embedded Developers Interest Group (WE-DIG) community project.
// http://www.we-dig.org
// 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:
Abstract:
PCCARD Platform dependent initialization functions
Notes:
--*/
#include <windows.h>
#include <types.h>
#include <socksv2.h>
#include <memory.h>
#include <ceddk.h>
#include <nkintr.h>
#include "pdsocket.h"
//////////////////////////////////////////////////////////////////////////
// special registry values for this driver
#define IRQ_VALUE_NAME TEXT("Irq")
#define SYSINTR_VALUE_NAME TEXT("SysIntr")
#define POLLEDDEVICES_VALUE_NAME TEXT("PolledDevices")
#define CLIENT_IRQ_VALUE_NAME TEXT("ClientIrq")
#define POLL_TIMEOUT_NAME TEXT("PollTimeout")
#define POLLING_MODE_NAME TEXT("PollingMode")
#define SLOT_NUMBER_NAME TEXT("SlotNumber")
#define DISABLE_SOCKET_NAME TEXT("DisableSocket")
#define CSC_THREAD_PRIORITY_NAME TEXT("CSCThreadPriority")
#define POWER_OPTION_NAME TEXT("RegPowerOption")
#define DEFAULT_PRIORITY 101
const SS_POWER_ENTRY CPcmciaCardSocket::m_rgPowerEntries[NUM_POWER_ENTRIES] =
{
{ 0, PWR_SUPPLY_VCC | PWR_SUPPLY_VPP1 | PWR_SUPPLY_VPP2 },
{ 33, PWR_SUPPLY_VCC | PWR_SUPPLY_VPP1 | PWR_SUPPLY_VPP2 },
{ 50, PWR_SUPPLY_VCC | PWR_SUPPLY_VPP1 | PWR_SUPPLY_VPP2 }
};
DWORD CPcmciaCardSocket::m_dwSocketLastIndex = 1;
STATUS CPcmciaCardSocket::GetPowerEntry( PDWORD pdwNumOfEntry,
PSS_POWER_ENTRY pPowerEntry )
{
STATUS status = CERR_BAD_ARGS;
if( pdwNumOfEntry != NULL && pPowerEntry != NULL )
{
DWORD dwNumOfCopied = min( *pdwNumOfEntry, NUM_POWER_ENTRIES );
if( dwNumOfCopied != 0 )
{
memcpy( pPowerEntry,
m_rgPowerEntries,
dwNumOfCopied * sizeof( SS_POWER_ENTRY ) );
*pdwNumOfEntry = dwNumOfCopied;
status = CERR_SUCCESS;
}
}
return status;
}
CPcmciaBusBridge::CPcmciaBusBridge( LPCTSTR RegPath ) : CPCCardBusBridgeBase( RegPath ),
CMiniThread( 0,
TRUE )
{
//m_fPCICCritSecInitialized = false;
m_hISTEvent = NULL;
m_prgCardSocket = NULL;
m_rgfPowerCycleEvent = FALSE;
m_rgForceEject = FALSE;
m_fPollingMode = TRUE;
};
CPcmciaBusBridge::~CPcmciaBusBridge()
{
GetSocketNumberFromCS( FALSE );
// Terminate IST
m_bTerminated = TRUE;
if( m_hISTEvent )
{
SetEvent( m_hISTEvent );
ThreadTerminated( 1000 );
if( !m_fPollingMode )
{
InterruptDisable( m_dwCSCSysIntr );
}
CloseHandle( m_hISTEvent );
};
RemovePcmciaCardSocket();
UnMapDeviceRegisters();
}
BOOL CPcmciaBusBridge::InstallIsr()
{
// CreateIST Event.
m_hISTEvent = CreateEvent( 0, FALSE, FALSE, NULL );
if( !m_fPollingMode )
{
InterruptInitialize( m_dwCSCSysIntr, m_hISTEvent, 0, 0 );
}
return(TRUE);
}
BOOL CPcmciaBusBridge::InitializeBridgeHW( void )
{
// slot timing configured by bootloader
return(TRUE);
}
BOOL CPcmciaBusBridge::UnMapDeviceRegisters( void )
{
if(m_pGPIORegs)
{
VirtualFree((PVOID)m_pGPIORegs, 0, MEM_RELEASE);
m_pGPIORegs = NULL;
}
if(m_pS1baseAttr)
{
VirtualFree((PVOID)m_pS1baseAttr, 0, MEM_RELEASE);
m_pS1baseAttr = NULL;
}
if(m_pOSTRegs)
{
VirtualFree((PVOID)m_pOSTRegs, 0, MEM_RELEASE);
m_pOSTRegs = NULL;
}
return(TRUE);
}
BOOL CPcmciaBusBridge::MapDeviceRegisters( void )
{
PHYSICAL_ADDRESS PA;
PA.QuadPart = PXA255_BASE_REG_PA_GPIO;
m_pGPIORegs = (volatile GPIO_REG_T *) MmMapIoSpace(PA, sizeof(GPIO_REG_T), FALSE);
PA.QuadPart = PXA255_BASE_REG_PA_PCMCIA_S1_ATTR;
m_pS1baseAttr = (volatile BYTE *) MmMapIoSpace(PA, sizeof(BYTE), FALSE);
PA.QuadPart = PXA255_BASE_REG_PA_OST;
m_pOSTRegs = (volatile OST_REG_T *) MmMapIoSpace(PA, sizeof(OST_REG_T), FALSE);
if (!m_pGPIORegs || !m_pS1baseAttr || !m_pOSTRegs)
{
return(FALSE);
}
return(TRUE);
} // MapDeviceRegisters.
//
// Function to get the initial settings from the registry
//
// NOTE: lpRegPath is assumed to be under HKEY_LOCAL_MACHINE
//
// Returns ERROR_SUCCESS on success or a Win32 error code on failure
//
DWORD CPcmciaBusBridge::GetRegistryConfig( void )
{
DWORD dwRet = 1;
DWORD dwSize, dwType, dwData;
// Get the PCMCIA window configurations
if( !LoadWindowsSettings() )
{
dwRet = ERROR_INVALID_DATA;
goto grc_fail;
}
// Read the registry to determine the physical slot number we're dealing with.
dwSize = sizeof( DWORD );
if( !RegQueryValueEx( SLOT_NUMBER_NAME,
&dwType,
( PUCHAR ) & dwData,
&dwSize ) )
{
DEBUGMSG( ZONE_PDD,
( TEXT( "PCMCIA:GetRegistyConfig RegQueryValueEx(%s) failed\r\n" ),
SLOT_NUMBER_NAME ) );
goto grc_fail;
}
m_SlotNumber = (UINT8)dwData;
// Get the polling mode value.
dwSize = sizeof( DWORD );
if( !RegQueryValueEx( POLLING_MODE_NAME,
&dwType,
( PUCHAR ) & dwData,
&dwSize ) )
{
m_fPollingMode = TRUE; // RegQueryValueEx failed, default to TRUE
}
else
{
m_fPollingMode = dwData ? TRUE : FALSE;
}
// Get client (function) IRQ.
dwSize = sizeof( DWORD );
if( !RegQueryValueEx( CLIENT_IRQ_VALUE_NAME,
&dwType,
( PUCHAR ) & dwData,
&dwSize ) )
{
DEBUGMSG( ZONE_PDD,
( TEXT( "PCMCIA:GetRegistyConfig RegQueryValueEx(%s) failed\r\n" ),
CLIENT_IRQ_VALUE_NAME ) );
goto grc_fail;
}
m_dwClientIrq = dwData;
// TODO - get CD IRQ and SYSINTR - no polling.
// For now just use polling mode.
// Get card status change (CSC) IRQ and SYSINTR values.
// NOTE: the CSC and CD IRQ values are part of the same IRQ multi-string in the registry.
dwSize = sizeof( DWORD );
if( !RegQueryValueEx( IRQ_VALUE_NAME,
&dwType,
( PUCHAR ) & dwData,
&dwSize ) )
{
m_dwCSCIrq = 0;
m_fPollingMode = TRUE;
}
else
{
m_dwCSCIrq = dwData;
}
dwSize = sizeof( DWORD );
if( !RegQueryValueEx( SYSINTR_VALUE_NAME,
&dwType,
( PUCHAR ) & dwData,
&dwSize ) )
{
m_dwCSCSysIntr = 0;
m_dwCSCIrq = 0;
m_fPollingMode = TRUE;
}
else
{
m_dwCSCSysIntr = dwData;
}
// Get the polling timeout value.
dwSize = sizeof( DWORD );
if( !RegQueryValueEx( POLL_TIMEOUT_NAME,
&dwType,
( PUCHAR ) & dwData,
&dwSize ) )
{
// RegQueryValueEx failed; if pooling, set the timeout to 0.5 sec, otherwise set to INFINITE
m_dwPollTimeout = m_fPollingMode ? 500 : INFINITE;
}
else
{
m_dwPollTimeout = dwData;
}
// Get thread priority from registry and set it.
m_uPriority = DEFAULT_PRIORITY;
dwSize = sizeof( DWORD );
if( RegQueryValueEx( CSC_THREAD_PRIORITY_NAME,
&dwType,
( PUCHAR ) & dwData,
&dwSize ) )
{
m_uPriority = ( UINT )dwData;
}
dwRet = ERROR_SUCCESS;
grc_fail : return dwRet;
} // GetRegistryConfig
BOOL CPcmciaBusBridge::InitCardBusBridge( void )
{
// Get PCCARD controller registry information.
if((GetRegistryConfig()) != ERROR_SUCCESS)
{
DEBUGMSG( ZONE_PDD,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -