Verifier Causes Breakpoint in WDFInterruptEnable

I am working on porting a very old pre pnp driver to be pnp using WDF. I seem to have things working and have been trying to do more robust testing. I got Prefast to be happy and then moved on to trying verifier. When I turn on verify with the normal settings, I find that a breakpoint is called in WDFInterruptEnable. The situation is this. In my EvtDeviceControl routine I prepare the hardware to do the requested task, then call WDFInterruptEnable to enable interrupts. When I run without verifier, everything seems to work fine. When verifier in on, Windbg shows a breakpoint has been hit in WDFInterrupt Enable. If I tell Windbg to continue, my EvtInterruptEnable is not called and the application hangs waiting for the request to complete. If I terminate the user task, the cancel routine is called and the request is canceled correctly.

I do not understand why this is happening and what it means. Have I coded something incorrectly?

Make sure you have symbols set up properly and then run

!wdfkd.wdflogdump (your driver)

And it should tell you what is wrong. But what you described is not a typical pattern for an interrupt. Typically you do not explicitly enable / disable the interrupt object, you let kmdf do it on power on/off for you.

d


From: xxxxx@verizon.netmailto:xxxxx
Sent: ?1/?24/?2013 4:56 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: [ntdev] Verifier Causes Breakpoint in WDFInterruptEnable

I am working on porting a very old pre pnp driver to be pnp using WDF. I seem to have things working and have been trying to do more robust testing. I got Prefast to be happy and then moved on to trying verifier. When I turn on verify with the normal settings, I find that a breakpoint is called in WDFInterruptEnable. The situation is this. In my EvtDeviceControl routine I prepare the hardware to do the requested task, then call WDFInterruptEnable to enable interrupts. When I run without verifier, everything seems to work fine. When verifier in on, Windbg shows a breakpoint has been hit in WDFInterrupt Enable. If I tell Windbg to continue, my EvtInterruptEnable is not called and the application hangs waiting for the request to complete. If I terminate the user task, the cancel routine is called and the request is canceled correctly.

I do not understand why this is happening and what it means. Have I coded something incorrectly?


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer</mailto:xxxxx></mailto:xxxxx>

> Make sure you have symbols set up properly and then run

!wdfkd.wdflogdump (your driver)

And it should tell you what is wrong. But what you described is not a
typical pattern for an interrupt. Typically you do not explicitly enable
/ disable the interrupt object, you let kmdf do it on power on/off for
you.

d


From: xxxxx@verizon.netmailto:xxxxx
> Sent: ý1/ý24/ý2013 4:56 PM
> To: Windows System Software Devs Interest Listmailto:xxxxx
> Subject: [ntdev] Verifier Causes Breakpoint in WDFInterruptEnable
>
> I am working on porting a very old pre pnp driver to be pnp using WDF. I
> seem to have things working and have been trying to do more robust
> testing. I got Prefast to be happy and then moved on to trying verifier.
> When I turn on verify with the normal settings, I find that a breakpoint
> is called in WDFInterruptEnable. The situation is this. In my
> EvtDeviceControl routine I prepare the hardware to do the requested task,
> then call WDFInterruptEnable to enable interrupts. When I run without
> verifier, everything seems to work fine. When verifier in on, Windbg
> shows a breakpoint has been hit in WDFInterrupt Enable. If I tell Windbg
> to continue, my EvtInterruptEnable is not called and the application hangs
> waiting for the request to complete. If I terminate the user task, the
> cancel routine is called and the request is canceled correctly.
>
> I do not understand why this is happening and what it means. Have I
> coded something incorrectly?
>
As I told my students in app space, if the program fails with error
checking enabled, then it is not correct. The problem, of course, is to
figure out what went wrong. Note that when verifier is installed, the
execution path is not the same, and in particular, the “virtualization” of
the I/O system by the verifier means that under the detected error
condition, the verifier may choose to return to the caller instead of
forwarding the request.

In app space, using MFC, we at least had the source. So you could look
inside it and see

if(…)
{
// Mars is in trine with Jupiter
// The Moon is full
// This call is disallowed
DebugBreak();
return;
}

So the answer is: you did something the verifier didn’t like. To which it
has done the equivalent of the poem

I do not like thee, Dr. Fell.
Exactly why, I cannot tell.
But this I know, and know full well,
I do not like thee, Dr. Fell.
See http://eclipse.rutgers.edu/goose/rhymes/fell/6.aspx

The verifier seems to be no more informed than poor Dr. Fell (1625-1696).
joe
>
> —
> NTDEV is sponsored by OSR
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
>
> —
> NTDEV is sponsored by OSR
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer</mailto:xxxxx></mailto:xxxxx>

When I tried to get the dump, this is the response

0: kd> !wdfsearchpath c:\winddk\7600.16385.1\tools\tracing\i386
Trace searchpath is: c:\winddk\7600.16385.1\tools\tracing\i386
0: kd> !wdflogdump sgrwdf
Trace searchpath is: c:\winddk\7600.16385.1\tools\tracing\i386

Trace format prefix is: %7!u!: %!FUNC! -
error: Could not retrieve WDF log header for driver sgrwdf.
hint: Build your driver with newer WDF libraries.

This was build with the WDK 7.1 build for XP WDF if 1.9

Fix your sympath to point to the public sym server, .reload Wdf01000.sys, and make sure your driver symbols are correct as well

d


From: xxxxx@verizon.netmailto:xxxxx
Sent: ?1/?24/?2013 8:41 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: RE:[ntdev] Verifier Causes Breakpoint in WDFInterruptEnable

When I tried to get the dump, this is the response

0: kd> !wdfsearchpath c:\winddk\7600.16385.1\tools\tracing\i386
Trace searchpath is: c:\winddk\7600.16385.1\tools\tracing\i386
0: kd> !wdflogdump sgrwdf
Trace searchpath is: c:\winddk\7600.16385.1\tools\tracing\i386

Trace format prefix is: %7!u!: %!FUNC! -
error: Could not retrieve WDF log header for driver sgrwdf.
hint: Build your driver with newer WDF libraries.

This was build with the WDK 7.1 build for XP WDF if 1.9


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer</mailto:xxxxx></mailto:xxxxx>

Doron,
Here is the log. I am afraid it tells me nothing…

0: kd> !wdfkd.wdflogdump sgrwdf
Trace searchpath is: c:\winddk\7600.16385.1\tools\tracing\i386

Trace format prefix is: %7!u!: %!FUNC! -
Log at 8aa7a000
Gather log: Please wait, this may take a moment (reading 4032 bytes).
% read so far … 10, 20, 30, 40, 50, 60, 70, 80, 90, 100
There are 91 log entries
— start of log —
Unknown( 14): GUID=1c6af04a-8c20-a063-1976-7299d70a2744 (No Format Information found).
Unknown( 15): GUID=9fad61e3-68ff-f42e-15fe-7a3fb252225e (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 15): GUID=9fad61e3-68ff-f42e-15fe-7a3fb252225e (No Format Information found).
Unknown( 14): GUID=1c6af04a-8c20-a063-1976-7299d70a2744 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 14): GUID=1c6af04a-8c20-a063-1976-7299d70a2744 (No Format Information found).
Unknown( 14): GUID=1c6af04a-8c20-a063-1976-7299d70a2744 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 14): GUID=1c6af04a-8c20-a063-1976-7299d70a2744 (No Format Information found).
Unknown( 14): GUID=1c6af04a-8c20-a063-1976-7299d70a2744 (No Format Information found).
Unknown( 18): GUID=d816b6e3-c6ba-363d-54b4-3533d1de16bb (No Format Information found).
Unknown( 15): GUID=9fad61e3-68ff-f42e-15fe-7a3fb252225e (No Format Information found).
Unknown( 15): GUID=9fad61e3-68ff-f42e-15fe-7a3fb252225e (No Format Information found).
Unknown( 15): GUID=9fad61e3-68ff-f42e-15fe-7a3fb252225e (No Format Information found).
Unknown( 15): GUID=9fad61e3-68ff-f42e-15fe-7a3fb252225e (No Format Information found).
Unknown( 14): GUID=1c6af04a-8c20-a063-1976-7299d70a2744 (No Format Information found).
Unknown( 15): GUID=9fad61e3-68ff-f42e-15fe-7a3fb252225e (No Format Information found).
Unknown( 26): GUID=b08d780f-dac6-1796-1fec-bf92340e06bb (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 15): GUID=9fad61e3-68ff-f42e-15fe-7a3fb252225e (No Format Information found).
Unknown( 14): GUID=1c6af04a-8c20-a063-1976-7299d70a2744 (No Format Information found).
Unknown( 14): GUID=1c6af04a-8c20-a063-1976-7299d70a2744 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 16): GUID=a06c4939-ec03-9e2b-f095-211ff9a6d5e5 (No Format Information found).
Unknown( 10): GUID=700c2c8f-7929-cc3b-0a3f-104b02a570ab (No Format Information found).
---- end of log ----

Sigh!

You need to set the TMF File Path to enable interpretation of the dump information.

!wdftmffile is the command you want. The TMF file you need is in the WDK, in the \tracing directory, and is specific to the version of KMDF that you’re using.

Peter
OSR

Thanks, I will try this. In the meantime, I went back and looked at the OSR DIO example which is what I started with. I found that there, they did not call WDFInterruptEnable, but instead directly called the EvtInterruptEnable. I changed my driver to do this, and it seems to resolve the problem. Now I am wondering does this fix a problem? Or only make verifier miss the problem? If it fixes it, why was it incorrect to call WDFInterruptEnable?

The log will tell you why verifier broke into the debugger

d


From: xxxxx@verizon.netmailto:xxxxx
Sent: ?1/?25/?2013 7:34 AM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: RE:[ntdev] Verifier Causes Breakpoint in WDFInterruptEnable

Thanks, I will try this. In the meantime, I went back and looked at the OSR DIO example which is what I started with. I found that there, they did not call WDFInterruptEnable, but instead directly called the EvtInterruptEnable. I changed my driver to do this, and it seems to resolve the problem. Now I am wondering does this fix a problem? Or only make verifier miss the problem? If it fixes it, why was it incorrect to call WDFInterruptEnable?


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer</mailto:xxxxx></mailto:xxxxx>

Ugh. That’s a VERY old example, that dates back to when KMDF was first released, and I quite frankly forgot that it was still available. Well, it’s not available any more in any case :wink:

That driver is old enough that is it no longer what I would consider “demonstration quality” today. In fact, some of it is downright embarrassing. The sample certainly no longer demonstrates best practices.

I will post the updated version at some point in the future.

The ugliness about which I am most concerned is mostly to do with cancellation and serialization. There’s some seriously ugly shit in that sample. We all live and learn, right?

Well, yes… it fixes the problem in that it enables and disables the interrupts on your device without asking KMDF to do it for you.

I’ll be the problem you’re encountering with calling WdfInterruptEnable is that you’re not calling it at IRQL PASSIVE_LEVEL. I’m not sure what it’s constrained to be called at IRQL PASSIVE_LEVEL (it doesn’t really make sense to me… and this is a very significant constraint for those drivers that need to manually enable/disable interrupts based on other things occuring), but indeed it is.

The major issue of which I am aware with calling the EvtInterruptEnable (or EvtInterruptDisable) callback directly in your code is that doing so does NOT serialize with your ISR unless you explicitly acquire your interrupt lock prior to calling.

While the DIO-24 sample is structured to avoid it, there is also an issue with having interrupts enabled on your device if the Framework doesn’t know about it.

In general, you should enable interrupts on your device when the Framework asks you to, and disable interrupts on your device when the Framework asks you to. There are VERY few cases when enabling interrupts at certain times based on driver decisions is the best idea. In fact, the DIO-24 driver doesn’t really NEED to do this, and the fact that it enables and disables interrupts based on the operating mode of the device really reflects the “old WDM way of thinking” of the author of that driver, and not best KMDF practices.

Peter
OSR

I’m guessing the OP is doing this instead of using an interrupt spinlock to
serialize state changes with his ISR. And I agree that there are perhaps
very few if any good reasons to call WdfInterruptEnable/Disable.

Mark Roddy

On Fri, Jan 25, 2013 at 11:47 AM, wrote:

>


>
> Ugh. That’s a VERY old example, that dates back to when KMDF was first
> released, and I quite frankly forgot that it was still available. Well,
> it’s not available any more in any case :wink:
>
> That driver is old enough that is it no longer what I would consider
> “demonstration quality” today. In fact, some of it is downright
> embarrassing. The sample certainly no longer demonstrates best practices.
>
> I will post the updated version at some point in the future.
>
> The ugliness about which I am most concerned is mostly to do with
> cancellation and serialization. There’s some seriously ugly shit in that
> sample. We all live and learn, right?
>
>


>
> Well, yes… it fixes the problem in that it enables and disables the
> interrupts on your device without asking KMDF to do it for you.
>
> I’ll be the problem you’re encountering with calling WdfInterruptEnable is
> that you’re not calling it at IRQL PASSIVE_LEVEL. I’m not sure what it’s
> constrained to be called at IRQL PASSIVE_LEVEL (it doesn’t really make
> sense to me… and this is a very significant constraint for those drivers
> that need to manually enable/disable interrupts based on other things
> occuring), but indeed it is.
>
> The major issue of which I am aware with calling the EvtInterruptEnable
> (or EvtInterruptDisable) callback directly in your code is that doing so
> does NOT serialize with your ISR unless you explicitly acquire your
> interrupt lock prior to calling.
>
> While the DIO-24 sample is structured to avoid it, there is also an issue
> with having interrupts enabled on your device if the Framework doesn’t know
> about it.
>
> In general, you should enable interrupts on your device when the Framework
> asks you to, and disable interrupts on your device when the Framework asks
> you to. There are VERY few cases when enabling interrupts at certain times
> based on driver decisions is the best idea. In fact, the DIO-24 driver
> doesn’t really NEED to do this, and the fact that it enables and disables
> interrupts based on the operating mode of the device really reflects the
> “old WDM way of thinking” of the author of that driver, and not best KMDF
> practices.
>
> Peter
> OSR
>
> —
> NTDEV is sponsored by OSR
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

That would be a very poor design indeed.

Peter
OSR

Do to other projects, I have not been able to get a log file yet. However since there seems be a lot of suggestions that you should not call WDFInterruptEnable, let me explain what I am trying to do and perhaps you can instruct me on the “correct” way of doing it.

The user calls the driver with DeviceIoControl to request data. The amount of data is specified by the size of the Output Buffer, the Input Buffer contains information about what to collect

The driver EvtDeviceControl function programs to device to collect the data, then enables interrupts (somehow TDB) then returns status = STATUS_PENDING

When an interrupt occurs, the ISR is called. It verifies that the interrupt belongs to it, clears the interrupt in the hardware, disables further interrupts from the hardware and then queues the DPC routine.

The DPC routine removes data from the hardware putting it in the outputbuffer until either there is not data left in the hardware (it has a FIFO) or the amount of data needed to satisfy the user has been collected. If enough data is collected, the Request is completed with the data. If not, Interrupts are enabled on the hardware (somehow, TBD).

In this situation, the WDF framework seems to call EvtInterruptEnable too early. That is before the EvtDeviceControl has been called by the user request. So what I did (again sort of following the example of the OSR DIO driver) was to use data in by deviceContext are to decide if I truly wanted to enable interrupts or not in the EvtInterruptEnable . Now the question is how does EvtDeviceControl enable interrupts when it is ready.

WDFInterruptEnable?
EvtInterruptEnable ?
Just write to the hardware registers to do it?

xxxxx@verizon.net wrote:

Do to other projects, I have not been able to get a log file yet. However since there seems be a lot of suggestions that you should not call WDFInterruptEnable, let me explain what I am trying to do and perhaps you can instruct me on the “correct” way of doing it.

The user calls the driver with DeviceIoControl to request data. The amount of data is specified by the size of the Output Buffer, the Input Buffer contains information about what to collect

The driver EvtDeviceControl function programs to device to collect the data, then enables interrupts (somehow TDB) then returns status = STATUS_PENDING

In many cases (I’d say “most”, but there are probably too many
exceptions), you enable interrupts when you enter D0 state, and disable
them when you leave D0 state, so interrupts remain enabled during the
life of your driver. Your ISR shouldn’t get hit unless there is a
request for it, so it’s not clear why you’d go to the trouble of
disabling and re-enabling.

If you can only service one thing at a time, then use a sequential queue
to ensure that you only submit one request at a time.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Some of the issues of interrupt enabling are highly dependent on the
nature of the device. For a device that does not interrupt unless it has
been asked to do someting, the enable-on-D0 works fine. But “streaming”
device might interrupt at regular intervals. Therefore, it may be
inappropriate to have interrupts enabled unless there is an IRP in
progress. Other devices that can lose data if the interrupt is not
serviced may find that interrupts are best enabled at IRP_MJ_CREATE and
disabled on IRP_MJ_CLOSE, with internal buffering to deal with what to do
with data coming in with no pending IRP. I have written many drivers over
the last 45 or so years whicj fell into one of these categories. I’ve
seen several Windows drivers that failed because the wrong scope was
chosen.
joe

xxxxx@verizon.net wrote:
> Do to other projects, I have not been able to get a log file yet.
> However since there seems be a lot of suggestions that you should not
> call WDFInterruptEnable, let me explain what I am trying to do and
> perhaps you can instruct me on the “correct” way of doing it.
>
> The user calls the driver with DeviceIoControl to request data. The
> amount of data is specified by the size of the Output Buffer, the Input
> Buffer contains information about what to collect
>
> The driver EvtDeviceControl function programs to device to collect the
> data, then enables interrupts (somehow TDB) then returns status =
> STATUS_PENDING

In many cases (I’d say “most”, but there are probably too many
exceptions), you enable interrupts when you enter D0 state, and disable
them when you leave D0 state, so interrupts remain enabled during the
life of your driver. Your ISR shouldn’t get hit unless there is a
request for it, so it’s not clear why you’d go to the trouble of
disabling and re-enabling.

If you can only service one thing at a time, then use a sequential queue
to ensure that you only submit one request at a time.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

> The driver EvtDeviceControl function programs to device to collect the data, then enables interrupts

Why not always keep the interrupts enabled? this is what the majority of drivers do.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

It’s a style thing. This is how WDF was designed, to allow the Framework to control whether interrupts are enabled at the device or not. Remember, the Framework is aware of the power state of your device and disconnects your ISR around Dx state transitions (unless you tell it otherwise). This prevents the dreaded interrupt storm for shared interrupts, where the powered-down device’s KINTERRUPT happens to be first in the list and reads his INTREQ register as all F’s (indicating an interrupt has been requested).

The best thing is to do as has already been suggested and enable/disable as requested by the framework (regardless of the device state).

If you really hate this, or your device’s architecture really won’t allow it, you *could* constrain your EvtIo event processing callbacks to run at IRQL PASSIVE_LEVEL and then use WdfInterruptEnable/WdfInterruptDisable as appropriate. But be sure that you really want to go against established convention before you take this approach.

Peter
OSR

If interrupts occurred before the user request, there would be nothing intelligent do with them. So it seemed logical not to enable them. Any data the device has prior to the user request is unacceptable. I am well aware that not all devices and applications are this way, but this one is.

Would doing what I suggest cause a problem with the Operating System?

I finally found the time to test things again. The log shows
178: imp_WdfDmaEnablerCreate - Called at wrong IRQL; at level 2, should be at level 0
---- end of log ----
I thought I had read the documentation and found that EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL was called at PASSIVE_LEVEL, but rereading it now I find that is not correct. So I guess this makes sense. I will think over things some more and see if I can just let the framework enable and disable interrupts and make make the other code just turn on and off the device function. Hopefully it will not cause interrupts when I do not want them.

Thank you for all of the help.

Typically you create a dma enabler once, usually in EvtDevicePrepareHardware(). You can still enable the interrupt in your IOCTL handler if you want

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@verizon.net
Sent: Tuesday, January 29, 2013 7:26 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Verifier Causes Breakpoint in WDFInterruptEnable

I finally found the time to test things again. The log shows
178: imp_WdfDmaEnablerCreate - Called at wrong IRQL; at level 2, should be at level 0
---- end of log ----
I thought I had read the documentation and found that EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL was called at PASSIVE_LEVEL, but rereading it now I find that is not correct. So I guess this makes sense. I will think over things some more and see if I can just let the framework enable and disable interrupts and make make the other code just turn on and off the device function. Hopefully it will not cause interrupts when I do not want them.

Thank you for all of the help.


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer