Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

576 lines
21 KiB

//==========================================================================;
//
// WDMXBar.CPP
// WDM Audio/Video CrossBar MiniDriver.
// AIW Hardware platform.
// CWDMAVXBar class implementation.
// Copyright (c) 1996 - 1997 ATI Technologies Inc. All Rights Reserved.
//
//==========================================================================;
extern "C"
{
#include "strmini.h"
#include "ksmedia.h"
#include "wdmdebug.h"
}
#include "atixbar.h"
#include "wdmdrv.h"
#include "aticonfg.h"
/*^^*
* AdapterCompleteInitialization()
* Purpose : Called when SRB_COMPLETE_INITIALIZATION SRB is received.
*
* Inputs : PHW_STREAM_REQUEST_BLOCK pSrb : pointer to the current Srb
*
* Outputs : BOOL : returns TRUE
* Author : IKLEBANOV
*^^*/
NTSTATUS CWDMAVXBar::AdapterCompleteInitialization( PHW_STREAM_REQUEST_BLOCK pSrb)
{
PADAPTER_DATA_EXTENSION pPrivateData = ( PADAPTER_DATA_EXTENSION)( pSrb->HwDeviceExtension);
NTSTATUS ntStatus;
ULONG nPinsNumber;
nPinsNumber = m_nNumberOfVideoInputs + m_nNumberOfAudioInputs +
m_nNumberOfVideoOutputs + m_nNumberOfAudioOutputs;
ENSURE
{
ntStatus = StreamClassRegisterFilterWithNoKSPins( \
pPrivateData->PhysicalDeviceObject, // IN PDEVICE_OBJECT DeviceObject,
&KSCATEGORY_CROSSBAR, // IN GUID * InterfaceClassGUID
nPinsNumber, // IN ULONG PinCount,
m_pXBarPinsDirectionInfo, // IN ULONG * Flags,
m_pXBarPinsMediumInfo, // IN KSPIN_MEDIUM * MediumList,
NULL); // IN GUID * CategoryList
if( !NT_SUCCESS( ntStatus))
FAIL;
OutputDebugTrace(( "CWDMAVXBar:AdapterCompleteInitialization() exit\n"));
} END_ENSURE;
if( !NT_SUCCESS( ntStatus))
OutputDebugError(( "CWDMAVXBar:AdapterCompleteInitialization() ntStatus=%x\n", ntStatus));
return( ntStatus);
}
/*^^*
* AdapterUnInitialize()
* Purpose : Called when SRB_UNINITIALIZE_DEVICE SRB is received.
*
* Inputs : PHW_STREAM_REQUEST_BLOCK pSrb : pointer to the current Srb
*
* Outputs : BOOL : returns TRUE
* Author : IKLEBANOV
*^^*/
BOOL CWDMAVXBar::AdapterUnInitialize( PHW_STREAM_REQUEST_BLOCK pSrb)
{
OutputDebugTrace(( "CWDMAVXBar:AdapterUnInitialize()\n"));
if( m_pXBarInputPinsInfo != NULL)
{
::ExFreePool( m_pXBarInputPinsInfo);
m_pXBarInputPinsInfo = NULL;
}
if( m_pXBarPinsMediumInfo != NULL)
{
::ExFreePool( m_pXBarPinsMediumInfo);
m_pXBarPinsMediumInfo = NULL;
}
if( m_pXBarPinsDirectionInfo != NULL)
{
::ExFreePool( m_pXBarPinsDirectionInfo);
m_pXBarPinsDirectionInfo = NULL;
}
pSrb->Status = STATUS_SUCCESS;
return( TRUE);
}
/*^^*
* AdapterGetStreamInfo()
* Purpose : Calles during StreamClass initialization procedure to get the information
* about data streams exposed by the MiniDriver
*
* Inputs : PHW_STREAM_REQUEST_BLOCK pSrb : pointer to the current Srb
*
* Outputs : BOOL : returns TRUE
* Author : IKLEBANOV
*^^*/
BOOL CWDMAVXBar::AdapterGetStreamInfo( PHW_STREAM_REQUEST_BLOCK pSrb)
{
// pick up the pointer to the stream header data structure
PHW_STREAM_HEADER pStreamHeader = ( PHW_STREAM_HEADER) \
&( pSrb->CommandData.StreamBuffer->StreamHeader);
// pick up the pointer to the stream information data structure
PHW_STREAM_INFORMATION pStreamInfo = ( PHW_STREAM_INFORMATION) \
&( pSrb->CommandData.StreamBuffer->StreamInfo);
// no streams are supported
DEBUG_ASSERT( pSrb->NumberOfBytesToTransfer >= sizeof( HW_STREAM_HEADER));
OutputDebugTrace(( "CWDMAVXBar:AdapterGetStreamInfo()\n"));
m_wdmAVXBarStreamHeader.NumberOfStreams = 0;
m_wdmAVXBarStreamHeader.SizeOfHwStreamInformation = sizeof( HW_STREAM_INFORMATION);
m_wdmAVXBarStreamHeader.NumDevPropArrayEntries = KSPROPERTIES_AVXBAR_NUMBER_SET;
m_wdmAVXBarStreamHeader.DevicePropertiesArray = m_wdmAVXBarPropertySet;
m_wdmAVXBarStreamHeader.NumDevEventArrayEntries = 0;
m_wdmAVXBarStreamHeader.DeviceEventsArray = NULL;
m_wdmAVXBarStreamHeader.Topology = &m_wdmAVXBarTopology;
* pStreamHeader = m_wdmAVXBarStreamHeader;
pSrb->Status = STATUS_SUCCESS;
return( TRUE);
}
/*^^*
* AdapterQueryUnload()
* Purpose : Called when the class driver is about to unload the MiniDriver
* The MiniDriver checks if any open stream left.
*
* Inputs : PHW_STREAM_REQUEST_BLOCK pSrb : pointer to the current Srb
*
* Outputs : BOOL : returns TRUE
* Author : IKLEBANOV
*^^*/
BOOL CWDMAVXBar::AdapterQueryUnload( PHW_STREAM_REQUEST_BLOCK pSrb)
{
OutputDebugTrace(( "CWDMAVXBar:AdapterQueryUnload()\n"));
pSrb->Status = STATUS_SUCCESS;
return( TRUE);
}
/*^^*
* operator new
* Purpose : CWDMAVXBar class overloaded operator new.
* Provides placement for a CWDMAVXBar class object from the PADAPTER_DEVICE_EXTENSION
* allocated by the StreamClassDriver for the MiniDriver.
*
* Inputs : UINT size_t : size of the object to be placed
* PVOID pAllocation : casted pointer to the CWDMAVXBar allocated data
*
* Outputs : PVOID : pointer of the CWDMAVXBar class object
* Author : IKLEBANOV
*^^*/
PVOID CWDMAVXBar::operator new( size_t size_t, PVOID pAllocation)
{
if( size_t != sizeof( CWDMAVXBar))
{
OutputDebugTrace(( "CWDMAVXBar: operator new() fails\n"));
return( NULL);
}
else
return( pAllocation);
}
/*^^*
* ~CWDMAVXBar()
* Purpose : CWDMAVXBar class destructor.
* Frees the allocated memory.
*
* Inputs : none
*
* Outputs : none
* Author : IKLEBANOV
*^^*/
CWDMAVXBar::~CWDMAVXBar()
{
OutputDebugTrace(( "CWDMAVXBar:~CWDMAVXBar() m_pXBarPinsInfo = %x\n", m_pXBarInputPinsInfo));
if( m_pXBarInputPinsInfo != NULL)
{
::ExFreePool( m_pXBarInputPinsInfo);
m_pXBarInputPinsInfo = NULL;
}
if( m_pXBarPinsMediumInfo != NULL)
{
::ExFreePool( m_pXBarPinsMediumInfo);
m_pXBarPinsMediumInfo = NULL;
}
if( m_pXBarPinsDirectionInfo != NULL)
{
::ExFreePool( m_pXBarPinsDirectionInfo);
m_pXBarPinsDirectionInfo = NULL;
}
}
/*^^*
* CWDMAVXBar()
* Purpose : CWDMAVXBar class constructor.
* Performs checking of the hardware presence. Sets the hardware in an initial state.
*
* Inputs : CI2CScript * pCScript : pointer to the I2CScript class object
* PUINT puiError : pointer to return a completion error code
*
* Outputs : none
* Author : IKLEBANOV
*^^*/
CWDMAVXBar::CWDMAVXBar( PPORT_CONFIGURATION_INFORMATION pConfigInfo, CI2CScript * pCScript, PUINT puiErrorCode)
:m_CATIConfiguration( pConfigInfo, pCScript, puiErrorCode)
{
UINT uiError;
ULONG ulInstance;
HANDLE hFolder = NULL;
OutputDebugTrace(( "CWDMAVXBar:CWDMAVXBar() enter\n"));
m_pXBarInputPinsInfo = m_pXBarOutputPinsInfo = NULL;
m_pXBarPinsMediumInfo = NULL;
m_pXBarPinsDirectionInfo = NULL;
m_ulPowerState = PowerDeviceD0;
// error code was caried over from ATIConfiguration class constructor
uiError = * puiErrorCode;
ENSURE
{
ULONG ulNumberOfPins, nPinIndex;
UINT uiTunerId, nIndex;
UCHAR uchTunerAddress;
KSPIN_MEDIUM mediumKSPin;
const KSPIN_MEDIUM * pMediumKSPin;
if( uiError != WDMMINI_NOERROR)
FAIL;
if( pCScript == NULL)
{
uiError = WDMMINI_INVALIDPARAM;
FAIL;
}
// first, find out whether any tuner type is installed. If not, we have only 2 video sources.
m_CATIConfiguration.GetTunerConfiguration( &uiTunerId, &uchTunerAddress);
m_nNumberOfVideoInputs = ( uchTunerAddress) ? 3 : 2;
m_nNumberOfVideoOutputs = m_nNumberOfVideoInputs;
m_CATIConfiguration.GetAudioProperties( &m_nNumberOfAudioInputs, &m_nNumberOfAudioOutputs);
if( !uchTunerAddress)
// if there is no tuner - no TVAudio input
m_nNumberOfAudioInputs --;
ulNumberOfPins = m_nNumberOfAudioInputs + m_nNumberOfVideoInputs + m_nNumberOfVideoOutputs + m_nNumberOfAudioOutputs;
m_pXBarInputPinsInfo = ( PXBAR_PIN_INFORMATION) \
::ExAllocatePool( NonPagedPool, sizeof( XBAR_PIN_INFORMATION) * ulNumberOfPins);
if( m_pXBarInputPinsInfo == NULL)
{
uiError = WDMMINI_ERROR_MEMORYALLOCATION;
FAIL;
}
m_pXBarPinsMediumInfo = ( PKSPIN_MEDIUM) \
::ExAllocatePool( NonPagedPool, sizeof( KSPIN_MEDIUM) * ulNumberOfPins);
if( m_pXBarPinsMediumInfo == NULL)
{
uiError = WDMMINI_ERROR_MEMORYALLOCATION;
FAIL;
}
m_pXBarPinsDirectionInfo = ( PBOOL) \
::ExAllocatePool( NonPagedPool, sizeof( BOOL) * ulNumberOfPins);
if( m_pXBarPinsDirectionInfo == NULL)
{
uiError = WDMMINI_ERROR_MEMORYALLOCATION;
FAIL;
}
m_pI2CScript = pCScript;
m_pXBarOutputPinsInfo = &m_pXBarInputPinsInfo[m_nNumberOfAudioInputs + m_nNumberOfVideoInputs];
// Medium pin data has an Instance number inside
ulInstance = ::GetDriverInstanceNumber( pConfigInfo->RealPhysicalDeviceObject);
hFolder = ::OpenRegistryFolder( pConfigInfo->RealPhysicalDeviceObject, &UNICODE_WDM_REG_PIN_MEDIUMS);
// initialize video input pins, TVTuner input is always the last one
for( nIndex = 0; nIndex < m_nNumberOfVideoInputs; nIndex ++)
{
switch( nIndex)
{
case 0:
// Composite
m_pXBarInputPinsInfo[nIndex].AudioVideoPinType = KS_PhysConn_Video_Composite;
// put the default value for the Medium first
::RtlCopyMemory( &m_pXBarPinsMediumInfo[nIndex], &MEDIUM_WILDCARD, sizeof( KSPIN_MEDIUM));
// LineIn is always the first audio pin
m_pXBarInputPinsInfo[nIndex].nRelatedPinNumber = m_nNumberOfVideoInputs;
break;
case 1:
// SVideo
m_pXBarInputPinsInfo[nIndex].AudioVideoPinType = KS_PhysConn_Video_SVideo;
// put the default value for the Medium first
::RtlCopyMemory( &m_pXBarPinsMediumInfo[nIndex], &MEDIUM_WILDCARD, sizeof( KSPIN_MEDIUM));
// LineIn is always the first audio pin
m_pXBarInputPinsInfo[nIndex].nRelatedPinNumber = m_nNumberOfVideoInputs;
break;
case 2:
// TVTuner
m_pXBarInputPinsInfo[nIndex].AudioVideoPinType = KS_PhysConn_Video_Tuner;
// put the default value for the Medium first
::RtlCopyMemory( &m_pXBarPinsMediumInfo[nIndex], &ATIXBarVideoTunerInMedium, sizeof( KSPIN_MEDIUM));
// TVAudio is always the last audio pin
m_pXBarInputPinsInfo[nIndex].nRelatedPinNumber = m_nNumberOfVideoInputs + m_nNumberOfAudioInputs - 1;
break;
default:
TRAP;
break;
}
// let's put another Medium value from the registry, if present
if( ::ReadPinMediumFromRegistryFolder( hFolder, nIndex, &mediumKSPin))
::RtlCopyMemory( &m_pXBarPinsMediumInfo[nIndex], &mediumKSPin, sizeof( KSPIN_MEDIUM));
m_pXBarInputPinsInfo[nIndex].pMedium = &m_pXBarPinsMediumInfo[nIndex];
m_pXBarPinsMediumInfo[nIndex].Id = ulInstance;
// all the pins here are inputs
m_pXBarPinsDirectionInfo[nIndex] = FALSE;
}
// initialize audio input pins, TV Audio input is always the last one
for( nIndex = 0; nIndex < m_nNumberOfAudioInputs; nIndex ++)
{
nPinIndex = nIndex + m_nNumberOfVideoInputs;
switch( nIndex)
{
case 0:
m_pXBarInputPinsInfo[nPinIndex].AudioVideoPinType = KS_PhysConn_Audio_Line;
// put the default value for the Medium first
::RtlCopyMemory( &m_pXBarPinsMediumInfo[nPinIndex], &MEDIUM_WILDCARD, sizeof( KSPIN_MEDIUM));
m_pXBarInputPinsInfo[nPinIndex].nRelatedPinNumber = 0;
break;
case 1:
m_pXBarInputPinsInfo[nPinIndex].AudioVideoPinType = KS_PhysConn_Audio_Tuner;
// put the default value for the Medium first
::RtlCopyMemory( &m_pXBarPinsMediumInfo[nPinIndex], &ATIXBarAudioTunerInMedium, sizeof( KSPIN_MEDIUM));
m_pXBarInputPinsInfo[nPinIndex].nRelatedPinNumber = m_nNumberOfVideoInputs - 1;
break;
default:
TRAP;
break;
}
// let's put another Medium value from the registry, if present
if( ::ReadPinMediumFromRegistryFolder( hFolder, nPinIndex, &mediumKSPin))
::RtlCopyMemory( &m_pXBarPinsMediumInfo[nPinIndex], &mediumKSPin, sizeof( KSPIN_MEDIUM));
m_pXBarInputPinsInfo[nPinIndex].pMedium = &m_pXBarPinsMediumInfo[nPinIndex];
m_pXBarPinsMediumInfo[nPinIndex].Id = ulInstance;
// all the pins here are inputs
m_pXBarPinsDirectionInfo[nPinIndex] = FALSE;
}
// initialize outputs video pins, no X-connection for Video
for( nIndex = 0; nIndex < m_nNumberOfVideoOutputs; nIndex ++)
{
nPinIndex = nIndex + m_nNumberOfVideoInputs + m_nNumberOfAudioInputs;
m_pXBarOutputPinsInfo[nIndex].AudioVideoPinType = m_pXBarInputPinsInfo[nIndex].AudioVideoPinType;
m_pXBarOutputPinsInfo[nIndex].nConnectedToPin = nIndex;
m_pXBarOutputPinsInfo[nIndex].nRelatedPinNumber = m_nNumberOfVideoOutputs; // jaybo
switch( m_pXBarOutputPinsInfo[nIndex].AudioVideoPinType)
{
case KS_PhysConn_Video_Tuner:
pMediumKSPin = &ATIXBarVideoTunerOutMedium;
break;
case KS_PhysConn_Video_SVideo:
pMediumKSPin = &ATIXBarVideoSVideoOutMedium;
break;
case KS_PhysConn_Video_Composite:
pMediumKSPin = &ATIXBarVideoCompositeOutMedium;
break;
default:
pMediumKSPin = &MEDIUM_WILDCARD;
break;
}
::RtlCopyMemory( &m_pXBarPinsMediumInfo[nPinIndex], pMediumKSPin, sizeof( KSPIN_MEDIUM));
// let's put another Medium value from the registry, if present
if( ::ReadPinMediumFromRegistryFolder( hFolder, nPinIndex, &mediumKSPin))
::RtlCopyMemory( &m_pXBarPinsMediumInfo[nPinIndex], &mediumKSPin, sizeof( KSPIN_MEDIUM));
m_pXBarOutputPinsInfo[nIndex].pMedium = &m_pXBarPinsMediumInfo[nPinIndex];
m_pXBarPinsMediumInfo[nPinIndex].Id = ulInstance;
// all the pins here are outputs
m_pXBarPinsDirectionInfo[nPinIndex] = TRUE;
}
// initialize outputs audio pins
for( nIndex = 0; nIndex < m_nNumberOfAudioOutputs; nIndex ++)
{
nPinIndex = nIndex + m_nNumberOfVideoInputs + m_nNumberOfAudioInputs + m_nNumberOfVideoOutputs;
m_pXBarOutputPinsInfo[nIndex + m_nNumberOfVideoInputs].AudioVideoPinType = KS_PhysConn_Audio_AudioDecoder;
// put the default value for the Medium first
/* jaybo
::RtlCopyMemory( &m_pXBarPinsMediumInfo[nPinIndex], ATIXBarAudioDecoderOutMedium, sizeof( KSPIN_MEDIUM));
*/
::RtlCopyMemory( &m_pXBarPinsMediumInfo[nPinIndex], &MEDIUM_WILDCARD, sizeof( KSPIN_MEDIUM));
// let's put another Medium value from the registry, if present
if( ::ReadPinMediumFromRegistryFolder( hFolder, nPinIndex, &mediumKSPin))
::RtlCopyMemory( &m_pXBarPinsMediumInfo[nPinIndex], &mediumKSPin, sizeof( KSPIN_MEDIUM));
m_pXBarOutputPinsInfo[nIndex + m_nNumberOfVideoInputs].nConnectedToPin = ( ULONG)-1;
m_pXBarOutputPinsInfo[nIndex + m_nNumberOfVideoInputs].nRelatedPinNumber = (ULONG)-1;
m_pXBarOutputPinsInfo[nIndex + m_nNumberOfVideoInputs].pMedium = &m_pXBarPinsMediumInfo[nPinIndex];
m_pXBarPinsMediumInfo[nPinIndex].Id = ulInstance;
// all the pins here are outputs
m_pXBarPinsDirectionInfo[nPinIndex] = TRUE;
}
if( hFolder != NULL)
::ZwClose( hFolder);
// mute the audio as the default power-up behaviour
m_CATIConfiguration.ConnectAudioSource( m_pI2CScript, AUDIOSOURCE_MUTE);
// these two functions has to be called after the CWDMAVXBar class object was build on
// on the stack and copied over into the DeviceExtension
// This commant was true for the case, where the class object was build on the stack first.
// There is an overloaded operator new provided for this class, and we can call it from here
SetWDMAVXBarKSProperties();
SetWDMAVXBarKSTopology();
// Set run-time WDM properties at the last
* puiErrorCode = WDMMINI_NOERROR;
OutputDebugTrace(( "CWDMAVXBar:CWDMAVXBar() exit\n"));
return;
} END_ENSURE;
* puiErrorCode = uiError;
OutputDebugError(( "CWDMAVXBar:CWDMAVXBar() Error = %x\n", uiError));
}
/*^^*
* AdapterSetPowerState()
* Purpose : Sets Power Management state for deviec
*
* Inputs : PHW_STREAM_REQUEST_BLOCK pSrb : pointer to the current Srb
*
* Outputs : NTSTATUS as the operation result
* Author : TOM
*^^*/
NTSTATUS CWDMAVXBar::AdapterSetPowerState( PHW_STREAM_REQUEST_BLOCK pSrb)
{
ULONG nAudioSource;
ULONG nInputPin;
NTSTATUS ntStatus;
UINT nIndex;
DEVICE_POWER_STATE nDeviceState = pSrb->CommandData.DeviceState;
ntStatus = STATUS_ADAPTER_HARDWARE_ERROR;
switch( nDeviceState)
{
case PowerDeviceD0:
case PowerDeviceD3:
if( nDeviceState != m_ulPowerState)
{
// if transition form D3 to D0 we have to restore audio connections
if(( nDeviceState == PowerDeviceD0) && ( m_ulPowerState == PowerDeviceD3))
{
for( nIndex = 0; nIndex < m_nNumberOfAudioOutputs; nIndex ++)
{
// we need to restore every audio output pin connection,
// video output pins are hardwired
nInputPin = m_pXBarOutputPinsInfo[nIndex + m_nNumberOfVideoOutputs].nConnectedToPin;
switch( m_pXBarInputPinsInfo[nInputPin].AudioVideoPinType)
{
case KS_PhysConn_Audio_Line:
nAudioSource = AUDIOSOURCE_LINEIN;
break;
case KS_PhysConn_Audio_Tuner:
nAudioSource = AUDIOSOURCE_TVAUDIO;
break;
case 0xFFFFFFFF:
nAudioSource = AUDIOSOURCE_MUTE;
return( STATUS_SUCCESS);
default:
OutputDebugError(( "CWDMAVXBar:AdapterSetPowerState() Audio Pin type=%x\n", m_pXBarInputPinsInfo[nInputPin].AudioVideoPinType));
return STATUS_SUCCESS;
}
if( m_CATIConfiguration.ConnectAudioSource( m_pI2CScript, nAudioSource))
ntStatus = STATUS_SUCCESS;
else
{
// error
ntStatus = STATUS_ADAPTER_HARDWARE_ERROR;
break;
}
}
}
else
ntStatus = STATUS_SUCCESS;
}
else
ntStatus = STATUS_SUCCESS;
m_ulPowerState = nDeviceState;
break;
case PowerDeviceUnspecified:
case PowerDeviceD1:
case PowerDeviceD2:
ntStatus = STATUS_SUCCESS;
break;
default:
ntStatus = STATUS_INVALID_PARAMETER;
break;
}
return( ntStatus);
}