阅读:1690回复:3
武安河DMA读的理解,+疑惑--重启,求助!
跟武安河的例子修改的PCI9054的驱动程序,
怎么一进行ReadFile(hDevice, buf, 0, &nRead, NULL);就重启了呢?? OnDmaReady程序如下: VOID PCI9054Device::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)) //返回true说明成功获得下一个传输描述符 { 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); //执行startDMA:PCI9054设置寄存器,启动DMA } serialRead()程序如下: void PCI9054Device::SerialRead(KIrp I) { //第一步,启动DMA读传输 NTSTATUS status = STATUS_SUCCESS; // Create a new DMA transfer object for this IRP m_CurrentTransfer = new(NonPagedPool) KDmaTransfer(this, &m_Dma); if ( m_CurrentTransfer == NULL ) { status = STATUS_INSUFFICIENT_RESOURCES; DbgPrint("unable to allocate transfer object: %x\n", status); I.Information() = 0; I.Status() = status; PnpNextIrp(I); } //下面采用应用程序的数据缓冲区作为DMA数据区,启动OnDmaReady线程 status = m_CurrentTransfer->Initiate( I.Mdl(), FromDeviceToMemory, // (I.MajorFunction() == IRP_MJ_READ) ? FromDeviceToMemory : FromMemoryToDevice, LinkTo(OnDmaReady), //回叫线程callback NULL, FALSE ); //此操作将使系统调用OnDmaReady例程 // If the transfer cannot be initiated, complete it with an error status. if ( ! NT_SUCCESS(status) ) { DbgPrint("unable to initiate transfer: %x\n", status); delete m_CurrentTransfer; m_CurrentTransfer = NULL; I.Information() = 0; I.Status() = status; // PnpNextIrp(I); m_DriverManagedQueue.PnpNextIrp(I); } } 有遇到类似情况的?? 谢谢了,,给点建议!! |
|
沙发#
发布于:2007-08-20 09:51
大侠们,帮回一下了?给电建议?
|
|
板凳#
发布于:2007-08-22 11:31
我时根据武安河的方法用的 ,
PTRANSFER_DESCRIPTOR ptd; pXfer->SequenceTransferDescriptors(&ptd) StartDMA(ptd->td_PhysAddr.LowPart,ptd->td_Length);生成的物理地址啊! 这种方法,可行?你怎么获得?? |
|