Freigeben über


IOCTL_SRIOV_NOTIFICATION IOCTL (pcivirt.h)

Die Anforderung gibt an, dass der Virtualisierungsstapel benachrichtigt werden möchte, wenn eines der in SRIOV_PF_EVENT aufgeführten Ereignisse auftritt.

Hauptcode

IRP_MJ_DEVICE_CONTROL

Ausgabepuffer

Ein Puffer, der einen wert vom Typ SRIOV_PF_EVENT enthält, der vom PF-Treiber (Physical Function) gefüllt wird, wenn die Anforderung abgeschlossen wird.

Länge des Ausgabepuffers

Ein Zeiger auf die Variable, der die Anzahl der geschriebenen Bytes dem Ausgabepuffer zugewiesen wird, wenn die Anforderung abgeschlossen ist.

Statusblock

Irp->IoStatus.Status ist auf STATUS_SUCCESS festgelegt, wenn die Anforderung erfolgreich ist. Andernfalls wird status für die entsprechende Fehlerbedingung als NTSTATUS-Code verwendet.

Hinweise

Diese IOCTL-Anforderung wird vom Virtualisierungsstapel an den PCI Express SR-IOV Physical Function-Treiber (PF) gesendet, der GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE verfügbar macht.

Die IOCTL_SRIOV_NOTIFICATION Anforderung wird vom PF-Treiber in einer Warteschlange gehalten, bis die Anforderung entweder vom Absender abgebrochen wird oder das Gerät eines der in SRIOV_PF_EVENT aufgeführten Ereignisse erlebt. Der Treiber schließt dann die ausstehende Anforderung ab.

Wenn der PF-Treiber diese IOCTL-Anforderung empfängt, während er ein Plug & Play Ereignis verarbeitet, für das der Treiber noch keine Benachrichtigung abgeschlossen hat, sollte er die IOCTL-Anforderung sofort mit den Ereignisdetails im Ausgabepuffer abschließen. Andernfalls sollte der Treiber die Anforderung in die Warteschlange stellen, bis sie abgebrochen wird oder ein Plug & Play Ereignis auftritt, das eine Benachrichtigung erfordert.

Der Virtualisierungsstapel kann die IOCTL_SRIOV_NOTIFICATION Anforderung unmittelbar nach Abschluss der vorherigen IOCTL_SRIOV_NOTIFICATION Anforderung senden. Der PF-Treiber muss die Tatsache nachverfolgen, dass eine Ereignisbenachrichtigung übermittelt wurde, und darf zwei IOCTL-Anforderungen für dasselbe Ereignis nicht zweimal ausführen.

Es wird vom PF-Treiber geschrieben, bis es vom Absender abgebrochen wird oder bis der PF-Treiber eines von mehreren PnP-Ereignissen erlebt, an dem er abgeschlossen ist.


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

Anforderungen

Anforderung Wert
Header pcivirt.h
IRQL PASSIVE_LEVEL