PCI Driver Structure when you have multiple character drivers

I’m fairly new to windows driver writing (I have written a few single function pci hardware drivers (like GPIO), but I have written several Linux drivers). I have been asked to write a driver for a PCI card that uses DMA (scatter gather), the PCI card has 8 independent UART devices. The 8 ports are identical.

In Linux I would normally setup a PCI device and incorporate 8 character devices within it (so it is really just 1 driver but I can create 8 separate device nodes to represent each “port” from user space). But in windows I’m not sure what the best way to do this is… Based on the all the reading I have done, it feel like I should be doing a bus driver with 8 child nodes? But I’m not sure, so I’m hoping for some direction or validation. In addition, if I am doing that how does windows do the deal with the sort of “different” handles to open the ports and control their independent IO? Any direction would be helpful :slight_smile:

Thanks!

The first question you need to answer, is this 8 UART’s sharing one PCI BAR and one interrupt, is it 8 UART’s with separate BAR’s and interrupts, or is it true multi-function device which appears as separate devices? The last one is easy, you don’t need anything besides a function driver for the UART. If it is the separate BAR/interrupt case look at https://docs.microsoft.com/en-us/windows-hardware/drivers/multifunction/

Finally, if it is the first case you need a bus driver. Note: this driver will have to handle the interrupts, since Microsoft does not have exposed support for sharing an interrupt. I’ve done this for a number of clients over the years, the simplest approach is to have the bus driver expose the PDO’s then the function driver setup an interface structure with interrupt service routine and interrupt context filled in to pass to the bus driver. The bus driver then returns this with the port resources, and a function and context that allow synchronization of interrupts like WdfSynchronizeInterrupt.

There is a bunch of work here, but mostly it is a simple bus driver, then modifying the serial driver sample to handle the device interface and bus owned interrupt synchronization.

No, the FIRST question to ask would be: Why would you post this question in the Announcements and Administration category of the forum?

I’ve moved it to the appropriate place (NTDEV).

Peter

the PCI card has 8 independent UART devices. The 8 ports are identical.

Mr. Burn asks the right questions. It would be more helpful for you to use precise terminology:

If by “independent UART devices” you mean:

  • A device with a single PCI function (ONE set of BARs)… Then the easiest thing to do would be to write a KMDF bus driver. There are other ways you could do this (such as with multiple symbolic links), but a KMDF bus driver would be the easiest.
  • A device with 8 independent functions (separate BARs for each device)… then you just write one driver and load it on 8 device instances
  • A device with multiple independent functions, but where some of the functionality is built in to a particular (we’ll call it “Primary”) function… and the rest of the functions have their own BARs but require some of the functionality of the Primary function. This device design is a mess, is broken by design, and I pity the poor engineer who’s stuck writing this driver. Though, there ARE some “tricks” that you can probably use to make this less painful.

Peter