PXENVBD_THREAD ScanThread;
KEVENT ScanEvent;
PXENBUS_STORE_WATCH ScanWatch;
- PXENVBD_THREAD FrontendThread;
// Statistics
LONG CurrentSrbs;
if (PdoCreate(Fdo,
Device,
TargetId,
- ThreadGetEvent(Fdo->FrontendThread),
DeviceType)) {
*NeedInvalidate = TRUE;
}
return STATUS_SUCCESS;
}
-__checkReturn
-static DECLSPEC_NOINLINE NTSTATUS
-FdoFrontend(
- __in PXENVBD_THREAD Thread,
- __in PVOID Context
- )
-{
- PXENVBD_FDO Fdo = Context;
-
- for (;;) {
- ULONG TargetId;
- KIRQL Irql;
-
- if (!ThreadWait(Thread))
- break;
-
- KeAcquireSpinLock(&Fdo->Lock, &Irql);
-
- if (Fdo->DevicePower != PowerDeviceD0) {
- KeReleaseSpinLock(&Fdo->Lock, Irql);
- continue;
- }
-
- for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) {
- PXENVBD_PDO Pdo = __FdoGetPdo(Fdo, TargetId);
- if (Pdo) {
- PdoBackendPathChanged(Pdo);
- PdoDereference(Pdo);
- }
- }
-
- KeReleaseSpinLock(&Fdo->Lock, Irql);
- }
-
- return STATUS_SUCCESS;
-}
-
//=============================================================================
// Initialize, Start, Stop
if (!NT_SUCCESS(Status))
goto fail3;
- Status = ThreadCreate(FdoFrontend, Fdo, &Fdo->FrontendThread);
- if (!NT_SUCCESS(Status))
- goto fail4;
-
Status = ThreadCreate(FdoDevicePower, Fdo, &Fdo->DevicePowerThread);
if (!NT_SUCCESS(Status))
- goto fail5;
+ goto fail4;
// query enumerator
// fix this up to query from device location(?)
Trace("<===== (%d)\n", KeGetCurrentIrql());
return STATUS_SUCCESS;
-fail5:
- Error("fail5\n");
- ThreadAlert(Fdo->FrontendThread);
- ThreadJoin(Fdo->FrontendThread);
- Fdo->FrontendThread = NULL;
fail4:
Error("fail4\n");
ThreadAlert(Fdo->ScanThread);
ThreadJoin(Fdo->DevicePowerThread);
Fdo->DevicePowerThread = NULL;
- // stop frontend thread
- ThreadAlert(Fdo->FrontendThread);
- ThreadJoin(Fdo->FrontendThread);
- Fdo->FrontendThread = NULL;
-
// stop enum thread
ThreadAlert(Fdo->ScanThread);
ThreadJoin(Fdo->ScanThread);
#include "notifier.h"
#include "blockring.h"
#include "granter.h"
+#include "thread.h"
#include <store_interface.h>
#include <suspend_interface.h>
// Backend State Watch
BOOLEAN Active;
- PKEVENT BackendEvent;
+ PXENVBD_THREAD BackendThread;
PXENBUS_STORE_WATCH BackendWatch;
};
Frontend->Store,
NULL,
Frontend->BackendPath,
- Frontend->BackendEvent,
+ ThreadGetEvent(Frontend->BackendThread),
&Frontend->BackendWatch);
if (!NT_SUCCESS(Status))
goto fail2;
return Status;
}
-__drv_requiresIRQL(DISPATCH_LEVEL)
-VOID
-FrontendBackendPathChanged(
- __in PXENVBD_FRONTEND Frontend
+__checkReturn
+static DECLSPEC_NOINLINE NTSTATUS
+FrontendBackend(
+ __in PXENVBD_THREAD Thread,
+ __in PVOID Context
)
{
- KIRQL Irql;
- KeAcquireSpinLock(&Frontend->StateLock, &Irql);
- // Only attempt this if Active, Active is set/cleared on D3->D0/D0->D3
- if (Frontend->Active) {
- // Note: Nothing may have changed with this target, this could be caused by another target changing
- __ReadDiskInfo(Frontend);
- __CheckBackendForEject(Frontend);
+ PXENVBD_FRONTEND Frontend = Context;
+
+ for (;;) {
+ KIRQL Irql;
+
+ if (ThreadWait(Thread))
+ break;
+
+ KeAcquireSpinLock(&Frontend->StateLock, &Irql);
+ // Only attempt this if Active, Active is set/cleared on D3->D0/D0->D3
+ if (Frontend->Active) {
+ __ReadDiskInfo(Frontend);
+ __CheckBackendForEject(Frontend);
+ }
+ KeReleaseSpinLock(&Frontend->StateLock, Irql);
}
- KeReleaseSpinLock(&Frontend->StateLock, Irql);
+
+ return STATUS_SUCCESS;
+
}
__checkReturn
__in PXENVBD_PDO Pdo,
__in PCHAR DeviceId,
__in ULONG TargetId,
- __in PKEVENT Event,
__out PXENVBD_FRONTEND* _Frontend
)
{
Frontend->State = XENVBD_INITIALIZED;
Frontend->DiskInfo.SectorSize = 512; // default sector size
Frontend->BackendId = DOMID_INVALID;
- Frontend->BackendEvent = Event;
Status = STATUS_INSUFFICIENT_RESOURCES;
Frontend->FrontendPath = DriverFormat("device/%s/%s", FdoEnum(PdoGetFdo(Pdo)), DeviceId);
if (!NT_SUCCESS(Status))
goto fail6;
+ Status = ThreadCreate(FrontendBackend, Frontend, &Frontend->BackendThread);
+ if (!NT_SUCCESS(Status))
+ goto fail7;
+
// kernel objects
KeInitializeSpinLock(&Frontend->StateLock);
*_Frontend = Frontend;
return STATUS_SUCCESS;
+fail7:
+ Error("fail7\n");
+ GranterDestroy(Frontend->Granter);
+ Frontend->Granter = NULL;
fail6:
Error("fail6\n");
BlockRingDestroy(Frontend->BlockRing);
PdoFreeInquiryData(Frontend->Inquiry);
Frontend->Inquiry = NULL;
+ ThreadAlert(Frontend->BackendThread);
+ ThreadJoin(Frontend->BackendThread);
+ Frontend->BackendThread = NULL;
+
GranterDestroy(Frontend->Granter);
Frontend->Granter = NULL;
__in XENVBD_STATE State
);
-__drv_requiresIRQL(DISPATCH_LEVEL)
-extern VOID
-FrontendBackendPathChanged(
- __in PXENVBD_FRONTEND Frontend
- );
-
__checkReturn
extern NTSTATUS
FrontendCreate(
__in PXENVBD_PDO Pdo,
__in PCHAR DeviceId,
__in ULONG TargetId,
- __in PKEVENT Event,
__out PXENVBD_FRONTEND* _Frontend
);
}
}
-__drv_requiresIRQL(DISPATCH_LEVEL)
-VOID
-PdoBackendPathChanged(
- __in PXENVBD_PDO Pdo
- )
-{
- FrontendBackendPathChanged(Pdo->Frontend);
-}
-
__checkReturn
NTSTATUS
PdoD3ToD0(
__in PXENVBD_FDO Fdo,
__in __nullterminated PCHAR DeviceId,
__in ULONG TargetId,
- __in PKEVENT FrontendEvent,
__in XENVBD_DEVICE_TYPE DeviceType
)
{
QueueInit(&Pdo->PreparedReqs);
QueueInit(&Pdo->SubmittedReqs);
QueueInit(&Pdo->ShutdownSrbs);
-
- Status = FrontendCreate(Pdo, DeviceId, TargetId, FrontendEvent, &Pdo->Frontend);
- if (!NT_SUCCESS(Status))
- goto fail2;
-
__LookasideInit(&Pdo->RequestList, sizeof(XENVBD_REQUEST), REQUEST_POOL_TAG);
__LookasideInit(&Pdo->SegmentList, sizeof(XENVBD_SEGMENT), SEGMENT_POOL_TAG);
__LookasideInit(&Pdo->IndirectList, sizeof(XENVBD_INDIRECT), INDIRECT_POOL_TAG);
+ Status = FrontendCreate(Pdo, DeviceId, TargetId, &Pdo->Frontend);
+ if (!NT_SUCCESS(Status))
+ goto fail2;
+
Status = PdoD3ToD0(Pdo);
if (!NT_SUCCESS(Status))
goto fail3;
fail3:
Error("Fail3\n");
- __LookasideTerm(&Pdo->IndirectList);
- __LookasideTerm(&Pdo->SegmentList);
- __LookasideTerm(&Pdo->RequestList);
FrontendDestroy(Pdo->Frontend);
Pdo->Frontend = NULL;
fail2:
Error("Fail2\n");
+ __LookasideTerm(&Pdo->IndirectList);
+ __LookasideTerm(&Pdo->SegmentList);
+ __LookasideTerm(&Pdo->RequestList);
__PdoFree(Pdo);
fail1:
ASSERT3S(Pdo->ReferenceCount, ==, 0);
ASSERT3U(PdoGetDevicePnpState(Pdo), ==, Deleted);
+ FrontendDestroy(Pdo->Frontend);
+ Pdo->Frontend = NULL;
+
__LookasideTerm(&Pdo->IndirectList);
__LookasideTerm(&Pdo->SegmentList);
__LookasideTerm(&Pdo->RequestList);
- FrontendDestroy(Pdo->Frontend);
- Pdo->Frontend = NULL;
-
ASSERT3U(Pdo->Signature, ==, PDO_SIGNATURE);
RtlZeroMemory(Pdo, sizeof(XENVBD_PDO));
__PdoFree(Pdo);
__in PXENVBD_FDO Fdo,
__in __nullterminated PCHAR DeviceId,
__in ULONG TargetId,
- __in PKEVENT FrontendEvent,
__in XENVBD_DEVICE_TYPE DeviceType
);
__in PXENVBD_PDO Pdo
);
-__drv_requiresIRQL(DISPATCH_LEVEL)
-extern VOID
-PdoBackendPathChanged(
- __in PXENVBD_PDO Pdo
- );
-
// PnP States
extern VOID
PdoSetMissing(