Author: janderwald
Date: Wed Oct 21 08:34:24 2009
New Revision: 43665
URL:
http://svn.reactos.org/svn/reactos?rev=43665&view=rev
Log:
[PORTCLS]
- Implement support for submitting multiple stream headers at once
- Return correct status code on error
[WDMAUD_KERNEL]
- Save correct length
Modified:
trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp
trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp
trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp
trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp [iso-8859-1] Wed Oct 21
08:34:24 2009
@@ -57,6 +57,16 @@
};
+#define OFFSET_HEADERINDEX (0)
+#define OFFSET_STREAMHEADER (2)
+#define OFFSET_HEADERCOUNT (3)
+
+
+#define STREAMHEADER_INDEX(Irp)
(PtrToUlong(Irp->Tail.Overlay.DriverContext[OFFSET_HEADERINDEX]))
+#define STREAMHEADER_COUNT(Irp)
(PtrToUlong(Irp->Tail.Overlay.DriverContext[OFFSET_HEADERCOUNT]))
+#define STREAMHEADER_CURRENT(Irp)
(Irp->Tail.Overlay.DriverContext[OFFSET_STREAMHEADER])
+
+
NTSTATUS
NTAPI
CIrpQueue::QueryInterface(
@@ -107,6 +117,8 @@
PKSSTREAM_HEADER Header;
NTSTATUS Status = STATUS_SUCCESS;
PIO_STACK_LOCATION IoStack;
+ ULONG NumHeaders, NumData, Index;
+ PMDL Mdl;
PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
@@ -132,31 +144,71 @@
return Status;
}
}
- // get the stream header
+
+ // get first stream header
Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer;
- PC_ASSERT(Header);
- PC_ASSERT(Irp->MdlAddress);
-
- DPRINT("Size %u DataUsed %u FrameExtent %u SizeHeader %u NumDataAvailable %u
OutputLength %u\n", Header->Size, Header->DataUsed, Header->FrameExtent,
sizeof(KSSTREAM_HEADER), m_NumDataAvailable,
IoStack->Parameters.DeviceIoControl.OutputBufferLength);
-
- Header->Data = MmGetSystemAddressForMdlSafe(Irp->MdlAddress,
NormalPagePriority);
- PC_ASSERT(Header->Data);
- //PC_ASSERT(Header->Size ==
IoStack->Parameters.DeviceIoControl.OutputBufferLength);
-
- // HACK
- Irp->Tail.Overlay.DriverContext[2] = (PVOID)Header;
-
- // sanity check
- PC_ASSERT(Header);
-
- // dont exceed max frame size
- //PC_ASSERT(m_MaxFrameSize >= Header->DataUsed);
-
- // increment num mappings
- InterlockedIncrement(&m_NumMappings);
-
- // increment num data available
- m_NumDataAvailable += Header->DataUsed;
+
+ // calculate num headers
+ NumHeaders = IoStack->Parameters.DeviceIoControl.OutputBufferLength /
Header->Size;
+
+ // assume headers of same length
+ PC_ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength % Header->Size
== 0);
+
+
+ // get first audio buffer
+ Mdl = Irp->MdlAddress;
+
+
+ // store the current stream header
+ Irp->Tail.Overlay.DriverContext[OFFSET_STREAMHEADER] = (PVOID)Header;
+ // store header count
+ Irp->Tail.Overlay.DriverContext[OFFSET_HEADERCOUNT] = UlongToPtr(NumHeaders);
+
+ // store current header index
+ Irp->Tail.Overlay.DriverContext[OFFSET_HEADERINDEX] = UlongToPtr(0);
+
+
+ NumData = 0;
+ // prepare all headers
+ for(Index = 0; Index < NumHeaders; Index++)
+ {
+ // sanity checks
+ PC_ASSERT(Header);
+ PC_ASSERT(Mdl);
+
+ Header->Data = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);
+
+ if (!Header->Data)
+ {
+ // insufficient resources
+ ExFreePool(Irp->AssociatedIrp.SystemBuffer);
+ Irp->AssociatedIrp.SystemBuffer = NULL;
+ // complete and forget request
+ Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ // increment num mappings
+ InterlockedIncrement(&m_NumMappings);
+
+ // increment available data
+ InterlockedExchangeAdd((PLONG)&m_NumDataAvailable,
+ (max(Header->DataUsed,
Header->FrameExtent)));
+
+ NumData += max(Header->DataUsed, Header->FrameExtent);
+
+ // move to next header
+ Header = (PKSSTREAM_HEADER)((ULONG_PTR)Header + Header->Size);
+
+ // move to next mdl
+ Mdl = Mdl->Next;
+ }
+
+ DPRINT("StreamHeaders %u NumData %u FrameSize %u NumDataAvailable %u\n",
NumHeaders, NumData, m_MaxFrameSize, m_NumDataAvailable);
+
// mark irp as pending
IoMarkIrpPending(Irp);
@@ -206,6 +258,7 @@
if (!Irp)
{
DPRINT("NoIrp\n");
+ return STATUS_UNSUCCESSFUL;
// no irp available, use silence buffer
*Buffer = (PUCHAR)m_SilenceBuffer;
*BufferSize = m_MaxFrameSize;
@@ -216,16 +269,8 @@
return STATUS_SUCCESS;
}
-#if 0
- // get current irp stack location
- IoStack = IoGetCurrentIrpStackLocation(Irp);
-
// get stream header
- StreamHeader =
(PKSSTREAM_HEADER)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
-#else
- // HACK get stream header
StreamHeader = (PKSSTREAM_HEADER)Irp->Tail.Overlay.DriverContext[2];
-#endif
// sanity check
PC_ASSERT(StreamHeader);
@@ -253,7 +298,7 @@
IN ULONG BytesWritten)
{
PKSSTREAM_HEADER StreamHeader;
- ULONG Size;
+ ULONG Size, NumData, Index;
if (!m_Irp)
{
@@ -262,7 +307,7 @@
}
// get stream header
- StreamHeader = (PKSSTREAM_HEADER)m_Irp->Tail.Overlay.DriverContext[2];
+ StreamHeader = (PKSSTREAM_HEADER)STREAMHEADER_CURRENT(m_Irp);
// sanity check
// ASSERT(StreamHeader);
@@ -282,20 +327,59 @@
if (m_CurrentOffset >= Size)
{
+ if (STREAMHEADER_INDEX(m_Irp) + 1 < STREAMHEADER_COUNT(m_Irp))
+ {
+ // the irp has at least one more stream header
+ m_Irp->Tail.Overlay.DriverContext[OFFSET_HEADERINDEX] =
UlongToPtr(STREAMHEADER_INDEX(m_Irp) + 1);
+
+ // get next stream header
+ StreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)StreamHeader +
StreamHeader->Size);
+
+ // store next stream header
+ STREAMHEADER_CURRENT(m_Irp) = (PVOID)StreamHeader;
+
+ // reset current offset
+ m_CurrentOffset = 0;
+
+ // done
+ return;
+ }
+
// irp has been processed completly
+
+ NumData = 0;
+ StreamHeader = (PKSSTREAM_HEADER)m_Irp->AssociatedIrp.SystemBuffer;
+
+ // loop all stream headers
+ for(Index = 0; Index < STREAMHEADER_COUNT(m_Irp); Index++)
+ {
+ PC_ASSERT(StreamHeader);
+
+ // add size of buffer
+ // depends on if the buffer is input / output
+ if (StreamHeader->DataUsed)
+ Size = StreamHeader->DataUsed;
+ else
+ Size = StreamHeader->FrameExtent;
+
+ // increment size
+ NumData += Size;
+
+ // get next stream header
+ StreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)StreamHeader +
StreamHeader->Size);
+ }
+
m_Irp->IoStatus.Status = STATUS_SUCCESS;
-
- // frame extend contains the original request size, DataUsed contains the real
buffer size
- //is different when kmixer performs channel conversion, upsampling etc
-
- m_Irp->IoStatus.Information = Size;
-
+ m_Irp->IoStatus.Information = NumData;
+
+#if 0
PC_ASSERT_IRQL(DISPATCH_LEVEL);
MmUnlockPages(m_Irp->MdlAddress);
IoFreeMdl(m_Irp->MdlAddress);
m_Irp->MdlAddress = NULL;
ExFreePool(m_Irp->AssociatedIrp.SystemBuffer);
m_Irp->AssociatedIrp.SystemBuffer = NULL;
+#endif
// complete the request
IoCompleteRequest(m_Irp, IO_SOUND_INCREMENT);
@@ -391,6 +475,9 @@
return STATUS_UNSUCCESSFUL;
}
+ //FIXME support more than one stream header
+ PC_ASSERT(STREAMHEADER_COUNT(Irp) == 1);
+
// HACK get stream header
StreamHeader = (PKSSTREAM_HEADER)Irp->Tail.Overlay.DriverContext[2];
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp [iso-8859-1]
(original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp [iso-8859-1] Wed
Oct 21 08:34:24 2009
@@ -601,10 +601,11 @@
else
m_Position.WriteOffset += Header->DataUsed;
- }
-
-
- return STATUS_PENDING;
+ return STATUS_PENDING;
+
+ }
+
+ return Status;
}
NTSTATUS
@@ -976,6 +977,11 @@
RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize);
+ PKSDATAFORMAT_WAVEFORMATEX Wave = (PKSDATAFORMAT_WAVEFORMATEX)m_Format;
+
+ DPRINT1("Bits %u Samples %u Channels %u Tag %u FrameSize %u\n",
Wave->WaveFormatEx.wBitsPerSample, Wave->WaveFormatEx.nSamplesPerSec,
Wave->WaveFormatEx.nChannels, Wave->WaveFormatEx.wFormatTag, m_FrameSize);
+
+
Port->AddRef();
Filter->AddRef();
@@ -985,9 +991,6 @@
DPRINT("Setting state to acquire %x\n",
m_Stream->SetState(KSSTATE_ACQUIRE));
DPRINT("Setting state to pause %x\n",
m_Stream->SetState(KSSTATE_PAUSE));
- DPRINT("Setting state to run %x\n", m_Stream->SetState(KSSTATE_RUN));
- m_State = KSSTATE_RUN;
-
return STATUS_SUCCESS;
}
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp [iso-8859-1]
(original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp [iso-8859-1] Wed Oct
21 08:34:24 2009
@@ -682,10 +682,10 @@
else
m_Position.WriteOffset += Header->DataUsed;
- }
-
-
- return STATUS_PENDING;
+ return STATUS_PENDING;
+ }
+
+ return Status;
}
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/w…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] Wed Oct 21
08:34:24 2009
@@ -331,7 +331,7 @@
if (!NT_SUCCESS(Status))
{
- DPRINT1("KsProbeStreamIrp failed with Status %x\n", Status);
+ DPRINT1("KsProbeStreamIrp failed with Status %x Cancel %u\n", Status,
Irp->Cancel);
return SetIrpIoStatus(Irp, Status, 0);
}
@@ -355,7 +355,7 @@
/* attach file object */
IoStack->FileObject = FileObject;
- IoStack->Parameters.Write.Length = sizeof(KSSTREAM_HEADER);
+ IoStack->Parameters.Write.Length = Length;
IoStack->MajorFunction = IRP_MJ_WRITE;
/* mark irp as pending */