共用方式為


IOCTL_SRIOV_NOTIFICATION IOCTL (pcivirt.h)

要求表示虛擬化堆疊想要在發生 SRIOV_PF_EVENT 中列出的其中一個事件時收到通知。

主要程序代碼

IRP_MJ_DEVICE_CONTROL

輸出緩衝區

緩衝區,其中包含實體函式在完成要求時, (PF) 驅動程式填入的 SRIOV_PF_EVENT類型值。

輸出緩衝區長度

變數的指標,這個指標會在要求完成時,將寫入的位元組數目指派給輸出緩衝區。

狀態區塊

Irp->如果要求成功,IoStatus.Status 會設定為 STATUS_SUCCESS。 否則, 狀態 為適當的錯誤狀況為 NTSTATUS 程式碼。

備註

此 IOCTL 要求是由虛擬化堆疊傳送至 PCI Express SR-IOV 實體函式, (公開GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE的 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