Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results
The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.
Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/
Hi Guys,
This is a general question regarding WDF drivers written for a PCIe device which has multiple interrupt sources (for example multiple queues). In my interrupt service routine I would like to identify every source without reading the "interrupt status" register. The message code that we get in the ISR should give me the source of the interrupt, so that I do not need to go and read a status register from the hardware. Few questions:
Any help highly appreciated.
Thanks
Ajitabh
Upcoming OSR Seminars | ||
---|---|---|
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead! | ||
Writing WDF Drivers | 12 September 2022 | Live, Online |
Internals & Software Drivers | 23 October 2022 | Live, Online |
Kernel Debugging | 14 November 2022 | Live, Online |
Developing Minifilters | 5 December 2022 | Live, Online |
Comments
Why don't you want to read the "interrupt status" register? That's what it's for, for gosh sakes.
In general, all of the interrupts for a single device are routed to the same CPU, so multiple MSI interrupts should be serialized. I doubt there is any guarantee of that.
Tim Roberts, [email protected]
Providenza & Boekelheide, Inc.
Because it's a serializing operation. One of the goals of MSI/MSI-X is to make it so that you don't need to touch ANY device registers in your ISR (or, in many cases, any time after device setup/initialization). This avoids the slow-downs due to serialization. In high -speed devices/transfers, like the OP, it's usually one of my goals to not touch any device registers in the ISR. You use the MSI message number (for example) to tell you which set of memory resident data structures you need to process in your ISR (and/or DPC).
Hmmmm... really? I've never heard this in all the years I've been writing drivers... and I'm not sure it matches my experience. Windows definitely connects devices to all CPUs... and I was under the impression that the ICH/PCH had "magic" to determine which CPU to which to route the interrupt from a given device (it's in one of the "colored" Intel books, IIRC).
It's definitely not the case for MSI-X where the device can actually CHOOSE the CPU to which to target the interrupt.
Well, yes or no, depending. The prototype for your ISR is:
Right? So, for MSI type interrupts, you just look at the MessageID in your ISR to determine which interrupt is being services. You'll get one Interrupt resource (passed to you in EvtDevicePrepareHardware) and you need to create one WDFINTERRUPT for each message thats assigned to you for that single Interrupt resource (see the u.MessageInterrupt.Raw.MessageCount field of the raw resource descriptor). The ISRs that you connect to this (one) interrupt resource will be called for all your MSIs. You differentiate using the MessageID field.
Except... you specifically said MSI-X in your title, not MSI.
For MSI-X things are slightly different. You'll get one interrupt resource (passed to you in EvtDevicePrepareHardware) for each MSI-X interrupt that you're granted. Therefore the ISR that's called will imply which interrupt was generated. You will need to connect these interrupts (calling WdfInterruptCreate) from your EvtDevicePrepareHardware Event Processing Callback.
The sort of basic documentation for this is here... it could definitely be more helpful, as it leaves a lot of pragmatic things unaddressed. But my comments above should fill those missing things in sufficiently for you.
Peter
ETA: Clarify that you need to call WdfInterruptCreate for each MSI, which was not clear in the original post
Peter Viscarola
OSR
@OSRDrivers
Thank you peter. This is really helpful. I will go through the documentation on this and will also look at samples. If you can recommend any samples that will be great.
I'm not sure why you're looking for a sample. There's really nothing to see, particularly in the ISR.
The only even slightly tricky item is calling WdfInterruptCreate from your EvtDevicePrepareHardware, which is badly described in the docs, but which might want to look something like this:
ETA: Clarify that the code above is intended ONLY for MSI-X, and will not work for MSI (where you need to create on WDFINTERRUPT for each message you receive, unlike in MSI-X where you create one WDFINTERRUPT for each Interrupt Resource you receive)
Peter Viscarola
OSR
@OSRDrivers
Thanks Peter. Really appreciate the explanation.