[Windows 10][PCIe][KMDF][Modern Standby] Bus Driver failed get D0Exit/D0Entry calls..

I have an interesting issue. I wrote a KMDF bus driver for a PCIe device, which creates a child device. The child device is a mini port driver. The bus driver opt to register with DFx(Directed Power Management ) by calling WdfDeviceAssignS0IdleSettings. The device is not wake capable. So it used “IdleCannotWakeFromS0” flag. The time out type is SystemManagedIdleTimeoutWithHint. The WdfDeviceAssignS0IdleSettingsAPI returned STAUS_SUCCESS.

Issue:

  1. The Bus driver does not get D0Exit/D0Entry while the system goes to Modern Stand by. What could be the reason?
  2. Does the bus driver need to call WdfDeviceAssignS0IdleSettings for the PDO (Which is created for the child device) as well?

Request your help…
By
Sam

The whole concept of “connected standby” is that no one needs to know. As along as the drivers have all said they are ready, the power can simply be removed , without any notifications, and restored later. Why do you need to know?

Hi Tim
When I did a Sleep Study (powercfg /SLEEPSTUDY), I found that my Pcie driver is the top offender, preventing the system from entering into Modern Stand By. This is very important for me ti have my driver MS compatible. Could you help me?

Why would modern standby be an issue for a PCIe device? Modern standby is mostly for tablets and phones that live on a tight power budget. It has always been problematic on desktops, which is the only place you find PCIe devices.

The basic difference behind modern standby and original standby is the notifications. The system looks at the current power state for all devices. If all devices are in D3, then the system can kill the power without letting anyone know. That means your driver must proactively go into a low-power state any time nothing is going on. You can’t wait for the system to prompt you. In the good old days, the system would send a request to all devices to go into D3. When they all responded, the system could drop power. With modern standby, the system doesn’t ask. It just checks its internal table of states and does it.

What that suggests is that you are not actually managing your power state, or your child driver is not managing its power state. The system doesn’t think you are in D3 yet.

It’s complicated.

When you opt-in to “SystemManagedIdleTimeoutWithHint” You are opting into handling power state transitions with the Power Management Frameworks (PoFx), and using F-States to get the equivalent power saving of D3, all while your device stays in D0.

In very brief: As Mr. Roberts suggests, the genesis of all this is tablets and phones, where there are few power rails and the relationships of those rails that do exist is only know to ACPI and/or the PEP. In such a setup, you can ask for your device to go into D3 all you want, but if you share the power rail with another device, while that other device is in D0 your device will never be in D3… EvtDeviceD0Exit being called or not.

So, I suspect the key piece that you’re missing is Functional power state managemen which is part of PoFx integration.

In your place, I’d try two things:

  1. Opt in to Directed Power Management (DPfx).
  2. If that doesn’t help: Try not specifying “SystemManagedIdleTimeoutWithHint” — Just specify a short, appropriate, timeout. When you get the D0Exit call, do as much as you can to power-down your device. Even on an Express bus, you probably share your power plane with another device. So, just like if you were on a SoC, when you’re told “D0 Exit” your device may not really lose power. IF there are things you can do to ACTIVELY manage the power consumption of your device (stopping a remote processor, suspending continuous DMA, whatever) by all means do that.
  3. If the above doesn’t work, you’re probably screwed. But try doing a PoFx-compliant implementation. This ALSO depends on you actively managing the Power usage of your device.

This stuff is absolutely non-trivial. It’s poorly documented, and it’s constantly evolving as the thinking/learning/understanding/goals in Windows continue to evolve.

I hope that helps,

Peter