sys: device: cleanup work

This commit is contained in:
Bill Zissimopoulos 2015-12-21 15:09:55 -08:00
parent 2254ed1107
commit b4ebd5e218

View File

@ -17,6 +17,8 @@ VOID FspDeviceInitComplete(PDEVICE_OBJECT DeviceObject);
VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject); VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject);
BOOLEAN FspDeviceRetain(PDEVICE_OBJECT DeviceObject); BOOLEAN FspDeviceRetain(PDEVICE_OBJECT DeviceObject);
VOID FspDeviceRelease(PDEVICE_OBJECT DeviceObject); VOID FspDeviceRelease(PDEVICE_OBJECT DeviceObject);
static BOOLEAN FspDeviceRetainAtDpcLevel(PDEVICE_OBJECT DeviceObject);
static VOID FspDeviceReleaseFromDpcLevel(PDEVICE_OBJECT DeviceObject);
static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject); static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject);
static VOID FspFsvolDeviceInitComplete(PDEVICE_OBJECT DeviceObject); static VOID FspFsvolDeviceInitComplete(PDEVICE_OBJECT DeviceObject);
static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject); static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject);
@ -73,8 +75,6 @@ NTSTATUS FspDeviceCreateSecure(UINT32 Kind, ULONG ExtraSize,
DeviceExtensionSize = sizeof(FSP_FSVOL_DEVICE_EXTENSION); DeviceExtensionSize = sizeof(FSP_FSVOL_DEVICE_EXTENSION);
break; break;
case FspFsvrtDeviceExtensionKind: case FspFsvrtDeviceExtensionKind:
DeviceExtensionSize = 0;
break;
case FspFsctlDeviceExtensionKind: case FspFsctlDeviceExtensionKind:
DeviceExtensionSize = 0; DeviceExtensionSize = 0;
break; break;
@ -108,7 +108,6 @@ NTSTATUS FspDeviceCreateSecure(UINT32 Kind, ULONG ExtraSize,
Result = FspFsvolDeviceInit(DeviceObject); Result = FspFsvolDeviceInit(DeviceObject);
break; break;
case FspFsvrtDeviceExtensionKind: case FspFsvrtDeviceExtensionKind:
break;
case FspFsctlDeviceExtensionKind: case FspFsctlDeviceExtensionKind:
break; break;
} }
@ -142,7 +141,6 @@ VOID FspDeviceInitComplete(PDEVICE_OBJECT DeviceObject)
FspFsvolDeviceInitComplete(DeviceObject); FspFsvolDeviceInitComplete(DeviceObject);
break; break;
case FspFsvrtDeviceExtensionKind: case FspFsvrtDeviceExtensionKind:
break;
case FspFsctlDeviceExtensionKind: case FspFsctlDeviceExtensionKind:
break; break;
default: default:
@ -165,7 +163,6 @@ VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject)
FspFsvolDeviceFini(DeviceObject); FspFsvolDeviceFini(DeviceObject);
break; break;
case FspFsvrtDeviceExtensionKind: case FspFsvrtDeviceExtensionKind:
break;
case FspFsctlDeviceExtensionKind: case FspFsctlDeviceExtensionKind:
break; break;
default: default:
@ -215,6 +212,44 @@ VOID FspDeviceRelease(PDEVICE_OBJECT DeviceObject)
FspDeviceDelete(DeviceObject); FspDeviceDelete(DeviceObject);
} }
_IRQL_requires_(DISPATCH_LEVEL)
static BOOLEAN FspDeviceRetainAtDpcLevel(PDEVICE_OBJECT DeviceObject)
{
// !PAGED_CODE();
BOOLEAN Result;
FSP_DEVICE_EXTENSION *DeviceExtension;
DeviceExtension = FspDeviceExtension(DeviceObject);
KeAcquireSpinLockAtDpcLevel(&DeviceExtension->SpinLock);
Result = 0 != DeviceExtension->RefCount;
if (Result)
DeviceExtension->RefCount++;
KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
return Result;
}
_IRQL_requires_(DISPATCH_LEVEL)
static VOID FspDeviceReleaseFromDpcLevel(PDEVICE_OBJECT DeviceObject)
{
// !PAGED_CODE();
BOOLEAN Delete = FALSE;
FSP_DEVICE_EXTENSION *DeviceExtension;
DeviceExtension = FspDeviceExtension(DeviceObject);
KeAcquireSpinLockAtDpcLevel(&DeviceExtension->SpinLock);
if (0 != DeviceExtension->RefCount)
{
DeviceExtension->RefCount--;
Delete = 0 == DeviceExtension->RefCount;
}
KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
ASSERT(!Delete);
}
static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject) static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject)
{ {
PAGED_CODE(); PAGED_CODE();
@ -279,7 +314,7 @@ static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject)
* *
* Our IoTimer routine will NOT be called again after IoStopTimer() returns. * Our IoTimer routine will NOT be called again after IoStopTimer() returns.
* However a work item may be in flight. For this reason our IoTimer routine * However a work item may be in flight. For this reason our IoTimer routine
* does an ObReferenceObject() on our DeviceObject before queueing work items. * retains our DeviceObject before queueing work items.
*/ */
IoStopTimer(DeviceObject); IoStopTimer(DeviceObject);
@ -313,23 +348,30 @@ static VOID FspFsvolDeviceTimerRoutine(PDEVICE_OBJECT DeviceObject, PVOID Contex
// !PAGED_CODE(); // !PAGED_CODE();
/* /*
* This routine runs at DPC level. Reference our DeviceObject and queue a work item * This routine runs at DPC level. Retain our DeviceObject and queue a work item
* so that we can do our processing at Passive level. Only do so if the work item * so that we can do our processing at Passive level. Only do so if the work item
* is not already in flight (otherwise we could requeue the same work item). * is not already in flight (otherwise we could requeue the same work item).
*/ */
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
if (!FspDeviceRetainAtDpcLevel(DeviceObject))
return;
BOOLEAN ExpirationInProgress;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
KeAcquireSpinLockAtDpcLevel(&FsvolDeviceExtension->ExpirationLock); KeAcquireSpinLockAtDpcLevel(&FsvolDeviceExtension->ExpirationLock);
if (!FsvolDeviceExtension->ExpirationInProgress) ExpirationInProgress = FsvolDeviceExtension->ExpirationInProgress;
if (!ExpirationInProgress)
{ {
FsvolDeviceExtension->ExpirationInProgress = TRUE; FsvolDeviceExtension->ExpirationInProgress = TRUE;
ObReferenceObject(DeviceObject);
ExQueueWorkItem(&FsvolDeviceExtension->ExpirationWorkItem, DelayedWorkQueue); ExQueueWorkItem(&FsvolDeviceExtension->ExpirationWorkItem, DelayedWorkQueue);
} }
KeReleaseSpinLockFromDpcLevel(&FsvolDeviceExtension->ExpirationLock); KeReleaseSpinLockFromDpcLevel(&FsvolDeviceExtension->ExpirationLock);
if (ExpirationInProgress)
FspDeviceReleaseFromDpcLevel(DeviceObject);
} }
static VOID FspFsvolDeviceExpirationRoutine(PVOID Context) static VOID FspFsvolDeviceExpirationRoutine(PVOID Context)
@ -337,9 +379,6 @@ static VOID FspFsvolDeviceExpirationRoutine(PVOID Context)
// !PAGED_CODE(); // !PAGED_CODE();
PDEVICE_OBJECT DeviceObject = Context; PDEVICE_OBJECT DeviceObject = Context;
if (FspDeviceRetain(DeviceObject))
try
{
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
LARGE_INTEGER Timeout; LARGE_INTEGER Timeout;
KIRQL Irql; KIRQL Irql;
@ -351,13 +390,8 @@ static VOID FspFsvolDeviceExpirationRoutine(PVOID Context)
KeAcquireSpinLock(&FsvolDeviceExtension->ExpirationLock, &Irql); KeAcquireSpinLock(&FsvolDeviceExtension->ExpirationLock, &Irql);
FsvolDeviceExtension->ExpirationInProgress = FALSE; FsvolDeviceExtension->ExpirationInProgress = FALSE;
KeReleaseSpinLock(&FsvolDeviceExtension->ExpirationLock, Irql); KeReleaseSpinLock(&FsvolDeviceExtension->ExpirationLock, Irql);
}
finally
{
FspDeviceRelease(DeviceObject);
}
ObDereferenceObject(DeviceObject); FspDeviceRelease(DeviceObject);
} }
PVOID FspFsvolDeviceLookupContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier) PVOID FspFsvolDeviceLookupContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier)