dunant
驱动牛犊
驱动牛犊
  • 注册日期2006-05-09
  • 最后登录2009-08-13
  • 粉丝0
  • 关注0
  • 积分192分
  • 威望64点
  • 贡献值0点
  • 好评度53点
  • 原创分0分
  • 专家分0分
阅读:1678回复:3

武安河DMA读的理解,+疑惑--重启,求助!

楼主#
更多 发布于:2007-08-18 21:02
跟武安河的例子修改的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);
    }
}
有遇到类似情况的??
谢谢了,,给点建议!!
dunant
驱动牛犊
驱动牛犊
  • 注册日期2006-05-09
  • 最后登录2009-08-13
  • 粉丝0
  • 关注0
  • 积分192分
  • 威望64点
  • 贡献值0点
  • 好评度53点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-08-20 09:51
大侠们,帮回一下了?给电建议?
bloomrain
驱动牛犊
驱动牛犊
  • 注册日期2005-03-23
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分290分
  • 威望30点
  • 贡献值0点
  • 好评度27点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-08-21 17:26
可能是你的物理地址没有映射对,在系统分配给对象的空间之外
dunant
驱动牛犊
驱动牛犊
  • 注册日期2006-05-09
  • 最后登录2009-08-13
  • 粉丝0
  • 关注0
  • 积分192分
  • 威望64点
  • 贡献值0点
  • 好评度53点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-08-22 11:31
我时根据武安河的方法用的 ,
PTRANSFER_DESCRIPTOR ptd;
pXfer->SequenceTransferDescriptors(&ptd)
StartDMA(ptd->td_PhysAddr.LowPart,ptd->td_Length);生成的物理地址啊!
这种方法,可行?你怎么获得??
游客

返回顶部