Ryan Malloy bbdcb243dc Normalize line endings to LF across entire repository
Apply .gitattributes normalization to convert all CRLF line
endings inherited from Windows-origin source files to Unix LF.
175 files, zero content changes.
2026-02-20 10:55:50 -07:00

1142 lines
38 KiB
C++

/*****************************************************************************
Company : Shree Ganesha Inc.
File Name : SkyWalker1Device.cpp
Author :
Date :
Purpose : Main Skywalker Device level Implementation
Revision History:
===============================================================================
DATE VERSION AUTHOR REMARK
===============================================================================
01 Initial Version
*****************************************************************************/
/* Include the Library and Other header file */
#include "SkyWalker1Main.h" //Header for the Tuner related definitions
/* End of Inclusion the Library and Other header file */
/* Macro Definitions */
/* End of Macro Definitions */
/* Global & Static variables Declaration */
static ULONG ulDeviceInstance = 0;
/* End of Global & Static variables Declaration */
/* External Variable Declaration */
/* End of External Variable Declaration */
/* Declare Enumerations here */
/* End of Enumeration declaration */
/* Function Prototypes */
void PrintDMAAdapter(PDMA_ADAPTER pDMAAdapter);
void PrintMappingInfo(IN PKSMAPPING pMapping);
/* End of Function prototype definitions */
/*****************************************************************************
Function : CSkyWalker1Device::Create
Description : This Function is called during the Add Device IRP Processing
IN PARAM : <PKSDEVICE > Pointer to the Enumerated Physical Device
KSDEVICE is a WDM Functional Device which is managed by the AVStream
OUT PARAM : <NTSTATUS> ntStatus of the Device Addition
STATUS_SUCCESS when the Device added to the System
Reason for Failure incase of Error
PreCondition : Driver is Loaded without Functional/ Filter Device Objects
PostCondtion : Functional Device Object [FDO] or Filter Device Object [FiDO] are created
Logic : NONE
Assumption : NONE
Note : NONE
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
*****************************************************************************/
NTSTATUS CSkyWalker1Device::Create(IN PKSDEVICE pKSDeviceObject)
{
NTSTATUS ntCreateStatus = STATUS_SUCCESS;
PrintFunctionEntry(__FUNCTION__);
if (pKSDeviceObject)
{
//Point the KSDEVICE at our device class.
pKSDeviceObject->Context = this;
m_pKSDevice = pKSDeviceObject;
//Make the resource available for a filter to use.
m_ulcResourceUsers = 0;
m_ulCurResourceID = 0;
//Get the instance number of this device.
m_ulDeviceInstance = ulDeviceInstance++;
//Hold requests until the device is started
QueueState = HoldRequests;
//Initialize the stop event to signaled.
KeInitializeEvent(&EvDeviceStopOk, //PKEVENT
NotificationEvent, //Type
TRUE); //State
//Initialize the remove event to not-signaled.
KeInitializeEvent(&EvDeviceRemoveOk, //PKEVENT
NotificationEvent, //Type
FALSE); //State
//The KeInitializeSpinLock routine initializes a variable of
//type KSPIN_LOCK.
KeInitializeSpinLock(&DeviceStateLock);
INITIALIZE_PNP_STATE(this);
//OutstandingIo count biased to 1.
//Transition to 0 during remove device means IO is finished.
//Transition to 1 means the device can be stopped
ulOutStandingIoCount = 1;
KeInitializeSpinLock(&kIoCountLock);
}
else
{
SkyWalkerDebugPrint(ENTRY_LEVEL,("Invalid KS Device Object Received\n"));
ntCreateStatus = STATUS_INVALID_PARAMETER;
}
PrintFunctionExit(__FUNCTION__,ntCreateStatus);
return ntCreateStatus;
}
/*****************************************************************************
Function : CSkyWalker1Device::Start
Description : This function Initializes the Tuner Hardware
IN PARAM : <PKSDEVICE> Reference to Device to be Started
<PIRP> IoRequest Packet
<PCM_RESOURCE_LIST> Resource List
<PCM_RESOURCE_LIST> Translated Resource List
OUT PARAM : <NTSTATUS> ntStatus of the Tuner Start
STATUS_SUCCESS in case of successful execution
Failure Code in other cases
PreCondition : Stopped Device or Device Enumerated for the First Time
PostCondtion : Device Initialized with the Newly allocated Resources,
Logic : NONE
Assumption : NONE
Note : NONE
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
*****************************************************************************/
NTSTATUS CSkyWalker1Device::Start(
IN PKSDEVICE pKSDeviceObject,
IN PIRP pIoRequestPacket,
IN PCM_RESOURCE_LIST pResourceList OPTIONAL,
IN PCM_RESOURCE_LIST pTranslatedResourceList OPTIONAL
)
{
NTSTATUS ntStartStatus = STATUS_SUCCESS;
CSkyWalker1Device * pDevice = NULL;
PKSFILTERFACTORY pKSFilterFactory = NULL;
PrintFunctionEntry(__FUNCTION__);
pDevice = reinterpret_cast<CSkyWalker1Device *>(pKSDeviceObject->Context);
//Initialize the Tuner Hardware.
ntStartStatus = pDevice->InitializeTuner(pKSDeviceObject,pIoRequestPacket);
SkyWalkerDebugPrint(EXTREME_LEVEL,("USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE = %d",USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE));
if (ntStartStatus == STATUS_SUCCESS)
{
//Create the the Filter Factory. This factory is used to
//create instances of the filter.
ntStartStatus = BdaCreateFilterFactoryEx(
pKSDeviceObject,
&SkyWalker1TunerFilterDescriptor,
&TunerFilterTemplate,
&pKSFilterFactory
);
}
if ((ntStartStatus == STATUS_SUCCESS) && pKSFilterFactory)
{
BdaFilterFactoryUpdateCacheData(
pKSFilterFactory,
TunerFilterTemplate.pFilterDescriptor
);
}
PrintFunctionExit(__FUNCTION__,ntStartStatus);
return ntStartStatus;
}
/*****************************************************************************
Function : CSkyWalker1Device::Stop
Description : This routine is invoked when the device is stopped.
This routine services Irp of minor type IRP_MN_STOP_DEVICE
IN PARAM : <PKSDEVICE> Pointer to KS Device Object
<PIRP> STOP DEVICE Irp
OUT PARAM : <NTSTATUS> ntStatus of the Device Stop
STATUS_SUCCESS on Successful execution
else Error
PreCondition : NONE
PostCondtion : USB Device Stopped
Logic : NONE
Assumption : NONE
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
*****************************************************************************/
NTSTATUS CSkyWalker1Device::Stop( IN PKSDEVICE pKSDeviceObject,
IN PIRP pIoRequestPacket)
{
NTSTATUS ntDeviceStopStatus = STATUS_SUCCESS;
PrintFunctionEntry(__FUNCTION__);
if(m_pDMAAdapter)
{
m_pDMAAdapter->DmaOperations->PutDmaAdapter(m_pDMAAdapter);
m_pDMAAdapter = NULL;
}
//Maintain the USB ntStatus i.e Remove the Selected Configuration by sending Null descriptor
ntDeviceStopStatus = StopUsbDevice(pKSDeviceObject,pIoRequestPacket);
PrintFunctionExit(__FUNCTION__,ntDeviceStopStatus);
return ntDeviceStopStatus;
}
/*****************************************************************************
Function : CSkyWalker1Device::Close
Description : This routine is invoked when the device is Removed.
This routine services Irp of minor type IRP_MN_REMOVE_DEVICE
IN PARAM : <PKSDEVICE> Pointer to KS Device Object
<PIRP> STOP DEVICE Irp
OUT PARAM : <NTSTATUS> ntStatus of the Device Remove
STATUS_SUCCESS on Successful execution
else Error
PreCondition : NONE
PostCondtion : USB Device Removed
Logic : NONE
Assumption : NONE
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
*****************************************************************************/
NTSTATUS CSkyWalker1Device::Close( IN PKSDEVICE pKSDeviceObject,
IN PIRP pIoRequestPacket)
{
NTSTATUS ntDeviceCloseStatus = STATUS_SUCCESS;
PrintFunctionEntry(__FUNCTION__);
ntDeviceCloseStatus = RemoveUsbDevice(pKSDeviceObject,pIoRequestPacket);
PrintFunctionExit(__FUNCTION__,ntDeviceCloseStatus);
return ntDeviceCloseStatus;
}
/*****************************************************************************
Function : CSkyWalker1Device::SetPower
Description : This routine is invoked when the Power Irp is received
This routine services Irp of minor type IRP_MJ_POWER
IN PARAM : <PKSDEVICE> Pointer to KS Device Object
<PIRP> STOP DEVICE Irp
OUT PARAM : <NTSTATUS> ntStatus of the Set POwer
STATUS_SUCCESS on Successful execution
else Error
PreCondition : NONE
PostCondtion : Power Condition Managed
Logic : NONE
Assumption : NONE
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
*****************************************************************************/
NTSTATUS CSkyWalker1Device::SetPower(
IN PKSDEVICE pKSDeviceObject, //Pointer to the device object
//provided by the system.
IN PIRP pIoRequestPacket, //Pointer to the IRP related to this request.
IN DEVICE_POWER_STATE To, //Requested power state.
IN DEVICE_POWER_STATE From //Current power state.
)
{
NTSTATUS ntSetPowerStatus = STATUS_SUCCESS;
PrintFunctionEntry(__FUNCTION__);
//Set USB Power condition from here
PrintFunctionExit(__FUNCTION__,ntSetPowerStatus);
return ntSetPowerStatus;
}
/*****************************************************************************
Function : CSkyWalker1Device::InitializeTuner
Description : This function is used to setup and initialize the Tuner
Interface
IN PARAM : <PKSDEVICE> Reference to Device to be Started
<PIRP> IoRequest Packet
OUT PARAM : <NTSTATUS> ntStatus of the Tuner Initializations
STATUS_SUCCESS in case of successful execution
Failure Code in other cases
PreCondition : Stopped Device or Device Enumerated for the First Time
PostCondtion : Device Initialized with the Newly allocated Resources,
Logic : NONE
Assumption : NONE
Note : This is called from the PASSIVE_LEVEL_IRQL
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
*****************************************************************************/
NTSTATUS CSkyWalker1Device::InitializeTuner(
IN PKSDEVICE pKSDeviceObject,
IN PIRP pIoRequestPacket)
{
NTSTATUS ntInitStatus = STATUS_SUCCESS;
PrintFunctionEntry(__FUNCTION__);
//Initialize the USB hardware here.
ntInitStatus = InitializeUsbDevice(pKSDeviceObject,pIoRequestPacket);
if(!NT_SUCCESS(ntInitStatus))
{
SkyWalkerDebugPrint(ENTRY_LEVEL,("Failed to Initialize the USB Device\n"));
goto ExitInitTuner;
}
//Setup the SkyWalker1 Device
ntInitStatus = SetupTunerPower(pKSDeviceObject,SWITCH_ON_TUNER);
if(!NT_SUCCESS(ntInitStatus))
{
SkyWalkerDebugPrint(ENTRY_LEVEL,("Failed to Setup the SkyWalker1 Device\n"));
goto ExitInitTuner;
}
//Initialize Adapter
ntInitStatus = InitializeAdapterStream(pKSDeviceObject);
if(!NT_SUCCESS(ntInitStatus))
{
SkyWalkerDebugPrint(ENTRY_LEVEL,("Failed to Initialize the Adapter Stream\n"));
goto ExitInitTuner;
}
ExitInitTuner:
PrintFunctionExit(__FUNCTION__,ntInitStatus);
return ntInitStatus;
}
/*****************************************************************************
Function : CSkyWalker1Device::InitializeAdapterStream
Description : This function is used to Register the Adapter Object and
setup the Private Memory for the Streams
IN PARAM : <PKSDEVICE> Reference to KS Device Object
OUT PARAM : <NTSTATUS> ntStatus of the Adapter Stream Initialization
STATUS_SUCCESS in case of successful execution
Failure Code in other cases
PreCondition : None
PostCondtion : Adapter Object Registered with the AVStream and Streaming
Memory allocated
Logic : NONE
Assumption : NONE
Note : NONE
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
*****************************************************************************/
NTSTATUS CSkyWalker1Device::InitializeAdapterStream(
IN PKSDEVICE pKSDeviceObject)
{
NTSTATUS ntInitStatus = STATUS_SUCCESS;
DEVICE_DESCRIPTION DeviceDescription; //Object to hold the Device description
ULONG ulMaxDMAMapRegisters = 0L;
PrintFunctionEntry(__FUNCTION__);
//Create DMA adapter
memset(&DeviceDescription, 0, sizeof(DeviceDescription));
DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
DeviceDescription.Master = TRUE;
DeviceDescription.ScatterGather = TRUE;
DeviceDescription.Dma32BitAddresses = TRUE;
DeviceDescription.Dma64BitAddresses = FALSE;
DeviceDescription.DmaChannel = ((ULONG) ~0);
DeviceDescription.InterfaceType = PCIBus;
DeviceDescription.MaximumLength = 0xfffffff8;
//not used
DeviceDescription.IgnoreCount;
DeviceDescription.DemandMode;
DeviceDescription.AutoInitialize;
DeviceDescription.DmaWidth;
DeviceDescription.Reserved1;
DeviceDescription.DmaSpeed;
DeviceDescription.DmaPort;
//The IoGetDmaAdapter routine returns a pointer to the DMA adapter structure
//for a physical device object.
m_pDMAAdapter = IoGetDmaAdapter(
pKSDeviceObject->PhysicalDeviceObject, //Pointer to Physical Device Object
//requesting the DMA Adapter structure
&DeviceDescription, //Pointer to the Device Descriptor Structure which
//describes the attributes of the Structure
&ulMaxDMAMapRegisters); //Maximum Map registers that driver can allocate for
//Dma transfer
if(!IS_VALID(m_pDMAAdapter))
{
SkyWalkerDebugPrint(ENTRY_LEVEL,("Unable to get the Dma Adapter for the Device\n"));
ntInitStatus = STATUS_UNSUCCESSFUL;
goto ExitInitAdapter;
}
if(!IS_VALID(m_pDMAAdapter->DmaOperations))
{
SkyWalkerDebugPrint(ENTRY_LEVEL,("No Dma Operatios found for the DMA Adapter\n"));
ntInitStatus = STATUS_UNSUCCESSFUL;
goto ExitInitAdapter;
}
//Print the DMA Adapter details
PrintDMAAdapter(m_pDMAAdapter);
SkyWalkerDebugPrint(EXTREME_LEVEL,("Number of Map Registers = %lu\n",ulMaxDMAMapRegisters));
//Register the DMA Adapter with the AVStream
//The KsDeviceRegisterAdapterObject function registers a DMA adapter object with
//AVStream for performing scatter/gather DMA on the specified device.
KsDeviceRegisterAdapterObject(
pKSDeviceObject, //Device For which to register an adapter object
m_pDMAAdapter, //Pointer to DMA Adapter (IoGetDmaAdapter)
0xfffffff8, //Maximum number of bytes that device can handle for a single mapping
sizeof(KSMAPPING)); //Number of bytes each entry in the mapping table requires
//Allocate the Space for storing the Streaming contents
KeInitializeEvent (&m_HardwareEvent,SynchronizationEvent,FALSE);
RtlZeroMemory(pUsbStreamIrp,sizeof(pUsbStreamIrp));
ExitInitAdapter:
PrintFunctionExit(__FUNCTION__,ntInitStatus);
return ntInitStatus;
}
/*****************************************************************************
Function : CSkyWalker1Device::ReadStream
Description : This function is called when streaming data from the USb
is requested to read.This function is called when the streaming
is started and every time after Stream processing to read a
new Stream
IN PARAM : <ULONG> Index of the Stream to Read
OUT PARAM : <NTSTATUS> ntStatus of the Read Stream
STATUS_SUCCESS in case of successful execution
Failure Code in other cases
PreCondition : None
PostCondtion : Stream Read
Logic : NONE
Assumption : NONE
Note : NONE
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
*****************************************************************************/
NTSTATUS CSkyWalker1Device::ReadStream(IN ULONG ulStreamIndex)
{
NTSTATUS ntReadStreamStatus = STATUS_SUCCESS;
PUCHAR pStreamBuffer = NULL;
ULONG ulPacketCount = PACKET_PER_FRAME;
ULONG ulPacketSize = MAX_BULK_PACKET_SIZE ;
PrintFunctionEntry(__FUNCTION__);
//Get the Stream buffer related to the Current Stream index
pStreamBuffer = m_SynthesisBuffer[ulStreamIndex];
//Set the number of Bytes read
m_NumberOfBytesRead[ulStreamIndex] = 0;
//Send the Read request of the 4K Size Each
for(ULONG ulPacketIndex = 0; ulPacketIndex <= ulPacketCount-1 ; ulPacketIndex++)
{
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamBuffer[%03lu] = 0x%p",ulPacketIndex,pStreamBuffer));
SkyWalkerDebugPrint(EXTREME_LEVEL,("m_SampleSize = %lu",m_SampleSize));
if(IS_VALID(pStreamBuffer))
{
if(ulPacketIndex == 23)
{
ulPacketSize = 2048;
}
ntReadStreamStatus = ReadWriteUsbDevice( m_pKSDevice,
ulStreamIndex,
ulPacketIndex,
pStreamBuffer,
ulPacketSize ,
true
);
if(NT_SUCCESS(ntReadStreamStatus))
{
SkyWalkerDebugPrint(EXTREME_LEVEL, ("Sent the Stream Read Request\n"));
}
else
{
SkyWalkerDebugPrint(ENTRY_LEVEL, ("Failed to Send Stream Read from the Device"));
}
pStreamBuffer += ulPacketSize;
}
else
{
SkyWalkerDebugPrint(ENTRY_LEVEL,("Invalid Stream Aborting Stream Read\n"));
break;
}
}
PrintFunctionExit(__FUNCTION__,ntReadStreamStatus);
return ntReadStreamStatus;
}
/*****************************************************************************
Function : CSkyWalker1Device::GetStatus
Description : This function is used to Get the Current ntStatus of the
Tuner i.e. Current Carrier Freq. Signal Locked status etc.
IN PARAM : <PBDATUNER_DEVICE_STATUS> Device ntStatus
OUT PARAM : <NTSTATUS> STATUS_SUCCESS in case of successful execution
Failure Code in other cases
PreCondition : None
PostCondtion : Device ntStatus updated and returned
Logic : NONE
Assumption : NONE
Note : This is called from the PASSIVE_LEVEL_IRQL
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
*****************************************************************************/
NTSTATUS CSkyWalker1Device::GetStatus(OUT PBDATUNER_DEVICE_STATUS pDeviceStatus)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
pDeviceStatus->fCarrierPresent = FALSE;
pDeviceStatus->fSignalLocked = FALSE;
pDeviceStatus->dwSignalQuality = 0;
pDeviceStatus->dwSignalStrength = 0;
PrintFunctionEntry(__FUNCTION__);
if(m_HardwareState != HardwareRunning)
{
SkyWalkerDebugPrint(EXTREME_LEVEL,("Streaming is not started yet\n"));
ntStatus = STATUS_UNSUCCESSFUL;
goto ExitGetStatus;
}
if(TimeToReadSignalStatus())
{
//It's Time to read Signal Status
//Get the signal status from the HW here
ReadTunerSignalStrength(m_pKSDevice,
&m_TunerStatus.dwSignalStrength);
m_TunerStatus.dwSignalQuality = (m_TunerStatus.dwSignalStrength * 100)/65535;
GetSignalStatus(m_pKSDevice,
&m_TunerStatus.fSignalLocked);
if(m_TunerStatus.fSignalLocked)
{
m_TunerStatus.fCarrierPresent = TRUE;
}
}
*pDeviceStatus = m_TunerStatus;
#ifdef FAKE_SIGNAL
pDeviceStatus->dwSignalStrength = 2;
pDeviceStatus->dwSignalQuality = 99;
pDeviceStatus->fCarrierPresent = TRUE;
pDeviceStatus->fSignalLocked = TRUE;
#endif
ExitGetStatus :
PrintFunctionExit(__FUNCTION__,ntStatus);
return ntStatus;
}
/*****************************************************************************
Function : CSkyWalker1Device::TimeToReadSignalStatus
Description : This function is used Check whether time to read
the status from device has occurred or not
IN PARAM : NONE
OUT PARAM : <BOOLEAN> TRUE = Time to read status from Device,
FALSE otherwise
PreCondition : None
PostCondtion : Whether time to read from device has occurred or not
is checked
Logic : NONE
Assumption : NONE
Note : NONE
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
*****************************************************************************/
BOOLEAN CSkyWalker1Device::TimeToReadSignalStatus(void)
{
LARGE_INTEGER CurrentTime;
ULONG ulReadPeriod = 10 * 1000 * 1000;
KeQuerySystemTime (&CurrentTime);
//If Current time is greater than the last
if(m_TunerStatus.fSignalLocked == FALSE)
{
SkyWalkerDebugPrint(EXTREME_LEVEL,("Signal Not Locked Reading Status @ 100msec\n"));
ulReadPeriod = 10 * 1000 * 100;
}
if(CurrentTime.QuadPart - m_PreviousStatusReadTime.QuadPart >= ulReadPeriod)
{
m_PreviousStatusReadTime.QuadPart = CurrentTime.QuadPart;
SkyWalkerDebugPrint(EXTREME_LEVEL,("Time to read signal status\n"));
return TRUE;
}
return FALSE;
}
/*****************************************************************************
Function : CSkyWalker1Device::Acquire
Description : This function is used to set the Tuner parameters and
called once when the tuner resources are acquired
From this function various device related command are executed
to set the device parameters
IN PARAM : <PBDATUNER_DEVICE_PARAMETER> New Device Parameters to be set
<PULONG> Resource ID
OUT PARAM : <NTSTATUS> STATUS_SUCCESS in case of successful execution
Failure Code in other cases
PreCondition : None
PostCondtion : Device ntStatus updated and returned
Logic : NONE
Assumption : NONE
Note : This is called from the PASSIVE_LEVEL_IRQL
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
*****************************************************************************/
NTSTATUS CSkyWalker1Device::Acquire(
IN PBDATUNER_DEVICE_PARAMETER pNewResource,
OUT PULONG pulAcquiredResourceID
)
{
NTSTATUS ntAcquireStatus = STATUS_SUCCESS;
PrintFunctionEntry(__FUNCTION__);
//Continue only if the Device is acquired currently
if (!m_ulcResourceUsers)
{
m_CurResource = *pNewResource;
//Generate a new resource ID and hand it back.
m_ulCurResourceID += 25;
*pulAcquiredResourceID = m_ulCurResourceID;
m_ulcResourceUsers += 1;
//Configure the new resource on the hardware here.
//Send the Tune, SetLnbVoltage etc Commands from here
ConfigureTuner(m_pKSDevice,pNewResource);
}
else
{
//Only one active filter is allowed
ntAcquireStatus = STATUS_DEVICE_BUSY;
}
PrintFunctionExit(__FUNCTION__,ntAcquireStatus);
return ntAcquireStatus;
}
/*****************************************************************************
Function : CSkyWalker1Device::Update
Description : This function is used to set the Tuner parameters and
called everytime after the tuner resources are acquired
From this function various device related command are executed
to set the device parameters
IN PARAM : <PBDATUNER_DEVICE_PARAMETER> New Device Parameters to be set
<ULONG> Resource ID
OUT PARAM : <NTSTATUS> STATUS_SUCCESS in case of successful execution
Failure Code in other cases
PreCondition : None
PostCondtion : Device ntStatus updated and returned
Logic : NONE
Assumption : NONE
Note : This is called from the PASSIVE_LEVEL_IRQL
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
*****************************************************************************/
NTSTATUS CSkyWalker1Device::Update(
IN PBDATUNER_DEVICE_PARAMETER pNewResource,
IN ULONG ulResourceID
)
{
NTSTATUS ntUpdateStatus = STATUS_SUCCESS;
LONGLONG ulhzFrequency;
PrintFunctionEntry(__FUNCTION__);
//Continue only if the Device is acquired currently
if (m_ulcResourceUsers && (ulResourceID == m_ulCurResourceID))
{
m_CurResource = *pNewResource;
//Configure the new resource on the hardware here.
//Send the Tune, SetLnbVoltage etc Commands from here
ConfigureTuner(m_pKSDevice,pNewResource);
}
else
{
//Only one active filter is allowed
ntUpdateStatus = STATUS_INVALID_DEVICE_REQUEST;
}
PrintFunctionExit(__FUNCTION__,ntUpdateStatus);
return ntUpdateStatus;
}
/*****************************************************************************
Function : CSkyWalker1Device::SendDiseqcCommand
Description : This function is used to send the Diseqc Command to the Tuner
IN PARAM : <PDISEQC_COMMAND> Diseqc Command to be sent to the Tuner
<ULONG> Resource ID
OUT PARAM : <NTSTATUS> STATUS_SUCCESS in case of successful execution
Failure Code in other cases
PreCondition : None
PostCondtion : Diseqc Command sent to the Tuner
Logic : NONE
Assumption : NONE
Note : This is called from the PASSIVE_LEVEL_IRQL
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
*****************************************************************************/
NTSTATUS CSkyWalker1Device::SendDiseqcCommand(
IN PDISEQC_COMMAND pDiseqcCommand,
IN ULONG ulResourceID
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PrintFunctionEntry(__FUNCTION__);
//Continue only if the Device is acquired currently
//if (m_ulcResourceUsers && (ulResourceID == m_ulCurResourceID))
{
SkyWalkerDebugPrint(EXTREME_LEVEL,("m_ulcResourceUsers = %lu\n",m_ulcResourceUsers));
SkyWalkerDebugPrint(EXTREME_LEVEL,("ulResourceID = %lu\n",ulResourceID));
SkyWalkerDebugPrint(EXTREME_LEVEL,("m_ulCurResourceID = %lu\n",m_ulCurResourceID));
//Send the Diseqc Command to the Tuner device
DiseqcCommand(m_pKSDevice,pDiseqcCommand);
}
//else
//{
// //Only one active filter is allowed
// ntStatus = STATUS_INVALID_DEVICE_REQUEST;
// }
PrintFunctionExit(__FUNCTION__,ntStatus);
return ntStatus;
}
/*****************************************************************************
Function : CSkyWalker1Device::Release
Description : This function is used to decrement the Resource User count
to allow other filters to use the resources
IN PARAM : <ULONG> Resource ID
OUT PARAM : <NTSTATUS> STATUS_SUCCESS in case of successful execution
Failure Code in other cases
PreCondition : None
PostCondtion : Device ntStatus updated and returned
Logic : NONE
Assumption : NONE
Note : This is called from the PASSIVE_LEVEL_IRQL
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
*****************************************************************************/
NTSTATUS CSkyWalker1Device::Release(IN ULONG ulResourceID)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PrintFunctionEntry(__FUNCTION__);
if(m_ulcResourceUsers && (ulResourceID == m_ulCurResourceID))
{
//Free the resource to be used by another filter.
m_ulcResourceUsers--;
}
else
{
ntStatus = STATUS_INVALID_DEVICE_REQUEST;
}
PrintFunctionExit(__FUNCTION__,ntStatus);
return ntStatus;
}
/*****************************************************************************
Function : CSkyWalker1Device::StartStream
Description : This function is used to Initialize the Prestreaming
parameters and also it sends the Streaming command to
the Tuner
IN PARAM : NONE
OUT PARAM : <NTSTATUS> STATUS_SUCCESS in case of successful execution
Failure Code in other cases
PreCondition : None
PostCondtion : Streaming Started on successful execution
Logic : NONE
Assumption : NONE
Note : NONE
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
*****************************************************************************/
NTSTATUS CSkyWalker1Device::StartStream ()
{
NTSTATUS ntStreamStartStatus = STATUS_SUCCESS;
PrintFunctionEntry(__FUNCTION__);
//Initializing the Streaming Parameters
m_TimePerFrame = m_TransportInfo->AvgTimePerFrame;
m_SampleSize = m_TransportInfo->ulcbPhyiscalFrame;
m_PacketSize = m_TransportInfo->ulcbPhyiscalPacket;
m_PacketsPerSample = m_TransportInfo->ulcbPhyiscalFrame / m_TransportInfo->ulcbPhyiscalPacket;
m_TunerStatus.fCarrierPresent = FALSE;
m_TunerStatus.fSignalLocked = FALSE;
m_TunerStatus.dwSignalQuality = 0;
m_TunerStatus.dwSignalStrength = 0;
//Allocate a scratch buffer for the Streaming Buffer.
for(int nBufferIndex = 0 ;
nBufferIndex < SIZEOF_ARRAY(m_SynthesisBuffer);
nBufferIndex++)
{
m_SynthesisBuffer[nBufferIndex] = reinterpret_cast <PUCHAR> (
ExAllocatePoolWithTag (
NonPagedPool,
m_SampleSize,
CAPTURE_MEM_TAG
)
);
if (!IS_VALID(m_SynthesisBuffer))
{
SkyWalkerDebugPrint(ENTRY_LEVEL,("Insufficient Resource for Scatter/Gather DMA\n"));
ntStreamStartStatus = STATUS_INSUFFICIENT_RESOURCES;
goto ExitStreamStart;
}
}
//Send Device Streaming Start Control
SetStreamingControl(m_pKSDevice,1);
m_HardwareState = HardwareRunning;
ExitStreamStart:
PrintFunctionExit(__FUNCTION__,ntStreamStartStatus);
return ntStreamStartStatus;
}
/*****************************************************************************
Function : CSkyWalker1Device::PauseStream
Description : This function is used to Pause/Run the Streaming if On/Off.
IN PARAM : <BOOLEAN> True : Pause Streaming , False : Start Streaming
OUT PARAM : <NTSTATUS> STATUS_SUCCESS in case of successful execution
Failure Code in other cases
PreCondition : None
PostCondtion : Streaming Paused/Started on successful execution
Logic : NONE
Assumption : NONE
Note : NONE
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
*****************************************************************************/
NTSTATUS CSkyWalker1Device::PauseStream (BOOLEAN bPausing)
{
NTSTATUS ntStreamPauseStatus = STATUS_SUCCESS;
PrintFunctionEntry(__FUNCTION__);
//If Streaming is in Progress then Stop the Streaming by
//Stop sending read requests and Cancelling any on going IRP
if (bPausing && (m_HardwareState == HardwareRunning))
{
m_StopHardware = TRUE;
//Stop Streaming
SetStreamingControl(m_pKSDevice,0);
for(int ulPacketIndex = 0;
ulPacketIndex < SIZEOF_ARRAY(pUsbStreamIrp) ;
ulPacketIndex++)
{
if(pUsbStreamIrp[ulPacketIndex])
{
SkyWalkerDebugPrint(EXTREME_LEVEL,("Cancelling pUsbStreamIrp[%lu] = 0x%p\n",
ulPacketIndex,pUsbStreamIrp[ulPacketIndex]));
IoCancelIrp(pUsbStreamIrp[ulPacketIndex]);
pUsbStreamIrp[ulPacketIndex] = NULL;
KeWaitForSingleObject (
&m_HardwareEvent,
Suspended,
KernelMode,
FALSE,
NULL
);
KeResetEvent(&m_HardwareEvent);
m_StopHardware = TRUE;
}
}
m_HardwareState = HardwarePaused;
}
else if (!bPausing && (m_HardwareState == HardwarePaused) )
{
m_HardwareState = HardwareRunning;
//Start Streaming
SetStreamingControl(m_pKSDevice,1);
}
PrintFunctionExit(__FUNCTION__,ntStreamPauseStatus);
return ntStreamPauseStatus;
}
/*****************************************************************************
Function : CSkyWalker1Device::StopStream
Description : This function is used to Stop the Streaming if On.
IN PARAM : NONE
OUT PARAM : <NTSTATUS> STATUS_SUCCESS in case of successful execution
Failure Code in other cases
PreCondition : None
PostCondtion : Streaming Stopped on successful execution
Logic : NONE
Assumption : NONE
Note : NONE
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
*****************************************************************************/
NTSTATUS CSkyWalker1Device::StopStream ()
{
NTSTATUS ntStreamStopStatus = STATUS_SUCCESS;
PrintFunctionEntry(__FUNCTION__);
//Stop the Streaming in case it's already on
if (m_HardwareState == HardwareRunning)
{
m_StopHardware = TRUE;
//Stop Streaming
SetStreamingControl(m_pKSDevice,0);
SkyWalkerDebugPrint(EXTREME_LEVEL,("SIZEOF_ARRAY[pUsbStreamIrp] = %d\n",
SIZEOF_ARRAY(pUsbStreamIrp)));
for(int ulPacketIndex = 0;
ulPacketIndex < SIZEOF_ARRAY(pUsbStreamIrp) ;
ulPacketIndex++)
{
if(pUsbStreamIrp[ulPacketIndex])
{
SkyWalkerDebugPrint(EXTREME_LEVEL,("Cancelling pUsbStreamIrp[%lu] = 0x%p\n",
ulPacketIndex,pUsbStreamIrp[ulPacketIndex]));
IoCancelIrp(pUsbStreamIrp[ulPacketIndex]);
pUsbStreamIrp[ulPacketIndex] = NULL;
KeWaitForSingleObject (
&m_HardwareEvent,
Suspended,
KernelMode,
FALSE,
NULL
);
KeResetEvent(&m_HardwareEvent);
m_StopHardware = TRUE;
}
}
}
m_HardwareState = HardwareStopped;
for(int nBufferIndex = 0 ;
nBufferIndex < SIZEOF_ARRAY(m_SynthesisBuffer) ;
nBufferIndex++)
{
if (m_SynthesisBuffer[nBufferIndex])
{
SkyWalkerDebugPrint(EXTREME_LEVEL,("Freeing Streaming Buffer m_SynthesisBuffer[%lu] = 0x%p\n",
nBufferIndex,m_SynthesisBuffer[nBufferIndex]));
ExFreePool (m_SynthesisBuffer[nBufferIndex]);
m_SynthesisBuffer[nBufferIndex] = NULL;
}
}
PrintFunctionExit(__FUNCTION__,ntStreamStopStatus);
return ntStreamStopStatus;
}
/*****************************************************************************
Function : CSkyWalker1Device::ProcessStream
Description : This function is used to Process the Streaming Data after
reading it.This function is called from the USB Read Write
Completion routine
IN PARAM : <ULONG> Index of the Stream whose read completed
OUT PARAM : <NTSTATUS> STATUS_SUCCESS in case of successful execution
Failure Code in other cases
PreCondition : None
PostCondtion : Read Stream is processed and Streaming data is filled into the
used Buffer.
Logic : NONE
Assumption : NONE
Note : NONE
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
*****************************************************************************/
void CSkyWalker1Device::ProcessStream(ULONG ulStreamIndex)
{
PrintFunctionEntry(__FUNCTION__);
//The hardware can be in a pause state in which case, it issues interrupts
//but does not complete mappings. In this case, don't bother synthesizing
//a frame and doing the work of looking through the mappings table.
if (m_HardwareState == HardwareRunning)
{
SkyWalkerDebugPrint(EXTREME_LEVEL,("(%d * %d) = %lu\n", TRANSPORT_PACKET_SIZE,
TRANSPORT_PACKET_COUNT,
m_SampleSize));
SkyWalkerDebugPrint(EXTREME_LEVEL,("m_NumberOfBytesRead[%lu] = %lu\n",
ulStreamIndex,
m_NumberOfBytesRead[ulStreamIndex]));
if (InterlockedCompareExchange((LONG *)&m_NumberOfBytesRead[ulStreamIndex],
m_SampleSize, m_SampleSize) == m_SampleSize)
{
//Inform the capture sink
m_CaptureSink->ReleaseStream(ulStreamIndex);
}
}
if (m_StopHardware)
{
//If someone is waiting on the hardware to stop, raise the stop
//event and clear the flag.
SkyWalkerDebugPrint(EXTREME_LEVEL,("Sending the Stop Event\n"));
m_StopHardware = FALSE;
KeSetEvent (&m_HardwareEvent, IO_NO_INCREMENT, FALSE);
}
PrintFunctionExit(__FUNCTION__,STATUS_SUCCESS);
}
/*****************************************************************************
Function : CSkyWalker1Device::SetupCaptureSink
Description : Acquire hardware resources for the capture hardware.
If the resources are already acquired, this will return
an error.The hardware configuration must be passed as
a VideoInfoHeader.
IN PARAM : <CaptureSink> The capture sink attempting to acquire
resources. When scatter /gather mappings are completed,
the capture sink specified here is what is notified
of the completions.
<VideoInfoHeader> Information about the capture stream.
This **MUST** remain stable until the caller releases
hardware resources. Note that this could also be guaranteed
by bagging it in the device object bag as well.
OUT PARAM : <NTSTATUS> STATUS_SUCCESS in case of successful execution
Failure Code in other cases
PreCondition : None
PostCondtion : Capture Pin to the notified and Video Info Header set in case
of successful execution
Logic : NONE
Assumption : NONE
Note : NONE
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
*****************************************************************************/
NTSTATUS CSkyWalker1Device:: SetupCaptureSink(
IN ICaptureSink *CaptureSink,
IN PBDA_TRANSPORT_INFO TransportInfo
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PrintFunctionEntry(__FUNCTION__);
//If we're the first pin to go into acquire (remember we can have
//a filter in another graph going simultaneously), grab the resources.
if (InterlockedCompareExchange(&m_PinsWithResources,1,0) == 0)
{
m_TransportInfo = TransportInfo;
m_CaptureSink = CaptureSink;
}
else
{
ntStatus = STATUS_SHARING_VIOLATION;
}
PrintFunctionExit(__FUNCTION__,ntStatus);
return ntStatus;
}
/*****************************************************************************
Function : CSkyWalker1Device::RemoveCaptureSink
Description : Release hardware resources. This should only be called by
an object which has acquired them.
IN PARAM : NONE
OUT PARAM : NONE
PreCondition : None
PostCondtion : Video Info Header and Capture Sink info cleared
Logic : NONE
Assumption : NONE
Note : NONE
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
*****************************************************************************/
void CSkyWalker1Device::RemoveCaptureSink()
{
PrintFunctionEntry(__FUNCTION__);
m_TransportInfo = NULL;
m_CaptureSink = NULL;
//Release our "lock" on hardware resources. This will allow another
//pin (perhaps in another graph) to acquire them.
InterlockedExchange(&m_PinsWithResources,0);
PrintFunctionExit(__FUNCTION__,STATUS_SUCCESS);
}
void PrintDMAAdapter(PDMA_ADAPTER pDMAAdapter)
{
SkyWalkerDebugPrint(ENTRY_LEVEL,("pDMAAdapter->Version = %u\n",pDMAAdapter->Version));
SkyWalkerDebugPrint(ENTRY_LEVEL,("pDMAAdapter->Size = %u\n",pDMAAdapter->Size));
SkyWalkerDebugPrint(ENTRY_LEVEL,("pDMAAdapter->DmaOperations = 0x%p\n",pDMAAdapter->DmaOperations));
}
void PrintMappingInfo(IN PKSMAPPING pMapping)
{
SkyWalkerDebugPrint(ENTRY_LEVEL,("pMapping->PhysicalAddress = %llu\n",pMapping->PhysicalAddress.QuadPart));
SkyWalkerDebugPrint(ENTRY_LEVEL,("pMapping->ByteCount = %lu\n",pMapping->ByteCount));
SkyWalkerDebugPrint(ENTRY_LEVEL,("pMapping->Alignment = %lu\n",pMapping->Alignment));
}