20 #define kOneMillisec (10 * 1000) 25 #define MPU401_REG_STATUS 0x01 // Status register 26 #define MPU401_DRR 0x40 // Output ready (for command or data) 28 #define MPU401_DSR 0x80 // Input ready (for data) 31 #define MPU401_REG_DATA 0x00 // Data in 32 #define MPU401_REG_COMMAND 0x01 // Commands 33 #define MPU401_CMD_RESET 0xFF // Reset command 34 #define MPU401_CMD_UART 0x3F // Switch to UART mod 70 :
public IMiniportDMus,
71 public IMusicTechnology,
292 #define STR_MODULENAME "DMusUART:Miniport: " 295 #pragma code_seg("PAGE") 298 #define UartFifoOkForWrite(status) ((status & MPU401_DRR) == 0) 299 #define UartFifoOkForRead(status) ((status & MPU401_DSR) == 0) 455 #define kMaxNumCaptureStreams 1 456 #define kMaxNumLegacyRenderStreams 1 457 #define kMaxNumDMusicRenderStreams 1 559 #define CONST_PCNODE_DESCRIPTOR(n) { 0, NULL, &n, NULL } 560 #define CONST_PCNODE_DESCRIPTOR_AUTO(n,a) { 0, &a, &n, NULL } 633 #pragma code_seg("PAGE") 640 #pragma code_seg("PAGE") 652 #pragma code_seg("PAGE") 666 ntStatus = interruptSync->CallSynchronizedRoutine(
InitMPU,
PVOID(portBase));
682 DPRINT(
"*** InitMPU returned with ntStatus 0x%08x ***", ntStatus);
746 DPRINT(
"First attempt to reset the MPU didn't get ACKed.\n");
772 if ((0xFE != dataByte) || !
success)
774 DPRINT(
"Second attempt to reset the MPU didn't get ACKed.\n");
775 DPRINT(
"Init Reset failure error. Ack = %X",
ULONG(dataByte));
823 context.BufferAddress = pMidiData;
907 DPRINT(
"SynchronizedDMusMPUWrite failed (0x%08x)",ntStatus);
915 #define kMPUPollTimeout 2 984 DPRINT(
"O: PortBase is zero\n");
1051 CMiniportDMusUARTStream::SourceEvtsToPort()
1056 DPRINT(
"SourceEvtsToPort");
1070 DPRINT(
"SourceEvtsToPort can't allocate DMKEvt");
1077 eventHead = aDMKEvt;
1081 eventTail = eventHead;
1113 aDMKEvt = eventHead;
1126 DPRINT(
"SourceEvtsToPort called on render stream");
1149 DPRINT(
"DMusMPUInterruptServiceRoutine");
1155 BOOL newBytesAvailable;
1160 newBytesAvailable =
FALSE;
1163 UCHAR portStatus = 0xff;
1192 DPRINT(
"*****MPU Input Buffer Overflow*****");
1204 newBytesAvailable =
TRUE;
1222 if (newBytesAvailable)
1250 ASSERT(OutFilterDescriptor);
1252 DPRINT(
"GetDescription");
1260 #pragma code_seg("PAGE") 1282 DPRINT(
"NewMiniportDMusUART %p Status %x\n", *OutMiniport,
Status);
1288 #pragma code_seg("PAGE") 1305 DPRINT(
"ProcessResources");
1321 DPRINT(
"Starting MPU401 Port 0x%lx",
ResourceList->FindTranslatedPort(0)->u.Port.Start.LowPart);
1335 DPRINT(
"Unknown ResourceList configuration");
1347 ntStatus = InitializeHardware(m_pInterruptSync,m_pPortBase);
1354 #pragma code_seg("PAGE") 1371 DPRINT(
"Miniport::NonDelegatingQueryInterface");
1416 #pragma code_seg("PAGE") 1427 DPRINT(
"~CMiniportDMusUART");
1460 #pragma code_seg("PAGE") 1567 UnknownInterruptSync =
NULL;
1569 if (UnknownInterruptSync)
1572 UnknownInterruptSync->QueryInterface
1648 (*ServiceGroup)->Release();
1649 (*ServiceGroup) =
NULL;
1661 #pragma code_seg("PAGE") 1699 DPRINT(
"CMiniportDMusUART::NewStream ResetHardware failed");
1729 (*ServiceGroup)->AddRef();
1750 DPRINT(
"NewStream failed, too many capture streams");
1754 DPRINT(
"NewStream failed, too many render streams");
1758 DPRINT(
"NewStream invalid stream type");
1766 #pragma code_seg("PAGE") 1777 IN const GUID * Technology
1801 #pragma code_seg("PAGE") 1822 DPRINT(
"InitializeHardware failed when resuming");
1837 #pragma code_seg("PAGE") 1854 DPRINT(
"Stream::NonDelegatingQueryInterface");
1884 #pragma code_seg("PAGE") 1895 DPRINT(
"~CMiniportDMusUARTStream");
1907 DPRINT(
"~CMiniportDMusUARTStream, no allocator, can't flush DMKEvts");
1933 #pragma code_seg("PAGE") 1998 #pragma code_seg("PAGE") 2006 CMiniportDMusUARTStream::
2014 DPRINT(
"SetState %d",NewState);
2026 DPRINT(
"CMiniportDMusUARTStream::SetState KSSTATE_RUN failed due to uninitialized MPU");
2070 #pragma code_seg("PAGE") 2079 CMiniportDMusUARTStream::
2080 ConnectOutput(
PMXF sinkMXF)
2094 DPRINT(
"ConnectOutput failed");
2099 DPRINT(
"ConnectOutput called on renderer; failed");
2105 #pragma code_seg("PAGE") 2114 CMiniportDMusUARTStream::
2115 DisconnectOutput(
PMXF sinkMXF)
2121 if ((
m_sinkMXF == sinkMXF) || (!sinkMXF))
2123 DPRINT(
"DisconnectOutput");
2129 DPRINT(
"DisconnectOutput failed");
2134 DPRINT(
"DisconnectOutput called on renderer; failed");
2163 DPRINT(
"PutMessage to render stream");
2192 (
void) ConsumeEvents();
2197 DPRINT(
"PutMessage to capture stream");
2226 DPRINT(
"PutMessage to render stream");
2255 (
void) ConsumeEvents();
2260 DPRINT(
"PutMessage to capture stream");
2283 NTSTATUS CMiniportDMusUARTStream::ConsumeEvents(
void)
2302 ASSERT(bytesRemaining > 0);
2303 if (bytesRemaining <= 0)
2305 bytesRemaining = aDMKEvt->
cbEvent;
2317 DPRINT(
"ConsumeEvents(Package)");
2335 DPRINT(
"ConsumeEvents: Write returned 0x%08x", ntStatus);
2353 ASSERT(m_DMKEvtOffset < aDMKEvt->cbEvent);
2406 Params->ChannelGroups = 1;
2408 else if (
Params->ChannelGroups != 1)
2410 Params->ChannelGroups = 1;
2446 DPRINT(
"DMusUARTTimerDPC");
2449 (
void) aStream->ConsumeEvents();
2489 switch (
pRequest->PropertyItem->Id)
2495 switch (
pRequest->PropertyItem->Id)
2503 switch (
pRequest->PropertyItem->Id)
2524 DPRINT(
"PropertyHandler_Synth:KSPROPERTY_SYNTH_CAPS");
2546 caps->
Guid = CLSID_MiniportDriverDMusUART;
2552 caps->
Guid = CLSID_MiniportDriverDMusUARTCapture;
2570 cLen *=
sizeof(
WCHAR);
2583 DPRINT(
"PropertyHandler_Synth:KSPROPERTY_SYNTH_PORTPARAMETERS");
2600 DPRINT(
"PropertyHandler_Synth:KSPROPERTY_SYNTH_CHANNELGROUPS");
2611 DPRINT(
"PropertyHandler_Synth:KSPROPERTY_SYNTH_LATENCYCLOCK");
2641 DPRINT(
"Unhandled property in PropertyHandler_Synth");
2667 if (
pRequest->ValueSize >= ulValueSize)
IN PUCHAR IN BOOLEAN fCapture
NTSTATUS NTAPI SynchronizedDMusMPUWrite(PINTERRUPTSYNC InterruptSync, PVOID syncWriteContext)
#define KeGetCurrentIrql()
#define MPU401_REG_COMMAND
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesWritten
struct SYNCWRITECONTEXT * PSYNCWRITECONTEXT
IServiceGroup * PSERVICEGROUP
#define KSAUDFNAME_DMUSIC_MPU_OUT
IN PUNKNOWN OuterUnknown IN POOL_TYPE IN ULONG IN DMUS_STREAM_TYPE StreamType
const GUID KSDATAFORMAT_TYPE_MUSIC
#define UartFifoOkForWrite(status)
USHORT m_NumRenderStreams
CMiniportDMusUART(IUnknown *Unknown)
friend class CMiniportDMusUARTStream
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
#define STATUS_INSUFFICIENT_RESOURCES
_In_ ULONG _In_ ULONG _In_ ULONG Length
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
union KSDATAFORMAT KSDATARANGE
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
#define CONST_PCNODE_DESCRIPTOR_AUTO(n, a)
STDMETHODIMP_(ULONG) AddRef()
friend NTSTATUS NTAPI PropertyHandler_Synth(IN PPCPROPERTY_REQUEST)
IN PUNKNOWN OuterUnknown IN POOL_TYPE IN ULONG PinID
#define READ_PORT_UCHAR(p)
const ULONG kMPUInputBufferSize
#define STATUS_INVALID_PARAMETER
IMusicTechnology * PMUSICTECHNOLOGY
static ULONGLONG startTime
GLuint GLuint GLsizei count
CMiniportDMusUART * Miniport
#define KSCATEGORY_RENDER
static PKSDATARANGE PinDataRangePointersBridge[]
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
ULONG m_MPUInputBufferTail
STDMETHODIMP QueryInterface(REFIID InterfaceId, PVOID *Interface)
SnapTimeStamp(PINTERRUPTSYNC InterruptSync, PVOID pStream)
ULONGLONG NTAPI PcGetTimeInterval(IN ULONGLONG Since)
#define STATUS_INVALID_DEVICE_REQUEST
#define KSCATEGORY_CAPTURE
#define kMaxNumCaptureStreams
GUID m_MusicFormatTechnology
ULONG m_MPUInputBufferHead
struct _SYNTH_PORTPARAMS SYNTH_PORTPARAMS
NTSTATUS NTAPI DMusMPUInterruptServiceRoutine(PINTERRUPTSYNC InterruptSync, PVOID DynamicContext)
REFERENCE_TIME m_InputTimeStamp
BOOL Init(PUSERCONNECT UserCon)
NTSTATUS WriteMPU(IN PUCHAR PortBase, IN BOOLEAN IsCommand, IN UCHAR Value)
static BOOL Write(PBYTE Address, PBYTE Data, SIZE_T Size)
_Must_inspect_result_ _In_ WDFIORESREQLIST _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFIORESLIST * ResourceList
#define KSPROPERTY_TYPE_GET
static KSDATARANGE PinDataRangesBridge[]
struct _DMUS_KERNEL_EVENT * pNextEvt
IMasterClock * PMASTERCLOCK
#define STATUS_BUFFER_TOO_SMALL
#define IsEqualGUIDAligned(guid1, guid2)
#define STATUS_INVALID_DEVICE_STATE
#define STATUS_IO_DEVICE_ERROR
_In_ WDFREQUEST _In_ size_t OutputBufferLength
IN PUCHAR IN BOOLEAN IN PAllocatorMXF allocatorMXF
PSERVICEGROUP m_pServiceGroup
STDMETHODIMP QueryInterface(REFIID InterfaceId, PVOID *Interface)
return STATUS_NOT_IMPLEMENTED
IN PUNKNOWN OuterUnknown IN POOL_TYPE IN ULONG IN DMUS_STREAM_TYPE IN PKSDATAFORMAT OUT PSERVICEGROUP IN PAllocatorMXF IN PMASTERCLOCK OUT PULONGLONG SchedulePreFetch
struct IAllocatorMXF * PAllocatorMXF
NTSTATUS NTAPI InitMPU(IN PINTERRUPTSYNC InterruptSync, IN PVOID DynamicContext)
GetDescription(OUT PPCFILTER_DESCRIPTOR *OutFilterDescriptor)
static PCCONNECTION_DESCRIPTOR MiniportConnections[]
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
const GUID KSCATEGORY_AUDIO
CMiniportDMusUART * m_pMiniport
PAllocatorMXF m_AllocatorMXF
friend NTSTATUS NTAPI PropertyHandler_Synth(IN PPCPROPERTY_REQUEST PropertyRequest)
UCHAR m_MPUInputBuffer[kMPUInputBufferSize]
BYTE abData[sizeof(PBYTE)]
#define GTI_MILLISECONDS(t)
const GUID KSDATAFORMAT_SPECIFIER_NONE
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
STDMETHODIMP_(NTSTATUS) SourceEvtsToPort()
#define STATUS_INVALID_PARAMETER_2
#define kMaxNumDMusicRenderStreams
#define DMUS_KEF_EVENT_INCOMPLETE
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
IN PUCHAR IN BOOLEAN IN PAllocatorMXF IN PMASTERCLOCK masterClock
STDMETHODIMP_(void) Service(void)
static PCNODE_DESCRIPTOR MiniportNodes[]
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
#define KSDATAFORMAT_SUBTYPE_DIRECTMUSIC
REFERENCE_TIME ullPresTime100ns
PDMUS_KERNEL_EVENT m_DMKEvtQueue
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
#define KSPROPERTY_TYPE_BASICSUPPORT
IN PUNKNOWN OuterUnknown IN POOL_TYPE PoolType
NTSTATUS NewMiniportDMusUART(OUT PMINIPORT *OutMiniport, IN REFCLSID ClassId)
IN PUNKNOWN OuterUnknown IN POOL_TYPE IN ULONG IN DMUS_STREAM_TYPE IN PKSDATAFORMAT OUT PSERVICEGROUP IN PAllocatorMXF AllocatorMXF
#define kMaxNumLegacyRenderStreams
static GUID MiniportCategories[]
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
struct _SYNTH_PORTPARAMS * PSYNTH_PORTPARAMS
#define NT_SUCCESS(StatCode)
USHORT m_NumCaptureStreams
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
STDMETHODIMP_(ULONG) Release()
const GUID KSDATAFORMAT_SUBTYPE_MIDI
DEVICE_POWER_STATE DeviceState
STDMETHODIMP_(ULONG) Release()
NTSTATUS NTAPI PcNewInterruptSync(OUT PINTERRUPTSYNC *OutInterruptSync, IN PUNKNOWN OuterUnknown OPTIONAL, IN PRESOURCELIST ResourceList, IN ULONG ResourceIndex, IN INTERRUPTSYNCMODE Mode)
BOOLEAN m_fMPUInitialized
#define success(from, fromstr, to, tostr)
struct _MINIPORT * PMINIPORT
#define STATICGUIDOF(guid)
_In_opt_ PVOID _In_ ULONG _In_ PVOID context
#define STATUS_UNSUCCESSFUL
NTSTATUS InitializeHardware(PINTERRUPTSYNC interruptSync, PUCHAR portBase)
static KSDATARANGE_MUSIC PinDataRangesStreamDMusic
#define InterlockedDecrement
#define SYNTH_PORTPARAMS_CHANNELGROUPS
#define WRITE_PORT_UCHAR(p, d)
friend NTSTATUS NTAPI DMusMPUInterruptServiceRoutine(PINTERRUPTSYNC InterruptSync, PVOID DynamicContext)
virtual ~CMiniportDMusUARTStream()
friend NTSTATUS NTAPI SynchronizedDMusMPUWrite(PINTERRUPTSYNC InterruptSync, PVOID syncWriteContext)
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
GLenum GLsizei GLuint GLint * bytesWritten
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
static PKSDATARANGE PinDataRangePointersStreamCombined[]
IResourceList * PRESOURCELIST
union KSDATAFORMAT * PKSDATARANGE
IN PUNKNOWN OuterUnknown IN POOL_TYPE IN ULONG IN DMUS_STREAM_TYPE IN PKSDATAFORMAT OUT PSERVICEGROUP IN PAllocatorMXF IN PMASTERCLOCK MasterClock
static PKSDATARANGE PinDataRangePointersStreamLegacy[]
BOOLEAN TryMPU(IN PUCHAR PortBase)
#define InterlockedIncrement
#define STATUS_BUFFER_OVERFLOW
static PCPIN_DESCRIPTOR MiniportPins[]
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
VOID NTAPI DMusUARTTimerDPC(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
NTSTATUS ResetHardware(PUCHAR portBase)
IMiniportDMus * PMINIPORTDMUS
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ WDF_DEVICE_POWER_STATE PowerState
IN PRESOURCELIST IN PPORTDMUS Port
NTSTATUS ProcessResources(IN PRESOURCELIST ResourceList)
virtual ~CMiniportDMusUART()
STDMETHODIMP_(ULONG) AddRef()
static ULONG WINAPI AddRef(IStream *iface)
IInterruptSync * PINTERRUPTSYNC
IN PRESOURCELIST IN PPORTDMUS OUT PSERVICEGROUP * ServiceGroup
static PKSDATARANGE PinDataRangePointersStreamDMusic[]
NTSTATUS NTAPI PropertyHandler_Synth(IN PPCPROPERTY_REQUEST PropertyRequest)
#define SYNTH_PC_EXTERNAL
IPowerNotify * PPOWERNOTIFY
#define KSAUDFNAME_DMUSIC_MPU_IN
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
PMASTERCLOCK m_MasterClock
NTSTATUS NTAPI PcNewServiceGroup(OUT PSERVICEGROUP *OutServiceGroup, IN PUNKNOWN OuterUnknown OPTIONAL)
static PCPROPERTY_ITEM SynthProperties[]
#define RtlZeroMemory(Destination, Length)
#define RtlCopyMemory(Destination, Source, Length)
#define KSPROPSETID_Synth
friend VOID NTAPI DMusUARTTimerDPC(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
REFERENCE_TIME m_SnapshotTimeStamp
DataRangeIntersection(IN ULONG PinId, IN PKSDATARANGE DataRange, IN PKSDATARANGE MatchingDataRange, IN ULONG OutputBufferLength, OUT PVOID ResultantFormat, OUT PULONG ResultantFormatLength)
static KSDATARANGE_MUSIC PinDataRangesStreamLegacy
union _DMUS_KERNEL_EVENT::@1919 uData
DEFINE_PCAUTOMATION_TABLE_PROP(AutomationSynth, SynthProperties)
PINTERRUPTSYNC m_pInterruptSync
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
#define STATUS_DEVICE_CONFIGURATION_ERROR
NTSTATUS ValidatePropertyRequest(IN PPCPROPERTY_REQUEST pRequest, IN ULONG ulValueSize, IN BOOLEAN fValueRequired)
static PHARDWARE_TIMER MasterClock
#define KSPROPERTY_TYPE_SET
struct _SYNTHCAPS SYNTHCAPS
static SERVICE_STATUS status
struct _DMUS_KERNEL_EVENT * pPackageEvt
friend VOID NTAPI DMusUARTTimerDPC(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
_Inout_opt_ PUNICODE_STRING _Inout_opt_ PUNICODE_STRING Stream
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
#define UartFifoOkForRead(status)
static PCFILTER_DESCRIPTOR MiniportFilterDescriptor
NTSTATUS HandlePortParams(IN PPCPROPERTY_REQUEST Request)
const GUID KSNODETYPE_SYNTHESIZER
#define MPU401_REG_STATUS
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID BufferAddress
PULONG MinorVersion OPTIONAL
_In_opt_ PVOID DeferredContext