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

📄 atitvsnd.cpp

📁 winddk src目录下的WDM源码压缩!
💻 CPP
字号:
//==========================================================================;
//
//  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.
//
//  Copyright (c) 1992 - 1996  Microsoft Corporation.  All Rights Reserved.
//
//  ATITVSnd.CPP
//  WDM TV Audio MiniDriver. 
//      AllInWonder/AllInWonderPro development platform. 
//          Main Source Module.
//
//      $Date:   01 Apr 1998 13:29:14  $
//  $Revision:   1.1  $
//    $Author:   KLEBANOV  $
//
//==========================================================================;

extern "C"
{
#include "strmini.h"
#include "ksmedia.h"

#include "wdmdebug.h"
}

#include "atitvsnd.h"
#include "wdmdrv.h"



/*^^*
 *      DriverEntry()
 * Purpose  : Called when an SRB_INITIALIZE_DEVICE request is received
 *
 * Inputs   : PVOID Arg1, PVOID Arg2
 *
 * Outputs  : result of StreamClassregisterAdapter()
 * Author   : IKLEBANOV
 *^^*/
extern "C" 
ULONG DriverEntry ( IN PDRIVER_OBJECT   pDriverObject,
                    IN PUNICODE_STRING  pRegistryPath )
{
    HW_INITIALIZATION_DATA HwInitData;

    SetMiniDriverDebugLevel( pRegistryPath);

    OutputDebugTrace(( "ATITVSnd: DriverEntry\n"));
     
    RtlZeroMemory( &HwInitData, sizeof( HwInitData));

    HwInitData.HwInitializationDataSize = sizeof(HwInitData);

    // Entry points for Port Driver

    HwInitData.HwInterrupt                  = NULL; // HwInterrupt;

    HwInitData.HwReceivePacket              = TVAudioReceivePacket;
    HwInitData.HwCancelPacket               = TVAudioCancelPacket;
    HwInitData.HwRequestTimeoutHandler      = TVAudioTimeoutPacket;

    HwInitData.DeviceExtensionSize          = sizeof( ADAPTER_DATA_EXTENSION);
    HwInitData.PerRequestExtensionSize      = sizeof( SRB_DATA_EXTENSION); 
    HwInitData.FilterInstanceExtensionSize  = 0;
    HwInitData.PerStreamExtensionSize       = 0;
    HwInitData.BusMasterDMA                 = FALSE;  
    HwInitData.Dma24BitAddresses            = FALSE;
    HwInitData.BufferAlignment              = 3;
//  HwInitData.TurnOffSynchronization       = FALSE;
    // we turn the synchronization ON. StreamClass is expected to call the MiniDriver
    // at passive level only
    HwInitData.TurnOffSynchronization       = TRUE;
    HwInitData.DmaBufferSize                = 0;

    OutputDebugTrace(( "ATITVSnd: StreamClassRegisterAdapter\n"));

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



/*^^*
 *      TVAudioReceivePacket()
 * Purpose  : Main entry point for receiving adapter based request SRBs from the Class Driver.
 *              Will always be called at passive level, because the drivers
 *              turned the synchronization ON.
 * Note     : This is an asyncronous entry point. The request only completes when a 
 *              StreamClassDeviceNotification on this SRB, of type  DeviceRequestComplete,
 *              is issued. As soon we're running at passive level, we can do everything 
 *              synchronously during the response to the SRBs with no worry
 *              to block somebody else for a long timer during I2C access
 *
 * Inputs   : PHW_STREAM_REQUEST_BLOCK pSrb : pointer to the current Srb
 *
 * Outputs  : none
 * Author   : IKLEBANOV
 *^^*/
extern "C" 
void STREAMAPI TVAudioReceivePacket( IN OUT PHW_STREAM_REQUEST_BLOCK pSrb)
{
    CWDMTVAudio *           pCTVAudio;
    KIRQL                   irqlCurrent;
    PADAPTER_DATA_EXTENSION pPrivateData = ( PADAPTER_DATA_EXTENSION)( pSrb->HwDeviceExtension);
    PSRB_DATA_EXTENSION     pSrbPrivate = ( PSRB_DATA_EXTENSION)( pSrb->SRBExtension);

    // check the device extension pointer
    if(( pPrivateData == NULL) || ( pSrbPrivate == NULL))
    {
        TRAP;
        pSrb->Status = STATUS_INVALID_PARAMETER;
        StreamClassDeviceNotification( DeviceRequestComplete, pSrb->HwDeviceExtension, pSrb);
    }

    OutputDebugInfo(( "ATITVSnd: TVAudioReceivePacket() SRB = %x\n", pSrb));

    if( pSrb->Command == SRB_INITIALIZE_DEVICE)
    {
        // this is the special case for SRB_INITIALIZE_DEVICE, because
        // no Queue has been initialized yet. Everything we need later on
        // is initialized during this SRB response
        TVAudioAdapterInitialize( pSrb);

        StreamClassDeviceNotification( DeviceRequestComplete, pSrb->HwDeviceExtension, pSrb);
        return;
    }

    // the rest of the SRBs are coming after SpinLock and SRBQueue have been initialized
    // during DRB_INITIALIZE_DEVICE SRB response.
    // I'll insert the SRB in the Queue first of all. The processing SRB from the Queue
    // can be triggered by finishing processing and SRB, or by the fact there is no SRB
    // is in process down here
    pSrbPrivate->pSrb = pSrb;

    // Everything we're doing with the Queue has to be protected from being interrupted
    KeAcquireSpinLock( &pPrivateData->adapterSpinLock, &irqlCurrent);
    InsertTailList( &pPrivateData->adapterSrbQueueHead, &pSrbPrivate->srbListEntry);

    if( pPrivateData->bSrbInProcess)
    {
        // there is another SRB being processed, and the new one will be picked up from
        // the Queue when it's its turn.
        KeReleaseSpinLock( &pPrivateData->adapterSpinLock, irqlCurrent);
        return;
    }

    while( !IsListEmpty( &pPrivateData->adapterSrbQueueHead))
    {
        // turn on the semaphore for the others coming after
        pPrivateData->bSrbInProcess = TRUE;

        // be carefull here, if you've changed the place where srbListEntry is defined
        // within the SRB_DATA_EXTENSION structure
        pSrbPrivate = ( PSRB_DATA_EXTENSION)RemoveHeadList( &pPrivateData->adapterSrbQueueHead);
        KeReleaseSpinLock( &pPrivateData->adapterSpinLock, irqlCurrent);

        // here is the place to process the SRB we have retrieved from the Queue
        pSrb = pSrbPrivate->pSrb;
        pPrivateData = ( PADAPTER_DATA_EXTENSION)( pSrb->HwDeviceExtension);
        pCTVAudio = &pPrivateData->CTVAudio;

        ASSERT( pSrb->Status != STATUS_CANCELLED);

        switch( pSrb->Command)
        {
            case SRB_INITIALIZATION_COMPLETE:
                // StreamClass has completed the initialization
                pSrb->Status = pCTVAudio->AdapterCompleteInitialization( pSrb);
                break;

            case SRB_UNINITIALIZE_DEVICE:
                // close the device.  
                pCTVAudio->AdapterUnInitialize( pSrb);
                break;

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

            case SRB_GET_STREAM_INFO:
                // return a block describing STREAM_INFO_HEADER and all the streams supported
                pCTVAudio->AdapterGetStreamInfo( pSrb);
                break;

            case SRB_CHANGE_POWER_STATE:
                pSrb->Status = pCTVAudio->AdapterSetPowerState( pSrb);
                break;

            case SRB_GET_DEVICE_PROPERTY:
                if( pCTVAudio->AdapterGetProperty( pSrb))
                    pSrb->Status = STATUS_SUCCESS;
                else
                    pSrb->Status = STATUS_INVALID_PARAMETER;
                break;        

            case SRB_SET_DEVICE_PROPERTY:
                if( pCTVAudio->AdapterSetProperty( pSrb))
                    pSrb->Status = STATUS_SUCCESS;
                else
                    pSrb->Status = STATUS_INVALID_PARAMETER;
                break;

            // We should never get the following since this is a single instance device
            case SRB_OPEN_DEVICE_INSTANCE:
            case SRB_CLOSE_DEVICE_INSTANCE:
                TRAP
                pSrb->Status = STATUS_NOT_IMPLEMENTED;
                break;

            case SRB_UNKNOWN_DEVICE_COMMAND:
                // we know we're getting some of these. Why should we?
                pSrb->Status = STATUS_NOT_IMPLEMENTED;
                break;

            default:
                // TRAP
                // this is a request that we do not understand.  Indicate invalid command and complete the request
                pSrb->Status = STATUS_NOT_IMPLEMENTED;
        }

        StreamClassDeviceNotification( DeviceRequestComplete, pPrivateData, pSrb);

        KeAcquireSpinLock( &pPrivateData->adapterSpinLock, &irqlCurrent);
    }

    // turn off the semaphore to enable the others coming after
    pPrivateData->bSrbInProcess = FALSE;

    KeReleaseSpinLock( &pPrivateData->adapterSpinLock, irqlCurrent);
    // there is no other SRB being processed at this time, let's start processing

}


extern "C" 
void STREAMAPI TVAudioCancelPacket( IN OUT PHW_STREAM_REQUEST_BLOCK pSrb)
{

    pSrb->Status = STATUS_CANCELLED;
}


extern "C" 
void STREAMAPI TVAudioTimeoutPacket( IN OUT PHW_STREAM_REQUEST_BLOCK pSrb)
{

    // not sure what to do here.
}


/*^^*
 *      TVAudioAdapterInitialize()
 * Purpose  : Called when SRB_INITIALIZE_DEVICE SRB is received.
 *              Performs checking of the hardware presence and I2C provider availability.
 *              Sets the hardware in an initial state.
 * Note     : The request does not completed unless we know everything
 *              about the hardware and we are sure it is capable to work in the current configuration.
 *              The hardware Caps are also aquised at this point. As soon this
 *              function is called at passive level, do everything synchronously
 *
 * Inputs   : PHW_STREAM_REQUEST_BLOCK pSrb : pointer to the current Srb
 *
 * Outputs  : none
 * Author   : IKLEBANOV
 *^^*/
void TVAudioAdapterInitialize( IN OUT PHW_STREAM_REQUEST_BLOCK pSrb)
{
    PPORT_CONFIGURATION_INFORMATION pConfigInfo = pSrb->CommandData.ConfigInfo;
    PADAPTER_DATA_EXTENSION pPrivateData = ( PADAPTER_DATA_EXTENSION)( pConfigInfo->HwDeviceExtension);
    NTSTATUS        ntStatus = STATUS_NO_SUCH_DEVICE;
    CWDMTVAudio *   pCTVAudio;
    CI2CScript *    pCScript = NULL;
    UINT            nErrorCode;

    OutputDebugTrace(( "ATITVSnd: TVAudioAdapterInitialize()\n"));

    ENSURE
    {
        if( pConfigInfo->NumberOfAccessRanges != 0) 
        {
            OutputDebugError(( "ATITVSnd: illegal NumberOfAccessRanges = %lx\n", pConfigInfo->NumberOfAccessRanges));
            FAIL;
        }

        // if we have I2CProvider implemented inside the MiniVDD, we have to
        // get a pointer to I2CInterface from the Provider.

        // There is an overloaded operator new provided for the CI2CScript Class.
        pCScript = ( CI2CScript *)new(( PVOID)&pPrivateData->CScript)
                        CI2CScript( pConfigInfo, &nErrorCode);
        if( nErrorCode != WDMMINI_NOERROR)
        {
            OutputDebugError(( "ATITVSnd: CI2CScript creation failure = %lx\n", nErrorCode));
            FAIL;
        }
        
        // The CI2CScript object was created successfully.
        // We'll try to allocate I2CProvider here for future possible I2C
        // operations needed at Initialization time.
        if( !pCScript->LockI2CProviderEx())
        {
            OutputDebugError(( "ATITVSnd: unable to lock I2CProvider"));
            FAIL;
        }

        // we did lock the provider.
        // There is an overloaded operator new provided for the CWDMTVAudio Class.
        pCTVAudio = ( CWDMTVAudio *)new(( PVOID)&pPrivateData->CTVAudio) CWDMTVAudio( pConfigInfo, pCScript, &nErrorCode);
        if( nErrorCode)
        {
            OutputDebugError(( "ATITVSnd: CWDMTVAudio constructor failure = %lx\n", nErrorCode));
            FAIL;
        }

        InitializeListHead ( &pPrivateData->adapterSrbQueueHead);
        KeInitializeSpinLock ( &pPrivateData->adapterSpinLock);

        pPrivateData->PhysicalDeviceObject = pConfigInfo->RealPhysicalDeviceObject;
        // no streams are supported
        pConfigInfo->StreamDescriptorSize = sizeof( HW_STREAM_HEADER);

        OutputDebugTrace(( "TVAudioAdapterInitialize(): exit\n"));

        ntStatus = STATUS_SUCCESS;

    } END_ENSURE;

    if (pCScript)
        pCScript->ReleaseI2CProvider();

    pSrb->Status = ntStatus;
    return;
}




⌨️ 快捷键说明

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