⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tuner.cpp

📁 windows 底层驱动
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*+++ *******************************************************************\
*
*   Copyright and Disclaimer:
*
*       ---------------------------------------------------------------
*       This software 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.
*
*       Copyright (c) 1999-2000 Conexant Systems, Inc.
*       All Rights Reserved.
*       ---------------------------------------------------------------
*
*   Abstract:
*
*       This module is responsible for handling tuner driver SRBs.
*
\******************************************************************* ---*/


#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif

#define INITGUID

#include "tuner.h"
#include "prop.h"
#include "debug.h"
#include "drv2user.h"
#include "drv2002.h"


LONG gDebugLevel   = 0;
BOOL gBreakOnError = TRUE;

// tuner pin guid definitions
KSPIN_MEDIUM TVTunerMediums[ 2 ] = {
        { M_GUID0, 0, 0},  // Pin 0
        { M_GUID1, 0, 0},  // Pin 1
    };

// tuner pin directions
BOOL TVTunerPinDirection[ 2 ] = {
        TRUE,                       // Output Pin 0
        TRUE,                       // Output Pin 1
    };



/*++ ********************************************************************\
*
*   Function:
*
*       ULONG GetSystemTime( )
*
*   Purpose:
*
*       Return the system tick time.
*
*   Return:
*       ULONG - system tick time.
*
*   History:
*
*
\******************************************************************** --*/
ULONG GetSystemTime()
{
    ULONGLONG ticks;
    ULONGLONG rate;

    ticks = (ULONGLONG)KeQueryPerformanceCounter((PLARGE_INTEGER)&rate).
            QuadPart;

    //
    // convert from ticks to 100ns clock
    //
    ticks = (ticks & 0xFFFFFFFF00000000) / rate * 10000000 + (ticks &
            0xFFFFFFFF) * 10000000 / rate;

    return (ULONG)(ticks);
}

/*++ ********************************************************************\
*
*   Function:
*
*       ULONG DriverEntry( PDRIVER_OBJECT pPDO,
*                          PUNICODE_STRING pRegistryPath )
*
*   Purpose:
*
*       Initializes the driver, and creates objects needed
*       to process I/O
*
*   Return:
*       Return value from:
*       StreamClassRegisterAdapter
*
*   History:
*
*
\******************************************************************** --*/
ULONG DriverEntry( PDRIVER_OBJECT pPDO, PUNICODE_STRING pRegistryPath )
{
    HW_INITIALIZATION_DATA HwInitData;

    RtlZeroMemory( &HwInitData, sizeof(HwInitData) );

    HwInitData.HwInitializationDataSize     = sizeof(HwInitData);
    HwInitData.HwInterrupt                  = NULL;
    HwInitData.HwReceivePacket              = TunerReceivePacket;
    HwInitData.HwCancelPacket               = TunerCancelPacket;
    HwInitData.HwRequestTimeoutHandler      = TunerTimeoutPacket;
    HwInitData.DeviceExtensionSize          = sizeof(TUNER_DATA_EXTENSION);
    HwInitData.PerRequestExtensionSize      = sizeof(SRB_DATA_EXTENSION);
    HwInitData.FilterInstanceExtensionSize  = 4;
    HwInitData.PerStreamExtensionSize       = 0;
    HwInitData.BusMasterDMA                 = FALSE;
    HwInitData.Dma24BitAddresses            = FALSE;
    HwInitData.BufferAlignment              = 4;
    HwInitData.TurnOffSynchronization       = TRUE;
    HwInitData.DmaBufferSize                = 0;

    return( StreamClassRegisterAdapter( pPDO, pRegistryPath, &HwInitData ) );
}

/*++ ********************************************************************\
*
*   Function:
*
*       void TunerCompleteDeviceSrb( PHW_STREAM_REQUEST_BLOCK pSrb )
*
*   Purpose:
*
*       Notify the stream class that we completed the SRB
*
*   Return:
*       none
*
*   History:
*
*
\******************************************************************** --*/
void TunerCompleteDeviceSrb( PHW_STREAM_REQUEST_BLOCK pSrb )
{
    StreamClassDeviceNotification( DeviceRequestComplete, pSrb->HwDeviceExtension, pSrb );
}

/*++ ********************************************************************\
*
*   AddToListIfBusy ( PHW_STREAM_REQUEST_BLOCK pSrb,
*                     KSPIN_LOCK *SpinLock,
*                     BOOL *BusyFlag,
*                     LIST_ENTRY *ListHead )
*
*   Purpose:
*
*       Grabs a spinlock, checks the busy flag, and if set adds an SRB to a queue
*
*   Returns:
*
*       The state of the busy flag on entry.  This will be TRUE if we're already
*       processing an SRB, and FALSE if no SRB is already in progress.
*
*   History:
*
*
\******************************************************************** --*/
BOOL STREAMAPI AddToListIfBusy ( IN PHW_STREAM_REQUEST_BLOCK pSrb,
                                 IN KSPIN_LOCK *SpinLock,
                                 IN OUT BOOL *BusyFlag,
                                 IN LIST_ENTRY *ListHead )
{
    KIRQL                       Irql;
    PSRB_EXTENSION              pSrbExt = (PSRB_EXTENSION)pSrb->SRBExtension;

    KeAcquireSpinLock (SpinLock, &Irql);

    // If we're already processing another SRB, add this current request
    // to the queue and return TRUE

    if (*BusyFlag == TRUE)
    {
        // Save the SRB pointer away in the SRB Extension
        pSrbExt->pSrb = pSrb;
        InsertTailList(ListHead, &pSrbExt->ListEntry);
        KeReleaseSpinLock(SpinLock, Irql);
        return TRUE;
    }

    // Otherwise, set the busy flag, release the spinlock, and return FALSE

    *BusyFlag = TRUE;
    KeReleaseSpinLock(SpinLock, Irql);

    return FALSE;
}

/*++ ********************************************************************\
*
*   RemoveFromListIfAvailable ( PHW_STREAM_REQUEST_BLOCK *pSrb,
*                               KSPIN_LOCK *SpinLock,
*                               BOOL *BusyFlag,
*                               LIST_ENTRY *ListHead )
*
*   Purpose:
*
*       Grabs a spinlock, checks for an available SRB, and removes it from the list
*
*   Return:
*
*       TRUE  - if an SRB was removed from the list
*       FALSE - if the list is empty
*
*   History:
*
*
\******************************************************************** --*/
BOOL STREAMAPI RemoveFromListIfAvailable ( IN OUT PHW_STREAM_REQUEST_BLOCK *pSrb,
                                           IN KSPIN_LOCK *SpinLock,
                                           IN OUT BOOL *BusyFlag,
                                           IN LIST_ENTRY *ListHead )
{
    KIRQL Irql;

    KeAcquireSpinLock (SpinLock, &Irql);

    // If the queue is now empty, clear the busy flag, and return

    if (IsListEmpty(ListHead))
    {
        *BusyFlag = FALSE;
        KeReleaseSpinLock(SpinLock, Irql);

        return FALSE;
    }

    // otherwise extract the SRB

    else
    {
        PUCHAR          ptr;
        PSRB_EXTENSION  pSrbExt;

        ptr = (PUCHAR)RemoveHeadList(ListHead);
        *BusyFlag = TRUE;
        KeReleaseSpinLock(SpinLock, Irql);
        // Get the SRB out of the SRB extension and return it
        pSrbExt = (PSRB_EXTENSION) (((PUCHAR) ptr) -
                     FIELDOFFSET(SRB_EXTENSION, ListEntry));
        *pSrb = pSrbExt->pSrb;
    }

    return TRUE;
}

/*++ ********************************************************************\
*
*   Function:
*
*       void TunerReceivePacket( PHW_STREAM_REQUEST_BLOCK pSrb )
*
*   Purpose:
*
*       Main function for handling all SRBs received by driver
*
*   Return:
*
*       none
*
*   History:
*
*
\******************************************************************** --*/
void STREAMAPI TunerReceivePacket( PHW_STREAM_REQUEST_BLOCK pSrb)
{
    BOOL Busy;
    PTUNER_DATA_EXTENSION pTunerDataExt = (PTUNER_DATA_EXTENSION)pSrb->HwDeviceExtension;

    if( ( pTunerDataExt == NULL ) || ( pSrb->SRBExtension == NULL ) )
    {
        KdBreakPoint();
        pSrb->Status = STATUS_INVALID_PARAMETER;
        TunerCompleteDeviceSrb( pSrb );
    }

    // The very first time through, we need to initialize the adapter spinlock
    // and queue
    if (!pTunerDataExt->bAdapterQueueInitialized)
    {
        InitializeListHead (&pTunerDataExt->leSrbQueueHead);
        KeInitializeSpinLock (&pTunerDataExt->ksSpinLock);
        pTunerDataExt->bAdapterQueueInitialized = TRUE;
        pTunerDataExt->bProcessingAdapterSRB = FALSE;
    }

    // If we're already processing an SRB, add it to the queue

    Busy = AddToListIfBusy (
                    pSrb,
                    &pTunerDataExt->ksSpinLock,
                    &pTunerDataExt->bProcessingAdapterSRB,
                    &pTunerDataExt->leSrbQueueHead );
    if (Busy)
    {
        return; // queue is not empty
    }

    // This will run until the SRB queue is empty

    while (TRUE)
    {
        // Assume success for now

        pSrb->Status = STATUS_SUCCESS;

        // process SRB
        switch (pSrb->Command)
        {
            case SRB_INITIALIZE_DEVICE:
                TunerInitialize( pSrb );
                break;

            case SRB_INITIALIZATION_COMPLETE:
                TunerCompleteInitialization( pSrb );
                break;

            case SRB_UNINITIALIZE_DEVICE:
                TunerUnInitialize( pSrb );
                break;

            case SRB_OPEN_STREAM:
                pSrb->Status = STATUS_NOT_IMPLEMENTED;
                break;

            case SRB_CLOSE_STREAM:
                pSrb->Status = STATUS_NOT_IMPLEMENTED;
                break;

            case SRB_GET_STREAM_INFO:
                TunerGetStreamInfo( pSrb );
                break;

            case SRB_CHANGE_POWER_STATE:
                pSrb->Status = TunerSetPowerState( pSrb );
                pSrb->Status = STATUS_SUCCESS;
                break;

            case SRB_GET_DEVICE_PROPERTY:
                AdapterGetProperty( pSrb );
                break;

            case SRB_SET_DEVICE_PROPERTY:
                AdapterSetProperty( pSrb );
                break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -