// pcivirt.h
SRIOV_SET_POWER_STATE SriovSetPowerState;
NTSTATUS SriovSetPowerState(
[in] PVOID Context,
[in] USHORT VfIndex,
[in] DEVICE_POWER_STATE PowerState,
[in] BOOLEAN Wake
)
{...}
View the official Windows Driver Kit DDI referenceNo description available.
Sets the power state of the specified PCI Express SR-IOV Virtual Function (VF).
Context [in]A pointer to a driver-defined context.
VfIndex [in]A zero-based index of the VF to which this power state set operation applies.
PowerState [in]A DEVICE_POWER_STATE-type value that indicates the Dx power state to set.
Wake [in]A boolean value that indicates whether to arm the device for a wake signal (PME for PCI Express devices), as it goes into the low power state. TRUE indicates the device is armed; FALSE otherwise. This value must be FALSE if PowerState is PowerDeviceD0.
Set to STATUS_SUCCESS if the request is successful. Otherwise, return appropriate a NTSTATUS code to indicate the error condition.
NTSTATUS SRIOV_SET_POWER_STATE(
_In_ PVOID Context,
_In_ USHORT VfIndex,
_In_ DEVICE_POWER_STATE PowerState,
_In_ BOOLEAN Wake
);
This callback function is implemented by the physical function (PF) driver. The callback is invoked when the system wants to change the power state of a virtual function.
The PF driver registers its implementation by setting the SetVfPowerState member of the SRIOV_DEVICE_INTERFACE_STANDARD, configuring a WDF_QUERY_INTERFACE_CONFIG structure, and calling WdfDeviceAddQueryInterface.
Here is an example implementation of this callback function.
NTSTATUS
Virtualization_SetPowerState (
__inout PVOID Context,
USHORT VfIndex,
DEVICE_POWER_STATE PowerState,
BOOLEAN Wake
)
{
PDEVICE_CONTEXT deviceContext;
WDF_POWER_DEVICE_STATE wdfPowerState;
NTSTATUS status;
PAGED_CODE();
status = STATUS_SUCCESS;
TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INTERFACE,
"Virtualization_SetPowerState received with \
VFIndex = %d, PowerState = %d, Wake = %d\n",
VfIndex, PowerState, Wake);
deviceContext = (PDEVICE_CONTEXT) Context;
if (VfIndex >= deviceContext->NumVFs)
{
TraceEvents(TRACE_LEVEL_ERROR, DBG_INTERFACE,
"VfIndex specified: %d was out of bounds. NumVFs: %d\n",
VfIndex, deviceContext->NumVFs);
return STATUS_INVALID_PARAMETER;
}
switch (PowerState)
{
case PowerDeviceD0:
wdfPowerState = WdfPowerDeviceD0;
break;
case PowerDeviceD1:
wdfPowerState = WdfPowerDeviceD1;
break;
case PowerDeviceD2:
wdfPowerState = WdfPowerDeviceD2;
break;
case PowerDeviceD3:
wdfPowerState = WdfPowerDeviceD3;
break;
default:
return STATUS_INVALID_PARAMETER;
}
WdfWaitLockAcquire(deviceContext->PowerStateLock, NULL);
deviceContext->VfContext[VfIndex].VfPowerDeviceState = wdfPowerState;
deviceContext->VfContext[VfIndex].VfWake = Wake;
WdfWaitLockRelease(deviceContext->PowerStateLock);
return status;
}