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/portcls/irpstream.cpp?rev=43665&r1=43664&r2=43665&view=diff
==============================================================================
--- 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/portcls/pin_wavecyclic.cpp?rev=43665&r1=43664&r2=43665&view=diff
==============================================================================
--- 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/portcls/pin_wavepci.cpp?rev=43665&r1=43664&r2=43665&view=diff
==============================================================================
--- 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/wdmaud/control.c?rev=43665&r1=43664&r2=43665&view=diff
==============================================================================
--- 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 */


Reply via email to