?? sonydcam.c
字號:
//===========================================================================
//
// 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.
Author:
Shaun Pierce 25-May-96
Modified:
Yee J. Wu 15-Oct-97
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();
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 nus 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;
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;
InitializeListHead(&pDevExt->IsochWaitingList);
KeInitializeSpinLock(&pDevExt->IsochWaitingLock);
pDevExt->bDevRemoved = FALSE;
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 + -