647 lines
15 KiB
C++
647 lines
15 KiB
C++
//**************************************************************************
|
|
//
|
|
// Title : WDMKServ.cpp
|
|
//
|
|
// Date : 1997.12.02 1st making
|
|
//
|
|
// Author : Toshiba [PCS](PSY) Hideki Yagi
|
|
//
|
|
// Copyright 1997 Toshiba Corporation. All Rights Reserved.
|
|
//
|
|
// -------------------------------------------------------------------------
|
|
//
|
|
// Change log :
|
|
//
|
|
// Date Revision Description
|
|
// ------------ ---------- -----------------------------------------------
|
|
// 1997.12.02 000.0000 1st making.
|
|
//
|
|
//**************************************************************************
|
|
#include "includes.h"
|
|
|
|
#include "hal.h"
|
|
#include "wdmkserv.h"
|
|
#include "mpevent.h"
|
|
#include "classlib.h"
|
|
#include "ctime.h"
|
|
#include "schdat.h"
|
|
#include "ccque.h"
|
|
#include "ctvctrl.h"
|
|
#include "hlight.h"
|
|
#include "hwdevex.h"
|
|
|
|
|
|
// 1998.06.09 Seichan
|
|
// このDefineを有効にすると、PCIのコンフィグ空間を直接操作するようになる
|
|
//#define DIRECTPCICONFIG
|
|
|
|
|
|
BOOL CWDMKernelService::Init( DWORD address, HW_DEVICE_EXTENSION *pHwDevExt, PCHAR szID )
|
|
{
|
|
if( address==0 || pHwDevExt==NULL ){
|
|
return( FALSE );
|
|
}
|
|
|
|
m_ioBase = address;
|
|
m_pHwDevExt = pHwDevExt;
|
|
m_IntCount = 0;
|
|
m_OldIrql = 0;
|
|
|
|
m_pThread = NULL;
|
|
|
|
m_Irql = (KIRQL)((pHwDevExt->Irq) & 0xFF );
|
|
if( m_Irql>31 ){
|
|
DBG_PRINTF( ("DVDWDM: Invalid IRQL!!\n\r") );
|
|
DBG_BREAK();
|
|
return( FALSE );
|
|
}
|
|
KeInitializeEvent( &m_Event, NotificationEvent, FALSE );
|
|
|
|
DBG_PRINTF( ("KSERV:HwDevExt=%08x\n\r", m_pHwDevExt) );
|
|
|
|
// save MAchine informaton.
|
|
strncpy( m_MachineID, szID, 19 );
|
|
m_MachineID[19] = '0';
|
|
DBG_PRINTF( ("KSERV:MachineID = %s\n\r", m_MachineID ) );
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
BOOL CWDMKernelService::InitConfig( DWORD Id )
|
|
{
|
|
#ifdef DIRECTPCICONFIG
|
|
if( Id==0 ){
|
|
return( FALSE );
|
|
}
|
|
|
|
ULONG OldPort = READ_PORT_ULONG( (PULONG)0xcf8 );
|
|
m_PCIConfigData = 0xffffffff;
|
|
|
|
for( ULONG i = 0 ; i < 32; i ++ )
|
|
{
|
|
for( ULONG j = 0 ; j < 32; j ++ )
|
|
{
|
|
WRITE_PORT_ULONG( (PULONG)0xcf8, ( i << 16 ) | (j << 11 ) | 0x80000000 );
|
|
ULONG Data = READ_PORT_ULONG( (PULONG)0xcfc );
|
|
if( Data != 0xffffffff )
|
|
{
|
|
DBG_PRINTF(("(%d,%d)=0x%x", i,j,Data ));
|
|
};
|
|
if( Data == Id )
|
|
{
|
|
DBG_PRINTF(("!!!!!!\r\n"));
|
|
m_PCIConfigData = (i << 16 ) | (j << 11 ) | 0x80000000;
|
|
break;
|
|
}
|
|
};
|
|
};
|
|
|
|
WRITE_PORT_ULONG( (PULONG)0xcf8, OldPort );
|
|
#endif
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
BOOL CWDMKernelService::SetPCIConfigData( DWORD address, DWORD data )
|
|
{
|
|
if( m_ioBase==0 || m_pHwDevExt==NULL ){
|
|
return( FALSE );
|
|
}
|
|
|
|
if( address>0xFF ){
|
|
DBG_BREAK();
|
|
return( FALSE );
|
|
}
|
|
|
|
#ifdef DIRECTPCICONFIG
|
|
// DBG_PRINTF( ("XXXPCIConfigData currIrql = 0x%0x LINE=%d\n\r", KeGetCurrentIrql(),__LINE__ ) );
|
|
|
|
if( m_PCIConfigData == 0xffffffff )
|
|
return FALSE;
|
|
|
|
ULONG OldPort = READ_PORT_ULONG( (PULONG)0xcf8 );
|
|
|
|
WRITE_PORT_ULONG( (PULONG)0xcf8, ( m_PCIConfigData | address) & 0xfffffffc );
|
|
WRITE_PORT_ULONG( (PULONG)0xcfc, data );
|
|
|
|
WRITE_PORT_ULONG( (PULONG)0xcf8, OldPort );
|
|
|
|
return TRUE;
|
|
#else
|
|
ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
|
|
return( StreamClassReadWriteConfig( m_pHwDevExt,
|
|
FALSE,
|
|
&data,
|
|
address,
|
|
4 ) );
|
|
#endif
|
|
}
|
|
|
|
|
|
BOOL CWDMKernelService::SetPCIConfigData( DWORD address, WORD data )
|
|
{
|
|
if( m_ioBase==0 || m_pHwDevExt==NULL ){
|
|
return( FALSE );
|
|
}
|
|
|
|
if( address>0xFF ){
|
|
DBG_BREAK();
|
|
return( FALSE );
|
|
}
|
|
|
|
#ifdef DIRECTPCICONFIG
|
|
// DBG_PRINTF( ("XXXPCIConfigData currIrql = 0x%0x LINE=%d\n\r", KeGetCurrentIrql(),__LINE__ ) );
|
|
|
|
if( m_PCIConfigData == 0xffffffff )
|
|
return FALSE;
|
|
|
|
ULONG OldPort = READ_PORT_ULONG( (PULONG)0xcf8 );
|
|
|
|
WRITE_PORT_ULONG( (PULONG)0xcf8, (m_PCIConfigData | address) & 0xfffffffc );
|
|
ULONG OrgData = READ_PORT_ULONG( (PULONG)0xcfc );
|
|
switch( address % 4 )
|
|
{
|
|
case 0:
|
|
WRITE_PORT_ULONG( (PULONG)0xcfc, (OrgData & 0xffff0000 ) | (DWORD)data );
|
|
break;
|
|
case 2:
|
|
WRITE_PORT_ULONG( (PULONG)0xcfc, (OrgData & 0x0000ffff ) | ((DWORD)data << 16) );
|
|
break;
|
|
default:
|
|
DBG_BREAK();
|
|
};
|
|
|
|
WRITE_PORT_ULONG( (PULONG)0xcf8, OldPort );
|
|
|
|
return TRUE;
|
|
#else
|
|
ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
|
|
return( StreamClassReadWriteConfig( m_pHwDevExt,
|
|
FALSE,
|
|
&data,
|
|
address,
|
|
2 ) );
|
|
#endif
|
|
}
|
|
|
|
|
|
BOOL CWDMKernelService::SetPCIConfigData( DWORD address, BYTE data )
|
|
{
|
|
if( m_ioBase==0 || m_pHwDevExt==NULL ){
|
|
return( FALSE );
|
|
}
|
|
|
|
if( address>0xFF ){
|
|
DBG_BREAK();
|
|
return( FALSE );
|
|
}
|
|
|
|
#ifdef DIRECTPCICONFIG
|
|
// DBG_PRINTF( ("XXXPCIConfigData currIrql = 0x%0x LINE=%d\n\r", KeGetCurrentIrql(),__LINE__ ) );
|
|
|
|
if( m_PCIConfigData == 0xffffffff )
|
|
return FALSE;
|
|
|
|
ULONG OldPort = READ_PORT_ULONG( (PULONG)0xcf8 );
|
|
|
|
WRITE_PORT_ULONG( (PULONG)0xcf8, (m_PCIConfigData | address) & 0xfffffffc );
|
|
ULONG OrgData = READ_PORT_ULONG( (PULONG)0xcfc );
|
|
switch( address % 4 )
|
|
{
|
|
case 0:
|
|
WRITE_PORT_ULONG( (PULONG)0xcfc, (OrgData & 0xffffff00 ) | (DWORD)data );
|
|
break;
|
|
case 1:
|
|
WRITE_PORT_ULONG( (PULONG)0xcfc, (OrgData & 0xffff00ff ) | ((DWORD)data << 8) );
|
|
break;
|
|
case 2:
|
|
WRITE_PORT_ULONG( (PULONG)0xcfc, (OrgData & 0xff00ffff ) | ((DWORD)data << 16) );
|
|
break;
|
|
case 3:
|
|
WRITE_PORT_ULONG( (PULONG)0xcfc, (OrgData & 0x00ffffff ) | ((DWORD)data << 24) );
|
|
break;
|
|
};
|
|
|
|
WRITE_PORT_ULONG( (PULONG)0xcf8, OldPort );
|
|
|
|
return TRUE;
|
|
#else
|
|
ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
|
|
return( StreamClassReadWriteConfig( m_pHwDevExt,
|
|
FALSE,
|
|
&data,
|
|
address,
|
|
1 ) );
|
|
#endif
|
|
}
|
|
|
|
|
|
BOOL CWDMKernelService::GetPCIConfigData( DWORD address, DWORD *data )
|
|
{
|
|
if( m_ioBase==0 || m_pHwDevExt==NULL ){
|
|
return( FALSE );
|
|
}
|
|
|
|
if( address>0xFF ){
|
|
DBG_BREAK();
|
|
return( FALSE );
|
|
}
|
|
|
|
#ifdef DIRECTPCICONFIG
|
|
// DBG_PRINTF( ("XXXPCIConfigData currIrql = 0x%0x LINE=%d\n\r", KeGetCurrentIrql(),__LINE__ ) );
|
|
|
|
if( m_PCIConfigData == 0xffffffff )
|
|
return FALSE;
|
|
|
|
ULONG OldPort = READ_PORT_ULONG( (PULONG)0xcf8 );
|
|
|
|
WRITE_PORT_ULONG( (PULONG)0xcf8, ( m_PCIConfigData | address) & 0xfffffffc );
|
|
*data = READ_PORT_ULONG( (PULONG)0xcfc );
|
|
|
|
WRITE_PORT_ULONG( (PULONG)0xcf8, OldPort );
|
|
|
|
// return TRUE;
|
|
|
|
#else
|
|
ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
|
|
StreamClassReadWriteConfig( m_pHwDevExt,
|
|
TRUE,
|
|
data,
|
|
address,
|
|
4 );
|
|
|
|
#endif
|
|
|
|
if( address==0x2C ){
|
|
if( *data!=0x8888123F ){
|
|
return( TRUE );
|
|
}
|
|
|
|
if( strncmp( m_MachineID, "TECRA", 5 )==0 ){
|
|
*data = 0x00011179;
|
|
}else if( strncmp( m_MachineID, "PORTEGE", 7 )==0 ){
|
|
*data = 0x00021179;
|
|
}
|
|
}
|
|
return( TRUE );
|
|
|
|
}
|
|
|
|
|
|
BOOL CWDMKernelService::GetPCIConfigData( DWORD address, WORD *data )
|
|
{
|
|
if( m_ioBase==0 || m_pHwDevExt==NULL ){
|
|
return( FALSE );
|
|
}
|
|
|
|
if( address>0xFF ){
|
|
DBG_BREAK();
|
|
return( FALSE );
|
|
}
|
|
|
|
#ifdef DIRECTPCICONFIG
|
|
// DBG_PRINTF( ("XXXPCIConfigData currIrql = 0x%0x LINE=%d\n\r", KeGetCurrentIrql(),__LINE__ ) );
|
|
if( m_PCIConfigData == 0xffffffff )
|
|
return FALSE;
|
|
|
|
ULONG OldPort = READ_PORT_ULONG( (PULONG)0xcf8 );
|
|
|
|
WRITE_PORT_ULONG( (PULONG)0xcf8, ( m_PCIConfigData | address) & 0xfffffffc );
|
|
switch( address % 4 )
|
|
{
|
|
case 0:
|
|
*data = (WORD)(READ_PORT_ULONG( (PULONG)0xcfc ) & 0xffff);
|
|
break;
|
|
case 2:
|
|
*data = (WORD)((READ_PORT_ULONG( (PULONG)0xcfc ) >> 16 ) & 0xffff );
|
|
break;
|
|
default:
|
|
*data = 0xffff;
|
|
DBG_BREAK();
|
|
};
|
|
|
|
WRITE_PORT_ULONG( (PULONG)0xcf8, OldPort );
|
|
|
|
// return TRUE;
|
|
#else
|
|
ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
|
|
StreamClassReadWriteConfig( m_pHwDevExt,
|
|
TRUE,
|
|
data,
|
|
address,
|
|
2 );
|
|
#endif
|
|
|
|
if( address==0x2C ){
|
|
if( *data!=0x123F ){
|
|
return( TRUE );
|
|
}
|
|
|
|
if( strncmp( m_MachineID, "TECRA", 5 )==0 ){
|
|
*data = 0x1179;
|
|
}else if( strncmp( m_MachineID, "PORTEGE", 7 )==0 ){
|
|
*data = 0x1179;
|
|
}
|
|
}
|
|
if( address==0x2E ){
|
|
if( *data!=0x8888 ){
|
|
return( TRUE );
|
|
}
|
|
|
|
if( strncmp( m_MachineID, "TECRA", 5 )==0 ){
|
|
*data = 0x0001;
|
|
}else if( strncmp( m_MachineID, "PORTEGE", 7 )==0 ){
|
|
*data = 0x0002;
|
|
}
|
|
}
|
|
|
|
return( TRUE );
|
|
|
|
}
|
|
|
|
|
|
BOOL CWDMKernelService::GetPCIConfigData( DWORD address, BYTE *data )
|
|
{
|
|
if( m_ioBase==0 || m_pHwDevExt==NULL ){
|
|
return( FALSE );
|
|
}
|
|
|
|
if( address>0xFF ){
|
|
DBG_BREAK();
|
|
return( FALSE );
|
|
}
|
|
|
|
#ifdef DIRECTPCICONFIG
|
|
// DBG_PRINTF( ("XXXPCIConfigData currIrql = 0x%0x LINE=%d\n\r", KeGetCurrentIrql(),__LINE__ ) );
|
|
if( m_PCIConfigData == 0xffffffff )
|
|
return FALSE;
|
|
|
|
ULONG OldPort = READ_PORT_ULONG( (PULONG)0xcf8 );
|
|
|
|
WRITE_PORT_ULONG( (PULONG)0xcf8, ( m_PCIConfigData | address) & 0xfffffffc );
|
|
switch( address % 4 )
|
|
{
|
|
case 0:
|
|
*data = (BYTE)(READ_PORT_ULONG( (PULONG)0xcfc ) & 0xff);
|
|
break;
|
|
case 1:
|
|
*data = (BYTE)((READ_PORT_ULONG( (PULONG)0xcfc ) >> 8 ) & 0xff );
|
|
break;
|
|
case 2:
|
|
*data = (BYTE)((READ_PORT_ULONG( (PULONG)0xcfc ) >> 16 ) & 0xff );
|
|
break;
|
|
case 3:
|
|
*data = (BYTE)((READ_PORT_ULONG( (PULONG)0xcfc ) >> 24 ) & 0xff );
|
|
break;
|
|
};
|
|
|
|
WRITE_PORT_ULONG( (PULONG)0xcf8, OldPort );
|
|
|
|
return TRUE;
|
|
#else
|
|
ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
|
|
return( StreamClassReadWriteConfig( m_pHwDevExt,
|
|
TRUE,
|
|
data,
|
|
address,
|
|
1 ) );
|
|
#endif
|
|
}
|
|
|
|
BOOL CWDMKernelService::SetPortData( DWORD address, DWORD data )
|
|
{
|
|
if( m_ioBase==0 || m_pHwDevExt==NULL ){
|
|
return( FALSE );
|
|
}
|
|
|
|
if( address>0xFFFF ){
|
|
DBG_BREAK();
|
|
return( FALSE );
|
|
}
|
|
|
|
PULONG addr = (PULONG)(m_ioBase + address);
|
|
ULONG o_data = (ULONG)data;
|
|
WRITE_PORT_ULONG( addr, o_data );
|
|
|
|
return( TRUE );
|
|
|
|
}
|
|
|
|
BOOL CWDMKernelService::SetPortData( DWORD address, WORD data )
|
|
{
|
|
if( m_ioBase==0 || m_pHwDevExt==NULL ){
|
|
return( FALSE );
|
|
}
|
|
|
|
if( address>0xFFFF ){
|
|
DBG_BREAK();
|
|
return( FALSE );
|
|
}
|
|
|
|
PUSHORT addr = (PUSHORT)(m_ioBase + address);
|
|
USHORT o_data = (USHORT)data;
|
|
WRITE_PORT_USHORT( addr, o_data );
|
|
|
|
return( TRUE );
|
|
|
|
}
|
|
|
|
|
|
BOOL CWDMKernelService::SetPortData( DWORD address, BYTE data )
|
|
{
|
|
if( m_ioBase==0 || m_pHwDevExt==NULL ){
|
|
return( FALSE );
|
|
}
|
|
|
|
if( address>0xFFFF ){
|
|
DBG_BREAK();
|
|
return( FALSE );
|
|
}
|
|
|
|
PUCHAR addr = (PUCHAR)(m_ioBase + address);
|
|
UCHAR o_data = (UCHAR)data;
|
|
WRITE_PORT_UCHAR( addr, o_data );
|
|
|
|
return( TRUE );
|
|
|
|
}
|
|
|
|
BOOL CWDMKernelService::GetPortData( DWORD address, DWORD *data )
|
|
{
|
|
if( m_ioBase==0 || m_pHwDevExt==NULL ){
|
|
return( FALSE );
|
|
}
|
|
|
|
if( address>0xFFFF ){
|
|
DBG_BREAK();
|
|
return( FALSE );
|
|
}
|
|
|
|
PULONG addr = (PULONG)(m_ioBase + address);
|
|
*data = READ_PORT_ULONG( addr );
|
|
|
|
return( TRUE );
|
|
|
|
}
|
|
|
|
BOOL CWDMKernelService::GetPortData( DWORD address, WORD *data )
|
|
{
|
|
if( m_ioBase==0 || m_pHwDevExt==NULL ){
|
|
return( FALSE );
|
|
}
|
|
|
|
if( address>0xFFFF ){
|
|
DBG_BREAK();
|
|
return( FALSE );
|
|
}
|
|
|
|
PUSHORT addr = (PUSHORT)(m_ioBase + address);
|
|
*data = READ_PORT_USHORT( addr );
|
|
|
|
return( TRUE );
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL CWDMKernelService::GetPortData( DWORD address, BYTE *data )
|
|
{
|
|
if( m_ioBase==0 || m_pHwDevExt==NULL ){
|
|
return( FALSE );
|
|
}
|
|
|
|
if( address>0xFFFF ){
|
|
DBG_BREAK();
|
|
return( FALSE );
|
|
}
|
|
|
|
PUCHAR addr = (PUCHAR)(m_ioBase + address);
|
|
*data = READ_PORT_UCHAR( addr );
|
|
|
|
return( TRUE );
|
|
|
|
}
|
|
|
|
|
|
BOOL CWDMKernelService::GetTickCount( DWORD *pTickCount )
|
|
{
|
|
ULONGLONG ticks;
|
|
ULONGLONG rate;
|
|
DWORD time;
|
|
|
|
ticks = (ULONGLONG)KeQueryPerformanceCounter((PLARGE_INTEGER)&rate).QuadPart;
|
|
|
|
//
|
|
// convert from ticks to 100ns clock
|
|
//
|
|
ticks = ( (ticks & 0xFFFFFFFF00000000) / rate * 10000000 +
|
|
(ticks & 0xFFFFFFFF) * 10000000 /rate );
|
|
//
|
|
// convert from ticks to 1ms clock
|
|
//
|
|
time = (DWORD)( ticks / 10000 );
|
|
*pTickCount = time;
|
|
|
|
return( TRUE );
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL CWDMKernelService::Sleep( DWORD SleepCount )
|
|
{
|
|
DWORD StartTime, EndTime, CurrentTime;
|
|
LARGE_INTEGER time, rate;
|
|
LARGE_INTEGER waittime;
|
|
|
|
time = KeQueryPerformanceCounter( &rate );
|
|
CurrentTime = (DWORD)(( (time.QuadPart*1000)/(rate.QuadPart) ));
|
|
// DBG_PRINTF(("Sleep: Start = x0x%x\n\r", CurrentTime ));
|
|
|
|
time = KeQueryPerformanceCounter( &rate );
|
|
StartTime = (DWORD)( (time.QuadPart*1000)/rate.QuadPart );
|
|
EndTime = StartTime + SleepCount;
|
|
|
|
if( KeGetCurrentIrql() > PASSIVE_LEVEL ){
|
|
|
|
while( TRUE ){
|
|
KeStallExecutionProcessor( 1000 );
|
|
|
|
time = KeQueryPerformanceCounter( &rate );
|
|
CurrentTime = (DWORD)(( (time.QuadPart*1000)/(rate.QuadPart) ));
|
|
//DBG_PRINTF(("Sleep: Current = x0%x, End = 0x%x\r\n", CurrentTime, EndTime ));
|
|
if( CurrentTime>=EndTime )
|
|
break;
|
|
}
|
|
|
|
}else{
|
|
|
|
waittime.QuadPart = SleepCount * 10000;
|
|
while( TRUE ){
|
|
|
|
KeWaitForSingleObject( &m_Event, Executive,
|
|
KernelMode, FALSE, &waittime );
|
|
time = KeQueryPerformanceCounter( &rate );
|
|
CurrentTime = (DWORD)(( (time.QuadPart*1000)/(rate.QuadPart) ));
|
|
if( CurrentTime >= EndTime ){
|
|
break;
|
|
}else{
|
|
waittime.QuadPart = (EndTime-CurrentTime) * 10000;
|
|
}
|
|
}
|
|
|
|
}
|
|
time = KeQueryPerformanceCounter( &rate );
|
|
CurrentTime = (DWORD)(( (time.QuadPart*1000)/(rate.QuadPart) ));
|
|
// DBG_PRINTF(("Sleep: End = 0x%x\n\r", CurrentTime ));
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
|
|
void CWDMKernelService::DisableHwInt( void )
|
|
{
|
|
KIRQL currIrql;
|
|
currIrql = KeGetCurrentIrql();
|
|
|
|
|
|
if( m_IntCount==0 ){
|
|
if( currIrql == m_Irql ){
|
|
m_OldIrql = m_Irql;
|
|
m_IntCount++;
|
|
return;
|
|
}
|
|
KeRaiseIrql( m_Irql, &m_OldIrql );
|
|
}
|
|
m_IntCount++;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void CWDMKernelService::EnableHwInt( void )
|
|
{
|
|
m_IntCount--;
|
|
|
|
if( m_IntCount==0 ){
|
|
if( m_OldIrql == m_Irql ){
|
|
return;
|
|
}
|
|
KeLowerIrql( m_OldIrql );
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
BOOL CWDMKernelService::CheckInt( void )
|
|
{
|
|
if( m_IntCount != 0 ){
|
|
DBG_BREAK();
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|