📄 luojincdriv01device.cpp
字号:
I.Status() = status;
// PnpNextIrp completes this IRP and starts
// processing for the next IRP in the queue.
PnpNextIrp(I);
}
inline NTSTATUS LuojincDriv01Device::Write(KIrp I)
{
t << "Entering LuojincDriv01Device::Write, " << I << EOL;
// TODO: Check the incoming request. Replace "FALSE" in the following
// line with a check that returns TRUE if the request is not valid.
if (FALSE)
{
// Invalid parameter in the Write request
I.Information() = 0;
return I.PnpComplete(this, STATUS_INVALID_PARAMETER);
}
// Always ok to write 0 elements.
if (I.WriteSize() == 0)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_SUCCESS);
}
// Queue the IRP for processing in StartIO
// The write function is performed in SerialWrite
return QueueIrp(I, LinkTo(CancelQueuedIrp));
}
inline NTSTATUS LuojincDriv01Device::DeviceControl(KIrp I)
{
NTSTATUS status;
t << "Entering LuojincDriv01Device::Device Control, " << I << EOL;
switch (I.IoctlCode())
{
case ReadMemConfigReg:
// Queue this request for serialized handling through StartIo
status = QueueIrp(I, LinkTo(CancelQueuedIrp));
break;
case ReadIoConfigReg:
// Queue this request for serialized handling through StartIo
status = QueueIrp(I, LinkTo(CancelQueuedIrp));
break;
case WriteMemConfigReg:
// Queue this request for serialized handling through StartIo
status = QueueIrp(I, LinkTo(CancelQueuedIrp));
break;
case WriteIoConfigReg:
// Queue this request for serialized handling through StartIo
status = QueueIrp(I, LinkTo(CancelQueuedIrp));
break;
case ReadLocalSpace0:
// Queue this request for serialized handling through StartIo
status = QueueIrp(I, LinkTo(CancelQueuedIrp));
break;
case ReadLocalSpace1:
// Queue this request for serialized handling through StartIo
status = QueueIrp(I, LinkTo(CancelQueuedIrp));
break;
case WriteLocalSpace0:
// Queue this request for serialized handling through StartIo
status = QueueIrp(I, LinkTo(CancelQueuedIrp));
break;
case WriteLocalSpace1:
// Queue this request for serialized handling through StartIo
status = QueueIrp(I, LinkTo(CancelQueuedIrp));
break;
case GetDriverInfo:
// Queue this request for serialized handling through StartIo
status = QueueIrp(I, LinkTo(CancelQueuedIrp));
break;
case SetDriverInfo:
// Queue this request for serialized handling through StartIo
status = QueueIrp(I, LinkTo(CancelQueuedIrp));
break;
default:
// Unrecognized IOCTL request
status = STATUS_INVALID_PARAMETER;
break;
}
if (status == STATUS_PENDING)
{
return status;
}
else
{
return I.PnpComplete(this, status);
}
}
inline VOID LuojincDriv01Device::ReadMemConfigRegFunc(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
KMemory Mem(I.Mdl());
PULONG pOutBuffer = (PULONG) Mem.MapToSystemSpace();
PULONG pInBuffer = (PULONG) I.IoctlBuffer();
ULONG Offset=0;
ULONG count;
Offset = *pInBuffer;
count = *(pInBuffer+1);
m_MemoryRange0.ind(Offset,pOutBuffer,count);
I.Information() = count;
I.Status() = status;
PnpNextIrp(I);
}
inline VOID LuojincDriv01Device::ReadIoConfigRegFunc(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering LuojincDriv01Device::ReadIoConfigRegFunc, " << I << EOL;
I.Information() = 0;
I.Status() = status;
PnpNextIrp(I);
}
inline VOID LuojincDriv01Device::WriteMemConfigRegFunc(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
KMemory Mem(I.Mdl());
PULONG pOutBuffer = (PULONG) Mem.MapToSystemSpace();
PULONG pInBuffer = (PULONG) I.IoctlBuffer();
ULONG Offset=0;
ULONG count;
Offset = *pInBuffer;
count = *(pInBuffer+1);
m_MemoryRange0.outd(Offset,pOutBuffer,count);
I.Information() = count;
I.Status() = status;
PnpNextIrp(I);
}
inline VOID LuojincDriv01Device::WriteIoConfigRegFunc(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering LuojincDriv01Device::WriteIoConfigRegFunc, " << I << EOL;
I.Information() = 0;
I.Status() = status;
PnpNextIrp(I);
}
inline VOID LuojincDriv01Device::ReadLocalSpace1Func(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering LuojincDriv01Device::ReadLocalSpace1Func, " << I << EOL;
I.Information() = 0;
I.Status() = status;
PnpNextIrp(I);
}
inline VOID LuojincDriv01Device::WriteLocalSpace0Func(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering LuojincDriv01Device::WriteLocalSpace0Func, " << I << EOL;
I.Information() = 0;
I.Status() = status;
PnpNextIrp(I);
}
inline VOID LuojincDriv01Device::WriteLocalSpace1Func(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering LuojincDriv01Device::WriteLocalSpace1Func, " << I << EOL;
I.Information() = 0;
I.Status() = status;
PnpNextIrp(I);
}
inline VOID LuojincDriv01Device::GetDriverInfoFunc(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering LuojincDriv01Device::GetDriverInfoFunc, " << I << EOL;
I.Information() = 0;
I.Status() = status;
PnpNextIrp(I);
}
inline VOID LuojincDriv01Device::SetDriverInfoFunc(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering LuojincDriv01Device::SetDriverInfoFunc, " << I << EOL;
I.Information() = 0;
I.Status() = status;
PnpNextIrp(I);
}
//----------------------读Local数据-------------------//
inline VOID LuojincDriv01Device::ReadLocalSpace0Func(KIrp I)
{
NTSTATUS status;
PIRP pCurrentIrp=PIRP(I);
PIO_STACK_LOCATION pIoStackLocation = IoGetCurrentIrpStackLocation(pCurrentIrp);
m_pMdl = pCurrentIrp->MdlAddress;
m_pTransferVa = (PUCHAR)MmGetMdlVirtualAddress(m_pMdl);
m_nBytesTransfered=0;
m_nBytesRequested = m_nBytesRemaining = MmGetMdlByteCount(m_pMdl);
status = m_pDmaAdapter->DmaOperations->AllocateAdapterChannel
(m_pDmaAdapter,m_pDeviceObject,m_MapRegisterCount,AdapterControl,this);
if (!NT_SUCCESS(status))
{
I.Information() = 0;
I.Status() = status;
PnpNextIrp(I);
}
}
//----------------------适配器回调例程-------------------//
inline IO_ALLOCATION_ACTION
AdapterControl(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp,IN PVOID MapRegisterBase,IN PVOID pContext )
{
LuojincDriv01Device* pThis = (LuojincDriv01Device*)pContext;
pThis->m_pMapRegisterBase = MapRegisterBase;
// KeFlushIoBuffers( pThis->m_pMdl,TRUE, TRUE );
PPLX9656_DESCRIPTOR pDescriptorVa = (PPLX9656_DESCRIPTOR)pThis->m_pCommBufferVa;
ULONG CommBufferPa = pThis->m_pCommBufferPa->LowPart;
ULONG BytesLeftInBuffer;
ULONG SegMentSize;
ULONG MapRegisterIndex=0;
PUCHAR SegmentVa;
PHYSICAL_ADDRESS PciAddr;
////////////////////////////////////////
BytesLeftInBuffer = pThis -> m_nBytesRemaining;
SegmentVa = pThis -> m_pTransferVa;
pThis ->m_nTransferSize=0;
while(MapRegisterIndex < pThis->m_MapRegisterCount && BytesLeftInBuffer > 0)
{
SegMentSize = BytesLeftInBuffer;
PciAddr=pThis->m_pDmaAdapter->DmaOperations->
MapTransfer( pThis->m_pDmaAdapter, pThis->m_pMdl , MapRegisterBase,
pThis->m_pTransferVa , &SegMentSize , false );
pThis->SetSgDesc( pDescriptorVa,//PPLX9656_DESCRIPTOR pDesc
PciAddr.LowPart,//PciLowPart
0,//PciHighPart,
0,//LocalAddr,
SegMentSize,//Length
true,//bValid?
false,//bEnd?
CommBufferPa+(MapRegisterIndex+1)*sizeof(PLX9656_DESCRIPTOR)//NextDescPtrPa
);
pDescriptorVa++;
MapRegisterIndex++;
BytesLeftInBuffer-=SegMentSize;
SegmentVa+=SegMentSize;
pThis ->m_nTransferSize+=SegMentSize;
}
pDescriptorVa--;
pThis->SetSgDesc( pDescriptorVa,//PPLX9656_DESCRIPTOR pDesc
PciAddr.LowPart,//PciLowPart
0,//PciHighPart,
0,//LocalAddr,
SegMentSize,//Length
true,//bValid?
true,//bEnd?
0 //NextDescPtrPa
);
pDescriptorVa = (PPLX9656_DESCRIPTOR)pThis->m_pCommBufferVa;
pThis->SetFirstSgDma(pDescriptorVa);
pThis->SetSgDmaMode();
pThis->EnableDMA0Interrupt(true);
pThis->StartDma();
return DeallocateObjectKeepRegisters;
}
//----------------------中断服务例程-------------------//
inline BOOLEAN LuojincDriv01Device::Isr_Irq(void)
{
if((m_MemoryRange0[PLX9656_INTCSR] &= PLX9656_INTCSR_DMA0IA)==0)
{ return false;}
else
{
EnableDMA0Interrupt(false);
ClearDMA0Interrupt();
if(!m_DpcFor_Irq.Request(NULL, NULL))
{
KIrp I(CurrentIrp());
I.Status()=STATUS_UNSUCCESSFUL;
I.Information()=0;
PnpNextIrp(I);
}
return true;
}
}
//----------------------中断延迟调用-------------------//
inline VOID LuojincDriv01Device::DpcFor_Irq(PVOID Arg1, PVOID Arg2)
{
//缓冲区刷新
m_pDmaAdapter->DmaOperations->FlushAdapterBuffers
(m_pDmaAdapter,m_pMdl,m_pMapRegisterBase, m_pTransferVa,m_nTransferSize,false);
//数据更新
m_nBytesTransfered+=m_nTransferSize;
m_pTransferVa+=m_nTransferSize;
m_nBytesRemaining-=m_nTransferSize;
if (m_nBytesRemaining > 0)
{
//局部变量
ULONG SegMentSize;
ULONG MapRegisterIndex=0;
PUCHAR SegmentVa;
PHYSICAL_ADDRESS PciAddr;
PPLX9656_DESCRIPTOR pDescriptorVa = (PPLX9656_DESCRIPTOR)m_pCommBufferVa;
ULONG CommBufferPa = m_pCommBufferPa->LowPart;
ULONG BytesLeftInBuffer=m_nBytesRemaining;
SegmentVa = m_pTransferVa;
m_nTransferSize=0;
while(MapRegisterIndex < m_MapRegisterCount && BytesLeftInBuffer > 0)
{
SegMentSize = BytesLeftInBuffer;
PciAddr=m_pDmaAdapter->DmaOperations->
MapTransfer( m_pDmaAdapter, m_pMdl , m_pMapRegisterBase,
m_pTransferVa , &SegMentSize , false );
SetSgDesc( pDescriptorVa,//PPLX9656_DESCRIPTOR pDesc
PciAddr.LowPart,//PciLowPart
0,//PciHighPart,
0,//LocalAddr,
SegMentSize,//Length
true,//bValid?
false,//bEnd?
CommBufferPa+(MapRegisterIndex+1)*sizeof(PLX9656_DESCRIPTOR)//NextDescPtrPa
);
pDescriptorVa++;
MapRegisterIndex++;
BytesLeftInBuffer-=SegMentSize;
SegmentVa+=SegMentSize;
m_nTransferSize+=SegMentSize;
}
pDescriptorVa--;
SetSgDesc( pDescriptorVa,//PPLX9656_DESCRIPTOR pDesc
PciAddr.LowPart,//PciLowPart
0,//PciHighPart,
0,//LocalAddr,
SegMentSize,//Length
true,//bValid?
true,//bEnd?
0 //NextDescPtrPa
);
pDescriptorVa = (PPLX9656_DESCRIPTOR)m_pCommBufferVa;
SetFirstSgDma(pDescriptorVa);
EnableDMA0Interrupt(true);
StartDma();
}
else
{
m_pDmaAdapter->DmaOperations->FreeMapRegisters(m_pDmaAdapter,m_pMapRegisterBase,m_MapRegisterCount);
KIrp I(CurrentIrp());
I.Status()=STATUS_SUCCESS;
I.Information()=m_nBytesTransfered;
PnpNextIrp(I);
}
UNREFERENCED_PARAMETER(Arg1);UNREFERENCED_PARAMETER(Arg2);
}
//-------------------------启动DMA----------------------//
inline VOID LuojincDriv01Device::StartDma(void)
{
m_MemoryRange0[PLX9656_DMACSR0] |= (UCHAR)(PLX9656_DMACSR0_E | PLX9656_DMACSR0_S);
}
//----------------------使能DMA0中断-------------------//
inline void LuojincDriv01Device::EnableDMA0Interrupt(bool YesOrNo)
{
if(YesOrNo)
{
m_MemoryRange0[PLX9656_INTCSR]=PLX9656_INTCSR_DMA0IE|PLX9656_INTCSR_IE;
}
else
{
m_MemoryRange0[PLX9656_INTCSR]=(ULONG)0;
}
}
//----------------------清除DMA0中断-------------------//
inline void LuojincDriv01Device::ClearDMA0Interrupt(void)
{
m_MemoryRange0[PLX9656_DMACSR0]=PLX9656_DMACSR0_CI;
}
//---------------------描述符表项记录------------------//
inline void LuojincDriv01Device::SetSgDesc(
PPLX9656_DESCRIPTOR pDesc,
ULONG PciLowPart,
ULONG PciHighPart,
ULONG LocalAddr,
ULONG Length,
bool bValid,
bool bEnd,
ULONG DescPtr)
{
pDesc->PciAddrLow = PciLowPart;
pDesc->PciAddrHigh =PciHighPart;
pDesc->LocalAddr = LocalAddr;
pDesc->Size = Length | (bValid ? PLX9656_DMASIZ0_V : 0);
pDesc->NextDescPtr = DescPtr |PLX9656_DMADPR0_DT| PLX9656_DMADPR0_DL | (bEnd ? PLX9656_DMADPR0_EC : 0);
}
//-------------------设置DMA传输寄存器----------------//
inline void LuojincDriv01Device::SetFirstSgDma(PPLX9656_DESCRIPTOR pDescriptorVa)
{
m_MemoryRange0[PLX9656_DMAPADR0] = pDescriptorVa->PciAddrLow;
m_MemoryRange0[PLX9656_DMADAC0] = pDescriptorVa->PciAddrHigh;
m_MemoryRange0[PLX9656_DMALADR0] = pDescriptorVa->LocalAddr;
m_MemoryRange0[PLX9656_DMASIZ0] = pDescriptorVa->Size;
m_MemoryRange0[PLX9656_DMADPR0] = pDescriptorVa->NextDescPtr;
}
//---------------设置DMA Scatter/Gather模式-------------//
inline void LuojincDriv01Device::SetSgDmaMode(void)
{
m_MemoryRange0[PLX9656_DMAMODE0] = PLX9656_DMAMODE0_IS | PLX9656_DMAMODE0_EOTEL |
PLX9656_DMAMODE0_CCM | PLX9656_DMAMODE0_DIE | PLX9656_DMAMODE0_SGM |
PLX9656_DMAMODE0_LBE | PLX9656_DMAMODE0_TARIE | Plx9656BitSize32;
}
//-----------------------结束,谢谢---------------------//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -