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

要求

要求
Header pcivirt.h
IRQL PASSIVE_LEVEL