With its integration into the Win8 WDK, I've been running SDV quite a bit on my drivers. I can honestly say that it's found one or two problems... when it doesn't accvio. But that's not why I'm posting here.
My KMDF driver was accused of being a violator of the DrvAckIoStop rule... which apparently means "Your driver could have a Request that was presented by a power managed Queue in progress when your device wants to leave D0, and you don't have an EvtIoStop or anything to deal with this." I'm obviously retarded, because it took me about an hour to figure this out. I thought maybe SDV was trying to teach me some deep, dark, subtlety of KMDF power managed Queues that was previously unknown to me.
It turns out that I'm not a cursed violator, and I didn't need an EvtIoStop function. But this also caused me to muse on the whole issue of when you do or do not need an EvtIoStop function in your driver. It turns out, after thinking about it for a while and discussing this a bit on NTDEV, that you need to use EvtIoStop more than I previously thought. And it turns out the folks at Microsoft have come to the same conclusion. Why do you need EvtIoStop? Well...
I) Before a device can transition to Dx, its power managed Queues must be stopped.
II) Before a power managed Queue can be stopped, any Requests that have been presented from that Queue, but not yet completed by the driver, must be "accounted for." You can "account for" each these Requests by:
-
Completing it in a timely manner
-
Successfully sending it to an I/O Target using Send And Forget
-
Forwarding it to another Queue
-
Registering an EvtIoStop event processing callback that does one of the following:
-
re-queues the Request if it currently owned by the driver, by calling WdfRequestStopAcknowledge with Requeue set to TRUE
-
holds the Request in progress by calling WdfRequestStopAcknowledge with Requeue set to FALSE
-
completes the Request (with whatever status makes sense)
-
successfully cancels the Request by calling WdfRequestCancelSentRequest if the Request has been previous sent to an I/O Target without using Send And Forget
-
Successfully send the Request to an I/O Target using Send And Forget
-
Forward the Request to another Queue
Granted 5 and 6 above are unusual possibilities, but they're technically valid. And I *think* that's the entire universe of correct possibilities.
EvtIoStop is probably poorly understood and hence under utilized. I know we don't talk about it much, if at all, in our KMDF seminars. I think I'll add some discussion on this topic.