wei_ziyong
驱动牛犊
驱动牛犊
  • 注册日期2003-12-31
  • 最后登录2010-04-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望16点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
阅读:1453回复:1

驱动DMA回调函数?

楼主#
更多 发布于:2004-05-10 09:18
在驱动程序中,定义了一个驱动程序的队列用来序列化DMA的IRP_MJ_READ请求,是如下定义的:
class WzyDevice_DriverManagedQueue : public KDriverManagedQueueEx
{
public:
SAFE_DESTRUCTORS;
VOID StartIo(KIrp I);
};

在设备类的Read(KIrp I) 函数中调用队列的m_DriverManagedQueue.QueueIrp(I)函数把IRP插入驱动队列。

NTSTATUS WzyDevice::Read(KIrp I)
{
if (I.ReadSize() == 0)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_SUCCESS);
}
return m_DriverManagedQueue.QueueIrp(I);
}

但是,当在DMA的准备就绪回调历程中,不进行任何的操作,只是完成
这个IRP时程序执行到这里机器就会自动重新启动。在softice中有如下的错误:
Break Due to KeBufCheckEx(unhandle kernel mode exception)
Error = A (IROQL_NOT_Less_or_EQAOL)
P1=60 D2=2  P3=0 P4=F47A0EC0

准备就绪回调历程如下:

VOID WzyDevice::OnDmaReady(KDmaTransfer* pXfer, KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

          
          I.Information() = 0;

I.Status() = status;


m_DriverManagedQueue.PnpNextIrp(I);
}

或是这样的编写准备就绪回调历程:

VOID WzyDevice::OnDmaReady(KDmaTransfer* pXfer, KIrp I)
{
if (pXfer->BytesRemaining() == 0)
{
pXfer->Terminate();

I.Information() = I.ReadSize(CURRENT);
I.Status() = STATUS_SUCCESS;
m_DriverManagedQueue.PnpNextIrp(I);

m_CurrentTransfer = NULL;
delete pXfer;
return;
}

PTRANSFER_DESCRIPTOR ptd;

while (pXfer->SequenceTransferDescriptors(&ptd)) {
t << \"Physical address 0x\" << ptd->td_PhysAddr.LowPart << \". Length is 0x\"
<< ptd->td_Length << \".\" << EOL;
}

        if ((ULONG) pXfer->BytesRemaining() == I.ReadSize())
StartDMA(ptd->td_PhysAddr.LowPart,ptd->td_Length);
}

DMA的启动历程中只是设置一个定时器并不进行任何的有关硬件的操作;
VOID WzyDevice::StartDMA(ULONG PAddress,ULONG NBytes)
{
LONGLONG DueTime = -10000000; // 100ns units(1sec)
m_IsrProxyTimer.Set(
DueTime,
LinkTo(IsrProxyTimer),
this
);
}

VOID WzyDevice::IsrProxyTimer(PVOID Arg1, PVOID Arg2)
{
m_CurrentTransfer->Continue(UseTransferSize);

}
这样来反复的调用dma准备就绪回调函数,当程序执行到准备就绪回调函数时,也是出现和上面的相同的错误和情况。
当采用系统自动创建的IRP队列时,不采用驱动程序自己定义的队列时(即KDriverManagedQueueEx不用这个定义的队列时),采用上述两种方法编写dma准备就绪回调函数就没没有何的错误,程序就能够正确执行。
请问这是什么原因阿?请高手们指点一下,谢谢。一下有程序程序的原码。
附件名称/大小 下载次数 最后更新
2004-05-10_wzy.rar (32KB)  34
lianzi
驱动牛犊
驱动牛犊
  • 注册日期2007-01-18
  • 最后登录2009-08-24
  • 粉丝0
  • 关注0
  • 积分18分
  • 威望135点
  • 贡献值0点
  • 好评度32点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2008-08-06 21:24
同问 同问
游客

返回顶部