static VOID VifDisable( IN PXENVIF_VIF_CONTEXT Context ) { PXENVIF_FRONTEND Frontend = PdoGetFrontend(Context->Pdo); KIRQL Irql; PKEVENT Event; Trace("====>\n"); AcquireMrswLockExclusive(&Context->Lock, &Irql); if (!Context->Enabled) { ReleaseMrswLockExclusive(&Context->Lock, Irql, FALSE); goto done; } Context->Enabled = FALSE; Event = MacGetEvent(FrontendGetMac(Frontend)); KeSetEvent(Event, IO_NO_INCREMENT, FALSE); SUSPEND(Deregister, Context->SuspendInterface, Context->SuspendCallbackLate); Context->SuspendCallbackLate = NULL; SUSPEND(Release, Context->SuspendInterface); Context->SuspendInterface = NULL; (VOID) FrontendSetState(Frontend, FRONTEND_CONNECTED); ReleaseMrswLockExclusive(&Context->Lock, Irql, TRUE); ReceiverWaitForPackets(FrontendGetReceiver(Frontend)); TransmitterAbortPackets(FrontendGetTransmitter(Frontend)); KeClearEvent(&Context->MonitorEvent); ThreadWake(Context->MonitorThread); Trace("waiting for monitor thread\n"); (VOID) KeWaitForSingleObject(&Context->MonitorEvent, Executive, KernelMode, FALSE, NULL); RtlZeroMemory(&Context->Callback, sizeof (VIF_CALLBACK)); ReleaseMrswLockShared(&Context->Lock); done: Trace("<====\n"); }
DECLSPEC_NOINLINE VOID PdoD3ToD0( IN PXENVBD_PDO Pdo ) { LogTrace("Target[%d] =====> (Irql=%d)\n", Pdo->Frontend.TargetId, KeGetCurrentIrql()); // connect to backend FrontendSetState(&Pdo->Frontend, XENVBD_ENABLED); LogTrace("Target[%d] <===== (Irql=%d)\n", Pdo->Frontend.TargetId, KeGetCurrentIrql()); }
DECLSPEC_NOINLINE VOID PdoD0ToD3( IN PXENVBD_PDO Pdo ) { LogTrace("Target[%d] =====> (Irql=%d)\n", Pdo->Frontend.TargetId, KeGetCurrentIrql()); // disconnect from backend FrontendSetState(&Pdo->Frontend, XENVBD_CLOSED); // target suspended LogTrace("Target[%d] <===== (Irql=%d)\n", Pdo->Frontend.TargetId, KeGetCurrentIrql()); }
static DECLSPEC_NOINLINE VOID VifSuspendCallbackLate( IN PVOID Argument ) { PXENVIF_VIF_CONTEXT Context = Argument; PXENVIF_FRONTEND Frontend = PdoGetFrontend(Context->Pdo); NTSTATUS status; status = FrontendSetState(Frontend, FRONTEND_ENABLED); ASSERT(NT_SUCCESS(status)); TransmitterAdvertizeAddresses(FrontendGetTransmitter(Frontend)); }
static NTSTATUS VifEnable( IN PXENVIF_VIF_CONTEXT Context, IN VOID (*Function)(PVOID, XENVIF_CALLBACK_TYPE, ...), IN PVOID Argument ) { PXENVIF_FRONTEND Frontend = PdoGetFrontend(Context->Pdo); KIRQL Irql; PVIF_CALLBACK Callback; PKEVENT Event; NTSTATUS status; Trace("====>\n"); AcquireMrswLockExclusive(&Context->Lock, &Irql); if (Context->Enabled) goto done; Callback = &Context->Callback; Callback->Function = Function; Callback->Argument = Argument; status = FrontendSetState(Frontend, FRONTEND_ENABLED); if (!NT_SUCCESS(status)) goto fail1; Context->SuspendInterface = FrontendGetSuspendInterface(Frontend); SUSPEND(Acquire, Context->SuspendInterface); status = SUSPEND(Register, Context->SuspendInterface, SUSPEND_CALLBACK_LATE, VifSuspendCallbackLate, Context, &Context->SuspendCallbackLate); if (!NT_SUCCESS(status)) goto fail2; Context->Enabled = TRUE; Event = MacGetEvent(FrontendGetMac(Frontend)); KeSetEvent(Event, IO_NO_INCREMENT, FALSE); done: ReleaseMrswLockExclusive(&Context->Lock, Irql, FALSE); Trace("<====\n"); return STATUS_SUCCESS; fail2: Error("fail2\n"); SUSPEND(Release, Context->SuspendInterface); Context->SuspendInterface = NULL; fail1: Error("fail1 (%08x)\n", status); RtlZeroMemory(&Context->Callback, sizeof (VIF_CALLBACK)); ReleaseMrswLockExclusive(&Context->Lock, Irql, FALSE); return status; }