Author: janderwald Date: Tue Apr 14 11:21:05 2009 New Revision: 40496
URL: http://svn.reactos.org/svn/reactos?rev=40496&view=rev Log: - Use a work item for each specific task: start, stop, close - Should fix bug 4365
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/adapter.c trunk/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.c trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h trunk/reactos/drivers/wdm/audio/backpln/portcls/resource.c
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/adapter.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/adapter.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/adapter.c [iso-8859-1] Tue Apr 14 11:21:05 2009 @@ -91,7 +91,7 @@ NTSTATUS status = STATUS_UNSUCCESSFUL; PDEVICE_OBJECT fdo = NULL; PDEVICE_OBJECT PrevDeviceObject; - PPCLASS_DEVICE_EXTENSION portcls_ext; + PPCLASS_DEVICE_EXTENSION portcls_ext = NULL;
DPRINT1("PcAddAdapterDevice called\n");
@@ -138,8 +138,8 @@ if (!portcls_ext->CreateItems) { /* not enough resources */ - IoDeleteDevice(fdo); - return STATUS_INSUFFICIENT_RESOURCES; + status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; }
/* store the physical device object */ @@ -157,32 +157,41 @@ fdo->Flags &= ~ DO_DEVICE_INITIALIZING;
/* allocate work item */ - portcls_ext->WorkItem = IoAllocateWorkItem(fdo); - - if (!portcls_ext->WorkItem) + portcls_ext->CloseWorkItem = IoAllocateWorkItem(fdo); + + if (!portcls_ext->CloseWorkItem) { /* not enough resources */ - FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS); - /* delete created fdo */ - IoDeleteDevice(fdo); - /* return error code */ - return STATUS_INSUFFICIENT_RESOURCES; - } - + goto cleanup; + status = 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 */ status = KsAllocateDeviceHeader(&portcls_ext->KsDeviceHeader, MaxObjects, portcls_ext->CreateItems); /* did we succeed */ if (!NT_SUCCESS(status)) { - /* free previously allocated create items */ - FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS); - /* free allocated work item */ - IoFreeWorkItem(portcls_ext->WorkItem); - /* delete created fdo */ - IoDeleteDevice(fdo); - /* return error code */ - return status; + goto cleanup; }
/* attach device to device stack */ @@ -196,16 +205,52 @@ } else { - /* free the device header */ - KsFreeDeviceHeader(portcls_ext->KsDeviceHeader); - /* free previously allocated create items */ - FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS); - /* free allocated work item */ - IoFreeWorkItem(portcls_ext->WorkItem); + /* return error code */ + status = STATUS_UNSUCCESSFUL; + goto cleanup; + } + return status; + +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 */ IoDeleteDevice(fdo); - /* return error code */ - return STATUS_UNSUCCESSFUL; }
return status;
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.c [iso-8859-1] Tue Apr 14 11:21:05 2009 @@ -404,6 +404,9 @@ KeLowerIrql(OldIrql);
This->DmaStarted = FALSE; + + IoFreeMdl(This->Mdl); + This->Mdl = NULL;
return STATUS_SUCCESS; }
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c [iso-8859-1] Tue Apr 14 11:21:05 2009 @@ -113,6 +113,7 @@ if (This->Pins[ConnectDetails->PinId] && This->Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount) { /* release existing instance */ + ASSERT(0); This->Pins[ConnectDetails->PinId]->lpVtbl->Close(This->Pins[ConnectDetails->PinId], DeviceObject, NULL); }
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c [iso-8859-1] Tue Apr 14 11:21:05 2009 @@ -199,12 +199,18 @@ IN PDEVICE_OBJECT DeviceObject, IN PVOID Context) { + PPCLASS_DEVICE_EXTENSION DeviceExtension; IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)Context;
+ /* Set the state to stop */ + This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP); + /* Set internal state to 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()); - - This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP); - This->State = KSSTATE_STOP; }
VOID @@ -219,15 +225,24 @@ PPCLASS_DEVICE_EXTENSION DeviceExtension; IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)DeferredContext;
+ ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); + + /* Has the audio stream resumed? */ if (This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue)) return;
+ /* Has the audio stream already stopped */ + if (This->State == KSSTATE_STOP) + return; + /* Get device object */ DeviceObject = GetDeviceObject(This->Port); + /* Get device extension */ DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + /* queue the work item */ - IoQueueWorkItem(DeviceExtension->WorkItem, StopStreamWorkerRoutine, DelayedWorkQueue, (PVOID)This); + IoQueueWorkItem(DeviceExtension->StopWorkItem, StopStreamWorkerRoutine, DelayedWorkQueue, (PVOID)This); }
static @@ -696,23 +711,18 @@
if (This->Stream) { - if (Irp) - { - This->CloseIrp = Irp; - IoMarkIrpPending(Irp); - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_PENDING; - } /* Get device extension */ DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + This->CloseIrp = Irp; + IoMarkIrpPending(Irp); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_PENDING; + /* defer work item */ - IoQueueWorkItem(DeviceExtension->WorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)This); - - if (Irp) - { - /* The WaveCyclic filter passes close request with NULL / IRP */ - return STATUS_PENDING; - } + IoQueueWorkItem(DeviceExtension->CloseWorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)This); + /* Return result */ + return STATUS_PENDING; }
if (Irp)
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c [iso-8859-1] Tue Apr 14 11:21:05 2009 @@ -602,8 +602,7 @@ Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_PENDING; IoMarkIrpPending(Irp); - IoQueueWorkItem(DeviceExt->WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context); - + IoQueueWorkItem(DeviceExt->StartWorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context); return STATUS_PENDING; } }
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h [iso-8859-1] Tue Apr 14 11:21:05 2009 @@ -156,7 +156,10 @@ ULONG MaxSubDevices; KSOBJECT_CREATE_ITEM * CreateItems;
- PIO_WORKITEM WorkItem; + PIO_WORKITEM StartWorkItem; + PIO_WORKITEM StopWorkItem; + PIO_WORKITEM CloseWorkItem; + IResourceList* resources; LIST_ENTRY SubDeviceList; LIST_ENTRY PhysicalConnectionList;
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/resource.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/resource.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/resource.c [iso-8859-1] Tue Apr 14 11:21:05 2009 @@ -29,7 +29,7 @@ */
NTSTATUS -STDMETHODCALLTYPE +NTAPI IResourceList_fnQueryInterface( IResourceList* iface, IN REFIID refiid, @@ -56,7 +56,7 @@ }
ULONG -STDMETHODCALLTYPE +NTAPI IResourceList_fnAddRef( IResourceList* iface) { @@ -66,7 +66,7 @@ }
ULONG -STDMETHODCALLTYPE +NTAPI IResourceList_fnRelease( IResourceList* iface) { @@ -93,7 +93,7 @@ */
ULONG -STDMETHODCALLTYPE +NTAPI IResourceList_fnNumberOfEntries(IResourceList* iface) { IResourceListImpl * This = (IResourceListImpl*)iface; @@ -102,7 +102,7 @@ }
ULONG -STDMETHODCALLTYPE +NTAPI IResourceList_fnNumberOfEntriesOfType( IResourceList* iface, IN CM_RESOURCE_TYPE Type) @@ -129,7 +129,7 @@ }
PCM_PARTIAL_RESOURCE_DESCRIPTOR -STDMETHODCALLTYPE +NTAPI IResourceList_fnFindTranslatedEntry( IResourceList* iface, IN CM_RESOURCE_TYPE Type, @@ -158,7 +158,7 @@ }
PCM_PARTIAL_RESOURCE_DESCRIPTOR -STDMETHODCALLTYPE +NTAPI IResourceList_fnFindUntranslatedEntry( IResourceList* iface, IN CM_RESOURCE_TYPE Type, @@ -186,7 +186,7 @@ }
NTSTATUS -STDMETHODCALLTYPE +NTAPI IResourceList_fnAddEntry( IResourceList* iface, IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Translated, @@ -242,7 +242,7 @@ }
NTSTATUS -STDMETHODCALLTYPE +NTAPI IResourceList_fnAddEntryFromParent( IResourceList* iface, IN IResourceList* Parent, @@ -281,7 +281,7 @@ }
PCM_RESOURCE_LIST -STDMETHODCALLTYPE +NTAPI IResourceList_fnTranslatedList( IResourceList* iface) { @@ -291,7 +291,7 @@ }
PCM_RESOURCE_LIST -STDMETHODCALLTYPE +NTAPI IResourceList_fnUntranslatedList( IResourceList* iface) { @@ -325,7 +325,9 @@ /* Factory for creating a resource list */ -PORTCLASSAPI NTSTATUS NTAPI +PORTCLASSAPI +NTSTATUS +NTAPI PcNewResourceList( OUT PRESOURCELIST* OutResourceList, IN PUNKNOWN OuterUnknown OPTIONAL, @@ -338,8 +340,6 @@ IResourceListImpl* NewList;
/* TODO: Validate parameters */ - - DPRINT("PcNewResourceList\n");
NewList = AllocateItem(PoolType, sizeof(IResourceListImpl), TAG_PORTCLASS);