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

📄 sonydcam.c

📁 1394 摄像头驱动程序源代码,学习驱动程序的人可以看看
💻 C
📖 第 1 页 / 共 2 页
字号:
//===========================================================================
//
// 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:

    sonydcam.c

Abstract:

    Stream class based WDM driver for 1934 Desktop Camera.
    This driver fits under the WDM stream class.

Environment:

    Kernel mode only

Revision History:


--*/

#include "strmini.h"
#include "1394.h"
#include "dbg.h"
#include "ksmedia.h"
#include "dcamdef.h"
#include "sonydcam.h"
#include "dcampkt.h"
#include "capprop.h"   // Video and camera property function prototype


CHAR szUnknownVendorName[] = "UnknownVendor";


#ifdef ALLOC_PRAGMA
    //#pragma alloc_text(INIT, DriverEntry)
    #pragma alloc_text(PAGE, DCamHwUnInitialize)
    #pragma alloc_text(PAGE, InitializeDeviceExtension)
    #pragma alloc_text(PAGE, DCamHwInitialize)
#endif


NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )

/*++

Routine Description:

    This where life begins for a driver.  The stream class takes care
    of alot of stuff for us, but we still need to fill in an initialization
    structure for the stream class and call it.

Arguments:

    DriverObject - Pointer to the driver object created by the system.
    RegistryPath - unused.

Return Value:

    The function value is the final status from the initialization operation.

--*/

{

    HW_INITIALIZATION_DATA HwInitData;
    
    PAGED_CODE();
    DbgMsg1(("SonyDCam DriverEntry: DriverObject=%x; RegistryPath=%x\n",
        DriverObject, RegistryPath));

    ERROR_LOG(("<<<<<<< Sonydcam.sys: %s; %s; %x %x >>>>>>>>\n", 
        __DATE__, __TIME__, DriverObject, RegistryPath));

    //
    // Fill in the HwInitData structure
    //
    RtlZeroMemory( &HwInitData, sizeof(HW_INITIALIZATION_DATA) );

    HwInitData.HwInitializationDataSize = sizeof(HwInitData);
    HwInitData.HwInterrupt              = NULL;
    HwInitData.HwReceivePacket          = DCamReceivePacket;
    HwInitData.HwCancelPacket           = DCamCancelOnePacket;
    HwInitData.HwRequestTimeoutHandler  = DCamTimeoutHandler;
    HwInitData.DeviceExtensionSize      = sizeof(DCAM_EXTENSION);
    HwInitData.PerStreamExtensionSize   = sizeof(STREAMEX); 
    HwInitData.PerRequestExtensionSize  = sizeof(IRB);
    HwInitData.FilterInstanceExtensionSize = 0;
    HwInitData.BusMasterDMA             = FALSE;
    HwInitData.Dma24BitAddresses        = FALSE;
    HwInitData.BufferAlignment          = sizeof(ULONG) - 1;
    HwInitData.TurnOffSynchronization   = TRUE;
    HwInitData.DmaBufferSize            = 0;

    return (StreamClassRegisterAdapter(DriverObject, RegistryPath, &HwInitData));

}



#define DEQUEUE_SETTLE_TIME      (ULONG)(-1 * MAX_BUFFERS_SUPPLIED * 10000) 

NTSTATUS
DCamHwUnInitialize(
    IN PHW_STREAM_REQUEST_BLOCK Srb
    )
/*++

Routine Description:

    Device is asked to be unloaded.
       
    Note: this can be called BEFORE CloseStream in the situation when a DCam 
    is unplugged while streaming in any state (RUN,PAUSE or STOP).  So if we 
    are here and the stream is not yet close, we will stop, close stream and then
    free resource.

Arguments:

    Srb - Pointer to stream request block

Return Value:

    Nothing

--*/
{
    NTSTATUS Status;
    PIRP pIrp;
    PIRB pIrb;    
    PDCAM_EXTENSION pDevExt = (PDCAM_EXTENSION) Srb->HwDeviceExtension;

    PAGED_CODE();


    //
    // Wait until all pending work items are completed!
    //

    KeWaitForSingleObject( &pDevExt->PendingWorkItemEvent, Executive, KernelMode, FALSE, NULL );


    ASSERT(pDevExt->PendingReadCount == 0);

    //
    // Host controller could be disabled which will cause us to be uninitialized.
    //
    if(DCamAllocateIrbAndIrp(&pIrb, &pIrp, pDevExt->BusDeviceObject->StackSize)) {

        //
        // un-register a bus reset callback notification
        //
        pIrb->FunctionNumber = REQUEST_BUS_RESET_NOTIFICATION;
        pIrb->Flags = 0;
        pIrb->u.BusResetNotification.fulFlags = DEREGISTER_NOTIFICATION_ROUTINE;
        pIrb->u.BusResetNotification.ResetRoutine = (PBUS_BUS_RESET_NOTIFICATION) DCamBusResetNotification;
        pIrb->u.BusResetNotification.ResetContext = 0; 
        Status = DCamSubmitIrpSynch(pDevExt, pIrp, pIrb);
        if(Status) {
            ERROR_LOG(("DCamHwUnInitialize: Error (Status %x) while trying to deregister reset callback routine.\n", Status));
        } 

        DbgMsg1(("DCamHwUnInitialize: DeRegister bus reset notification done; status %x.\n", Status));

        DCamFreeIrbIrpAndContext(0, pIrb, pIrp);
    } else {
        ERROR_LOG(("DCamBusResetNotification: DcamAllocateIrbAndIrp has failed!!\n\n\n"));
        ASSERT(FALSE);   
    }

    // Free resource (from below)
    if(pDevExt->UnitDirectory) {
        ExFreePool(pDevExt->UnitDirectory);
        pDevExt->UnitDirectory = 0;
    }

    if(pDevExt->UnitDependentDirectory) {
        ExFreePool(pDevExt->UnitDependentDirectory);
        pDevExt->UnitDependentDirectory = 0;
    }

    if(pDevExt->ModelLeaf) {
        ExFreePool(pDevExt->ModelLeaf);
        pDevExt->ModelLeaf = 0;
    }

    if (pDevExt->ConfigRom) {
        ExFreePool(pDevExt->ConfigRom);
        pDevExt->ConfigRom = 0;
    }

    if (pDevExt->VendorLeaf) {
        ExFreePool(pDevExt->VendorLeaf);
        pDevExt->VendorLeaf = 0;
    }
      
    return STATUS_SUCCESS;
}




VOID 
InitializeDeviceExtension(
    PPORT_CONFIGURATION_INFORMATION ConfigInfo
    )
{
    PDCAM_EXTENSION pDevExt;

    PAGED_CODE();

    pDevExt = (PDCAM_EXTENSION) ConfigInfo->HwDeviceExtension;
    pDevExt->SharedDeviceObject = ConfigInfo->ClassDeviceObject;
    pDevExt->BusDeviceObject = ConfigInfo->PhysicalDeviceObject;  // Used in IoCallDriver()
    pDevExt->PhysicalDeviceObject = ConfigInfo->RealPhysicalDeviceObject;  // Used in PnP API
    // In case sonydcam is used with old stream.sys, 
    // which has not implemented RealPhysicalDeviceObject.   
    if(!pDevExt->PhysicalDeviceObject)
        pDevExt->PhysicalDeviceObject = pDevExt->BusDeviceObject;
    ASSERT(pDevExt->PhysicalDeviceObject != 0);
    pDevExt->BaseRegister = 0;
    pDevExt->FrameRate = DEFAULT_FRAME_RATE;
    InitializeListHead(&pDevExt->IsochDescriptorList);
    KeInitializeSpinLock(&pDevExt->IsochDescriptorLock);
    pDevExt->bNeedToListen = FALSE;
    pDevExt->hResource = NULL;
    pDevExt->hBandwidth = NULL;
    pDevExt->IsochChannel = ISOCH_ANY_CHANNEL;
    pDevExt->PendingReadCount = 0; 
    pDevExt->pStrmEx = 0;

    pDevExt->bDevRemoved = FALSE;

    pDevExt->PendingWorkItemCount = 0;
    // Initialize to signal state and is set to unsignalled state if there is a pending work item
    KeInitializeEvent( &pDevExt->PendingWorkItemEvent, NotificationEvent , TRUE );  

    pDevExt->CurrentPowerState = PowerDeviceD0;  // full power state.

    KeInitializeMutex( &pDevExt->hMutexProperty, 0);  // Level 0 and in Signal state
}


NTSTATUS
DCamHwInitialize(
    IN PHW_STREAM_REQUEST_BLOCK Srb
    )

/*++

Routine Description:

    This where we perform the necessary initialization tasks.

Arguments:

    Srb - Pointer to stream request block

Return Value:

    Nothing

--*/

{

    PIRB pIrb;
    PIRP pIrp;
    CCHAR StackSize;
    ULONG i;
    ULONG DirectoryLength;
    NTSTATUS status = STATUS_SUCCESS;
    PDCAM_EXTENSION pDevExt;
    PPORT_CONFIGURATION_INFORMATION ConfigInfo; 

         

    PAGED_CODE();

    ConfigInfo = Srb->CommandData.ConfigInfo;
    pIrb = (PIRB) Srb->SRBExtension;
    pDevExt = (PDCAM_EXTENSION) ConfigInfo->HwDeviceExtension;

    //
    // Initialize DeviceExtension
    //
    InitializeDeviceExtension(ConfigInfo); 


    StackSize = pDevExt->BusDeviceObject->StackSize;
    pIrp = IoAllocateIrp(StackSize, FALSE);
    if (!pIrp) {

        ASSERT(FALSE);
        return (STATUS_INSUFFICIENT_RESOURCES);
    }

    //
    // find what the host adaptor below us supports...
    //
    pIrb->FunctionNumber = REQUEST_GET_LOCAL_HOST_INFO;
    pIrb->Flags = 0;
    pIrb->u.GetLocalHostInformation.nLevel = GET_HOST_CAPABILITIES;
    pIrb->u.GetLocalHostInformation.Information = &pDevExt->HostControllerInfomation;
    status = DCamSubmitIrpSynch(pDevExt, pIrp, pIrb);
    if (status) {

        ERROR_LOG(("DCamHwInitialize: Error (Status=%x) while trying to get local hsot info.\n", status));
        status = STATUS_UNSUCCESSFUL;
        goto AbortLoading;
    }        


    //
    // find what the max buffer size is supported by the host.
    //
    pIrb->FunctionNumber = REQUEST_GET_LOCAL_HOST_INFO;
    pIrb->Flags = 0;
    pIrb->u.GetLocalHostInformation.nLevel = GET_HOST_DMA_CAPABILITIES;
    pIrb->u.GetLocalHostInformation.Information = &pDevExt->HostDMAInformation;
    status = DCamSubmitIrpSynch(pDevExt, pIrp, pIrb);
    if (status) {
        ERROR_LOG(("DCamHwInitialize: Error (Status=%x) while trying to get GET_HOST_DMA_CAPABILITIES.\n", status));
        // May not supported in the ealier version of 1394
        // Set default.
    } else {
        ERROR_LOG(("\'GET_HOST_DMA_CAPABILITIES: HostDmaCapabilities;:%x; MaxDmaBufferSize:(Quad:%x; High:%x;Low:%x)\n",
            pDevExt->HostDMAInformation.HostDmaCapabilities, 
            (DWORD) pDevExt->HostDMAInformation.MaxDmaBufferSize.QuadPart,
            pDevExt->HostDMAInformation.MaxDmaBufferSize.u.HighPart,
            pDevExt->HostDMAInformation.MaxDmaBufferSize.u.LowPart
            ));
    }
    

    //
    // Make a call to determine what the generation # is on the bus,
    // followed by a call to find out about ourself (config rom info)
    //
    //
    // Get the current generation count first
    //

    pIrb->FunctionNumber = REQUEST_GET_GENERATION_COUNT;
    pIrb->Flags = 0;

    status = DCamSubmitIrpSynch(pDevExt, pIrp, pIrb);

    if (status) {

        ERROR_LOG(("\'DCamHwInitialize: Error %x while trying to get generation number\n", status));
        status = STATUS_UNSUCCESSFUL;
        goto AbortLoading;
    }

    InterlockedExchange(&pDevExt->CurrentGeneration, pIrb->u.GetGenerationCount.GenerationCount);

    //
    // Now that we have the current generation count, find out how much
    // configuration space we need by setting lengths to zero.
    //

    pIrb->FunctionNumber = REQUEST_GET_CONFIGURATION_INFO;
    pIrb->Flags = 0;
    pIrb->u.GetConfigurationInformation.UnitDirectoryBufferSize = 0;
    pIrb->u.GetConfigurationInformation.UnitDependentDirectoryBufferSize = 0;
    pIrb->u.GetConfigurationInformation.VendorLeafBufferSize = 0;
    pIrb->u.GetConfigurationInformation.ModelLeafBufferSize = 0;

    status = DCamSubmitIrpSynch(pDevExt, pIrp, pIrb);

    if (status) {

        ERROR_LOG(("\'DCamHwInitialize: Error %x while trying to get configuration info (1)\n", status));
        status = STATUS_UNSUCCESSFUL;
        goto AbortLoading;
    }

    //
    // Now go thru and allocate what we need to so we can get our info.
    //

    pDevExt->ConfigRom = ExAllocatePoolWithTag(PagedPool, sizeof(CONFIG_ROM), 'macd');
    if (!pDevExt->ConfigRom) {

        ERROR_LOG(("\'DCamHwInitialize: Couldn't allocate memory for the Config Rom\n"));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto AbortLoading;
    }


    pDevExt->UnitDirectory = ExAllocatePoolWithTag(PagedPool, pIrb->u.GetConfigurationInformation.UnitDirectoryBufferSize, 'macd');
    if (!pDevExt->UnitDirectory) {

        ERROR_LOG(("\'DCamHwInitialize: Couldn't allocate memory for the UnitDirectory\n"));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto AbortLoading;
    }


    if (pIrb->u.GetConfigurationInformation.UnitDependentDirectoryBufferSize) {

        pDevExt->UnitDependentDirectory = ExAllocatePoolWithTag(PagedPool, pIrb->u.GetConfigurationInformation.UnitDependentDirectoryBufferSize, 'macd');
        if (!pDevExt->UnitDependentDirectory) {

            ERROR_LOG(("\'DCamHwInitialize: Couldn't allocate memory for the UnitDependentDirectory\n"));
            status = STATUS_INSUFFICIENT_RESOURCES;
            goto AbortLoading;
        }
    }


    if (pIrb->u.GetConfigurationInformation.VendorLeafBufferSize) {

        // From NonPaged pool since vendor name can be used in a func with DISPATCH level
        pDevExt->VendorLeaf = ExAllocatePoolWithTag(NonPagedPool, pIrb->u.GetConfigurationInformation.VendorLeafBufferSize, 'macd');
        if (!pDevExt->VendorLeaf) {

            ERROR_LOG(("\'DCamHwInitialize: Couldn't allocate memory for the VendorLeaf\n"));
            status = STATUS_INSUFFICIENT_RESOURCES;
            goto AbortLoading;
        }
    } 

⌨️ 快捷键说明

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