Author: janderwald Date: Wed May 6 03:41:59 2009 New Revision: 40805
URL: http://svn.reactos.org/svn/reactos?rev=40805&view=rev Log: - Return status code if releasing the mapping has succeeded - Fix calculation of number of tags to be allocate per irp - Fix multiple bugs when acquiring the mapping and releasing the mapping - Vortex AU8810 WDM is now starting to play
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepcistream.c trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [iso-8859-1] Wed May 6 03:41:59 2009 @@ -227,7 +227,7 @@ OUT PULONG ByteCount, OUT PULONG Flags);
- STDMETHOD_(VOID, ReleaseMappingWithTag)(THIS_ + STDMETHOD_(NTSTATUS, ReleaseMappingWithTag)(THIS_ IN PVOID Tag);
STDMETHOD_(BOOL, HasLastMappingFailed)(THIS); @@ -518,7 +518,7 @@ IN PDEVICE_OBJECT DeviceObject) PURE; };
-typedef IPortPinWavePci *PPORTPINWAVERT; +typedef IPortPinWaveRT *PPORTPINWAVERT;
#endif
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c [iso-8859-1] Wed May 6 03:41:59 2009 @@ -56,6 +56,11 @@ IoCompleteRequest(CurMapping->Irp, IO_SOUND_INCREMENT); }
+ if (CurMapping->Tag) + { + FreeItem(CurMapping->Tag, TAG_PORTCLASS); + } + ExFreePool(CurMapping->Header->Data); ExFreePool(CurMapping->Header);
@@ -152,14 +157,28 @@
if (This->MaxFrameSize) { - Mapping->NumTags = max((Mapping->Header->DataUsed / This->MaxFrameSize) + 1, 1); + if (This->MaxFrameSize > Mapping->Header->DataUsed) + { + /* small mapping */ + Mapping->NumTags = 1; + } + else + { + ULONG Rest = Mapping->Header->DataUsed % This->MaxFrameSize; + + Mapping->NumTags = Mapping->Header->DataUsed / This->MaxFrameSize; + if (Rest) + { + Mapping->NumTags++; + } + } Mapping->Tag = AllocateItem(NonPagedPool, sizeof(PVOID) * Mapping->NumTags, TAG_PORTCLASS); Mapping->ReferenceCount = Mapping->NumTags; }
This->NumDataAvailable += Mapping->Header->DataUsed;
- DPRINT("IIrpQueue_fnAddMapping NumMappings %u SizeOfMapping %lu NumDataAvailable %lu Irp %p\n", This->NumMappings, Mapping->Header->DataUsed, This->NumDataAvailable, Irp); + DPRINT("IIrpQueue_fnAddMapping NumMappings %u SizeOfMapping %lu NumDataAvailable %lu Mapping %p ReferenceCount %u FrameSize %u\n", This->NumMappings, Mapping->Header->DataUsed, This->NumDataAvailable, Mapping, Mapping->ReferenceCount, This->MaxFrameSize);
ExInterlockedInsertTailList(&This->ListHead, &Mapping->Entry, &This->Lock); (void)InterlockedIncrement((volatile long*)&This->NumMappings); @@ -298,6 +317,59 @@ This->StartStream = FALSE;
} + +VOID +GetMapping( + IIrpQueueImpl * This, + IN ULONG Index, + IN PVOID Tag, + IN PIRP_MAPPING CurMapping, + OUT PPHYSICAL_ADDRESS PhysicalAddress, + OUT PVOID *VirtualAddress, + OUT PULONG ByteCount, + OUT PULONG Flags) +{ + ULONG Offset; + + /* store the tag */ + This->LastTag = Tag; + + /* calculate the offset */ + if (Index) + Offset = (Index + 1) * This->MaxFrameSize; + else + Offset = 0; + + ASSERT(CurMapping->Header->DataUsed > Offset); + + *VirtualAddress = (PUCHAR)CurMapping->Header->Data + Offset; + *PhysicalAddress = MmGetPhysicalAddress(*VirtualAddress); + /* FIXME alignment */ + *ByteCount = min(CurMapping->Header->DataUsed - Offset, This->MaxFrameSize); + + /* reset out of mapping indicator */ + This->OutOfMapping = FALSE; + + /* decrement available byte counter */ + This->NumDataAvailable -= *ByteCount; + + + /* store the tag */ + if (Index) + CurMapping->Tag[Index+1] = Tag; + else + CurMapping->Tag[Index] = Tag; + + if (Index + 1 == CurMapping->NumTags - 1) + { + /* indicate end of packet */ + *Flags = 1; + } + + DPRINT("IIrpQueue_fnGetMappingWithTag Tag %p Mapping %p NumTags %u ReferenceCount %u\n", Tag, CurMapping, CurMapping->NumTags, CurMapping->ReferenceCount); + +} +
NTSTATUS NTAPI @@ -310,14 +382,12 @@ OUT PULONG Flags) { PIRP_MAPPING CurMapping; - PIRP_MAPPING Result; PLIST_ENTRY CurEntry; ULONG Index; - ULONG Offset; IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
*Flags = 0; - Result = NULL; + ASSERT(This->MaxFrameSize);
KeAcquireSpinLockAtDpcLevel(&This->Lock);
@@ -326,60 +396,61 @@ { KeReleaseSpinLockFromDpcLevel(&This->Lock); This->OutOfMapping = TRUE; + This->StartStream = FALSE; return STATUS_UNSUCCESSFUL; } -
while (CurEntry != &This->ListHead) { CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry); for(Index = 0; Index < CurMapping->NumTags; Index++) { + /* first stream mapping */ + if (This->LastTag == NULL) + { + ASSERT(Index == 0); + GetMapping(This, Index, Tag, CurMapping, PhysicalAddress, VirtualAddress, ByteCount, Flags); + KeReleaseSpinLockFromDpcLevel(&This->Lock); + return STATUS_SUCCESS; + } + if (CurMapping->Tag[Index] == This->LastTag) { + ASSERT(Index); if (Index + 1 < CurMapping->NumTags) { - CurMapping->Tag[Index+1] = Tag; - Result = CurMapping; - - if (Index + 1 == CurMapping->NumTags - 1) - { - /* indicate end of packet */ - *Flags = 1; - } - Offset = (Index + 1) * This->MaxFrameSize; - ASSERT(Result->Header->DataUsed > Offset); - *VirtualAddress = (PUCHAR)Result->Header->Data + Offset; - *PhysicalAddress = MmGetPhysicalAddress(*VirtualAddress); - *ByteCount = min(Result->Header->DataUsed - Offset, This->MaxFrameSize); - break; + /* found a free mapping within audio irp */ + GetMapping(This, Index, Tag, CurMapping, PhysicalAddress, VirtualAddress, ByteCount, Flags); + KeReleaseSpinLockFromDpcLevel(&This->Lock); + return STATUS_SUCCESS; }
+ /* last tag was at at last mapping, iterate to next audio irp */ CurEntry = CurEntry->Flink; if (&This->ListHead == CurEntry) { + /* no more items available */ This->OutOfMapping = TRUE; + This->StartStream = FALSE; KeReleaseSpinLockFromDpcLevel(&This->Lock); return STATUS_UNSUCCESSFUL; } - Result = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry); - Result->Tag[0] = Tag; - *VirtualAddress = (PUCHAR)Result->Header->Data; - *PhysicalAddress = MmGetPhysicalAddress(*VirtualAddress); - *ByteCount = min(Result->Header->DataUsed, This->MaxFrameSize); - break; + + CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry); + GetMapping(This, 0, Tag, CurMapping, PhysicalAddress, VirtualAddress, ByteCount, Flags); + KeReleaseSpinLockFromDpcLevel(&This->Lock); + return STATUS_SUCCESS; } } CurEntry = CurEntry->Flink; } - KeReleaseSpinLockFromDpcLevel(&This->Lock); - This->LastTag = Tag; - This->OutOfMapping = FALSE; - return STATUS_SUCCESS; -} - -VOID + This->OutOfMapping = TRUE; + This->StartStream = FALSE; + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS NTAPI IIrpQueue_fnReleaseMappingWithTag( IN IIrpQueue *iface, @@ -388,40 +459,55 @@ PIRP_MAPPING CurMapping; PLIST_ENTRY CurEntry; ULONG Index; - IIrpQueueImpl * This = (IIrpQueueImpl*)iface; - - KeAcquireSpinLockAtDpcLevel(&This->Lock); - CurEntry = This->ListHead.Flink; - - while (CurEntry != &This->ListHead) - { - CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry); - for(Index = 0; Index < CurMapping->NumTags; Index++) + ULONG Found; + IIrpQueueImpl * This = (IIrpQueueImpl*)iface; + + ASSERT(This->MaxFrameSize); + + DPRINT("IIrpQueue_fnReleaseMappingWithTag Tag %p\n", Tag); + + CurEntry = ExInterlockedRemoveHeadList(&This->ListHead, &This->Lock); + + if (!CurEntry) + { + DPRINT("Empty List while releasing mapping!\n"); + return STATUS_UNSUCCESSFUL; + } + + CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry); + Found = FALSE; + + for(Index = 0; Index < CurMapping->NumTags; Index++) + { + if (CurMapping->Tag[Index] == Tag) { - if (CurMapping->Tag[Index] == Tag) - { - CurMapping->ReferenceCount--; - if (!CurMapping->ReferenceCount) - { - RemoveEntryList(&CurMapping->Entry); - if (CurMapping->Irp) - { - CurMapping->Irp->IoStatus.Information = CurMapping->Header->FrameExtent; - CurMapping->Irp->IoStatus.Status = STATUS_SUCCESS; - IoCompleteRequest(CurMapping->Irp, IO_SOUND_INCREMENT); - } - ExFreePool(CurMapping->Header->Data); - ExFreePool(CurMapping->Header); - ExFreePool(CurMapping->Tag); - ExFreePool(CurMapping); - } - break; - } + CurMapping->Tag[Index] = NULL; + InterlockedDecrement((PLONG)&CurMapping->ReferenceCount); + Found = TRUE; + break; } - CurEntry = CurEntry->Flink; - } - - KeReleaseSpinLockFromDpcLevel(&This->Lock); + } + + if (!Found) + { + DPRINT("Tag %p not in first mapping %p\n", Tag, CurMapping); + ExInterlockedInsertHeadList(&This->ListHead, &CurMapping->Entry, &This->Lock); + return STATUS_UNSUCCESSFUL; + } + + if (!CurMapping->ReferenceCount) + { + DPRINT("Freeing mapping %p\n", CurMapping); + InterlockedDecrement(&This->NumMappings); + FreeMappingRoutine(CurMapping); + } + else + { + /* insert item back into list as it still has references */ + ExInterlockedInsertHeadList(&This->ListHead, &CurMapping->Entry, &This->Lock); + } + + return STATUS_SUCCESS; }
BOOL
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.c [iso-8859-1] Wed May 6 03:41:59 2009 @@ -202,9 +202,7 @@ ASSERT_IRQL(DISPATCH_LEVEL);
Status = This->Stream->lpVtbl->GetPosition(This->Stream, &Position); - DPRINT("Position %ull Status %x\n", Position, Status); - - This->Stream->lpVtbl->Service(This->Stream); + DPRINT("Position %llu Status %x\n", Position, Status); }
static IServiceSinkVtbl vt_IServiceSink =
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepcistream.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepcistream.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepcistream.c [iso-8859-1] Wed May 6 03:41:59 2009 @@ -86,12 +86,9 @@ OUT PULONG Flags) { IPortWavePciStreamImpl * This = (IPortWavePciStreamImpl*)iface; - NTSTATUS Status; + ASSERT_IRQL(DISPATCH_LEVEL); - Status = This->Queue->lpVtbl->GetMappingWithTag(This->Queue, Tag, PhysicalAddress, VirtualAddress, ByteCount, Flags); - - DPRINT("IPortWavePciStream_fnGetMapping Tag %p Status %x\n", Tag, Status); - return Status; + return This->Queue->lpVtbl->GetMappingWithTag(This->Queue, Tag, PhysicalAddress, VirtualAddress, ByteCount, Flags); }
static @@ -104,9 +101,7 @@ IPortWavePciStreamImpl * This = (IPortWavePciStreamImpl*)iface;
ASSERT_IRQL(DISPATCH_LEVEL); - DPRINT("IPortWavePciStream_fnReleaseMapping Tag %p\n", Tag); - This->Queue->lpVtbl->ReleaseMappingWithTag(This->Queue, Tag); - return STATUS_SUCCESS; + return This->Queue->lpVtbl->ReleaseMappingWithTag(This->Queue, Tag); }
static @@ -117,7 +112,6 @@ { UNIMPLEMENTED ASSERT_IRQL(DISPATCH_LEVEL); - DPRINT("IPortWavePciStream_fnTerminatePacket\n"); return STATUS_SUCCESS; }
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild [iso-8859-1] Wed May 6 03:41:59 2009 @@ -3,6 +3,7 @@ <module name="portcls" type="kernelmodedriver" installbase="system32/drivers" installname="portcls.sys" entrypoint="0"> <importlibrary definition="portcls.spec" /> <define name="PC_NO_IMPORTS" /> + <redefine name="_WIN32_WINNT">0x600</redefine> <include base="portcls">../include</include> <library>ntoskrnl</library> <library>ks</library> @@ -10,39 +11,43 @@ <library>rtl</library> <library>hal</library> <library>libcntpr</library> + <file>adapter.c</file> <file>api.c</file> <file>connection.c</file> <file>dispatcher.c</file> <file>dll.c</file> <file>dma_slave.c</file> + <file>drm.c</file> <file>drm_port.c</file> - <file>adapter.c</file> <file>filter_wavecyclic.c</file> <file>filter_wavepci.c</file> + <file>filter_wavert.c</file> <file>guids.c</file> + <file>interrupt.c</file> <file>irp.c</file> <file>irpstream.c</file> - <file>interrupt.c</file> - <file>drm.c</file> - <file>undoc.c</file> - <file>resource.c</file> - <file>registry.c</file> - <file>service_group.c</file> + <file>miniport.c</file> + <file>miniport_dmus.c</file> + <file>miniport_fmsynth.c</file> <file>pin_wavecyclic.c</file> <file>pin_wavepci.c</file> + <file>pin_wavert.c</file> <file>pool.c</file> <file>port.c</file> - <file>power.c</file> <file>port_dmus.c</file> <file>port_midi.c</file> <file>port_topology.c</file> + <file>port_wavecyclic.c</file> <file>port_wavepci.c</file> - <file>port_wavecyclic.c</file> <file>port_wavepcistream.c</file> + <file>port_wavert.c</file> + <file>port_wavertstream.c</file> + <file>power.c</file> <file>propertyhandler.c</file> - <file>miniport.c</file> - <file>miniport_dmus.c</file> - <file>miniport_fmsynth.c</file> + <file>registry.c</file> + <file>resource.c</file> + <file>service_group.c</file> + <file>undoc.c</file> <file>version.c</file> <file>portcls.rc</file> </module>