mirror of
https://github.com/reactos/reactos.git
synced 2025-08-01 23:53:07 +00:00
- Use a work item for each specific task: start, stop, close
- Should fix bug 4365 svn path=/trunk/; revision=40496
This commit is contained in:
parent
4efcc91b49
commit
391fa4acd9
7 changed files with 121 additions and 60 deletions
|
@ -91,7 +91,7 @@ PcAddAdapterDevice(
|
||||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||||
PDEVICE_OBJECT fdo = NULL;
|
PDEVICE_OBJECT fdo = NULL;
|
||||||
PDEVICE_OBJECT PrevDeviceObject;
|
PDEVICE_OBJECT PrevDeviceObject;
|
||||||
PPCLASS_DEVICE_EXTENSION portcls_ext;
|
PPCLASS_DEVICE_EXTENSION portcls_ext = NULL;
|
||||||
|
|
||||||
DPRINT1("PcAddAdapterDevice called\n");
|
DPRINT1("PcAddAdapterDevice called\n");
|
||||||
|
|
||||||
|
@ -138,8 +138,8 @@ PcAddAdapterDevice(
|
||||||
if (!portcls_ext->CreateItems)
|
if (!portcls_ext->CreateItems)
|
||||||
{
|
{
|
||||||
/* not enough resources */
|
/* not enough resources */
|
||||||
IoDeleteDevice(fdo);
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* store the physical device object */
|
/* store the physical device object */
|
||||||
|
@ -157,32 +157,41 @@ PcAddAdapterDevice(
|
||||||
fdo->Flags &= ~ DO_DEVICE_INITIALIZING;
|
fdo->Flags &= ~ DO_DEVICE_INITIALIZING;
|
||||||
|
|
||||||
/* allocate work item */
|
/* allocate work item */
|
||||||
portcls_ext->WorkItem = IoAllocateWorkItem(fdo);
|
portcls_ext->CloseWorkItem = IoAllocateWorkItem(fdo);
|
||||||
|
|
||||||
if (!portcls_ext->WorkItem)
|
if (!portcls_ext->CloseWorkItem)
|
||||||
{
|
{
|
||||||
/* not enough resources */
|
/* not enough resources */
|
||||||
FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS);
|
goto cleanup;
|
||||||
/* delete created fdo */
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
IoDeleteDevice(fdo);
|
|
||||||
/* return error code */
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* allocate work item */
|
||||||
|
portcls_ext->StartWorkItem = IoAllocateWorkItem(fdo);
|
||||||
|
|
||||||
|
if (!portcls_ext->StartWorkItem)
|
||||||
|
{
|
||||||
|
/* not enough resources */
|
||||||
|
goto cleanup;
|
||||||
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate work item */
|
||||||
|
portcls_ext->StopWorkItem = IoAllocateWorkItem(fdo);
|
||||||
|
|
||||||
|
if (!portcls_ext->StopWorkItem)
|
||||||
|
{
|
||||||
|
/* not enough resources */
|
||||||
|
goto cleanup;
|
||||||
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
/* allocate the device header */
|
/* allocate the device header */
|
||||||
status = KsAllocateDeviceHeader(&portcls_ext->KsDeviceHeader, MaxObjects, portcls_ext->CreateItems);
|
status = KsAllocateDeviceHeader(&portcls_ext->KsDeviceHeader, MaxObjects, portcls_ext->CreateItems);
|
||||||
/* did we succeed */
|
/* did we succeed */
|
||||||
if (!NT_SUCCESS(status))
|
if (!NT_SUCCESS(status))
|
||||||
{
|
{
|
||||||
/* free previously allocated create items */
|
goto cleanup;
|
||||||
FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS);
|
|
||||||
/* free allocated work item */
|
|
||||||
IoFreeWorkItem(portcls_ext->WorkItem);
|
|
||||||
/* delete created fdo */
|
|
||||||
IoDeleteDevice(fdo);
|
|
||||||
/* return error code */
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* attach device to device stack */
|
/* attach device to device stack */
|
||||||
|
@ -196,16 +205,52 @@ PcAddAdapterDevice(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* free the device header */
|
/* return error code */
|
||||||
KsFreeDeviceHeader(portcls_ext->KsDeviceHeader);
|
status = STATUS_UNSUCCESSFUL;
|
||||||
/* free previously allocated create items */
|
goto cleanup;
|
||||||
FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS);
|
}
|
||||||
/* free allocated work item */
|
return status;
|
||||||
IoFreeWorkItem(portcls_ext->WorkItem);
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
if (portcls_ext)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (portcls_ext->KsDeviceHeader)
|
||||||
|
{
|
||||||
|
/* free the device header */
|
||||||
|
KsFreeDeviceHeader(portcls_ext->KsDeviceHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (portcls_ext->CloseWorkItem)
|
||||||
|
{
|
||||||
|
/* free allocated work item */
|
||||||
|
IoFreeWorkItem(portcls_ext->CloseWorkItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (portcls_ext->StartWorkItem)
|
||||||
|
{
|
||||||
|
/* free allocated work item */
|
||||||
|
IoFreeWorkItem(portcls_ext->StartWorkItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (portcls_ext->StopWorkItem)
|
||||||
|
{
|
||||||
|
/* free allocated work item */
|
||||||
|
IoFreeWorkItem(portcls_ext->StopWorkItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (portcls_ext->CreateItems)
|
||||||
|
{
|
||||||
|
/* free previously allocated create items */
|
||||||
|
FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fdo)
|
||||||
|
{
|
||||||
/* delete created fdo */
|
/* delete created fdo */
|
||||||
IoDeleteDevice(fdo);
|
IoDeleteDevice(fdo);
|
||||||
/* return error code */
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|
|
@ -405,6 +405,9 @@ IDmaChannelSlave_fnStop(
|
||||||
|
|
||||||
This->DmaStarted = FALSE;
|
This->DmaStarted = FALSE;
|
||||||
|
|
||||||
|
IoFreeMdl(This->Mdl);
|
||||||
|
This->Mdl = NULL;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,7 @@ IPortFilterWaveCyclic_fnNewIrpTarget(
|
||||||
if (This->Pins[ConnectDetails->PinId] && This->Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount)
|
if (This->Pins[ConnectDetails->PinId] && This->Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount)
|
||||||
{
|
{
|
||||||
/* release existing instance */
|
/* release existing instance */
|
||||||
|
ASSERT(0);
|
||||||
This->Pins[ConnectDetails->PinId]->lpVtbl->Close(This->Pins[ConnectDetails->PinId], DeviceObject, NULL);
|
This->Pins[ConnectDetails->PinId]->lpVtbl->Close(This->Pins[ConnectDetails->PinId], DeviceObject, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -199,12 +199,18 @@ StopStreamWorkerRoutine(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PVOID Context)
|
IN PVOID Context)
|
||||||
{
|
{
|
||||||
|
PPCLASS_DEVICE_EXTENSION DeviceExtension;
|
||||||
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)Context;
|
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)Context;
|
||||||
|
|
||||||
DPRINT1("Stopping %u Irql %u\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue), KeGetCurrentIrql());
|
/* Set the state to stop */
|
||||||
|
|
||||||
This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP);
|
This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP);
|
||||||
|
/* Set internal state to stop */
|
||||||
This->State = KSSTATE_STOP;
|
This->State = KSSTATE_STOP;
|
||||||
|
|
||||||
|
/* Get device extension */
|
||||||
|
DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
DPRINT1("Stopping %u Irql %u\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue), KeGetCurrentIrql());
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -219,15 +225,24 @@ StopStreamRoutine(
|
||||||
PPCLASS_DEVICE_EXTENSION DeviceExtension;
|
PPCLASS_DEVICE_EXTENSION DeviceExtension;
|
||||||
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)DeferredContext;
|
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)DeferredContext;
|
||||||
|
|
||||||
|
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
|
||||||
|
|
||||||
|
/* Has the audio stream resumed? */
|
||||||
if (This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue))
|
if (This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Has the audio stream already stopped */
|
||||||
|
if (This->State == KSSTATE_STOP)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Get device object */
|
/* Get device object */
|
||||||
DeviceObject = GetDeviceObject(This->Port);
|
DeviceObject = GetDeviceObject(This->Port);
|
||||||
|
|
||||||
/* Get device extension */
|
/* Get device extension */
|
||||||
DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
/* queue the work item */
|
/* queue the work item */
|
||||||
IoQueueWorkItem(DeviceExtension->WorkItem, StopStreamWorkerRoutine, DelayedWorkQueue, (PVOID)This);
|
IoQueueWorkItem(DeviceExtension->StopWorkItem, StopStreamWorkerRoutine, DelayedWorkQueue, (PVOID)This);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -696,23 +711,18 @@ IPortPinWaveCyclic_fnClose(
|
||||||
|
|
||||||
if (This->Stream)
|
if (This->Stream)
|
||||||
{
|
{
|
||||||
if (Irp)
|
|
||||||
{
|
|
||||||
This->CloseIrp = Irp;
|
|
||||||
IoMarkIrpPending(Irp);
|
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
Irp->IoStatus.Status = STATUS_PENDING;
|
|
||||||
}
|
|
||||||
/* Get device extension */
|
/* Get device extension */
|
||||||
DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
/* defer work item */
|
|
||||||
IoQueueWorkItem(DeviceExtension->WorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)This);
|
|
||||||
|
|
||||||
if (Irp)
|
This->CloseIrp = Irp;
|
||||||
{
|
IoMarkIrpPending(Irp);
|
||||||
/* The WaveCyclic filter passes close request with NULL / IRP */
|
Irp->IoStatus.Information = 0;
|
||||||
return STATUS_PENDING;
|
Irp->IoStatus.Status = STATUS_PENDING;
|
||||||
}
|
|
||||||
|
/* defer work item */
|
||||||
|
IoQueueWorkItem(DeviceExtension->CloseWorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)This);
|
||||||
|
/* Return result */
|
||||||
|
return STATUS_PENDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Irp)
|
if (Irp)
|
||||||
|
|
|
@ -602,8 +602,7 @@ PcCreateItemDispatch(
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
Irp->IoStatus.Status = STATUS_PENDING;
|
Irp->IoStatus.Status = STATUS_PENDING;
|
||||||
IoMarkIrpPending(Irp);
|
IoMarkIrpPending(Irp);
|
||||||
IoQueueWorkItem(DeviceExt->WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
|
IoQueueWorkItem(DeviceExt->StartWorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
|
||||||
|
|
||||||
return STATUS_PENDING;
|
return STATUS_PENDING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,7 +156,10 @@ typedef struct
|
||||||
ULONG MaxSubDevices;
|
ULONG MaxSubDevices;
|
||||||
KSOBJECT_CREATE_ITEM * CreateItems;
|
KSOBJECT_CREATE_ITEM * CreateItems;
|
||||||
|
|
||||||
PIO_WORKITEM WorkItem;
|
PIO_WORKITEM StartWorkItem;
|
||||||
|
PIO_WORKITEM StopWorkItem;
|
||||||
|
PIO_WORKITEM CloseWorkItem;
|
||||||
|
|
||||||
IResourceList* resources;
|
IResourceList* resources;
|
||||||
LIST_ENTRY SubDeviceList;
|
LIST_ENTRY SubDeviceList;
|
||||||
LIST_ENTRY PhysicalConnectionList;
|
LIST_ENTRY PhysicalConnectionList;
|
||||||
|
|
|
@ -29,7 +29,7 @@ typedef struct CResourceList
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDMETHODCALLTYPE
|
NTAPI
|
||||||
IResourceList_fnQueryInterface(
|
IResourceList_fnQueryInterface(
|
||||||
IResourceList* iface,
|
IResourceList* iface,
|
||||||
IN REFIID refiid,
|
IN REFIID refiid,
|
||||||
|
@ -56,7 +56,7 @@ IResourceList_fnQueryInterface(
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
STDMETHODCALLTYPE
|
NTAPI
|
||||||
IResourceList_fnAddRef(
|
IResourceList_fnAddRef(
|
||||||
IResourceList* iface)
|
IResourceList* iface)
|
||||||
{
|
{
|
||||||
|
@ -66,7 +66,7 @@ IResourceList_fnAddRef(
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
STDMETHODCALLTYPE
|
NTAPI
|
||||||
IResourceList_fnRelease(
|
IResourceList_fnRelease(
|
||||||
IResourceList* iface)
|
IResourceList* iface)
|
||||||
{
|
{
|
||||||
|
@ -93,7 +93,7 @@ IResourceList_fnRelease(
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
STDMETHODCALLTYPE
|
NTAPI
|
||||||
IResourceList_fnNumberOfEntries(IResourceList* iface)
|
IResourceList_fnNumberOfEntries(IResourceList* iface)
|
||||||
{
|
{
|
||||||
IResourceListImpl * This = (IResourceListImpl*)iface;
|
IResourceListImpl * This = (IResourceListImpl*)iface;
|
||||||
|
@ -102,7 +102,7 @@ IResourceList_fnNumberOfEntries(IResourceList* iface)
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
STDMETHODCALLTYPE
|
NTAPI
|
||||||
IResourceList_fnNumberOfEntriesOfType(
|
IResourceList_fnNumberOfEntriesOfType(
|
||||||
IResourceList* iface,
|
IResourceList* iface,
|
||||||
IN CM_RESOURCE_TYPE Type)
|
IN CM_RESOURCE_TYPE Type)
|
||||||
|
@ -129,7 +129,7 @@ IResourceList_fnNumberOfEntriesOfType(
|
||||||
}
|
}
|
||||||
|
|
||||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR
|
PCM_PARTIAL_RESOURCE_DESCRIPTOR
|
||||||
STDMETHODCALLTYPE
|
NTAPI
|
||||||
IResourceList_fnFindTranslatedEntry(
|
IResourceList_fnFindTranslatedEntry(
|
||||||
IResourceList* iface,
|
IResourceList* iface,
|
||||||
IN CM_RESOURCE_TYPE Type,
|
IN CM_RESOURCE_TYPE Type,
|
||||||
|
@ -158,7 +158,7 @@ IResourceList_fnFindTranslatedEntry(
|
||||||
}
|
}
|
||||||
|
|
||||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR
|
PCM_PARTIAL_RESOURCE_DESCRIPTOR
|
||||||
STDMETHODCALLTYPE
|
NTAPI
|
||||||
IResourceList_fnFindUntranslatedEntry(
|
IResourceList_fnFindUntranslatedEntry(
|
||||||
IResourceList* iface,
|
IResourceList* iface,
|
||||||
IN CM_RESOURCE_TYPE Type,
|
IN CM_RESOURCE_TYPE Type,
|
||||||
|
@ -186,7 +186,7 @@ IResourceList_fnFindUntranslatedEntry(
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDMETHODCALLTYPE
|
NTAPI
|
||||||
IResourceList_fnAddEntry(
|
IResourceList_fnAddEntry(
|
||||||
IResourceList* iface,
|
IResourceList* iface,
|
||||||
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Translated,
|
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Translated,
|
||||||
|
@ -242,7 +242,7 @@ IResourceList_fnAddEntry(
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDMETHODCALLTYPE
|
NTAPI
|
||||||
IResourceList_fnAddEntryFromParent(
|
IResourceList_fnAddEntryFromParent(
|
||||||
IResourceList* iface,
|
IResourceList* iface,
|
||||||
IN IResourceList* Parent,
|
IN IResourceList* Parent,
|
||||||
|
@ -281,7 +281,7 @@ IResourceList_fnAddEntryFromParent(
|
||||||
}
|
}
|
||||||
|
|
||||||
PCM_RESOURCE_LIST
|
PCM_RESOURCE_LIST
|
||||||
STDMETHODCALLTYPE
|
NTAPI
|
||||||
IResourceList_fnTranslatedList(
|
IResourceList_fnTranslatedList(
|
||||||
IResourceList* iface)
|
IResourceList* iface)
|
||||||
{
|
{
|
||||||
|
@ -291,7 +291,7 @@ IResourceList_fnTranslatedList(
|
||||||
}
|
}
|
||||||
|
|
||||||
PCM_RESOURCE_LIST
|
PCM_RESOURCE_LIST
|
||||||
STDMETHODCALLTYPE
|
NTAPI
|
||||||
IResourceList_fnUntranslatedList(
|
IResourceList_fnUntranslatedList(
|
||||||
IResourceList* iface)
|
IResourceList* iface)
|
||||||
{
|
{
|
||||||
|
@ -325,7 +325,9 @@ static const IResourceListVtbl vt_ResourceListVtbl =
|
||||||
/*
|
/*
|
||||||
Factory for creating a resource list
|
Factory for creating a resource list
|
||||||
*/
|
*/
|
||||||
PORTCLASSAPI NTSTATUS NTAPI
|
PORTCLASSAPI
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
PcNewResourceList(
|
PcNewResourceList(
|
||||||
OUT PRESOURCELIST* OutResourceList,
|
OUT PRESOURCELIST* OutResourceList,
|
||||||
IN PUNKNOWN OuterUnknown OPTIONAL,
|
IN PUNKNOWN OuterUnknown OPTIONAL,
|
||||||
|
@ -339,8 +341,6 @@ PcNewResourceList(
|
||||||
|
|
||||||
/* TODO: Validate parameters */
|
/* TODO: Validate parameters */
|
||||||
|
|
||||||
DPRINT("PcNewResourceList\n");
|
|
||||||
|
|
||||||
NewList = AllocateItem(PoolType, sizeof(IResourceListImpl), TAG_PORTCLASS);
|
NewList = AllocateItem(PoolType, sizeof(IResourceListImpl), TAG_PORTCLASS);
|
||||||
|
|
||||||
if (!NewList)
|
if (!NewList)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue