Compartilhar via


IOCTL_SRIOV_NOTIFICATION IOCTL (pcivirt.h)

A solicitação indica que a pilha de virtualização deseja ser notificada quando um dos eventos listados no SRIOV_PF_EVENT ocorrer.

Código principal

IRP_MJ_DEVICE_CONTROL

Buffer de saída

Um buffer que contém um valor de tipo SRIOV_PF_EVENTque é preenchido pelo driver de função física (PF) quando ele conclui a solicitação.

Comprimento do buffer de saída

Um ponteiro para a variável, que recebe o número de bytes gravados no buffer de saída quando a solicitação é concluída.

Bloco de status

Irp->IoStatus.Status será definido como STATUS_SUCCESS se a solicitação for bem-sucedida. Caso contrário, status à condição de erro apropriada como um código de NTSTATUS.

Observações

Essa solicitação IOCTL é enviada pela pilha de virtualização para o driver PF (PCI Express SR-IOV Physical Function) que expõe GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE.

A solicitação IOCTL_SRIOV_NOTIFICATION é mantida em uma fila pelo driver PF até que a solicitação seja cancelada pelo remetente ou o dispositivo experimente um dos eventos listados em SRIOV_PF_EVENT. Em seguida, o driver conclui a solicitação pendente.

Se o driver PF receber essa solicitação IOCTL durante o processamento de um evento Plug and Play para o qual o driver ainda não concluiu uma notificação, ele deverá concluir a solicitação IOCTL imediatamente com os detalhes do evento no buffer de saída. Caso contrário, o driver deverá enfileirar a solicitação até que ela seja cancelada ou um evento Plug and Play que exija a notificação.

A pilha de virtualização pode enviar a solicitação de IOCTL_SRIOV_NOTIFICATION imediatamente após a conclusão da solicitação de IOCTL_SRIOV_NOTIFICATION anterior. O driver PF deve acompanhar o fato de que uma notificação de evento foi entregue e não deve concluir duas solicitações IOCTL para o mesmo evento duas vezes.

Ele está pendente pelo driver PF até que seja cancelado pelo remetente ou até que o driver PF experimente um dos vários eventos PnP, momento em que ele é concluído.


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

Requisitos

Requisito Valor
cabeçalho pcivirt.h
IRQL PASSIVE_LEVEL