ReactOS 0.4.15-dev-7670-g69b08be
CMiniportWaveICHStream Class Reference

#include <wavepcistream.h>

Inheritance diagram for CMiniportWaveICHStream:
Collaboration diagram for CMiniportWaveICHStream:

Public Member Functions

 DECLARE_STD_UNKNOWN ()
 
 DEFINE_STD_CONSTRUCTOR (CMiniportWaveICHStream)
 
 ~CMiniportWaveICHStream ()
 
NTSTATUS Init_ ()
 
void PowerChangeNotify_ (IN POWER_STATE NewState)
 
void InterruptServiceRoutine ()
 
- Public Member Functions inherited from CMiniportStream
 ~CMiniportStream ()
 
void ResetDMA (void)
 
void PauseDMA (void)
 
void ResumeDMA (ULONG state=DMA_ENGINE_ON)
 
int GetBuffPos (DWORD *buffPos)
 
void WriteReg8 (ULONG addr, UCHAR data)
 
void WriteReg16 (ULONG addr, USHORT data)
 
void WriteReg32 (ULONG addr, ULONG data)
 
UCHAR ReadReg8 (ULONG addr)
 
USHORT ReadReg16 (ULONG addr)
 
ULONG ReadReg32 (ULONG addr)
 
 STDMETHODIMP_ (NTSTATUS) SetFormat(_In_ PKSDATAFORMAT Format)
 
void PowerChangeNotify (IN POWER_STATE NewState)
 
virtual void PowerChangeNotify_ (IN POWER_STATE NewState)
 
ULONG GetCurrentSampleRate (void)
 
NTSTATUS Init (IN CMiniport *Miniport_, IN PUNKNOWN PortStream, IN WavePins Pin_, IN BOOLEAN Capture_, IN PKSDATAFORMAT DataFormat_, OUT PSERVICEGROUP *ServiceGroup_)
 
virtual void InterruptServiceRoutine () PURE
 
virtual NTSTATUS Init_ () PURE
 
NTSTATUS NonDelegatingQueryInterface (_In_ REFIID Interface, _COM_Outptr_ PVOID *Object, _In_ REFIID iStream, _In_ PUNKNOWN stream)
 
NTSTATUS SetState (_In_ KSSTATE State)
 
NTSTATUS NormalizePhysicalPosition (_Inout_ PLONGLONG PhysicalPosition)
 
PVOID BDList_Alloc ()
 
void BDList_Free ()
 
void UpdateLviCyclic ()
 

Public Attributes

 IMP_IMiniportWavePciStream
 
- Public Attributes inherited from CUnknown
union {
   IUnknown   IUnknown
 
   INonDelegatingUnknown   INonDelegatingUnknown
 
}; 
 
LONG m_ref_count
 
PUNKNOWN m_outer_unknown
 
- Public Attributes inherited from CMiniportStream
CMiniportMiniport
 
WavePins Pin
 
BOOL Capture
 
WORD NumberOfChannels
 
DEVICE_POWER_STATE m_PowerState
 
PPORTSTREAM_ PortStream
 
PKSDATAFORMAT_WAVEFORMATEX DataFormat
 
PSERVICEGROUP ServiceGroup
 
ULONG CurrentRate
 
ULONG DMAEngineState
 
ULONG m_ulBDAddr
 
PHYSICAL_ADDRESS BDList_PhysAddr
 
tBDEntryBDList
 
 IMP_IDrmAudioStream
 

Private Member Functions

NTSTATUS GetNewMappings (void)
 
NTSTATUS ReleaseUsedMappings (void)
 
CMiniportWaveICHWave ()
 

Private Attributes

KSPIN_LOCK MapLock
 
ULONGLONG TotalBytesMapped
 
ULONGLONG TotalBytesReleased
 
BOOL m_inGetMapping
 
tBDList stBDList
 

Detailed Description

Definition at line 57 of file wavepcistream.h.

Constructor & Destructor Documentation

◆ ~CMiniportWaveICHStream()

CMiniportWaveICHStream::~CMiniportWaveICHStream ( )

Definition at line 73 of file wavepcistream.cpp.

74{
75 PAGED_CODE ();
76
77
78 DOUT (DBG_PRINT, ("[CMiniportWaveICHStream::~CMiniportWaveICHStream]"));
79
80 //
81 // Print information about the scatter gather list.
82 //
83 DOUT (DBG_DMA, ("Head %d, Tail %d, Entries %d.",
86
87 // Release the scatter/gather table.
89}
#define PAGED_CODE()
void BDList_Free()
Definition: stream2.cpp:25
#define DOUT(lvl, strings)
Definition: debug.h:82
const int DBG_DMA
Definition: debug.h:24
#define DBG_PRINT(ppi, ch, level)
Definition: win32kdebug.h:168

Member Function Documentation

◆ DECLARE_STD_UNKNOWN()

CMiniportWaveICHStream::DECLARE_STD_UNKNOWN ( )

◆ DEFINE_STD_CONSTRUCTOR()

CMiniportWaveICHStream::DEFINE_STD_CONSTRUCTOR ( CMiniportWaveICHStream  )

◆ GetNewMappings()

NTSTATUS CMiniportWaveICHStream::GetNewMappings ( void  )
private

Definition at line 553 of file wavepcistream.cpp.

554{
556
557 NTSTATUS ntStatus = STATUS_SUCCESS;
558 ULONG ulBytesMapped = 0;
559 int nInsertMappings = 0;
560 int nTail; // aut. variable
561
562 DOUT (DBG_PRINT, ("[CMiniportWaveICHStream::GetNewMappings]"));
563
564 // acquire the mapping spin lock
566
567 // detect reentrance
568 if(m_inGetMapping) {
569 m_inGetMapping = 2;
571 return STATUS_SUCCESS;
572 }
573
574#if (DBG)
575 if (ReadReg16 (X_SR) & SR_CELV)
576 {
577 //
578 // We starve. :-(
579 //
580 DOUT (DBG_DMA, ("[GetNewMappings] We starved ... Head %d, Tail %d, Entries %d.",
582 }
583#endif
584
585 //
586 // Get available mappings up to the max of 31 that we can hold in the BDL.
587 //
588 while (stBDList.nBDEntries < (MAX_BDL_ENTRIES - 1))
589 {
590 //
591 // Get the information from the list.
592 //
593 ULONG Flags;
595 ULONG ulBufferLength;
596 PHYSICAL_ADDRESS PhysAddr;
597 PVOID VirtAddr;
598
599
600 // Release the mapping spin lock
601NEW_MAPPINGS_AVAILBLE_MAYBE:
604
605 //
606 // Try to get the mapping from the port.
607 // Here comes the problem: When calling GetMapping or ReleaseMapping we
608 // cannot hold our spin lock. So we need to buffer the return values and
609 // stick the information into the structure later when we have the spin
610 // lock acquired.
611 //
612 ntStatus = PortStream->GetMapping ((PVOID)ULongToPtr(ulTag),
613 (PPHYSICAL_ADDRESS)&PhysAddr,
614 &VirtAddr,
615 &ulBufferLength,
616 &Flags);
617
618 // Acquire the mapping spin lock
620
621 //
622 // Quit this loop when we run out of mappings.
623 //
624 if (!NT_SUCCESS (ntStatus))
625 {
626 if(m_inGetMapping == 2)
627 goto NEW_MAPPINGS_AVAILBLE_MAYBE;
628 break;
629 }
630
631 // Sanity check: The audio stack will not give you data
632 // that you cannot handle, but an application could use
633 // DirectKS and send bad buffer down.
634
635 // One mapping needs to be <0x1FFFF bytes for mono
636 // streams on the AC97.
637 if (ulBufferLength > 0x1FFFE)
638 {
639 // That is a little too long. That should never happen.
640 DOUT (DBG_ERROR, ("[GetNewMappings] Buffer length too long!"));
641 ulBufferLength = 0x1FFFE;
642 }
643
644 // The AC97 can only handle WORD aligned buffers.
645 if (PhysAddr.LowPart & 0x01)
646 {
647 // we cannot play that! Set the buffer length to 0 so
648 // that the HW will skip the buffer.
649 DOUT (DBG_WARNING, ("[GetNewMappings] Buffer address unaligned!"));
650 ulBufferLength = 0;
651 }
652
653 // The AC97 cannot handle unaligned mappings with respect
654 // to the frame size (eg. 42 bytes on 4ch playback).
655 if (ulBufferLength % NumberOfChannels)
656 {
657 // modify the length (don't play the rest of the bytes)
658 DOUT (DBG_WARNING, ("[GetNewMappings] Buffer length unaligned!"));
659 ulBufferLength -= ulBufferLength % NumberOfChannels;
660 }
661
662 //
663 // Save the mapping.
664 //
665 nTail = stBDList.nTail;
666 stBDList.pMapData[nTail].ulBufferLength = ulBufferLength;
667 stBDList.pMapData[nTail].ulState = 1;
668 ulBytesMapped += ulBufferLength;
669
670 //
671 // Fill in the BDL entry with pointer to physical address and length.
672 //
673 BDList[nTail].dwPtrToPhyAddress = PhysAddr.LowPart;
674 BDList[nTail].wLength = (WORD)(ulBufferLength >> 1);
675 BDList[nTail].wPolicyBits = BUP_SET;
676
677 //
678 // Generate an interrupt when portcls tells us to or roughly every 10ms.
679 //
680 if (Flags || (ulBytesMapped > (CurrentRate * NumberOfChannels * 2) / 100))
681 {
682 BDList[nTail].wPolicyBits |= IOC_ENABLE;
683 ulBytesMapped = 0;
684 }
685
686 //
687 // Take the new mapping into account.
688 //
691 TotalBytesMapped += (ULONGLONG)ulBufferLength;
692 nInsertMappings++;
693
694 //
695 // Set last valid index (LVI) register! We need to do this here to avoid inconsistency
696 // of the BDList with the HW. Note that we need to release spin locks every time
697 // we call into portcls, that means we can be interrupted by ReleaseUsedMappings.
698 //
699 WriteReg8 (X_LVI, (UCHAR)nTail);
700 }
701
702 //
703 // If there were processed mappings, print out some debug messages and eventually try to
704 // restart DMA engine.
705 //
706 if (nInsertMappings)
707 {
708 //
709 // Print debug information ...
710 //
711 DOUT (DBG_DMA, ("[GetNewMappings] Got %d mappings.", nInsertMappings));
712 DOUT (DBG_DMA, ("[GetNewMappings] Head %d, Tail %d, Entries %d.",
714
715 if(stBDList.nBDEntries >= 2)
717 }
718
719 // Release the mapping spin lock
722
723 return ntStatus;
724}
LONG NTSTATUS
Definition: precomp.h:26
#define ULongToPtr(ul)
Definition: basetsd.h:92
tBDEntry * BDList
Definition: stream.h:61
WORD NumberOfChannels
Definition: stream.h:45
void ResumeDMA(ULONG state=DMA_ENGINE_ON)
Definition: stream.cpp:599
ULONG CurrentRate
Definition: stream.h:56
USHORT ReadReg16(ULONG addr)
Definition: stream.cpp:631
PPORTSTREAM_ PortStream
Definition: stream.h:48
void WriteReg8(ULONG addr, UCHAR data)
Definition: stream.cpp:623
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
const int DBG_WARNING
Definition: debug.h:18
const int DMA_ENGINE_PAUSE
Definition: stream.h:5
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
unsigned short WORD
Definition: ntddk_ex.h:93
const USHORT IOC_ENABLE
Definition: ichreg.h:103
const ULONG X_LVI
Definition: ichreg.h:52
const ULONG X_SR
Definition: ichreg.h:53
const USHORT BUP_SET
Definition: ichreg.h:104
const USHORT SR_CELV
Definition: ichreg.h:62
#define DBG_ERROR
Definition: nfs41_debug.h:78
const int MAX_BDL_ENTRIES
Definition: rtstream.h:24
const int BDL_MASK
Definition: rtstream.h:29
#define STATUS_SUCCESS
Definition: shellext.h:65
WORD wPolicyBits
Definition: stream.h:33
WORD wLength
Definition: stream.h:32
DWORD dwPtrToPhyAddress
Definition: stream.h:31
tMapData * pMapData
ULONG ulState
Definition: wavepcistream.h:30
ULONG ulBufferLength
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
ULONG LowPart
Definition: typedefs.h:106
_In_ ULONG _In_ ULONG ulTag
Definition: winddi.h:3942
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by STDMETHODIMP_().

◆ Init_()

NTSTATUS CMiniportWaveICHStream::Init_ ( )
virtual

Reimplemented from CMiniportStream.

Definition at line 99 of file wavepcistream.cpp.

100{
101 PAGED_CODE ();
102
103 DOUT (DBG_PRINT, ("[CMiniportWaveICHStream::Init]"));
104
105 //
106 // The rule here is that we return when we fail without a cleanup.
107 // The destructor will relase the allocated memory.
108 //
109
110 //
111 // Initialize the BDL spinlock.
112 //
114
115 //
116 // Setup the Buffer Descriptor List (BDL)
117 // Allocate 32 entries of 8 bytes (one BDL entry).
118 // The pointer is aligned on a 8 byte boundary (that's what we need).
119 //
120
121 if (!BDList_Alloc())
122 {
123 DOUT (DBG_ERROR, ("Failed AllocateCommonBuffer!"));
125 }
126
127 PPREFETCHOFFSET PreFetchOffset;
128 //
129 // Query for the new interface "PreFetchOffset" and use
130 // function offered there in case the interface is offered.
131 //
132 if (NT_SUCCESS(PortStream->QueryInterface(IID_IPreFetchOffset, (PVOID *)&PreFetchOffset)))
133 {
134 // why don't we pad by 32 sample frames
135 PreFetchOffset->SetPreFetchOffset(32 * (DataFormat->WaveFormatEx.nChannels * 2));
136 PreFetchOffset->Release();
137 }
138
139 return STATUS_SUCCESS;
140}
PVOID BDList_Alloc()
Definition: stream2.cpp:11
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
nsrefcnt Release()
IPreFetchOffset * PPREFETCHOFFSET
Definition: portcls.h:2297
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158

◆ InterruptServiceRoutine()

void CMiniportWaveICHStream::InterruptServiceRoutine ( )
virtual

Reimplemented from CMiniportStream.

Definition at line 417 of file rtstream.cpp.

418{
419 //
420 // Update the LVI so that we cycle around in the scatter gather list.
421 //
423}
void UpdateLviCyclic()
Definition: stream.h:172

◆ PowerChangeNotify_()

void CMiniportWaveICHStream::PowerChangeNotify_ ( IN POWER_STATE  NewState)
virtual

Reimplemented from CMiniportStream.

Definition at line 202 of file wavepcistream.cpp.

206{
208
210
211 if(NewState.DeviceState == PowerDeviceD0)
212 {
213 ResetDMA ();
214
215 // Restore the remaining DMA registers, that is last valid index
216 // only if the index is not pointing to 0. Note that the index is
217 // equal to head + entries.
218 if (stBDList.nTail)
219 {
221 }
222 }
223 else
224 {
225
226 // Disable interrupts and stop DMA just in case.
227 WriteReg8 (X_CR, (UCHAR)0);
228
229 // Get current index
230 // int nCurrentIndex = (int)ReadReg8 (X_CIV);
231 }
232
234}
void ResetDMA(void)
Definition: stream.cpp:544
const ULONG X_CR
Definition: ichreg.h:56
@ PowerDeviceD0
Definition: ntpoapi.h:49

◆ ReleaseUsedMappings()

NTSTATUS CMiniportWaveICHStream::ReleaseUsedMappings ( void  )
private

Definition at line 735 of file wavepcistream.cpp.

736{
738 int nMappingsReleased = 0;
739
740 DOUT (DBG_PRINT, ("[CMiniportWaveICHStream::ReleaseUsedMappings]"));
741
742 // acquire the mapping spin lock
744
745 //
746 // Clean up everything to that index.
747 //
748 while (stBDList.nBDEntries)
749 {
750 //
751 // Get current index
752 //
753 int nCurrentIndex = (int)ReadReg8 (X_CIV);
754
755 //
756 // When CIV is == Head -1 we released all mappings.
757 //
758 if (nCurrentIndex == ((stBDList.nHead - 1) & BDL_MASK))
759 {
760 break;
761 }
762
763 //
764 // Check if CIV is between head and tail.
765 //
766 if (nCurrentIndex < stBDList.nHead)
767 {
768 //
769 // Check for CIV being outside range.
770 //
771 if ((nCurrentIndex + MAX_BDL_ENTRIES) >=
773 {
774 DOUT (DBG_ERROR, ("[ReleaseUsedMappings] CIV out of range!"));
775 break;
776 }
777 }
778 else
779 {
780 //
781 // Check for CIV being outside range.
782 //
783 if (nCurrentIndex >= (stBDList.nHead + stBDList.nBDEntries))
784 {
785 DOUT (DBG_ERROR, ("[ReleaseUsedMappings] CIV out of range!"));
786 break;
787 }
788 }
789
790 //
791 // Check to see if we've released all the buffers.
792 //
793 if (stBDList.nHead == nCurrentIndex)
794 {
795 if (nCurrentIndex == ((stBDList.nTail - 1) & BDL_MASK))
796 {
797 //
798 // A special case is starvation or stop of stream, when the
799 // DMA engine finished playing the buffers, CVI is equal LVI
800 // and SR_CELV is set.
801 //
802 if (!(ReadReg16 (X_SR) & SR_CELV))
803 {
804 // It is still playing the last buffer.
805 break;
806 }
807
808 //
809 // In case the CVI=LVI bit is set, nBDEntries should be 1
810 //
811 if (stBDList.nBDEntries != 1)
812 {
813 DOUT (DBG_ERROR, ("[ReleaseUsedMappings] Inconsitency: Tail reached and Entries != 1."));
814 }
815 }
816 else
817 {
818 //
819 // Bail out. Current Index did not move.
820 //
821 break;
822 }
823 }
824
825 //
826 // Save the tag and remove the entry from the list.
827 //
831 nMappingsReleased++;
832
833 // if entry has not been revoked
835 {
837
838 // Release the mapping spin lock
840
841 //
842 // Release this entry.
843 //
844 PortStream->ReleaseMapping ((PVOID)ULongToPtr(ulTag));
845
846 // acquire the mapping spin lock
848 }
849
851 }
852
853
854 // Print some debug information in case we released mappings.
855 if (nMappingsReleased)
856 {
857 //
858 // Print release information and return.
859 //
860 DOUT (DBG_DMA, ("[ReleaseUsedMappings] Head %d, Tail %d, Entries %d.",
862 }
863
864 // Release the mapping spin lock
866
867 return STATUS_SUCCESS;
868}
UCHAR ReadReg8(ULONG addr)
Definition: stream.cpp:629
ULONGLONG TotalBytesReleased
Definition: wavepcistream.h:67
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
const ULONG X_CIV
Definition: ichreg.h:51

Referenced by STDMETHODIMP_().

◆ Wave()

CMiniportWaveICH * CMiniportWaveICHStream::Wave ( )
inlineprivate

Definition at line 91 of file wavepcistream.h.

91 {
92 return (CMiniportWaveICH*)Miniport; }
CMiniport * Miniport
Definition: stream.h:42

Member Data Documentation

◆ IMP_IMiniportWavePciStream

CMiniportWaveICHStream::IMP_IMiniportWavePciStream

Definition at line 114 of file wavepcistream.h.

◆ m_inGetMapping

BOOL CMiniportWaveICHStream::m_inGetMapping
private

Definition at line 68 of file wavepcistream.h.

Referenced by GetNewMappings().

◆ MapLock

KSPIN_LOCK CMiniportWaveICHStream::MapLock
private

Definition at line 65 of file wavepcistream.h.

Referenced by GetNewMappings(), Init_(), PowerChangeNotify_(), and ReleaseUsedMappings().

◆ stBDList

tBDList CMiniportWaveICHStream::stBDList
private

◆ TotalBytesMapped

ULONGLONG CMiniportWaveICHStream::TotalBytesMapped
private

Definition at line 66 of file wavepcistream.h.

Referenced by GetNewMappings().

◆ TotalBytesReleased

ULONGLONG CMiniportWaveICHStream::TotalBytesReleased
private

Definition at line 67 of file wavepcistream.h.

Referenced by ReleaseUsedMappings().


The documentation for this class was generated from the following files: