Condividi tramite


IOCTL_SRIOV_NOTIFICATION IOCTL (pcivirt.h)

La richiesta indica che lo stack di virtualizzazione vuole ricevere una notifica quando si verifica uno degli eventi elencati in SRIOV_PF_EVENT.

Codice principale

IRP_MJ_DEVICE_CONTROL

Buffer di output

Buffer che contiene un valore di tipo SRIOV_PF_EVENTriempito dal driver della funzione fisica (PF) al termine della richiesta.

Lunghezza del buffer di output

Puntatore alla variabile, a cui viene assegnato il numero di byte scritti al buffer di output al termine della richiesta.

Blocco di stato

Irp-> IoStatus.Status è impostato su STATUS_SUCCESS se la richiesta ha esito positivo. In caso contrario, stato alla condizione di errore appropriata come codice NTSTATUS.

Osservazioni

Questa richiesta IOCTL viene inviata dallo stack di virtualizzazione al driver PCI Express SR-IOV Physical Function (PF) che espone GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE.

La richiesta di IOCTL_SRIOV_NOTIFICATION viene mantenuta in una coda dal driver PF fino a quando la richiesta non viene annullata dal mittente o dal dispositivo si verifica uno degli eventi elencati in SRIOV_PF_EVENT. Il driver completa quindi la richiesta in sospeso.

Se il driver PF riceve questa richiesta IOCTL durante l'elaborazione di un evento Plug and Play per cui il driver non ha ancora completato una notifica, deve completare immediatamente la richiesta IOCTL con i dettagli dell'evento nel buffer di output. In caso contrario, il driver deve accodarla fino a quando non viene annullata o viene generato un evento Plug and Play che richiede la notifica.

Lo stack di virtualizzazione può inviare la richiesta di IOCTL_SRIOV_NOTIFICATION immediatamente dopo il completamento della richiesta di IOCTL_SRIOV_NOTIFICATION precedente. Il driver PF deve tenere traccia del fatto che è stata recapitata una notifica degli eventi e non deve completare due richieste IOCTL per lo stesso evento due volte.

Viene inserita dal driver PF fino a quando non viene annullata dal mittente o fino a quando il driver PF non verifica uno dei diversi eventi PnP, a quel punto viene completato.


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

Fabbisogno

Requisito Valore
intestazione pcivirt.h
IRQL PASSIVE_LEVEL