IOCTL_SRIOV_NOTIFICATION IOCTL (pcivirt.h)
请求指示虚拟化堆栈希望在发生 SRIOV_PF_EVENT 中列出的某个事件时收到通知。
主要代码
输出缓冲区
一 个缓冲区,其中包含SRIOV_PF_EVENT类型值,该值在完成请求时由 PF) 驱动程序 (物理函数填充。
输出缓冲区长度
指向 变量的指针,该变量在请求完成时分配给输出缓冲区的写入字节数。
状态块
Irp->如果请求成功,IoStatus.Status 设置为 STATUS_SUCCESS。 否则, 状态 为相应的错误条件作为 NTSTATUS 代码。
注解
此 IOCTL 请求由虚拟化堆栈发送到公开GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE的 PCI Express SR-IOV 物理功能 (PF) 驱动程序。
IOCTL_SRIOV_NOTIFICATION请求由 PF 驱动程序保留在队列中,直到发送方取消请求或设备遇到SRIOV_PF_EVENT中列出的事件之一。 然后,驱动程序完成挂起的请求。
如果 PF 驱动程序在处理驱动程序尚未完成通知的即插即用事件时收到此 IOCTL 请求,则应立即完成 IOCTL 请求,并在输出缓冲区中提供事件详细信息。 否则,驱动程序应将请求排入队列,直到取消请求或发生需要通知的即插即用事件。
虚拟化堆栈可以在上 一个IOCTL_SRIOV_NOTIFICATION 请求完成后立即发送 IOCTL_SRIOV_NOTIFICATION 请求。 PF 驱动程序必须跟踪事件通知已送达的事实,并且不能两次完成同一事件的两个 IOCTL 请求。
它由 PF 驱动程序设置,直到它被发送方取消,或直到 PF 驱动程序遇到多个 PnP 事件之一,此时该事件完成。
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;
}
要求
要求 | 值 |
---|---|
Header | pcivirt.h |
IRQL | PASSIVE_LEVEL |