IOCTL_SRIOV_NOTIFICATION IOCTL (pcivirt.h)
La solicitud indica que la pila de virtualización quiere recibir una notificación cuando se produce uno de los eventos enumerados en SRIOV_PF_EVENT.
Código principal
Búfer de salida
Búfer que contiene un valor de tipo SRIOV_PF_EVENTque rellena el controlador de función física (PF) cuando completa la solicitud.
Longitud del búfer de salida
Puntero a la variable , que se asigna el número de bytes escritos al búfer de salida cuando se completa la solicitud.
Bloque de estado
Irp->ioStatus.Status se establece en STATUS_SUCCESS si la solicitud se realiza correctamente. De lo contrario, estado a la condición de error adecuada como código NTSTATUS.
Observaciones
La pila de virtualización envía esta solicitud IOCTL al controlador pci Express SR-IOV función física (PF) que expone GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE.
El controlador PF mantiene la solicitud IOCTL_SRIOV_NOTIFICATION en una cola hasta que el remitente cancela la solicitud o el dispositivo experimenta uno de los eventos enumerados en SRIOV_PF_EVENT. A continuación, el controlador completa la solicitud pendiente.
Si el controlador PF recibe esta solicitud de IOCTL mientras procesa un evento Plug and Play para el que el controlador aún no ha completado una notificación, debe completar la solicitud IOCTL inmediatamente con los detalles del evento en el búfer de salida. De lo contrario, el controlador debe poner en cola la solicitud hasta que se cancele o se produzca un evento Plug and Play que requiera notificación.
La pila de virtualización puede enviar la solicitud de IOCTL_SRIOV_NOTIFICATION inmediatamente después de que se complete la solicitud de IOCTL_SRIOV_NOTIFICATION anterior. El controlador PF debe realizar un seguimiento del hecho de que se ha entregado una notificación de eventos y no debe completar dos solicitudes de IOCTL para el mismo evento dos veces.
El controlador PF lo inserta hasta que el remitente lo cancela o hasta que el controlador PF experimenta uno de varios eventos PnP, momento en el que se completa.
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 |
---|---|
encabezado de | pcivirt.h |
irQL | PASSIVE_LEVEL |