SRIOV_SET_POWER_STATE callback function (pcivirt.h)

Sets the power state of the specified PCI Express SR-IOV Virtual Function (VF).

Syntax

SRIOV_SET_POWER_STATE SriovSetPowerState;

NTSTATUS SriovSetPowerState(
  [in] PVOID Context,
  [in] USHORT VfIndex,
  [in] DEVICE_POWER_STATE PowerState,
  [in] BOOLEAN Wake
)
{...}

Parameters

[in] Context

A pointer to a driver-defined context.

[in] VfIndex

A zero-based index of the VF to which this power state set operation applies.

[in] PowerState

A DEVICE_POWER_STATE-type value that indicates the Dx power state to set.

[in] Wake

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.

Return value

Set to STATUS_SUCCESS if the request is successful. Otherwise, return appropriate a NTSTATUS code to indicate the error condition.

Remarks

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;
}

Requirements

Requirement Value
Minimum supported client Windows 10
Minimum supported server Windows Server 2016
Target Platform Windows
Header pcivirt.h
IRQL PASSIVE_LEVEL