|
|
1.1 root 1: /*++ BUILD Version: 0001 // Increment this if a change has global effects
2:
3:
4: Copyright (c) 1990 Microsoft Corporation
5:
6: Module Name:
7:
8: wave.h
9:
10: Abstract:
11:
12: This include file defines common structures for wave drivers
13:
14: Author:
15:
16: Robin Speed (RobinSp) 17-Oct-92
17:
18: Revision History:
19:
20: --*/
21:
22: //
23: // Minimum buffer size for DMA (in case we couldn't get what we asked for).
24: // 4K
25: //
26: #define SOUND_MINIMUM_WAVE_BUFFER_SIZE (4096)
27:
28: //
29: // Common DMA buffer for auto-initialize DMA and structures
30: // for using double-buffered DMA
31: //
32:
33:
34: typedef struct {
35: PADAPTER_OBJECT AdapterObject[2]; // The adapter object(s) -
36: // We may use 2 channels
37: ULONG BufferSize; // Size of the buffer
38: PVOID VirtualAddress; // Address of buffer
39: PHYSICAL_ADDRESS LogicalAddress; // Where is it really?
40: PMDL Mdl; // Mdl we are using for the buffer
41: } SOUND_DMA_BUFFER, *PSOUND_DMA_BUFFER;
42:
43:
44: typedef struct {
45: //
46: // Values for NextHalf field. This is the half of the DMA buffer
47: // to fill next. If wave data is being played or recorded this is
48: // also the 'live' part of the buffer (the part DMA is running on)
49: // and hence the next part to become free.
50: //
51: enum {LowerHalf = 0,
52: UpperHalf}
53: NextHalf; // Where we are now
54: ULONG BufferSize; // Size of the buffer
55: struct SOUND_DMABUF {
56: ULONG Size;
57: ULONG nBytes; // Our 2 half buffers
58: PUCHAR Buf;
59: } Buffer[2];
60: UCHAR Pad; // Padding byte to use
61:
62: // reprogramming (SB versions < 2.0)
63: } SOUND_DOUBLE_BUFFER, *PSOUND_DOUBLE_BUFFER;
64:
65: //
66: // Control processing of device queue
67: //
68:
69: typedef struct {
70: LIST_ENTRY QueueHead; // head of the queue if Irps
71: // for writing to / reading from
72: // device.
73: // Entries are cancellable Irps.
74: ULONG BytesProcessed; // Bytes put into or copied from buffers
75: ULONG UserBufferSize; // Size of user buffer
76: ULONG UserBufferPosition; // Position in buffer and
77: PUCHAR UserBuffer; // buffer corresponding to next user
78: PIRP pIrp; // pointer to the current request
79:
80: //
81: // Variables for controlling wave output sequencing of Irps
82: // to ensure that wave output is not signalled as finished until
83: // the data has actually played
84: //
85:
86: LIST_ENTRY ProgressQueue; // Wave output buffers in progress
87: // Entries on this queue are not
88: // cancellable
89:
90: } SOUND_BUFFER_QUEUE, *PSOUND_BUFFER_QUEUE;
91:
92: //
93: // Hardware interface routine type for Wave processing
94: //
95:
96:
97: struct _WAVE_INFO;
98: typedef BOOLEAN WAVE_INTERFACE_ROUTINE(struct _WAVE_INFO *);
99: typedef WAVE_INTERFACE_ROUTINE *PWAVE_INTERFACE_ROUTINE;
100: typedef NTSTATUS SOUND_QUERY_FORMAT_ROUTINE (PLOCAL_DEVICE_INFO, PPCMWAVEFORMAT);
101: typedef SOUND_QUERY_FORMAT_ROUTINE *PSOUND_QUERY_FORMAT_ROUTINE;
102:
103: enum {
104: SoundNoDMA,
105: SoundAutoInitDMA, // Use autoinitialize
106: SoundReprogramOnInterruptDMA, // Reprogram on interrupt
107: Sound2ChannelDMA // Keep 2 channels going
108: };
109:
110: typedef struct _WAVE_INFO {
111: ULONG Key; // Debugging
112:
113: #define WAVE_INFO_KEY (*(ULONG *)"Wave")
114:
115: PDEVICE_OBJECT DeviceObject; // Current real device (back pointer)
116:
117: //
118: // Information input to this component about our DMA buffer
119: //
120:
121: SOUND_DMA_BUFFER
122: DMABuf;
123:
124: //
125: // Data for manipulation of the buffer, INTERNAL to this component
126: //
127:
128: SOUND_DOUBLE_BUFFER
129: DoubleBuffer;
130:
131: //
132: // Data for maninpulation of input queue of data INTERNAL to this
133: // component
134: //
135:
136: SOUND_BUFFER_QUEUE
137: BufferQueue;
138: //
139: // Current wave format data - created by this component - INPUT to
140: // hardware interface routines
141: //
142:
143: ULONG SamplesPerSec;
144: UCHAR BitsPerSample;
145: UCHAR Channels;
146: BOOLEAN FormatChanged; // New format has been set
147: // Initially TRUE
148: PVOID MRB[2]; // Info about adapter for DMA
149:
150: //
151: // Event to wait for Dma channel to be allocated
152: //
153:
154: KEVENT DmaSetupEvent;
155:
156: //
157: // The following events are reset by SoundStopDMA and waited on
158: // if DpcQueued is set after resetting it. The Dpc routine sets
159: // this event when it has finished.
160: //
161:
162: KEVENT DpcEvent;
163: KEVENT TimerDpcEvent;
164: KSPIN_LOCK DeviceSpinLock; // spin lock for synchrnonizing with
165: // Dpc routine
166: #if DBG
167: BOOLEAN LockHeld; // Get spin locks right
168: #endif
169:
170: PKINTERRUPT Interrupt; // interrupt object
171:
172: BOOLEAN Direction; // TRUE = out, FALSE = in
173: UCHAR DMAType; // Type of DMA :
174: // SoundAutoInitDMA
175: // SoundReprogramOnInterruptDMA
176: // Sound2DMAChannelDMA
177: UCHAR InterruptHalf; // Used with SoundReprogramOnInterruptDMA
178: // as next half to use.
179:
180: volatile BOOLEAN
181: DMABusy; // set if dma in progress
182: // Dpc routine can turn it off
183: // so make it volatile
184:
185: volatile BOOLEAN
186: DpcQueued; // Set by Isr, cleared by Dpc routine
187: // tested by SoundStopDMA
188: ULONG Overrun; // Interrupts overran Dpcs
189: // Managed at DEVICE level
190:
191: PVOID HwContext; // Context for hardware interface
192: // routines
193:
194: //
195: // Callouts back to device specific code
196: //
197:
198:
199: //
200: // This routine returns TRUE if a wave format passed to it can be
201: // handled by the device.
202: //
203:
204: PSOUND_QUERY_FORMAT_ROUTINE
205: QueryFormat; // Format query and set routine
206:
207:
208: PWAVE_INTERFACE_ROUTINE
209: HwSetupDMA, // Outside spin lock - sets up parms
210: // for DMA
211: HwStopDMA, // Outside spin lock - stop device
212: // gracefully
213: HwSetWaveFormat; // Set the format to use
214:
215: KDPC TimerDpc; // Check if the device keeps
216: KTIMER DeviceCheckTimer; // going
217: BOOLEAN GotWaveDpc; // This flag is set if we are
218: // still going
219: BOOLEAN DeviceBad; // Failed timer test
220: BOOLEAN TimerActive; // Need to synch timer routine
221: UCHAR FailureCount; // If we fail 30 times in a row give up
222: } WAVE_INFO, *PWAVE_INFO;
223:
224: //
225: // Macros to assist in safely using our spin lock
226: //
227:
228: #if DBG
229: #define DMAEnter(pWave) \
230: { \
231: KIRQL OldIrql; \
232: KeAcquireSpinLock(&(pWave)->DeviceSpinLock, &OldIrql);\
233: ASSERT((pWave)->LockHeld == FALSE); \
234: (pWave)->LockHeld = TRUE;
235:
236: #define DMALeave(pWave) \
237: ASSERT((pWave)->LockHeld == TRUE); \
238: (pWave)->LockHeld = FALSE; \
239: KeReleaseSpinLock(&(pWave)->DeviceSpinLock, OldIrql);\
240: }
241: #else
242: #define DMAEnter(pWave) \
243: { \
244: KIRQL OldIrql; \
245: ASSERT((pWave)->LockHeld == FALSE); \
246: KeAcquireSpinLock(&(pWave)->DeviceSpinLock, &OldIrql);
247:
248: #define DMALeave(pWave) \
249: ASSERT((pWave)->LockHeld == TRUE); \
250: KeReleaseSpinLock(&(pWave)->DeviceSpinLock, OldIrql);\
251: }
252: #endif
253:
254: //
255: // Exported routines
256: //
257:
258: VOID
259: SoundInitializeWaveInfo(
260: PWAVE_INFO WaveInfo,
261: UCHAR DMAType,
262: PSOUND_QUERY_FORMAT_ROUTINE QueryFormat,
263: PVOID HwContext
264: );
265:
266: NTSTATUS
267: SoundGetCommonBuffer(
268: IN PDEVICE_DESCRIPTION DeviceDescription,
269: IN OUT PSOUND_DMA_BUFFER SoundAutoData
270: );
271:
272: VOID
273: SoundFreeCommonBuffer(
274: IN OUT PSOUND_DMA_BUFFER SoundAutoData
275: );
276:
277: //
278: // New Routine used by WAVE.C
279: //
280: ULONG SoundGetDMABufferSize( IN OUT PWAVE_INFO WaveInfo );
281:
282: int
283: SoundTestWaveDevice(
284: IN PDEVICE_OBJECT pDO
285: );
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.