IOCTL_SRIOV_NOTIFICATION IOCTL (pcivirt.h)
要求表示虛擬化堆疊想要在發生 SRIOV_PF_EVENT 中列出的其中一個事件時收到通知。
主要程序代碼
輸出緩衝區
緩衝區,其中包含實體函式在完成要求時, (PF) 驅動程式填入的 SRIOV_PF_EVENT類型值。
輸出緩衝區長度
變數的指標,這個指標會在要求完成時,將寫入的位元組數目指派給輸出緩衝區。
狀態區塊
Irp->如果要求成功,IoStatus.Status 會設定為 STATUS_SUCCESS。 否則, 狀態 為適當的錯誤狀況為 NTSTATUS 程式碼。
備註
此 IOCTL 要求是由虛擬化堆疊傳送至 PCI Express SR-IOV 實體函式, (公開GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE的 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;
}
規格需求
需求 | 值 |
---|---|
標頭 | pcivirt.h |
IRQL | PASSIVE_LEVEL |