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
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),
¬ification,
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 |