I'm having a problem with a PCI express board in the 32bit Windows 7 environment. This board is an audo/video capture device that performs real-time H.264 encoding of 32 separate SD analog video channels. It uses DMA to deliver compressed frames to the Win7 host driver.

At system bootup, the board driver allocates DMA buffers from the non-paged pool using the AllocateCommonBuffer function of the DmaAdapter object. The buffers must all reside in the same 256MB physical address range in order to be mapped to the board. This allocation is always successful when the win7 host system boots.

The board does not have any resident firmware other than a simple bootloader; it requires the firmware image to be downloaded (via the driver) to the board at application runtime. However, as part of this firmware download process, the windows application must issue a BOARD_RESET ioctl through the driver to get the board into a known state. Unfortunately, when the board receives the reset command, it briefly "disappears" from view of the win7 PnP manager, which thinks a SURPRISE_REMOVAL event has occurred. Subsequently, the board driver is forced to release all of its allocated DMA buffers back to the non-paged pool, and wait for the StartDevice event from PnP manager.

When the next StartDevice event is received, the board driver cannot complete the DMA allocation anymore. It is unable to find enough buffers from the non-paged pool that can be mapped to the same physical address range, due to fragmentation. The driver fails the StartDevice event and is then removed from service by PnP manager.

I am looking for a programmatic workaround for this situation. Is it possible to suspend the device node somehow during board reset, so PnP manager does not detect it as a removal? Is there a PnP configuration that can override device removal detection? Is there any way to hang onto the DMA buffers that the driver successfully acquired the first time it started? Is there a way to reserve page ranges in the non-paged pool for use by this driver only? The DMA buffers are rather large: 200 buffers, each 634880 bytes, and they must all come from the same 256MB range (i.e, on 0x10000000 boundaries). I have the complete source code for the board driver and can make any necessary modifications; it is part of a purchased reference design from a vendor. This is my first exposure to windows device drivers.

I have to think about it, but one possible solution would be to install a virtual device driver which communicates with the original device driver. This can acquire the DMA buffers on startup and give them out to the board driver.
–
ChristopherMar 14 '12 at 20:46

I'm also wondering if implementing power management functions for this board could work. The vendor did not originally supply any power management handlers (e.g. IRP_MJ_POWER) in the driver code. The board does not support any low power or sleep states, but perhaps I could change the board reset handler to appear like a 'sleep/wakeup' cycle to the windows power manager? Maybe that way the device node and context will be preserved?
–
pioMar 15 '12 at 15:09