次の方法で共有


IOCTL_SRIOV_NOTIFICATION IOCTL (pcivirt.h)

要求は、SRIOV_PF_EVENTに一覧表示されているイベント のいずれかが発生したときに 仮想化スタックに通知されることを示します。

メジャー コード

IRP_MJ_DEVICE_CONTROL

出力バッファー

要求の完了時に物理関数 (PF) ドライバーによって入力される SRIOV_PF_EVENT型の値を含むバッファー。

出力バッファーの長さ

変数へのポインター。要求の完了時に出力バッファーに書き込まれたバイト数が割り当てられます。

ステータス ブロック

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 ドライバーは、イベント通知が配信され、同じイベントに対して 2 つの IOCTL 要求を 2 回完了してはならないという事実を追跡する必要があります。

PF ドライバーは、送信者によって取り消されるまで、または PF ドライバーでいくつかの PnP イベントのいずれかが発生し、その時点で完了するまで PF ドライバーによって処理されます。


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