我在32位Windows 7环境中遇到PCI Express板问题。该板是一个音频/视频捕获设备,可对32个独立的SD模拟视频通道执行实时H.264编码。它使用DMA将压缩帧传送到Win7主机驱动程序。
在系统启动时,板驱动程序使用DmaAdapter对象的AllocateCommonBuffer函数从非分页池中分配DMA缓冲区。缓冲区必须全部驻留在相同的256MB物理地址范围内,以便映射到电路板。当win7主机系统启动时,此分配始终成功。
除简单的引导加载程序外,该板没有任何常驻固件;它需要在应用程序运行时将固件映像(通过驱动程序)下载到电路板。但是,作为此固件下载过程的一部分,Windows应用程序必须通过驱动程序发出BOARD_RESET ioctl,以使电路板进入已知状态。不幸的是,当主板收到重置命令时,它会从win7 PnP管理器的视图中短暂“消失”,该管理器认为发生了SURPRISE_REMOVAL事件。随后,板驱动程序被强制将其所有已分配的DMA缓冲区释放回非页面缓冲池,并等待来自PnP管理器的StartDevice事件。
当收到下一个StartDevice事件时,板驱动程序无法再完成DMA分配。由于碎片,它无法从非页面缓冲池中找到可以映射到相同物理地址范围的足够缓冲区。驱动程序未通过StartDevice事件,然后由PnP管理器从服务中删除。
我正在寻找针对这种情况的程序化解决方法。是否可以在电路板复位期间以某种方式暂停器件节点,因此PnP管理器不会将其检测为删除?是否有可以覆盖设备删除检测的PnP配置?有没有办法挂起驱动程序第一次启动时成功获取的DMA缓冲区?有没有办法在非分页池中保留页面范围,仅供此驱动程序使用? DMA缓冲区相当大:200个缓冲区,每个634880字节,它们必须都来自相同的256MB范围(即,在0x10000000边界上)。我有电路板驱动程序的完整源代码,可以进行任何必要的修改;它是供应商购买的参考设计的一部分。这是我第一次接触到Windows设备驱动程序。