IOCTL_SRIOV_NOTIFICATION IOCTL (pcivirt.h)

请求指示虚拟化堆栈希望在发生 SRIOV_PF_EVENT 中列出的某个事件时收到通知。

主要代码

IRP_MJ_DEVICE_CONTROL

输出缓冲区

一个缓冲区,其中包含一个 SRIOV_PF_EVENT类型值,该值在完成请求时由物理函数 (PF) 驱动程序填充。

输出缓冲区长度

指向变量的指针,该变量在请求完成后将写入字节数分配给输出缓冲区。

状态块

Irp->IoStatus.Status 设置为STATUS_SUCCESS(如果请求成功)。 否则,状态 相应的错误条件作为 NTSTATUS 代码。

言论

此 IOCTL 请求由虚拟化堆栈发送到公开GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE的 PCI Express SR-IOV 物理功能(PF)驱动程序。

IOCTL_SRIOV_NOTIFICATION 请求由 PF 驱动程序保存在队列中,直到发送方取消请求或设备遇到 SRIOV_PF_EVENT中列出的事件之一。 然后,驱动程序完成挂起的请求。

如果 PF 驱动程序在处理驱动程序尚未完成通知的即插即用事件时收到此 IOCTL 请求,则应立即完成 IOCTL 请求,并在输出缓冲区中显示事件详细信息。 否则,驱动程序应将请求排入队列,直到请求被取消或需要通知的即插即用事件发生。

虚拟化堆栈可以在上一个 IOCTL_SRIOV_NOTIFICATION 请求完成之后立即发送 IOCTL_SRIOV_NOTIFICATION 请求。 PF 驱动程序必须跟踪已传递事件通知的事实,并且不能为同一事件完成两次 IOCTL 请求。

它由 PF 驱动程序笔写,直到发送方取消,或者直到 PF 驱动程序遇到多个 PnP 事件之一,此时它完成。


case IOCTL_SRIOV_NOTIFICATION:
        TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL,
            "IOCTL_SRIOV_NOTIFICATION:\n");

        status = WdfRequestForwardToIoQueue(Request,
                                            fdoContext->NotificationQueue);
        if (!NT_SUCCESS(status))
        {
            // not able to push it into manual queue, too bad.
            TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                        "WdfRequestForwardToIoQueue failed status=%!STATUS!\n",
                        status);
            break;
        }

        //
        // Pnp might arrived before SRIOV_NOTIFICATION. Serve the new
        // outstanding pnp if there is one.
        //
        CheckPendingNotifications(fdoContext);
        status = STATUS_PENDING;
        break;



VOID
CheckPendingNotifications(
    __in PDEVICE_CONTEXT DeviceContext
    )
/*++

Routine Description:

    This routine checks if there is a pending event and a pending request
    for notification and if so completes the request.

Arguments:

    DeviceContext - Pointer to the device context

Return Value:

    None.

--*/
{
    PSRIOV_PF_EVENT notification;
    WDFQUEUE        queue;
    WDFREQUEST      request;
    NTSTATUS        status;

    PAGED_CODE();

    WdfWaitLockAcquire(DeviceContext->PnpStateLock, NULL);

    queue = DeviceContext->NotificationQueue;
    if (DeviceContext->PnpEventNew
        && NT_SUCCESS(WdfIoQueueRetrieveNextRequest(queue, &request)))
    {
        NT_ASSERT(DeviceContext->PnpEventPending != FALSE);
        DeviceContext->PnpEventNew = FALSE;

        status = WdfRequestRetrieveOutputBuffer(request,
                                                sizeof(*notification),
                                                &notification,
                                                NULL);
        if (!NT_SUCCESS(status))
        {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                "WdfRequestRetrieveOutputBuffer[SRIOV_NOTIFICATION] fail: %!STATUS!", status);
            WdfRequestComplete(request, status);
        }
        else
        {
            TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "Retrieved IoQueue request buffer (notification)\n");

            *notification = DeviceContext->PnpEventCode;
            WdfRequestCompleteWithInformation(request,
                                              STATUS_SUCCESS,
                                              sizeof(*notification));
        }
    }

    WdfWaitLockRelease(DeviceContext->PnpStateLock);

    return;
}

要求

要求 价值
标头 pcivirt.h
IRQL PASSIVE_LEVEL