kingfishzju
驱动牛犊
驱动牛犊
  • 注册日期2003-05-20
  • 最后登录2006-06-28
  • 粉丝0
  • 关注0
  • 积分12分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
阅读:1571回复:6

求救:RtlCopyMemory在writedispatch出现page fault

楼主#
更多 发布于:2005-03-01 20:08
用DS3.0开发2000下PCI FPGA仿真加速卡的WDM驱动,busmaster,DO_DIRECT_IO,
因为数据传输量小(128字节)而且严格遵循收发间隔的半双工状态,所以使用common buffer,作为Tx和Rx DMA缓冲区。

NTSTATUS FPGAPCIWriteDispatch(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp
    )
{
    PFPGAPCI_DEVICE_EXTENSION    deviceExtension;
    NTSTATUS                        status;
    PIO_STACK_LOCATION              irpStack;
    PVOID                           writeBuffer;
    ULONG                           writeLength;
    ULONG                           numberOfMapRegisters;
    BOOLEAN                         isRead = FALSE;
    KIRQL                           oldIrql;

    FPGAPCIDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__\"++. IRP %p\", Irp);

    deviceExtension = (PFPGAPCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    status = FPGAPCICheckIoLock(&deviceExtension->IoLock, Irp);
    if (!NT_SUCCESS(status) || (status == STATUS_PENDING))
    {
        FPGAPCIDebugPrint(DBG_IO, DBG_WARN, __FUNCTION__\"--. IRP %p STATUS %x\", Irp, status);

        return status;
    }

//save current IRP
deviceExtension->WriteCurrentIrp = Irp;

    // Get our IRP stack location
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    // Get the write buffer length
    writeLength = irpStack->Parameters.Write.Length;

    writeBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);

    // dma allocations should be called at DISPATCH_LEVEL
    //KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);

    RtlCopyMemory(deviceExtension->RxCmBuf.StartVa, writeBuffer, writeLength);  //错误!!!Page Fault (0Eh). Fault=0002
    SetTxDma(deviceExtension,TRUE);

    //KeLowerIrql(oldIrql);

    FPGAPCIDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__\"--. IRP %p STATUS %x\", Irp, status);

    return status;
}

原先我以为是writeBuffer是分页内存的原因,但是我在
RtlCopyMemory(deviceExtension->RxCmBuf.StartVa, writeBuffer, writeLength)前加
RtlZeroMemory(writeBuffer, 128); //能正确执行
RtlZeroMemory(deviceExtension->RxCmBuf.StartVa, 128); //现象同上Page Fault (0Eh). Fault=0002
由此我判断是deviceExtension->RxCmBuf.StartVa是分页内存造成的错误。
使用DO_BUFFER_IO也是同样的现象,

哪位大侠能指点迷津,不胜感激!

aiwadgj
驱动老牛
驱动老牛
  • 注册日期2004-11-13
  • 最后登录2020-12-24
  • 粉丝0
  • 关注0
  • 积分119分
  • 威望84点
  • 贡献值0点
  • 好评度14点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2005-03-01 20:23
RtlCopyMemory只有在两个常驻内存的区域互相拷贝的时候,,才可以运行在DISPATCH_LEVEL........

否则只能在小于DISPATCH_LEVEL下使用,,,。。

这里没有在dispztch 级下运行。。。。怎么会出现缺页bug那?。。

酒也在沉溺,何时麻醉我抑郁。过去了的一切会平息。。。。。。。
kingfishzju
驱动牛犊
驱动牛犊
  • 注册日期2003-05-20
  • 最后登录2006-06-28
  • 粉丝0
  • 关注0
  • 积分12分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-03-01 20:39
原来在在DISPATCH_LEVEL出现分页错误,我就该用DO_BUFFER_IO,错误还是没有变,所以就把KeRaiseIrql函数去掉了,但是这个问题仍然没有消除。
难道是AllocateCommonBuffer调用时有问题?
kingfishzju
驱动牛犊
驱动牛犊
  • 注册日期2003-05-20
  • 最后登录2006-06-28
  • 粉丝0
  • 关注0
  • 积分12分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-03-01 21:46
我想知道我这种把user data拷贝到common buffer中,然后配置DMA发送,这种思路是否可行?
aiwadgj
驱动老牛
驱动老牛
  • 注册日期2004-11-13
  • 最后登录2020-12-24
  • 粉丝0
  • 关注0
  • 积分119分
  • 威望84点
  • 贡献值0点
  • 好评度14点
  • 原创分0分
  • 专家分0分
  • 社区居民
地下室#
发布于:2005-03-01 21:54
我想知道我这种把user data拷贝到common buffer中,然后配置DMA发送,这种思路是否可行?
 


你看看。。《windows WDM 驱动开发指南》那有这么个buffer传输例子

我记得不清楚了,,,

那本书网上也有电子版的,,找找吧,,好运!
酒也在沉溺,何时麻醉我抑郁。过去了的一切会平息。。。。。。。
tiamo
VIP专家组
VIP专家组
  • 注册日期2002-02-26
  • 最后登录2018-01-09
  • 粉丝17
  • 关注4
  • 积分50分
  • 威望142点
  • 贡献值1点
  • 好评度40点
  • 原创分2分
  • 专家分15分
  • 原创先锋奖
  • 社区居民
5楼#
发布于:2005-03-01 22:58
方式是没有错
你检查过那个length么

在rtlcopymemory那里设置一个断点
然后用page 命令看看?

common buffer就是这样使用的啊....

其实
你的pci设备既然是bus master...那就应该会支持 gather scatter的吧....

为什么不使用
AllocateChannel
MapTransfer
FreeChannel
这样的函数呢....

bus master跟 gather scatter的设备所调用的这些函数基本都是直接return的....
kingfishzju
驱动牛犊
驱动牛犊
  • 注册日期2003-05-20
  • 最后登录2006-06-28
  • 粉丝0
  • 关注0
  • 积分12分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2005-03-03 13:40
问题已经解决,用page查看发现deviceExtension->RxCmBuf.StartVa为NULL,是我在前面的程序不小心把它设置为NULL的。

怎么给分?
游客

返回顶部