📄 miniport.cpp
字号:
/*****************************************************************************
* miniport.cpp - UART miniport implementation
*****************************************************************************
* Copyright (c) 1997-1999 Microsoft Corporation. All Rights Reserved.
*
*/
#include "private.h"
#include "ksdebug.h"
#define STR_MODULENAME "UartMini: "
#pragma code_seg("PAGE")
/*****************************************************************************
* PinDataRangesStream
*****************************************************************************
* Structures indicating range of valid format values for streaming pins.
*/
static
KSDATARANGE_MUSIC PinDataRangesStream[] =
{
{
{
sizeof(KSDATARANGE_MUSIC),
0,
0,
0,
STATICGUIDOF(KSDATAFORMAT_TYPE_MUSIC),
STATICGUIDOF(KSDATAFORMAT_SUBTYPE_MIDI),
STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE)
},
STATICGUIDOF(KSMUSIC_TECHNOLOGY_PORT),
0,
0,
0xFFFF
}
};
/*****************************************************************************
* PinDataRangePointersStream
*****************************************************************************
* List of pointers to structures indicating range of valid format values
* for live pins.
*/
static
PKSDATARANGE PinDataRangePointersStream[] =
{
PKSDATARANGE(&PinDataRangesStream[0])
};
/*****************************************************************************
* PinDataRangesBridge
*****************************************************************************
* Structures indicating range of valid format values for bridge pins.
*/
static
KSDATARANGE PinDataRangesBridge[] =
{
{
sizeof(KSDATARANGE),
0,
0,
0,
STATICGUIDOF(KSDATAFORMAT_TYPE_MUSIC),
STATICGUIDOF(KSDATAFORMAT_SUBTYPE_MIDI_BUS),
STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE)
}
};
/*****************************************************************************
* PinDataRangePointersBridge
*****************************************************************************
* List of pointers to structures indicating range of valid format values
* for bridge pins.
*/
static
PKSDATARANGE PinDataRangePointersBridge[] =
{
&PinDataRangesBridge[0]
};
#define kMaxNumCaptureStreams 1
#define kMaxNumRenderStreams 1
/*****************************************************************************
* MiniportPins
*****************************************************************************
* List of pins.
*/
static
PCPIN_DESCRIPTOR MiniportPins[] =
{
{
kMaxNumRenderStreams,kMaxNumRenderStreams,0, // InstanceCount
NULL, // AutomationTable
{ // KsPinDescriptor
0, // InterfacesCount
NULL, // Interfaces
0, // MediumsCount
NULL, // Mediums
SIZEOF_ARRAY(PinDataRangePointersStream), // DataRangesCount
PinDataRangePointersStream, // DataRanges
KSPIN_DATAFLOW_IN, // DataFlow
KSPIN_COMMUNICATION_SINK, // Communication
(GUID *) &KSCATEGORY_AUDIO, // Category
&KSAUDFNAME_MIDI, // Name
0 // Reserved
}
},
{
0,0,0, // InstanceCount
NULL, // AutomationTable
{ // KsPinDescriptor
0, // InterfacesCount
NULL, // Interfaces
0, // MediumsCount
NULL, // Mediums
SIZEOF_ARRAY(PinDataRangePointersBridge), // DataRangesCount
PinDataRangePointersBridge, // DataRanges
KSPIN_DATAFLOW_OUT, // DataFlow
KSPIN_COMMUNICATION_NONE, // Communication
(GUID *) &KSCATEGORY_AUDIO, // Category
NULL, // Name
0 // Reserved
}
},
{
kMaxNumCaptureStreams,kMaxNumCaptureStreams,0, // InstanceCount
NULL, // AutomationTable
{ // KsPinDescriptor
0, // InterfacesCount
NULL, // Interfaces
0, // MediumsCount
NULL, // Mediums
SIZEOF_ARRAY(PinDataRangePointersStream), // DataRangesCount
PinDataRangePointersStream, // DataRanges
KSPIN_DATAFLOW_OUT, // DataFlow
KSPIN_COMMUNICATION_SINK, // Communication
(GUID *) &KSCATEGORY_AUDIO, // Category
&KSAUDFNAME_MIDI, // Name
0 // Reserved
}
},
{
0,0,0, // InstanceCount
NULL, // AutomationTable
{ // KsPinDescriptor
0, // InterfacesCount
NULL, // Interfaces
0, // MediumsCount
NULL, // Mediums
SIZEOF_ARRAY(PinDataRangePointersBridge), // DataRangesCount
PinDataRangePointersBridge, // DataRanges
KSPIN_DATAFLOW_IN, // DataFlow
KSPIN_COMMUNICATION_NONE, // Communication
(GUID *) &KSCATEGORY_AUDIO, // Category
NULL, // Name
0 // Reserved
}
}
};
/*****************************************************************************
* MiniportConnections
*****************************************************************************
* List of connections.
*/
static
PCCONNECTION_DESCRIPTOR MiniportConnections[] =
{
{ PCFILTER_NODE, 0, PCFILTER_NODE, 1 },
{ PCFILTER_NODE, 3, PCFILTER_NODE, 2 }
};
/*****************************************************************************
* MiniportFilterDescriptor
*****************************************************************************
* Complete miniport filter description.
*/
static
PCFILTER_DESCRIPTOR MiniportFilterDescriptor =
{
0, // Version
NULL, // AutomationTable
sizeof(PCPIN_DESCRIPTOR), // PinSize
SIZEOF_ARRAY(MiniportPins), // PinCount
MiniportPins, // Pins
sizeof(PCNODE_DESCRIPTOR), // NodeSize
0, // NodeCount
NULL, // Nodes
SIZEOF_ARRAY(MiniportConnections), // ConnectionCount
MiniportConnections, // Connections
0, // CategoryCount
NULL // Categories
};
#pragma code_seg("PAGE")
/*****************************************************************************
* CMiniportMidiUart::GetDescription()
*****************************************************************************
* Gets the topology.
*/
STDMETHODIMP
CMiniportMidiUart::
GetDescription
(
OUT PPCFILTER_DESCRIPTOR * OutFilterDescriptor
)
{
PAGED_CODE();
ASSERT(OutFilterDescriptor);
_DbgPrintF(DEBUGLVL_VERBOSE,("GetDescription"));
*OutFilterDescriptor = &MiniportFilterDescriptor;
return STATUS_SUCCESS;
}
#pragma code_seg("PAGE")
/*****************************************************************************
* CreateMiniportMidiUart()
*****************************************************************************
* Creates a MPU-401 miniport driver for the adapter. This uses a
* macro from STDUNK.H to do all the work.
*/
NTSTATUS
CreateMiniportMidiUart
(
OUT PUNKNOWN * Unknown,
IN REFCLSID,
IN PUNKNOWN UnknownOuter OPTIONAL,
IN POOL_TYPE PoolType
)
{
PAGED_CODE();
_DbgPrintF(DEBUGLVL_BLAB,("CreateMiniportDMusUART"));
ASSERT(Unknown);
STD_CREATE_BODY(CMiniportMidiUart,Unknown,UnknownOuter,PoolType);
}
#pragma code_seg("PAGE")
/*****************************************************************************
* CMiniportMidiUart::ProcessResources()
*****************************************************************************
* Processes the resource list, setting up helper objects accordingly.
*/
NTSTATUS
CMiniportMidiUart::
ProcessResources
(
IN PRESOURCELIST ResourceList
)
{
PAGED_CODE();
_DbgPrintF(DEBUGLVL_BLAB,("ProcessResources"));
ASSERT(ResourceList);
if (!ResourceList)
{
return STATUS_DEVICE_CONFIGURATION_ERROR;
}
//
// Get counts for the types of resources.
//
ULONG countIO = ResourceList->NumberOfPorts();
ULONG countIRQ = ResourceList->NumberOfInterrupts();
ULONG countDMA = ResourceList->NumberOfDmas();
ULONG lengthIO = ResourceList->FindTranslatedPort(0)->u.Port.Length;
#if (DBG)
_DbgPrintF(DEBUGLVL_VERBOSE,("Starting MPU401 Port 0x%X",
ResourceList->FindTranslatedPort(0)->u.Port.Start.LowPart) );
#endif
NTSTATUS ntStatus = STATUS_SUCCESS;
//
// Make sure we have the expected number of resources.
//
if ( (countIO != 1)
|| (countIRQ > 1)
|| (countDMA != 0)
|| (lengthIO == 0)
)
{
_DbgPrintF(DEBUGLVL_TERSE,("Unknown ResourceList configuraton"));
ntStatus = STATUS_DEVICE_CONFIGURATION_ERROR;
}
if (NT_SUCCESS(ntStatus))
{
//
// Get the port address.
//
m_pPortBase =
PUCHAR(ResourceList->FindTranslatedPort(0)->u.Port.Start.LowPart);
ntStatus = InitializeHardware(m_pInterruptSync,m_pPortBase);
}
return ntStatus;
}
#pragma code_seg("PAGE")
/*****************************************************************************
* CMiniportMidiUart::NonDelegatingQueryInterface()
*****************************************************************************
* Obtains an interface. This function works just like a COM QueryInterface
* call and is used if the object is not being aggregated.
*/
STDMETHODIMP
CMiniportMidiUart::
NonDelegatingQueryInterface
(
REFIID Interface,
PVOID * Object
)
{
PAGED_CODE();
_DbgPrintF(DEBUGLVL_BLAB,("Miniport::NonDelegatingQueryInterface"));
ASSERT(Object);
if (IsEqualGUIDAligned(Interface,IID_IUnknown))
{
*Object = PVOID(PUNKNOWN(this));
}
else
if (IsEqualGUIDAligned(Interface,IID_IMiniport))
{
*Object = PVOID(PMINIPORT(this));
}
else
if (IsEqualGUIDAligned(Interface,IID_IMiniportMidi))
{
*Object = PVOID(PMINIPORTMIDI(this));
}
else
{
*Object = NULL;
}
if (*Object)
{
//
// We reference the interface for the caller.
//
PUNKNOWN(*Object)->AddRef();
return STATUS_SUCCESS;
}
return STATUS_INVALID_PARAMETER;
}
#pragma code_seg("PAGE")
/*****************************************************************************
* CMiniportMidiUart::~CMiniportMidiUart()
*****************************************************************************
* Destructor.
*/
CMiniportMidiUart::~CMiniportMidiUart(void)
{
PAGED_CODE();
_DbgPrintF(DEBUGLVL_BLAB,("~CMiniportMidiUart"));
ASSERT(0 == m_NumCaptureStreams);
ASSERT(0 == m_NumRenderStreams);
// reset the HW so we don't get any more interrupts
if (m_UseIRQ && m_pInterruptSync)
{
(void) m_pInterruptSync->CallSynchronizedRoutine(InitLegacyMPU,PVOID(m_pPortBase));
}
else
{
(void) InitLegacyMPU(NULL,PVOID(m_pPortBase));
}
if (m_pInterruptSync)
{
// m_pInterruptSync->Disconnect();
m_pInterruptSync->Release();
m_pInterruptSync = NULL;
}
if (m_pServiceGroup)
{
m_pServiceGroup->Release();
m_pServiceGroup = NULL;
}
if (m_pPort)
{
m_pPort->Release();
m_pPort = NULL;
}
}
#pragma code_seg("PAGE")
/*****************************************************************************
* CMiniportMidiUart::Init()
*****************************************************************************
* Initializes a the miniport.
*/
STDMETHODIMP
CMiniportMidiUart::
Init
(
IN PUNKNOWN UnknownInterruptSync OPTIONAL,
IN PRESOURCELIST ResourceList,
IN PPORTMIDI Port_,
OUT PSERVICEGROUP * ServiceGroup
)
{
PAGED_CODE();
ASSERT(ResourceList);
if (!ResourceList)
{
return STATUS_DEVICE_CONFIGURATION_ERROR;
}
ASSERT(Port_);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -