Bus Driver - Power Policy / Wake caps

Hi

I have a Bus driver (loaded by PCI.sys) which creates 2 FDOs (static enumeration). I have disabled 1 child FDO in Device Manager for now. Also my device has S0Idle and SxWake capabilities, but not true multifunctional device.

  1. When the stack comes up., both Bus FDO and Child FDO say they are the power policy owner. Is that correct? I am not calling WdfDeviceInitSetPowerPolicyOwnership() anywhere.
  2. If I do WdfDeviceInitSetPowerPolicyOwnership(DeviceInit, FALSE); for child FDO, then WdfDeviceAssignS0IdleSettings() for the child fails with below status. Also I do not get child D0Exit() when idle.

Error code: (NTSTATUS) 0xc0000010 (3221225488) - The specified request is not a valid operation for the target device.

  1. Since not true multi-func device, I want/should disable wake caps for child FDOs’ (and enable only for BUSDriver)?
    The Child PDOs’ are not doing any WdfDeviceSetPowerCapabilities(PDO)/WdfDeviceAssignS0IdleSettings()/WdfDeviceAssignSxWakeSettings().

3.1) Should I disable the wake capabilities for child FDOs’ through WdfDeviceSetPowerCapabilities(). But MDSN says
_“If more than one driver in the device’s driver stack call WdfDeviceSetPowerCapabilities(), the power manager uses the values that are supplied by the driver that is highest in the stack.” _
I am assuming here, BOTH my child FDOs’ would be top of the stack.

Also the default code I had,

  • Child FDO was calling WdfDeviceAssignS0IdleSettings(IdleCaps.IdleCanWakeFromS0) and WdfDeviceAssignSxWakeSettings(default wake settings). Then on idle for Child, I was getting child EvtDeviceArmWakeFromS0 / Disarm (no D0Exit/Entry).
  • Changing child to WdfDeviceAssignS0IdleSettings(IdleCannotWakeFromS0) and no WdfDeviceAssignSxWakeSettings(), I get child D0Exit/Entry on idle.

Which option should I use?
(All calls were succeeding in above cases - no STATUS_POWER_STATE_INVALID).

Thanks

On Jan 23, 2019, at 10:49 PM, msr wrote:
>
> I have a Bus driver (loaded by PCI.sys) which creates 2 FDOs (static enumeration). I have disabled 1 child FDO in Device Manager for now. Also my device has S0Idle and SxWake capabilities, but not true multifunctional device.

Well, if you are a PnP bus driver, then your bus driver FDO is creating 2 PDOs, and those PDOs trigger the loading of 2 FDOs. In that case, the bus FDO and child FDOs are two different stacks. Consider a USB host and the USB devices. The USB devices are children of the bus, but each of them has separate power management.

What do you mean by “not true multifunctional device”? If you are a bus driver creating child PDOs, then you are just like every other bus driver.

> 1) When the stack comes up., both Bus FDO and Child FDO say they are the power policy owner. Is that correct? I am not calling WdfDeviceInitSetPowerPolicyOwnership() anywhere.

Right. The child FDO is the power policy owner for the child device. The bus FDO is the power policy owner for the bus.

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

Note: The email was trying to reply to an invalid Discussion (290975).

Thanks Tim.

What do you mean by “not true multifunctional device”?
Consider a USB host and the USB devices. The USB devices are children of the bus, but each of them has separate power management.
I am not a true PCIe multi-function as spec mandates. Resources for the individual enumerated child devices are just carved out of the same BAR etc, as of now even the interrupt is same for both (logical) children.

I am ‘Single component, single state (F0)’, like mentioned in below MSDN. I do not have any distinct functional power states for each logical component of a device. All of device goes to Dx, Dis/Arm Wake.
https://docs.microsoft.com/en-us/windows-hardware/drivers/wdf/supporting-functional-power-states

In that case, the bus FDO and child FDOs are two different stacks.
O.k., this is where I think I got it wrong. I thought my 2 child devices are top of the stack, and if I did WdfDeviceSetPowerCapabilities(cannot_wake) in them, it will also turn off the wake caps of the BUS FDO as well.
My understanding is child doesn’t have to deal with Dis/Arm wake, Trigger. Child FDOs’ will/can still independently Idle in/out, go to Dx and KMDF then depending of Childs’ current state, will take care of Idling in/out, Dx of BusDriver. Additionally only BusDriver will/have to deal with Dis/Arm Wake, Trigger and when any of these callbacks happen, BusDriver will do the needed hw handling (and KMDF will bring the child devices to appropriate state as well)

Thanks

I can’t help but wonder if PoFx F-State management wouldn’t help here. You have one device, with two individual functional components. Assuming you can programmatically control the power usage of each of those “components” individually, and you want to transition the entire device to D3 when both components are in their lowest functional power stakes, this would be a good fit.

Not sure if you need a bus driver for other purposes, but… it’s something for you to consider at least.

Peter

Thanks Peter.

I was able to test with wake caps enabled/disabled for Child (always enabled for Bus) FDOs. Both Child/Bus idle in/out and S0 wake arm/disarm callbacks being called . Though I see significant delay below before the next callback is called in the scenario.

Sequence below [I (ofcourse) do not see calls marked X if child is IdleCannotWakeFromS0]

Child/Bus going to Dx (w/ wake aps enabled on both child/Bus)
Child_Pdo_EvtDeviceEnableWakeAtBus X
Child_Fdo_EvtDeviceArmWakeFromS0 X
Child_Fdo_EvtDeviceD0ExitPreInterruptsDisabled / ChildFdo_WdfEvtDeviceD0Exit
BusFdo_EvtDeviceArmWakeFromS0
BusFdo_EvtDeviceD0ExitPreInterruptsDisabled / BusFdo_EvtDeviceD0Exit

 Coming out of Dx both
BusFdo_EvtDeviceD0Entry / BusFdo_EvtDeviceD0EntryPostInterruptsEnabled
Delay***
BusFdo_EvtDeviceDisarmWakeFromS0
Child_Pdo_EvtDeviceDisableWakeAtBus X
Child_Fdo_WdfEvtDeviceD0Entry / ChildFdo_EvtDeviceD0EntryPostInterruptsEnabled
Delay*****
Child_Fdo_EvtDeviceDisarmWakeFromS0 X

I do not yet have setup to test bus level wakeup. I just have some I/O happening on ChildFDO as the trigger here, so no EvtDeviceWakeFromS0Triggered() called anywhere and the child also wakes up along with the BusFDo. Looks like child behaviour can be controlled with below.
WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS.ArmForWakeIfChildrenAreArmedForWake = FALSE;
WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS.IndicateChildWakeOnParentWake = FALSE; // I don’t know, just set to FALSE for now.
WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS.PowerUpIdleDeviceOnSystemWake

Also the Child PDOs’ are only doing WdfPdoInitSetEventCallbacks() (wake callbacks, but still no-ops for now), they not doing any WdfDeviceSetPowerCapabilities(PDO) / WdfDeviceAssignS0IdleSettings() / WdfDeviceAssignSxWakeSettings() yet. So I am not calling WdfDeviceIndicateWakeStatus() as well anywhere.

I use below WdfDeviceSetPowerCapabilities() for both Child/Bus FDOs’.
powerCaps.WakeFromD0 = WdfTrue;
//
powerCaps.DeviceD1 = WdfTrue;
powerCaps.WakeFromD1 = WdfTrue;
//
powerCaps.DeviceD2 = WdfTrue;
powerCaps.WakeFromD2 = WdfTrue;
//
powerCaps.WakeFromD3 = WdfTrue;
//
powerCaps.SystemWake = PowerSystemWorking;
powerCaps.DeviceWake = PowerDeviceD3;
//
powerCaps.DeviceState[PowerSystemWorking] = PowerDeviceD3;
powerCaps.DeviceState[PowerSystemSleeping1] = PowerDeviceD3;
powerCaps.DeviceState[PowerSystemSleeping2] = PowerDeviceD3;
powerCaps.DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
powerCaps.DeviceState[PowerSystemHibernate] = PowerDeviceD3;
powerCaps.DeviceState[PowerSystemShutdown] = PowerDeviceD3;

I’m sorry… it I have to ask: What are you trying to accomplish with this design? Because you’ve created a LOT of complexity, and I don’t see what it gets you… except for the requirement that there be two separate drivers for the child devices, both of which must be independently PnP aware (but for which they’ll really not get the behavior they expect… sort of like power management in the old days for USB devices on stupid hubs).

Peter

Peter

Yes, it is sort of complex now. The port driver architecture of one of the child devices changed, so had to split the drivers now itself. Also HW is planned to drive in the required features as well - logical component level power mgmt, individual component bus wake capability, true PCIe multi-func device.

Thanks