20#define kOneMillisec (10 * 1000)
25#define MPU401_REG_STATUS 0x01
26#define MPU401_DRR 0x40
28#define MPU401_DSR 0x80
31#define MPU401_REG_DATA 0x00
32#define MPU401_REG_COMMAND 0x01
33#define MPU401_CMD_RESET 0xFF
34#define MPU401_CMD_UART 0x3F
253#define STR_MODULENAME "DMusUART:Miniport: "
256#pragma code_seg("PAGE")
259#define UartFifoOkForWrite(status) ((status & MPU401_DRR) == 0)
260#define UartFifoOkForRead(status) ((status & MPU401_DSR) == 0)
416#define kMaxNumCaptureStreams 1
417#define kMaxNumLegacyRenderStreams 1
418#define kMaxNumDMusicRenderStreams 1
520#define CONST_PCNODE_DESCRIPTOR(n) { 0, NULL, &n, NULL }
521#define CONST_PCNODE_DESCRIPTOR_AUTO(n,a) { 0, &a, &n, NULL }
594#pragma code_seg("PAGE")
601#pragma code_seg("PAGE")
613#pragma code_seg("PAGE")
627 ntStatus = interruptSync->CallSynchronizedRoutine(
InitMPU,
PVOID(portBase));
643 DPRINT(
"*** InitMPU returned with ntStatus 0x%08x ***", ntStatus);
707 DPRINT(
"First attempt to reset the MPU didn't get ACKed.\n");
733 if ((0xFE != dataByte) || !
success)
735 DPRINT(
"Second attempt to reset the MPU didn't get ACKed.\n");
736 DPRINT(
"Init Reset failure error. Ack = %X",
ULONG(dataByte));
754CMiniportDMusUARTStream::
784 context.BufferAddress = pMidiData;
868 DPRINT(
"SynchronizedDMusMPUWrite failed (0x%08x)",ntStatus);
876#define kMPUPollTimeout 2
945 DPRINT(
"O: PortBase is zero\n");
1012CMiniportDMusUARTStream::SourceEvtsToPort()
1017 DPRINT(
"SourceEvtsToPort");
1031 DPRINT(
"SourceEvtsToPort can't allocate DMKEvt");
1038 eventHead = aDMKEvt;
1042 eventTail = eventHead;
1074 aDMKEvt = eventHead;
1087 DPRINT(
"SourceEvtsToPort called on render stream");
1110 DPRINT(
"DMusMPUInterruptServiceRoutine");
1116 BOOL newBytesAvailable;
1121 newBytesAvailable =
FALSE;
1124 UCHAR portStatus = 0xff;
1153 DPRINT(
"*****MPU Input Buffer Overflow*****");
1165 newBytesAvailable =
TRUE;
1183 if (newBytesAvailable)
1211 ASSERT(OutFilterDescriptor);
1213 DPRINT(
"GetDescription");
1221#pragma code_seg("PAGE")
1243 DPRINT(
"NewMiniportDMusUART %p Status %x\n", *OutMiniport,
Status);
1249#pragma code_seg("PAGE")
1266 DPRINT(
"ProcessResources");
1282 DPRINT(
"Starting MPU401 Port 0x%lx",
ResourceList->FindTranslatedPort(0)->u.Port.Start.LowPart);
1296 DPRINT(
"Unknown ResourceList configuration");
1315#pragma code_seg("PAGE")
1332 DPRINT(
"Miniport::NonDelegatingQueryInterface");
1377#pragma code_seg("PAGE")
1388 DPRINT(
"~CMiniportDMusUART");
1421#pragma code_seg("PAGE")
1528 UnknownInterruptSync =
NULL;
1530 if (UnknownInterruptSync)
1533 UnknownInterruptSync->QueryInterface
1609 (*ServiceGroup)->Release();
1610 (*ServiceGroup) =
NULL;
1622#pragma code_seg("PAGE")
1660 DPRINT(
"CMiniportDMusUART::NewStream ResetHardware failed");
1690 (*ServiceGroup)->AddRef();
1711 DPRINT(
"NewStream failed, too many capture streams");
1715 DPRINT(
"NewStream failed, too many render streams");
1719 DPRINT(
"NewStream invalid stream type");
1727#pragma code_seg("PAGE")
1738 IN const GUID * Technology
1762#pragma code_seg("PAGE")
1783 DPRINT(
"InitializeHardware failed when resuming");
1798#pragma code_seg("PAGE")
1815 DPRINT(
"Stream::NonDelegatingQueryInterface");
1845#pragma code_seg("PAGE")
1856 DPRINT(
"~CMiniportDMusUARTStream");
1868 DPRINT(
"~CMiniportDMusUARTStream, no allocator, can't flush DMKEvts");
1894#pragma code_seg("PAGE")
1902CMiniportDMusUARTStream::
1959#pragma code_seg("PAGE")
1967CMiniportDMusUARTStream::
1975 DPRINT(
"SetState %d",NewState);
1987 DPRINT(
"CMiniportDMusUARTStream::SetState KSSTATE_RUN failed due to uninitialized MPU");
2031#pragma code_seg("PAGE")
2040CMiniportDMusUARTStream::
2041ConnectOutput(
PMXF sinkMXF)
2055 DPRINT(
"ConnectOutput failed");
2060 DPRINT(
"ConnectOutput called on renderer; failed");
2066#pragma code_seg("PAGE")
2075CMiniportDMusUARTStream::
2076DisconnectOutput(
PMXF sinkMXF)
2082 if ((
m_sinkMXF == sinkMXF) || (!sinkMXF))
2084 DPRINT(
"DisconnectOutput");
2090 DPRINT(
"DisconnectOutput failed");
2095 DPRINT(
"DisconnectOutput called on renderer; failed");
2124 DPRINT(
"PutMessage to render stream");
2153 (
void) ConsumeEvents();
2158 DPRINT(
"PutMessage to capture stream");
2187 DPRINT(
"PutMessage to render stream");
2216 (
void) ConsumeEvents();
2221 DPRINT(
"PutMessage to capture stream");
2244NTSTATUS CMiniportDMusUARTStream::ConsumeEvents(
void)
2263 ASSERT(bytesRemaining > 0);
2264 if (bytesRemaining <= 0)
2266 bytesRemaining = aDMKEvt->
cbEvent;
2278 DPRINT(
"ConsumeEvents(Package)");
2296 DPRINT(
"ConsumeEvents: Write returned 0x%08x", ntStatus);
2314 ASSERT(m_DMKEvtOffset < aDMKEvt->cbEvent);
2367 Params->ChannelGroups = 1;
2369 else if (
Params->ChannelGroups != 1)
2371 Params->ChannelGroups = 1;
2407 DPRINT(
"DMusUARTTimerDPC");
2410 (
void) aStream->ConsumeEvents();
2450 switch (
pRequest->PropertyItem->Id)
2456 switch (
pRequest->PropertyItem->Id)
2464 switch (
pRequest->PropertyItem->Id)
2485 DPRINT(
"PropertyHandler_Synth:KSPROPERTY_SYNTH_CAPS");
2507 caps->
Guid = CLSID_MiniportDriverDMusUART;
2513 caps->
Guid = CLSID_MiniportDriverDMusUARTCapture;
2531 cLen *=
sizeof(
WCHAR);
2544 DPRINT(
"PropertyHandler_Synth:KSPROPERTY_SYNTH_PORTPARAMETERS");
2561 DPRINT(
"PropertyHandler_Synth:KSPROPERTY_SYNTH_CHANNELGROUPS");
2572 DPRINT(
"PropertyHandler_Synth:KSPROPERTY_SYNTH_LATENCYCLOCK");
2602 DPRINT(
"Unhandled property in PropertyHandler_Synth");
2628 if (
pRequest->ValueSize >= ulValueSize)
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID BufferAddress
STDMETHODIMP QueryInterface(REFIID InterfaceId, PVOID *Interface)
STDMETHODIMP_(NTSTATUS) ConsumeEvents()
friend VOID NTAPI DMusUARTTimerDPC(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
friend NTSTATUS NTAPI PropertyHandler_Synth(IN PPCPROPERTY_REQUEST)
STDMETHODIMP_(NTSTATUS) Write(IN PVOID BufferAddress
IN PUCHAR IN BOOLEAN fCapture
IN PUCHAR IN BOOLEAN IN PAllocatorMXF IN PMASTERCLOCK masterClock
IN PUCHAR IN BOOLEAN IN PAllocatorMXF allocatorMXF
CMiniportDMusUART * m_pMiniport
STDMETHODIMP_(NTSTATUS) SourceEvtsToPort()
PAllocatorMXF m_AllocatorMXF
NTSTATUS HandlePortParams(IN PPCPROPERTY_REQUEST Request)
PDMUS_KERNEL_EVENT m_DMKEvtQueue
virtual ~CMiniportDMusUARTStream()
STDMETHODIMP_(NTSTATUS) Init(IN CMiniportDMusUART *pMiniport
STDMETHODIMP_(NTSTATUS) PutMessageLocked(PDMUS_KERNEL_EVENT pDMKEvt)
REFERENCE_TIME m_SnapshotTimeStamp
IN PUNKNOWN OuterUnknown IN POOL_TYPE IN ULONG IN DMUS_STREAM_TYPE IN PKSDATAFORMAT OUT PSERVICEGROUP IN PAllocatorMXF IN PMASTERCLOCK MasterClock
IN PUNKNOWN OuterUnknown IN POOL_TYPE IN ULONG IN DMUS_STREAM_TYPE StreamType
UCHAR m_MPUInputBuffer[kMPUInputBufferSize]
NTSTATUS InitializeHardware(PINTERRUPTSYNC interruptSync, PUCHAR portBase)
REFERENCE_TIME m_InputTimeStamp
IN PUNKNOWN OuterUnknown IN POOL_TYPE PoolType
IN PUNKNOWN OuterUnknown IN POOL_TYPE IN ULONG IN DMUS_STREAM_TYPE IN PKSDATAFORMAT OUT PSERVICEGROUP IN PAllocatorMXF IN PMASTERCLOCK OUT PULONGLONG SchedulePreFetch
IN PRESOURCELIST IN PPORTDMUS Port
DataRangeIntersection(IN ULONG PinId, IN PKSDATARANGE DataRange, IN PKSDATARANGE MatchingDataRange, IN ULONG OutputBufferLength, OUT PVOID ResultantFormat, OUT PULONG ResultantFormatLength)
STDMETHODIMP_(NTSTATUS) NewStream(OUT PMXF *Stream
PMASTERCLOCK m_MasterClock
GetDescription(OUT PPCFILTER_DESCRIPTOR *OutFilterDescriptor)
ULONG m_MPUInputBufferTail
friend NTSTATUS NTAPI SynchronizedDMusMPUWrite(PINTERRUPTSYNC InterruptSync, PVOID syncWriteContext)
PINTERRUPTSYNC m_pInterruptSync
NTSTATUS ProcessResources(IN PRESOURCELIST ResourceList)
friend NTSTATUS NTAPI PropertyHandler_Synth(IN PPCPROPERTY_REQUEST PropertyRequest)
CMiniportDMusUART(IUnknown *Unknown)
friend VOID NTAPI DMusUARTTimerDPC(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
BOOLEAN m_fMPUInitialized
virtual ~CMiniportDMusUART()
STDMETHODIMP_(void) Service(void)
ULONG m_MPUInputBufferHead
IN PRESOURCELIST IN PPORTDMUS OUT PSERVICEGROUP * ServiceGroup
friend NTSTATUS NTAPI DMusMPUInterruptServiceRoutine(PINTERRUPTSYNC InterruptSync, PVOID DynamicContext)
STDMETHODIMP_(NTSTATUS) Init(IN PUNKNOWN UnknownAdapter
IN PUNKNOWN OuterUnknown IN POOL_TYPE IN ULONG PinID
USHORT m_NumCaptureStreams
USHORT m_NumRenderStreams
friend class CMiniportDMusUARTStream
GUID m_MusicFormatTechnology
PSERVICEGROUP m_pServiceGroup
STDMETHODIMP QueryInterface(REFIID InterfaceId, PVOID *Interface)
IN PUNKNOWN OuterUnknown IN POOL_TYPE IN ULONG IN DMUS_STREAM_TYPE IN PKSDATAFORMAT OUT PSERVICEGROUP IN PAllocatorMXF AllocatorMXF
#define NT_SUCCESS(StatCode)
static ULONGLONG startTime
#define KSAUDFNAME_DMUSIC_MPU_OUT
struct IAllocatorMXF * PAllocatorMXF
IMiniportDMus * PMINIPORTDMUS
IMasterClock * PMASTERCLOCK
@ DMUS_STREAM_MIDI_RENDER
@ DMUS_STREAM_MIDI_CAPTURE
#define DMUS_KEF_EVENT_INCOMPLETE
#define KSAUDFNAME_DMUSIC_MPU_IN
@ KSPROPERTY_SYNTH_PORTPARAMETERS
@ KSPROPERTY_SYNTH_CHANNELGROUPS
@ KSPROPERTY_SYNTH_LATENCYCLOCK
#define SYNTH_PORTPARAMS_CHANNELGROUPS
#define SYNTH_PC_EXTERNAL
struct _SYNTH_PORTPARAMS * PSYNTH_PORTPARAMS
#define KSDATAFORMAT_SUBTYPE_DIRECTMUSIC
#define KSPROPSETID_Synth
struct _SYNTHCAPS SYNTHCAPS
struct _SYNTH_PORTPARAMS SYNTH_PORTPARAMS
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
struct _MINIPORT * PMINIPORT
ULONGLONG NTAPI PcGetTimeInterval(IN ULONGLONG Since)
#define KSPROPERTY_TYPE_SET
#define STATICGUIDOF(guid)
#define KSPROPERTY_TYPE_BASICSUPPORT
#define KSPROPERTY_TYPE_GET
#define KeGetCurrentIrql()
#define KeInitializeSpinLock(sl)
GLuint GLuint GLsizei count
GLenum GLsizei GLuint GLint * bytesWritten
NTSTATUS NTAPI PcNewInterruptSync(OUT PINTERRUPTSYNC *OutInterruptSync, IN PUNKNOWN OuterUnknown OPTIONAL, IN PRESOURCELIST ResourceList, IN ULONG ResourceIndex, IN INTERRUPTSYNCMODE Mode)
#define KSDATAFORMAT_SPECIFIER_NONE
union KSDATAFORMAT KSDATARANGE
@ KSPIN_COMMUNICATION_NONE
@ KSPIN_COMMUNICATION_SINK
#define KSCATEGORY_CAPTURE
#define KSCATEGORY_RENDER
union KSDATAFORMAT * PKSDATARANGE
struct SYNCWRITECONTEXT * PSYNCWRITECONTEXT
NTSTATUS WriteMPU(IN PUCHAR PortBase, IN BOOLEAN IsCommand, IN UCHAR Value)
static PCPROPERTY_ITEM SynthProperties[]
NTSTATUS NTAPI InitMPU(IN PINTERRUPTSYNC InterruptSync, IN PVOID DynamicContext)
static KSDATARANGE PinDataRangesBridge[]
static KSDATARANGE_MUSIC PinDataRangesStreamDMusic
static PKSDATARANGE PinDataRangePointersStreamDMusic[]
static PKSDATARANGE PinDataRangePointersBridge[]
NTSTATUS NewMiniportDMusUART(OUT PMINIPORT *OutMiniport, IN REFCLSID ClassId)
NTSTATUS NTAPI SynchronizedDMusMPUWrite(PINTERRUPTSYNC InterruptSync, PVOID syncWriteContext)
static PKSDATARANGE PinDataRangePointersStreamCombined[]
static PCPIN_DESCRIPTOR MiniportPins[]
NTSTATUS NTAPI PropertyHandler_Synth(IN PPCPROPERTY_REQUEST PropertyRequest)
#define MPU401_REG_COMMAND
static GUID MiniportCategories[]
VOID NTAPI DMusUARTTimerDPC(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
static KSDATARANGE_MUSIC PinDataRangesStreamLegacy
#define kMaxNumCaptureStreams
NTSTATUS NTAPI DMusMPUInterruptServiceRoutine(PINTERRUPTSYNC InterruptSync, PVOID DynamicContext)
#define CONST_PCNODE_DESCRIPTOR_AUTO(n, a)
#define kMaxNumDMusicRenderStreams
static PKSDATARANGE PinDataRangePointersStreamLegacy[]
BOOLEAN TryMPU(IN PUCHAR PortBase)
SnapTimeStamp(PINTERRUPTSYNC InterruptSync, PVOID pStream)
#define kMaxNumLegacyRenderStreams
NTSTATUS ResetHardware(PUCHAR portBase)
const ULONG kMPUInputBufferSize
NTSTATUS ValidatePropertyRequest(IN PPCPROPERTY_REQUEST pRequest, IN ULONG ulValueSize, IN BOOLEAN fValueRequired)
#define UartFifoOkForWrite(status)
#define MPU401_REG_STATUS
#define UartFifoOkForRead(status)
static PCNODE_DESCRIPTOR MiniportNodes[]
static PCCONNECTION_DESCRIPTOR MiniportConnections[]
static PCFILTER_DESCRIPTOR MiniportFilterDescriptor
static HRESULT QueryInterface(REFIID, void **)
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
_In_ ULONG _In_ ULONG _In_ ULONG Length
#define STATUS_INVALID_PARAMETER_2
#define STATUS_DEVICE_CONFIGURATION_ERROR
#define STATUS_NOT_IMPLEMENTED
#define READ_PORT_UCHAR(p)
#define WRITE_PORT_UCHAR(p, d)
static PHARDWARE_TIMER MasterClock
IInterruptSync * PINTERRUPTSYNC
IResourceList * PRESOURCELIST
IMusicTechnology * PMUSICTECHNOLOGY
#define GTI_MILLISECONDS(t)
#define DEFINE_PCAUTOMATION_TABLE_PROP(AutomationTable, PropertyTable)
NTSTATUS(NTAPI * PINTERRUPTSYNCROUTINE)(IN struct IInterruptSync *InterruptSync, IN PVOID DynamicContext)
IServiceGroup * PSERVICEGROUP
@ InterruptSyncModeNormal
IPowerNotify * PPOWERNOTIFY
#define KeAcquireSpinLockAtDpcLevel(SpinLock)
#define KeReleaseSpinLockFromDpcLevel(SpinLock)
NTSTATUS NTAPI PcNewServiceGroup(OUT PSERVICEGROUP *OutServiceGroup, IN PUNKNOWN OuterUnknown OPTIONAL)
#define STATUS_BUFFER_TOO_SMALL
#define STATUS_BUFFER_OVERFLOW
PULONG MinorVersion OPTIONAL
CMiniportDMusUART * Miniport
struct _DMUS_KERNEL_EVENT * pPackageEvt
struct _DMUS_KERNEL_EVENT * pNextEvt
BYTE abData[sizeof(PBYTE)]
REFERENCE_TIME ullPresTime100ns
union _DMUS_KERNEL_EVENT::@1902 uData
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
#define RtlCopyMemory(Destination, Source, Length)
#define RtlZeroMemory(Destination, Length)
#define STATUS_IO_DEVICE_ERROR
#define STATUS_INVALID_DEVICE_REQUEST
#define STATUS_INVALID_PARAMETER
#define STATUS_UNSUCCESSFUL
#define STATUS_INVALID_DEVICE_STATE
#define STATUS_INSUFFICIENT_RESOURCES
DEVICE_POWER_STATE DeviceState
static BOOL Write(PBYTE Address, PBYTE Data, SIZE_T Size)
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ WDF_DEVICE_POWER_STATE PowerState
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE Interface
_In_ WDFREQUEST _In_ size_t OutputBufferLength
_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
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
_Must_inspect_result_ _In_ WDFIORESREQLIST _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFIORESLIST * ResourceList
#define IsEqualGUIDAligned(guid1, guid2)
#define success(from, fromstr, to, tostr)
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
_In_opt_ PVOID DeferredContext
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2