WDF and multi-function serial devices

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance



I am investigating how to use KMDF for a PCI Express card. The card can have
multiple high speed UARTs. All N UARTs will share the same PCI memory BAR.
The card will need to be supported under Windows 2000, XP and Vista.

We already have a set of WDM drivers that work with an equivalent PCI cards.
This set consists of a multifunction driver and UART driver. The
multifunction driver (bus FDO) enumerates all of the UARTs and creates a
number of UART PDOs.
The UART driver uses a private interface (exposed by the multifunction
driver) to obtain resources to be handled by each of the UARTs. The resources
are not reassigned to UART driver; they are just handled by it.

The old PCI resources are:
1) 1st memory BAR - 256 * N consecutive memory addresses (all UARTs in one
PCI BAR). Handled by UART driver.
2) 2nd memory BAR - common interrupt status register (statuses for all
UARTs). Handled by UART driver (but can easily be handled by the
multifunction driver).
3) A single PCI interrupt - shared by all UARTs. Handled by UART driver (but
can easily be handled by the multifunction driver).

The old UART FDOs would connect to the shared interrupt only once. This way
the interrupt latency is reduced: no multiple spin lock acquires/releases,
and just a single interrupt status register read in order to dispatch
interrupts to the appropriate UART FDOs.

The new PCI Express resources are (the card is able to use MSI-X interrupts):
1) The same as above.
2) 2nd memory BAR - common interrupt status register (statuses for all
UARTs). Used only if the system (OS or motherboard) doesn't support MSI-X,
i.e. normally unused.
3) One MSI-X interrupt per UART.
4) One "old" PCI interrupt - Used only if the system (OS or motherboard)
doesn’t support MSI-X; in this case shared by all UARTs, i.e. normally unused.

In our new driver I would like to use a WDFINTERRUPT object, including
EvtInterruptEnable() and EvtInterruptDisable(), for each UART since this
would tie nicely with the WDF power management.
What worries me is the following excerpt from the WDF documentation: "Your
driver should create a framework interrupt object for each interrupt vector
or MSI message that the device can support. If the PnP manager does not grant
the device all of the interrupt resources that the device can support, the
extra interrupt objects will not be used and their callback functions will
not be called."

My questions regarding this are:
1) It seems to me that with KMDF I actually have to reassign UART resources
to the UART driver PDOs if I want to use WDFINTERRUPT objects. Is this
correct?

2) If MSI-X interrupts are used, can I un-assign up to N PCI interrupt
resources from the bus FDO in the multifunction driver's
EvtDeviceFilterRemoveResourceRequirements(), and assign them to the UART PDOs
(that reside on the bus newly created by the multifunction driver, and not on
the PCI bus) in the multifunction driver's
EvtDeviceResourceRequirementsQuery()?

3) In case MSI-X interrupts are not supported on a particular system, I
guess I would have to un-assign the only interrupt from the bus FDO and then
assign it to each UART PDO. So, un-assign once, assign up to N times.
This would generate the correct number of WDFINTERRUPT objects, but then the
latency would be unacceptable. I still need only one ISR to be called. Do you
have any suggestions?

4) If I handle all the interrupts in the multifunction driver, it seems that
I will lose all the power management related benefits of WDFINTERRUPT (on a
per UART basis). Is this correct?

5) Is there any other way to handle this?

I would really appreciate if you could help me with this as I am a bit stuck
here.
Thank you very much.

.



Relevant Pages

  • Re: [PATCH RFC v2] net: add PCINet driver
    ... PCI bus as its transport mechanism. ... wait for me to get a driver for your platform, but I hope we can join ... particularly nice to have the network unit grab that of_device. ... I tried to keep the network and uart as seperate as possible ...
    (Linux-Kernel)
  • 16550 Over-run errors on 200 MHz Atmel AT91SAM9263 @ 115200 on Windows CE 6.0
    ... My system is using a Quad UART from EXAR (shared interrupt). ... In order to use Shared Interrupts I am using the isr16550 driver. ... ISR is used) the hardware fifo's overflow well before Flow-Control ...
    (microsoft.public.windowsce.platbuilder)
  • RE: xr16c864 Quad uart and shared interrupts
    ... When one ore more of the UARTS generate an interrupt, ... UARTS are simple enough to write a single-layered driver from scratch, ... I have a geode system which uses a XR16C864 quad uart chip (connected ... The old ISR was actually just GIISR.DLL, ...
    (microsoft.public.windowsce.platbuilder)
  • xr16c864 Quad uart and shared interrupts
    ... I have a geode system which uses a XR16C864 quad uart chip (connected ... The old ISR was actually just GIISR.DLL, ... the COM16550 driver completely. ... interrupt is not registered in the driver, ...
    (microsoft.public.windowsce.platbuilder)
  • [PATCH 1/1] 8250_kgdb driver reworked
    ... This is the I/O driver for any 8250-compatible UARTs. ... small hooks into the normal serial core so that we can take away the uart and ... for all platforms to always work as an override of the compiled in port. ... static int __init serial8250_init ...
    (Linux-Kernel)