Jake Oshins wrote:
KMDF was built to be a completely generic implementation of a device driver,
one that can be dropped into any bus and it will function.
I understand and I’m sure we all agree with that approach.
I had another goal, by the way, when I layed out this part of KMDF. I knew
that we rarely executed the rebalance code(*) and I wanted to be sure that
every KMDF driver automatically just worked when a rebalance came along. So
we modeled it as a normal partial tear-down so that the callback functions
invoked would be ones that were well tested.
That was a very smart idea!
We have no intention of changing the WDM contract,
I know, but you must agree with me that at least in this specific case, the WDK is so ambiguous that it is almost impossible to deduce what actually the contract is.
> The other comment is that a *subsequent* Pnp START should
> not be considered an implicit power-up. I don’t see any sense
> whatsoever in powering-up a device (if it was powered down
> for idle reasons), just for the purpose of rebalance.
If a device is powered down, but its interrupt is still enabled (though
probably masked) then we have to power the device back up to allow the
driver to disable that interrupt in the device hardware. This is why KMDF
transitions back to D0 when a device has idled out to a low power state and
then a new PnP state transition occurs. The situation gets even more
complicated when the device has a wake signal that is armed. Subsequent
events (during the rebalance, after uninstallation, whatever…) could cause
a PME interrupt or a device interrupt, neither of which can be handled
because the driver isn’t in place and ready to manipulate the device.
I’m not sure I follow your logic here. That is, I understand the KMDF approach. But I still don’t understand why pci.sys must put the device in D0 after a *second* START, except for possible compatibility reasons. Just in case I wasn’t clear, I am not talking here about the KDMF behavior on STOP and other Pnp state changes. I am talking about the PCI.SYS behavior on START (on any START following a STOP, not on the initial START one).
If the device was in D3 state before the STOP, then interrupts are usually already disabled. Either because the hardware does it automatically, or either because the driver did it manually. Otherwise, and if there is any risk of the hardware generating an interrupt, then the driver would indeed need to power-up to disable them. But in the worst case this would need to be done on STOP, not on START.
If wake-up was armed then, depending on the case, it might need to be disarmed and re-armed with the inherent power transitions. The driver would need to handle this.
And I mentioned idle, because that’s the only possibility I see for the device being powered down when receiving a STOP. So the pci.sys behavior on a subsequent START, is relevant only when the device was idle on STOP.
I didn’t insist with this issue when replying to Dave, because even when he didn’t answered this, I understood from his post that compatibility is an utmost goal. And changing the pci.sys behavior on START, might be a bit risky. To be honest, I suspect very few drivers if at all would break by this change alone. Most drivers that will break in rebalance, they probably would break anyway. But I understand you won’t take chances, specially not when KDMF is doing all those power transitions anyway.
Thanks for your post and all the “insider and historical” information. Was a very interesting read.
Btw, I understand you are “hal-man”. I have a good laugh the other day tracing kernel timers on one of my old machines, and finding it uses a function named … “HalAcpiBrokenPiiX” 