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

📄 dcampkt.c

📁 winddk src目录下的WDM源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
//===========================================================================
//
// 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) 1996 - 2000  Microsoft Corporation.  All Rights Reserved.
//
//===========================================================================
/*++

Module Name:

    dcampkt.c

Abstract:

    Stream class based WDM driver for 1934 Desktop Camera.
    This file contains code to handle the stream class packets.

Author:
    
    Shaun Pierce 25-May-96

Modified:

    Yee J. Wu 15-Oct-97

Environment:

    Kernel mode only

Revision History:


--*/


#include "strmini.h"
#include "ksmedia.h"
#include "1394.h"
#include "wdm.h"       // for DbgBreakPoint() defined in dbg.h
#include "dbg.h"
#include "dcamdef.h"
#include "dcampkt.h"
#include "strmdata.h"  // stream format and data ranges; static data
#include "capprop.h"   // Video and camera property function prototype
#include "ntintsafe.h"

static
NTSTATUS
RTL_SAFE_KS_SIZE_VIDEOHEADER(const KS_VIDEOINFOHEADER* pvih, ULONG* pulSize)
{
    return RtlULongAdd(pvih->bmiHeader.biSize, KS_SIZE_PREHEADER, pulSize);
}

#define WAIT_FOR_SLOW_DEVICE


#ifdef ALLOC_PRAGMA
    #pragma alloc_text(PAGE, DCamProcessPnpIrp)
    #pragma alloc_text(PAGE, DCamGetStreamInfo)
    #pragma alloc_text(PAGE, DCamFreeIsochResource)    
    #pragma alloc_text(PAGE, InitializeStreamExtension)    
    #pragma alloc_text(PAGE, DCamOpenStream)   
    #pragma alloc_text(PAGE, DCamCloseStream)           
    #pragma alloc_text(PAGE, AdapterCompareGUIDsAndFormatSize)    
    #pragma alloc_text(PAGE, AdapterVerifyFormat)    
    #pragma alloc_text(PAGE, AdapterFormatFromRange)    
    #pragma alloc_text(PAGE, VideoGetProperty)    
    #pragma alloc_text(PAGE, VideoGetState)    
    #pragma alloc_text(PAGE, VideoStreamGetConnectionProperty)    
    #pragma alloc_text(PAGE, VideoStreamGetDroppedFramesProperty)    
    #pragma alloc_text(PAGE, VideoIndicateMasterClock)    
    #pragma alloc_text(PAGE, DCamReceivePacket)
    #pragma alloc_text(PAGE, DCamChangePower)
#endif

void 
tmGetStreamTime(
    IN PHW_STREAM_REQUEST_BLOCK Srb,
    PSTREAMEX pStrmEx, 
    ULONGLONG * ptmStream) 
/*++

Routine Description:

   Query the current time used to timestamp the frame or calculating the dropped frame.
   This is used in IsochCallback so must be paged in always.

Arguments:

    Srb - Pointer to Stream request block

Return Value:

    Nothing

--*/
{

    HW_TIME_CONTEXT TimeContext;

    TimeContext.HwDeviceExtension = (PVOID) Srb->HwDeviceExtension;
    TimeContext.HwStreamObject    = Srb->StreamObject;
    TimeContext.Function          = TIME_GET_STREAM_TIME;
    TimeContext.Time              = 0;
    TimeContext.SystemTime        = 0;

    StreamClassQueryMasterClockSync(
        pStrmEx->hMasterClock,
        &TimeContext);

    *ptmStream = TimeContext.Time;
}

BOOL
DCamAllocateIrbAndIrp(
    PIRB * ppIrb,
    PIRP * ppIrp,
    CCHAR StackSize
    )
{

    // Allocate Irb and Irp
    *ppIrb = ExAllocatePoolWithTag(NonPagedPool, sizeof(IRB), 'macd');
    if(!*ppIrb) {           
        return FALSE;
    }

    *ppIrp = IoAllocateIrp(StackSize, FALSE);
    if(!*ppIrp) {
        ExFreePool(*ppIrb);
        *ppIrb = NULL;
        return FALSE;
    }

    // Initialize IRB
    RtlZeroMemory(*ppIrb, sizeof(IRB));

    return TRUE;
}


BOOL
DCamAllocateIrbIrpAndContext(
    PDCAM_IO_CONTEXT * ppDCamIoContext,
    PIRB * ppIrb,
    PIRP * ppIrp,
    CCHAR StackSize
    )
{

    // Allocate DCamIoContext
    *ppDCamIoContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(DCAM_IO_CONTEXT), 'macd');
    if(!*ppDCamIoContext) {            
        return FALSE;
    }

    // Allocate Irb and Irp
    *ppIrb = ExAllocatePoolWithTag(NonPagedPool, sizeof(IRB), 'macd');
    if(!*ppIrb) {
        ExFreePool(*ppDCamIoContext);            
        *ppDCamIoContext = NULL;
        return FALSE;
    }

    *ppIrp = IoAllocateIrp(StackSize, FALSE);
    if(!*ppIrp) {
        ExFreePool(*ppDCamIoContext);
        *ppDCamIoContext = NULL;
        ExFreePool(*ppIrb);
        *ppIrb = NULL;
        return FALSE;
    }


    // Initialize this context
    RtlZeroMemory(*ppDCamIoContext, sizeof(DCAM_IO_CONTEXT));
    (*ppDCamIoContext)->dwSize      = sizeof(DCAM_IO_CONTEXT);
    (*ppDCamIoContext)->pIrb        = *ppIrb;

    // Initialize IRB
    RtlZeroMemory(*ppIrb, sizeof(IRB));

    return TRUE;
}

void
DCamFreeIrbIrpAndContext(
    PDCAM_IO_CONTEXT pDCamIoContext,
    PIRB pIrb,
    PIRP pIrp   
    )
{
    if(pIrp)
        IoFreeIrp(pIrp);
    if(pIrb)
        ExFreePool(pIrb);
    if(pDCamIoContext)
        ExFreePool(pDCamIoContext);
}


BOOL
DCamIsoEnable(
    PIRB pIrb,
    PDCAM_EXTENSION pDevExt,
    BOOL Enable  
    ) 
/*
    Start or start isoch transmission by setting the ISOEnable bit.
    TRUE: Start transmission; 
    FALSE: Stop transmission.
*/
{
    BOOL EnableVerify;
    DCamRegArea RegArea;
    NTSTATUS Status;
    LARGE_INTEGER stableTime;
    LONG lRetries = MAX_READ_REG_RETRIES;

    do {
        RegArea.AsULONG = (Enable ? START_ISOCH_TRANSMISSION : STOP_ISOCH_TRANSMISSION);
        Status = DCamWriteRegister(pIrb, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, IsoEnable), RegArea.AsULONG);
        EnableVerify = DCamDeviceInUse(pIrb, pDevExt);
        if(!NT_SUCCESS(Status) || EnableVerify != Enable) {
            ERROR_LOG(("\'DCAmIsoEnable: St:%x; Enable:%d vs EnableVerify:%d\n", Status, Enable, EnableVerify));
            if(lRetries >= 1) {
                stableTime.LowPart = DCAM_REG_STABLE_DELAY;
                stableTime.HighPart = -1;
                KeDelayExecutionThread(KernelMode, TRUE, &stableTime);
                ERROR_LOG(("\'DCamIsoEnable: delayed and try again...\n"))
            }
        }
    } while (--lRetries > 0 && (!NT_SUCCESS(Status) || (EnableVerify != Enable)) );

    return (EnableVerify == Enable);
}

void
DCamProcessPnpIrp(
    IN PHW_STREAM_REQUEST_BLOCK Srb,
    PIO_STACK_LOCATION IrpStack,
    PDCAM_EXTENSION pDevExt
    )

/*++

Routine Description:

    Process PnP Irp. 

Arguments:

    Srb - Pointer to Stream request block

Return Value:

    Nothing

--*/
{
    PSTREAMEX pStrmEx;

    PAGED_CODE();

    switch (IrpStack->MinorFunction) {

    case IRP_MN_QUERY_POWER:
        pStrmEx = (PSTREAMEX) pDevExt->pStrmEx;
        ERROR_LOG(("IRP_MN_QUERY_POWER: pStrmEx:%x\n", pStrmEx));
        if(!pStrmEx) {
            Srb->Status = STATUS_SUCCESS;
            break;
        }

        if(pStrmEx->KSState == KSSTATE_PAUSE || pStrmEx->KSState == KSSTATE_RUN) {
            ERROR_LOG(("Does not support hibernation while streaming!\n"));
            Srb->Status = STATUS_NOT_SUPPORTED;
        } else {
            ERROR_LOG(("OK to hibernation if not streaming\n"));
            Srb->Status = STATUS_SUCCESS;
        }
        break;
        
    case IRP_MN_QUERY_CAPABILITIES: 
        ERROR_LOG(("\'SonyDCamProcessPnpIrp: IRP_MN_QUERY_CAPABILITIES: Srb->Status = STATUS_NOT_IMPLEMENTED.\n"));
        // Purposely pass thru
    case IRP_MN_BUS_RESET: // no longer use; instead, Use bus reset callback to reclaim isoch resource.
    default:
        Srb->Status = STATUS_NOT_IMPLEMENTED;
        break;
    }
}


VOID 
DCamChangePower(
    IN PHW_STREAM_REQUEST_BLOCK pSrb
)

/*++

Routine Description:

    Process chnaging this device's power state.  

Arguments:

    Srb - Pointer to Stream request block

Return Value:

    Nothing

--*/
{
    PDCAM_EXTENSION pDevExt;
    PSTREAMEX pStrmEx;
    PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(pSrb->Irp);
    DEVICE_POWER_STATE DevicePowerState = pSrb->CommandData.DeviceState;

    PAGED_CODE();

    pDevExt = (PDCAM_EXTENSION) pSrb->HwDeviceExtension;
    DbgMsg2(("\'DCamChangePower: pSrb=%x; pDevExt=%x\n", pSrb, pDevExt));

    ASSERT(pDevExt != NULL);
    if(!pDevExt) {   
        pSrb->Status = STATUS_INVALID_PARAMETER;
        ERROR_LOG(("DCamChangePower: pDevExt is NULL!\n"));
        return;
    }

    pStrmEx = (PSTREAMEX) pDevExt->pStrmEx;     
    if (pStrmEx ==NULL) {        
        pSrb->Status = STATUS_SUCCESS;
        pDevExt->CurrentPowerState = DevicePowerState;
        DbgMsg2(("DCamChangePower: pStrmEx is NULL => Stream is not open. That is Ok!!\n"));
        return;
    }

   


    // 
    // We can honor power state change:
    //
    //    D0: device is on and running
    //    D1,D2: not implemented.
    //    D3: device is off and not running.  Device context is lost.  
    //        Power can be removed from the device.
    //        when power is back on, we will get a bus reset.
    //
    //    (0) Remove DontSuspendIfStreamsAreRunning from INF
    //    save current state.
    //    (1) ->D3, to PAUSE/STOP state (depends on if pending buffers can be kept by its lower driver)
    //    (2) ->D0, to restore saved state
    //
    // We can do the above but we do not know at this point 
    // how our client application react
    //
    if(IrpStack->MinorFunction == IRP_MN_SET_POWER) {
        DbgMsg2(("DCamChangePower: changin power state from %d to %d.\n", pDevExt->CurrentPowerState, DevicePowerState));

        pSrb->Status = STATUS_SUCCESS;

        if(pDevExt->CurrentPowerState != DevicePowerState) {

            switch (DevicePowerState) {
            case PowerDeviceD3:        // D0->D3: save state, stop streaming and Sleep
                if( pDevExt->CurrentPowerState == PowerDeviceD0 ) {
                    DbgMsg1(("DCamChangePower: Switching from D0 to D3; Save current state.\n"));
                    // Save current state to be restored when awake
                    pStrmEx->KSSavedState = pStrmEx->KSState;
                }
                break;

            case PowerDeviceD0:  // to Wakeup, restore state and running
                if( pDevExt->CurrentPowerState == PowerDeviceD3 ) {
                    DbgMsg1(("DCamChangePower: Switching from D3 to D0; restore state.\n"));
                    pStrmEx->KSState = pStrmEx->KSSavedState;                         
                }
                break;

            // These state are not defined and noe used.
            case PowerDeviceD1:
            case PowerDeviceD2:               
            default:
                ERROR_LOG(("DCamChangePower: Invalid PowerState %d\n", DevicePowerState));                  
                pSrb->Status = STATUS_INVALID_PARAMETER;
                break;
            }
        }            

        if(pSrb->Status == STATUS_SUCCESS) 
            pDevExt->CurrentPowerState = DevicePowerState;         

    } else {
       
        pSrb->Status = STATUS_NOT_IMPLEMENTED;

    }


}




VOID
DCamGetStreamInfo(
    IN PHW_STREAM_REQUEST_BLOCK Srb
    )

/*++

⌨️ 快捷键说明

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