|
|
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.