IOCTL_SRIOV_NOTIFICATION IOCTL (pcivirt.h)
要求は、SRIOV_PF_EVENTに一覧表示されているイベント のいずれかが発生したときに 仮想化スタックに通知されることを示します。
メジャー コード
出力バッファー
要求の完了時に物理関数 (PF) ドライバーによって入力される SRIOV_PF_EVENT型の値を含むバッファー。
出力バッファーの長さ
変数へのポインター。要求の完了時に出力バッファーに書き込まれたバイト数が割り当てられます。
ステータス ブロック
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 ドライバーは、イベント通知が配信され、同じイベントに対して 2 つの IOCTL 要求を 2 回完了してはならないという事実を追跡する必要があります。
PF ドライバーは、送信者によって取り消されるまで、または PF ドライバーでいくつかの PnP イベントのいずれかが発生し、その時点で完了するまで PF ドライバーによって処理されます。
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 |