IOCTL_SRIOV_ATTACH IOCTL (pcivirt.h)

The request indicates that the virtualization stack wants to register for Plug and Play events received by the SR-IOV device.

Major code

IRP_MJ_DEVICE_CONTROL

Status block

Irp->IoStatus.Status is set to STATUS_SUCCESS if the request is successful. Otherwise, Status to the appropriate error condition as a NTSTATUS code.

Remarks

This IOCTL request is sent by the virtualization stack to the PCI Express SR-IOV Physical Function (PF) driver that exposes GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE.

This request is unsafe if the PF device is currently stopped or stopping for resource re-balance. A device is considered to be stopped after it received IRP_MN_QUERY_STOP_DEVICE and restarted when it receives IRP_MN_CANCEL_STOP_DEVICE or when IRP_MN_START_DEVICE is completed by the lower devices in the stack. In this case, the driver must delay the completion of this request until the device is restarted.

It is not necessary to keep this IRP pending because the request always a sent as a synchronous kernel-mode IRP causing the caller to block the thread in any case.

Upon the completion of this request, the VSP can subsequently send IOCTL_SRIOV_NOTIFICATION and IOCTL_SRIOV_EVENT_COMPLETE requests.

To unregister for Plug and Play events, the VSP sends the IOCTL_SRIOV_DETACH request.

These events (defined in SRIOV_PF_EVENT) cause the completion of IOCTL_SRIOV_NOTIFICATION and a wait for IOCTL_SRIOV_EVENT_COMPLETE:

In this example handling of the IOCTL_SRIOV_ATTACH request, the PF driver maintains PnP states in its device context. The deviceContext->PnpRebalancing is set to TRUE, when the driver receives IRP_MN_QUERY_STOP_DEVICE and set to FALSE when it receives IRP_MN_START_DEVICE.
    case IOCTL_SRIOV_ATTACH:
        TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "IOCTL_SRIOV_ATTACH:\n");

        WdfWaitLockAcquire(fdoContext->PnpStateLock, NULL);

        //
        // Block until it is safe for the VSP to attach.  Don't
        // bother with pending this IRP since this is always a sent as
        // a synchronous kernel-mode IRP and the caller would block
        // the thread anyway.  May need to repeat the wait since
        // waiting for the safe-to-attach event must not be done while
        // holding the state lock.
        //
        while (fdoContext->PnpSafeToAttach == FALSE)
        {
            WdfWaitLockRelease(fdoContext->PnpStateLock);

            KeWaitForSingleObject(&fdoContext->PnpSafeEvent,
                                  Executive,
                                  KernelMode,
                                  FALSE,
                                  NULL);

            WdfWaitLockAcquire(fdoContext->PnpStateLock, NULL);
        }

        //
        // Allow only a single attach at any time.
        //
        if (fdoContext->PnpVspAttached == FALSE)
        {
            fdoContext->PnpVspAttached = TRUE;
            status = STATUS_SUCCESS;
        }
        else
        {
            status = STATUS_SHARING_VIOLATION;
        }
        WdfWaitLockRelease(fdoContext->PnpStateLock);

        break;

Requirements

Requirement Value
Header pcivirt.h
IRQL PASSIVE_LEVEL

See also

WdfIoTargetSendInternalIoctlSynchronously

WdfIoTargetSendInternalIoctlOthersSynchronously

Creating IOCTL Requests in Drivers

IOCTL_SRIOV_DETACH

WdfIoTargetSendIoctlSynchronously