IOCTL_SRIOV_NOTIFICATION IOCTL (pcivirt.h)

La demande indique que la pile de virtualisation souhaite être avertie quand l’un des événements répertoriés dans SRIOV_PF_EVENT se produit.

Code principal

IRP_MJ_DEVICE_CONTROL

Mémoire tampon de sortie

Mémoire tampon qui contient une valeur de type SRIOV_PF_EVENT qui est remplie par le pilote de fonction physique (PF) lorsqu’il termine la requête.

Longueur de la mémoire tampon de sortie

Pointeur vers la variable, qui reçoit le nombre d’octets écrits dans la mémoire tampon de sortie une fois la demande terminée.

Bloc d’état

Irp->IoStatus.Status est défini sur STATUS_SUCCESS si la demande réussit. Sinon, état à la condition d’erreur appropriée en tant que code NTSTATUS .

Remarques

Cette requête IOCTL est envoyée par la pile de virtualisation au pilote PCI Express SR-IOV Physical Function (PF) qui expose GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE.

La demande IOCTL_SRIOV_NOTIFICATION est conservée dans une file d’attente par le pilote PF jusqu’à ce que la demande soit annulée par l’expéditeur ou que l’appareil rencontre l’un des événements répertoriés dans SRIOV_PF_EVENT. Le pilote termine ensuite la requête en attente.

Si le pilote PF reçoit cette demande IOCTL lors du traitement d’un événement Plug-and-Play pour lequel le pilote n’a pas encore terminé de notification, il doit immédiatement terminer la demande IOCTL avec les détails de l’événement dans la mémoire tampon de sortie. Sinon, le pilote doit mettre la demande en file d’attente jusqu’à ce qu’elle soit annulée ou qu’un événement Plug-and-Play nécessitant une notification se produise.

La pile de virtualisation peut envoyer la requête IOCTL_SRIOV_NOTIFICATION immédiatement après la fin de la demande de IOCTL_SRIOV_NOTIFICATION précédente. Le pilote PF doit garder la trace du fait qu’une notification d’événement a été remise et ne doit pas remplir deux fois les demandes IOCTL pour le même événement.

Il est suspendu par le pilote PF jusqu’à ce qu’il soit annulé par l’expéditeur ou jusqu’à ce que le pilote PF rencontre l’un des plusieurs événements PnP, auquel cas il est terminé.


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

Configuration requise

Condition requise Valeur
En-tête pcivirt.h
IRQL PASSIVE_LEVEL