- Rewrite PcRegisterIoTimeout, PcUnregisterIoTimeout to support more than one PIO_TIMER_ROUTINE per device object

svn path=/trunk/; revision=41621
This commit is contained in:
Johannes Anderwald
2009-06-26 12:05:13 +00:00
parent d6d058ab49
commit 28685db4e4
3 changed files with 125 additions and 42 deletions
@@ -153,6 +153,14 @@ PcAddAdapterDevice(
InitializeListHead(&portcls_ext->SubDeviceList);
/* prepare the physical connection list */
InitializeListHead(&portcls_ext->PhysicalConnectionList);
/* initialize timer lock */
KeInitializeSpinLock(&portcls_ext->TimerListLock);
/* initialize timer list */
InitializeListHead(&portcls_ext->TimerList);
/* initialize io timer */
IoInitializeTimer(PhysicalDeviceObject, PcIoTimerRoutine, NULL);
/* start the io timer */
IoStartTimer(PhysicalDeviceObject);
/* set io flags */
fdo->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
+117 -18
View File
@@ -40,7 +40,41 @@ PcGetTimeInterval(
}
/*
* @unimplemented
* @implemented
*/
VOID
NTAPI
PcIoTimerRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context)
{
PPCLASS_DEVICE_EXTENSION DeviceExtension;
KIRQL OldIrql;
PLIST_ENTRY ListEntry;
PTIMER_CONTEXT CurContext;
if (!DeviceObject || !DeviceObject->DeviceExtension)
return;
DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
KeAcquireSpinLock(&DeviceExtension->TimerListLock, &OldIrql);
ListEntry = DeviceExtension->TimerList.Flink;
while(ListEntry != &DeviceExtension->TimerList)
{
CurContext = (PTIMER_CONTEXT)CONTAINING_RECORD(ListEntry, TIMER_CONTEXT, Entry);
CurContext->pTimerRoutine(DeviceObject, CurContext->Context);
ListEntry = ListEntry->Flink;
}
KeReleaseSpinLock(&DeviceExtension->TimerListLock, OldIrql);
}
/*
* @implemented
*/
NTSTATUS NTAPI
PcRegisterIoTimeout(
@@ -48,42 +82,107 @@ PcRegisterIoTimeout(
IN PIO_TIMER_ROUTINE pTimerRoutine,
IN PVOID pContext)
{
NTSTATUS Status;
NTSTATUS Status = STATUS_SUCCESS;
PTIMER_CONTEXT TimerContext, CurContext;
KIRQL OldIrql;
PLIST_ENTRY ListEntry;
BOOLEAN bFound;
PPCLASS_DEVICE_EXTENSION DeviceExtension;
ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
/* FIXME
* check if timer is already used
*/
if (!pDeviceObject || !pDeviceObject->DeviceExtension)
return STATUS_INVALID_PARAMETER;
Status = IoInitializeTimer(pDeviceObject, pTimerRoutine, pContext);
if (!NT_SUCCESS(Status))
DeviceExtension = (PPCLASS_DEVICE_EXTENSION)pDeviceObject->DeviceExtension;
TimerContext = AllocateItem(NonPagedPool, sizeof(TIMER_CONTEXT), TAG_PORTCLASS);
if (!TimerContext)
{
DPRINT1("IoInitializeTimer failed with %x\n", Status);
return Status;
DPRINT1("Failed to allocate memory\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
IoStartTimer(pDeviceObject);
return STATUS_SUCCESS;
KeAcquireSpinLock(&DeviceExtension->TimerListLock, &OldIrql);
ListEntry = DeviceExtension->TimerList.Flink;
bFound = FALSE;
while(ListEntry != &DeviceExtension->TimerList)
{
CurContext = (PTIMER_CONTEXT)CONTAINING_RECORD(ListEntry, TIMER_CONTEXT, Entry);
if (CurContext->Context == pContext && CurContext->pTimerRoutine == pTimerRoutine)
{
bFound = TRUE;
Status = STATUS_UNSUCCESSFUL;
ExFreePool(TimerContext);
break;
}
ListEntry = ListEntry->Flink;
}
if (!bFound)
{
TimerContext->Context = pContext;
TimerContext->pTimerRoutine = pTimerRoutine;
InsertTailList(&DeviceExtension->TimerList, &TimerContext->Entry);
}
KeReleaseSpinLock(&DeviceExtension->TimerListLock, OldIrql);
return Status;
}
/*
* @unimplemented
* @implemented
*/
NTSTATUS NTAPI
NTSTATUS
NTAPI
PcUnregisterIoTimeout(
IN PDEVICE_OBJECT pDeviceObject,
IN PIO_TIMER_ROUTINE pTimerRoutine,
IN PVOID pContext)
{
PTIMER_CONTEXT CurContext;
KIRQL OldIrql;
PLIST_ENTRY ListEntry;
BOOLEAN bFound;
PPCLASS_DEVICE_EXTENSION DeviceExtension;
ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
/* FIXME
* check if timer is already used
*/
if (!pDeviceObject || !pDeviceObject->DeviceExtension)
return STATUS_INVALID_PARAMETER;
IoStopTimer(pDeviceObject);
return STATUS_SUCCESS;
DeviceExtension = (PPCLASS_DEVICE_EXTENSION)pDeviceObject->DeviceExtension;
KeAcquireSpinLock(&DeviceExtension->TimerListLock, &OldIrql);
ListEntry = DeviceExtension->TimerList.Flink;
bFound = FALSE;
while(ListEntry != &DeviceExtension->TimerList)
{
CurContext = (PTIMER_CONTEXT)CONTAINING_RECORD(ListEntry, TIMER_CONTEXT, Entry);
if (CurContext->Context == pContext && CurContext->pTimerRoutine == pTimerRoutine)
{
bFound = TRUE;
RemoveEntryList(&CurContext->Entry);
ExFreePool(CurContext);
break;
}
ListEntry = ListEntry->Flink;
}
KeReleaseSpinLock(&DeviceExtension->TimerListLock, OldIrql);
if (bFound)
return STATUS_SUCCESS;
else
return STATUS_NOT_FOUND;
}
@@ -327,27 +327,3 @@ PcValidateConnectRequest(
return KsValidateConnectRequest(Irp, Factory->PinDescriptorCount, Factory->KsPinDescriptor, Connect);
}
/* PcDeleteSubdeviceDescriptor */
/* PcFreeEventTable */
/* PcFreePropertyTable */
/* PcGenerateEventDeferredRoutine */
/* PcGenerateEventList */
/* PcHandleDisableEventWithTable */
/* PcHandleEnableEventWithTable */
/* PcHandlePropertyWithTable */
/* PcPinPropertyHandler */
/* PcTerminateConnection */
/* PcValidateConnectRequest */
/* PcVerifyFilterIsReady */