代码在这里:
typedef struct _HW_DEVICE_EXTENSION
{
//省略原来部分,下面这些是我添加的,最后一行是DPC对象
PULONG BAR0;
BYTE FrameCount;
PHW_STREAM_REQUEST_BLOCK CurrentSRB;
PUCHAR CurrentVirtualAddress;
ULONG CurrentCount;
KDPC DpcForIsr;
} HW_DEVICE_EXTENSION, *PHW_DEVICE_EXTENSION;
BOOLEAN STREAMAPI HwInitialize ( IN OUT PHW_STREAM_REQUEST_BLOCK pSrb )
{
STREAM_PHYSICAL_ADDRESS adr;
ULONG Size;
PUCHAR pDmaBuf;
int j;
PPORT_CONFIGURATION_INFORMATION ConfigInfo = pSrb->CommandData.ConfigInfo;
PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)ConfigInfo->HwDeviceExtension;
DbgLogInfo(("Testcap: HwInitialize()\n"));
/* 有无硬件无所谓
if (ConfigInfo->NumberOfAccessRanges != 0)
{
DbgLogError(("Testcap: illegal config info\n"));
pSrb->Status = STATUS_NO_SUCH_DEVICE;
return (FALSE);
}
*/
// ReadCfg();
if (ConfigInfo->NumberOfAccessRanges != 0)
{
pHwDevExt->BAR0 = (PULONG)(ULONG_PTR)(ConfigInfo->AccessRanges[0].RangeStart.LowPart);
// pHwDevExt->BAR2 = (PULONG)(ULONG_PTR)(ConfigInfo->AccessRanges[2].RangeStart.LowPart);
pHwDevExt->ioBaseLocal = (PULONG)(ULONG_PTR)(ConfigInfo->AccessRanges[1].RangeStart.LowPart);
}
DbgLogInfo(("TestCap: Number of access ranges = %lx\n", ConfigInfo->NumberOfAccessRanges));
DbgLogInfo(("TestCap: Memory Range = %lx\n", pHwDevExt->ioBaseLocal));
DbgLogInfo(("TestCap: IRQ = %lx\n", ConfigInfo->BusInterruptLevel));
pHwDevExt->Irq = (USHORT)(ConfigInfo->BusInterruptLevel);
ConfigInfo->StreamDescriptorSize = sizeof (HW_STREAM_HEADER) + DRIVER_STREAM_COUNT * sizeof (HW_STREAM_INFORMATION);
pDmaBuf = StreamClassGetDmaBuffer(pHwDevExt);
adr = StreamClassGetPhysicalAddress(pHwDevExt, NULL, pDmaBuf, DmaBuffer, &Size);
// Init VideoProcAmp properties
pHwDevExt->Brightness = BrightnessDefault;
pHwDevExt->BrightnessFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO;
pHwDevExt->Contrast = ContrastDefault;
pHwDevExt->ContrastFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO;
pHwDevExt->ColorEnable = ColorEnableDefault;
pHwDevExt->ColorEnableFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL;
// Init CameraControl properties
pHwDevExt->Focus = FocusDefault;
pHwDevExt->FocusFlags = KSPROPERTY_CAMERACONTROL_FLAGS_AUTO;
pHwDevExt->Zoom = ZoomDefault;
pHwDevExt->ZoomFlags = KSPROPERTY_CAMERACONTROL_FLAGS_AUTO;
// Init VideoControl properties
pHwDevExt->VideoControlMode = 0;
// Init VideoCompression properties
pHwDevExt->CompressionSettings.CompressionKeyFrameRate = 15;
pHwDevExt->CompressionSettings.CompressionPFramesPerKeyFrame = 3;
pHwDevExt->CompressionSettings.CompressionQuality = 5000;
pHwDevExt->PDO = ConfigInfo->RealPhysicalDeviceObject;
pHwDevExt->FDO = ConfigInfo->ClassDeviceObject;
DbgLogInfo(("TestCap: Physical Device Object = %lx\n", pHwDevExt->PDO));
for (j = 0; j < MAX_TESTCAP_STREAMS; j++)
{
// For each stream, maintain a separate queue for data and control
InitializeListHead (&pHwDevExt->StreamSRBList[j]);
InitializeListHead (&pHwDevExt->StreamControlSRBList[j]);
KeInitializeSpinLock (&pHwDevExt->StreamSRBSpinLock[j]);
pHwDevExt->StreamSRBListSize[j] = 0;
}
// Init ProtectionStatus
pHwDevExt->ProtectionStatus = 0;
// The following allows multiple instance of identical hardware
// to be installed. GlobalDriverMediumInstanceCount is set in the Medium.Id field.
pHwDevExt->DriverMediumInstanceCount = GlobalDriverMediumInstanceCount++;
/****************2009年10月21日初始化IO定时器、DPC和FrameCount***************/
IoInitializeTimer( pHwDevExt->PDO, OnTimer, &(pHwDevExt->FrameCount) );
pHwDevExt->FrameCount = 0;
[color=#FF0000]KeInitializeDpc( &(pHwDevExt->DpcForIsr), DpcForIsrRoutine, pHwDevExt );[/color]//此句初始化DPC对象
DbgLogInfo(("TestCap: Exit, HwInitialize()\n"));
pSrb->Status = STATUS_SUCCESS;
return (TRUE);
}
BOOLEAN HwInterrupt( IN PHW_DEVICE_EXTENSION pHwDevExt )
{
const int Count = 192;
PHYSICAL_ADDRESS address;
BOOLEAN fMyIRQ = FALSE;
ULONG InterruptFlag;
ULONG Length;
ULONG BytesLeave;
InterruptFlag = READ_REGISTER_ULONG( pHwDevExt->BAR0+0X10/4 );
if(InterruptFlag)
{
WRITE_REGISTER_ULONG( pHwDevExt->BAR0+0X10/4, 0 );
fMyIRQ = TRUE;
if( pHwDevExt->CurrentCount )
{
/* if( InterruptFlag&0x00000010 )
{
pHwDevExt->VCount = 1;
//将地址修改为最后一行 即添加768*767
address = StreamClassGetPhysicalAddress( pHwDevExt, pHwDevExt->CurrentSRB,
pHwDevExt->CurrentVirtualAddress + 768*767, SRBDataBuffer, &Length );
// address = MmGetPhysicalAddress ( pHwDevExt->CurrentVirtualAddress );
WRITE_REGISTER_ULONG( pHwDevExt->BAR0+10, address.LowPart );
if( Length < 768 )
{
WRITE_REGISTER_ULONG( pHwDevExt->BAR0+12, Length/4 );
BytesLeave = 768 - Length;
address = StreamClassGetPhysicalAddress( pHwDevExt, pHwDevExt->CurrentSRB,
pHwDevExt->CurrentVirtualAddress+Length + 768*767,
SRBDataBuffer, &Length );
WRITE_REGISTER_ULONG( pHwDevExt->BAR0+10, address.LowPart );
WRITE_REGISTER_ULONG( pHwDevExt->BAR0+12, BytesLeave/4);
}
else
{
WRITE_REGISTER_ULONG( pHwDevExt->BAR0+12, Count );
}
pHwDevExt->CurrentCount -= Count * 4;
}
else
{
if( pHwDevExt->VCount )
{
address = StreamClassGetPhysicalAddress( pHwDevExt, pHwDevExt->CurrentSRB,
pHwDevExt->CurrentVirtualAddress + 768 * (767-pHwDevExt->VCount),
SRBDataBuffer, &Length );
// address = MmGetPhysicalAddress ( (pHwDevExt->CurrentVirtualAddress) + 768*(pHwDevExt->VCount) );
WRITE_REGISTER_ULONG( pHwDevExt->BAR0+10, address.LowPart );
if( Length < 768 )
{
WRITE_REGISTER_ULONG( pHwDevExt->BAR0+12, Length/4 );
BytesLeave = 768 - Length;
address = StreamClassGetPhysicalAddress( pHwDevExt, pHwDevExt->CurrentSRB,
pHwDevExt->CurrentVirtualAddress + 768 * (767-pHwDevExt->VCount)+Length,
SRBDataBuffer, &Length );
WRITE_REGISTER_ULONG( pHwDevExt->BAR0+10, address.LowPart );
WRITE_REGISTER_ULONG( pHwDevExt->BAR0+12, BytesLeave/4);
}
else
{
WRITE_REGISTER_ULONG( pHwDevExt->BAR0+12, Count );
}
pHwDevExt->CurrentCount -= Count * 4;
++pHwDevExt->VCount;
}
else
{
WRITE_REGISTER_ULONG( pHwDevExt->BAR0+10, pHwDevExt->DMABaseAddress );
WRITE_REGISTER_ULONG( pHwDevExt->BAR0+12, Count);
pHwDevExt->CurrentCount -= Count * 4;
}
// [color=#FF0000]IoRequestDpc( pHwDevExt->FDO, pHwDevExt->CurrentSRB->Irp, NULL);[/color]//此处调用DPC对象
}
*/ WRITE_REGISTER_ULONG( pHwDevExt->BAR0+10, pHwDevExt->DMABaseAddress+4 );
WRITE_REGISTER_ULONG( pHwDevExt->BAR0+12, 128 );
pHwDevExt->CurrentCount -= 768;
}
else
{
if(pHwDevExt->CurrentSRB)
CompleteStreamSRB ( pHwDevExt->CurrentSRB );
pHwDevExt->CurrentSRB = NULL;
pHwDevExt->CurrentVirtualAddress = NULL;
pHwDevExt->DMABaseAddress = 0;
}
}
return fMyIRQ;
}
复制代码