2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/port_wavepci.cpp
5 * PURPOSE: Wave PCI Port driver
6 * PROGRAMMER: Johannes Anderwald
11 class CPortWavePci
: public IPortWavePci
,
17 STDMETHODIMP
QueryInterface( REFIID InterfaceId
, PVOID
* Interface
);
19 STDMETHODIMP_(ULONG
) AddRef()
21 InterlockedIncrement(&m_Ref
);
24 STDMETHODIMP_(ULONG
) Release()
26 InterlockedDecrement(&m_Ref
);
39 CPortWavePci(IUnknown
*OuterUnknown
){}
40 virtual ~CPortWavePci() {}
44 PMINIPORTWAVEPCI m_Miniport
;
45 PDEVICE_OBJECT m_pDeviceObject
;
46 PSERVICEGROUP m_ServiceGroup
;
47 PPINCOUNT m_pPinCount
;
48 PPOWERNOTIFY m_pPowerNotify
;
49 PPCFILTER_DESCRIPTOR m_pDescriptor
;
50 PSUBDEVICE_DESCRIPTOR m_SubDeviceDescriptor
;
51 IPortFilterWavePci
* m_Filter
;
53 LIST_ENTRY m_EventList
;
54 KSPIN_LOCK m_EventListLock
;
58 friend PDEVICE_OBJECT
GetDeviceObjectFromPortWavePci(IPortWavePci
* iface
);
59 friend PMINIPORTWAVEPCI
GetWavePciMiniport(PPORTWAVEPCI iface
);
63 static GUID InterfaceGuids
[3] =
67 0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
71 0x65E8773EL
, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
74 /// KSCATEGORY_CAPTURE
75 0x65E8773DL
, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
79 DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterWavePciTopologySet
, TopologyPropertyHandler
);
80 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterWavePciPinSet
, PinPropertyHandler
, PinPropertyHandler
, PinPropertyHandler
);
82 KSPROPERTY_SET WavePciPropertySet
[] =
85 &KSPROPSETID_Topology
,
86 sizeof(PortFilterWavePciTopologySet
) / sizeof(KSPROPERTY_ITEM
),
87 (const KSPROPERTY_ITEM
*)&PortFilterWavePciTopologySet
,
93 sizeof(PortFilterWavePciPinSet
) / sizeof(KSPROPERTY_ITEM
),
94 (const KSPROPERTY_ITEM
*)&PortFilterWavePciPinSet
,
101 //---------------------------------------------------------------
107 CPortWavePci::AddEventToEventList(
108 IN PKSEVENT_ENTRY EventEntry
)
112 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
114 KeAcquireSpinLock(&m_EventListLock
, &OldIrql
);
115 InsertTailList(&m_EventList
, &EventEntry
->ListEntry
);
116 KeReleaseSpinLock(&m_EventListLock
, OldIrql
);
123 CPortWavePci::GenerateEventList(
124 IN GUID
* Set OPTIONAL
,
133 //---------------------------------------------------------------
139 CPortWavePci::RequestService()
141 //DPRINT("IServiceSink_fnRequestService entered\n");
144 m_Miniport
->Service();
148 //---------------------------------------------------------------
154 CPortWavePci::QueryInterface(
158 UNICODE_STRING GuidString
;
160 DPRINT("IPortWavePci_fnQueryInterface entered\n");
162 if (IsEqualGUIDAligned(refiid
, IID_IPortWavePci
) ||
163 IsEqualGUIDAligned(refiid
, IID_IUnknown
) ||
164 IsEqualGUIDAligned(refiid
, IID_IPort
))
166 *Output
= PVOID(PPORTWAVEPCI(this));
167 PUNKNOWN(*Output
)->AddRef();
168 return STATUS_SUCCESS
;
170 else if (IsEqualGUIDAligned(refiid
, IID_IServiceSink
))
172 *Output
= PVOID(PSERVICESINK(this));
173 PUNKNOWN(*Output
)->AddRef();
174 return STATUS_SUCCESS
;
176 else if (IsEqualGUIDAligned(refiid
, IID_IPortEvents
))
178 *Output
= PVOID(PPORTEVENTS(this));
179 PUNKNOWN(*Output
)->AddRef();
180 return STATUS_SUCCESS
;
182 else if (IsEqualGUIDAligned(refiid
, IID_ISubdevice
))
184 *Output
= PVOID(PSUBDEVICE(this));
185 PUNKNOWN(*Output
)->AddRef();
186 return STATUS_SUCCESS
;
188 else if (IsEqualGUIDAligned(refiid
, IID_IDrmPort
) ||
189 IsEqualGUIDAligned(refiid
, IID_IDrmPort2
))
191 return NewIDrmPort((PDRMPORT2
*)Output
);
193 else if (IsEqualGUIDAligned(refiid
, IID_IPortClsVersion
))
195 return NewPortClsVersion((PPORTCLSVERSION
*)Output
);
197 else if (IsEqualGUIDAligned(refiid
, IID_IUnregisterSubdevice
))
199 return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE
*)Output
);
201 else if (IsEqualGUIDAligned(refiid
, IID_IUnregisterPhysicalConnection
))
203 return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION
*)Output
);
206 if (RtlStringFromGUID(refiid
, &GuidString
) == STATUS_SUCCESS
)
208 DPRINT("IPortWavePci_fnQueryInterface no interface!!! iface %S\n", GuidString
.Buffer
);
209 RtlFreeUnicodeString(&GuidString
);
212 return STATUS_UNSUCCESSFUL
;
218 IN PDEVICE_OBJECT DeviceObject
,
220 IN PUNKNOWN UnknownMiniport
,
221 IN PUNKNOWN UnknownAdapter OPTIONAL
,
222 IN PRESOURCELIST ResourceList
)
224 IMiniportWavePci
* Miniport
;
225 PSERVICEGROUP ServiceGroup
;
228 PPOWERNOTIFY PowerNotify
;
230 DPRINT("IPortWavePci_fnInit entered with This %p, DeviceObject %p Irp %p UnknownMiniport %p, UnknownAdapter %p ResourceList %p\n",
231 this, DeviceObject
, Irp
, UnknownMiniport
, UnknownAdapter
, ResourceList
);
232 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
234 Status
= UnknownMiniport
->QueryInterface(IID_IMiniportWavePci
, (PVOID
*)&Miniport
);
235 if (!NT_SUCCESS(Status
))
237 DPRINT("IPortWavePci_fnInit called with invalid IMiniport adapter\n");
238 return STATUS_INVALID_PARAMETER
;
241 // Initialize port object
242 m_Miniport
= Miniport
;
243 m_pDeviceObject
= DeviceObject
;
245 InitializeListHead(&m_EventList
);
246 KeInitializeSpinLock(&m_EventListLock
);
248 // increment reference on miniport adapter
251 Status
= Miniport
->Init(UnknownAdapter
, ResourceList
, this, &ServiceGroup
);
252 if (!NT_SUCCESS(Status
))
254 DPRINT("IPortWavePci_fnInit failed with %x\n", Status
);
256 // release reference on miniport adapter
261 // check if the miniport adapter provides a valid device descriptor
262 Status
= Miniport
->GetDescription(&m_pDescriptor
);
263 if (!NT_SUCCESS(Status
))
265 DPRINT("failed to get description\n");
270 // create the subdevice descriptor
271 Status
= PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor
,
287 if (!NT_SUCCESS(Status
))
289 DPRINT("PcCreateSubdeviceDescriptor failed with %x\n", Status
);
294 // did we get a service group
297 // store service group in context
298 m_ServiceGroup
= ServiceGroup
;
300 // add ourselves to service group which is called when miniport receives an isr
301 m_ServiceGroup
->AddMember(PSERVICESINK(this));
303 // increment reference on service group
304 m_ServiceGroup
->AddRef();
307 // store for node property requests
308 m_SubDeviceDescriptor
->UnknownMiniport
= UnknownMiniport
;
310 // check if it supports IPinCount interface
311 Status
= UnknownMiniport
->QueryInterface(IID_IPinCount
, (PVOID
*)&PinCount
);
312 if (NT_SUCCESS(Status
))
314 // store IPinCount interface
315 m_pPinCount
= PinCount
;
318 // does the Miniport adapter support IPowerNotify interface*/
319 Status
= UnknownMiniport
->QueryInterface(IID_IPowerNotify
, (PVOID
*)&PowerNotify
);
320 if (NT_SUCCESS(Status
))
323 m_pPowerNotify
= PowerNotify
;
326 DPRINT("IPortWavePci_Init sucessfully initialized\n");
327 return STATUS_SUCCESS
;
332 CPortWavePci::NewRegistryKey(
333 OUT PREGISTRYKEY
*OutRegistryKey
,
334 IN PUNKNOWN OuterUnknown OPTIONAL
,
335 IN ULONG RegistryKeyType
,
336 IN ACCESS_MASK DesiredAccess
,
337 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
338 IN ULONG CreateOptions OPTIONAL
,
339 OUT PULONG Disposition OPTIONAL
)
341 DPRINT("IPortWavePci_fnNewRegistryKey entered\n");
342 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
344 return PcNewRegistryKey(OutRegistryKey
,
357 CPortWavePci::GetDeviceProperty(
358 IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty
,
359 IN ULONG BufferLength
,
360 OUT PVOID PropertyBuffer
,
361 OUT PULONG ReturnLength
)
363 DPRINT("IPortWavePci_fnGetDeviceProperty entered\n");
364 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
366 return IoGetDeviceProperty(m_pDeviceObject
, DeviceRegistryProperty
, BufferLength
, PropertyBuffer
, ReturnLength
);
371 CPortWavePci::NewMasterDmaChannel(
372 OUT PDMACHANNEL
*DmaChannel
,
373 IN PUNKNOWN OuterUnknown OPTIONAL
,
374 IN POOL_TYPE PoolType
,
375 IN PRESOURCELIST ResourceList OPTIONAL
,
376 IN BOOLEAN ScatterGather
,
377 IN BOOLEAN Dma32BitAddresses
,
378 IN BOOLEAN Dma64BitAddresses
,
379 IN BOOLEAN IgnoreCount
,
380 IN DMA_WIDTH DmaWidth
,
381 IN DMA_SPEED DmaSpeed
,
382 IN ULONG MaximumLength
,
386 DEVICE_DESCRIPTION DeviceDescription
;
388 DPRINT("IPortWavePci_fnNewMasterDmaChannel This %p entered\n", this);
389 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
391 Status
= PcDmaMasterDescription(ResourceList
, ScatterGather
, Dma32BitAddresses
, IgnoreCount
, Dma64BitAddresses
, DmaWidth
, DmaSpeed
, MaximumLength
, DmaPort
, &DeviceDescription
);
392 if (NT_SUCCESS(Status
))
394 return PcNewDmaChannel(DmaChannel
, OuterUnknown
, PoolType
, &DeviceDescription
, m_pDeviceObject
);
402 CPortWavePci::Notify(
403 IN PSERVICEGROUP ServiceGroup
)
405 //DPRINT("IPortWavePci_fnNotify entered %p, ServiceGroup %p\n", This, ServiceGroup);
409 ServiceGroup
->RequestService ();
413 //---------------------------------------------------------------
414 // ISubdevice interface
419 CPortWavePci::NewIrpTarget(
420 OUT
struct IIrpTarget
**OutTarget
,
423 IN POOL_TYPE PoolType
,
424 IN PDEVICE_OBJECT DeviceObject
,
426 IN KSOBJECT_CREATE
*CreateObject
)
429 IPortFilterWavePci
* Filter
;
431 DPRINT("ISubDevice_NewIrpTarget this %p\n", this);
435 *OutTarget
= (IIrpTarget
*)m_Filter
;
436 return STATUS_SUCCESS
;
439 Status
= NewPortFilterWavePci(&Filter
);
440 if (!NT_SUCCESS(Status
))
445 Status
= Filter
->Init((IPortWavePci
*)this);
446 if (!NT_SUCCESS(Status
))
452 *OutTarget
= (IIrpTarget
*)Filter
;
459 CPortWavePci::ReleaseChildren()
462 return STATUS_UNSUCCESSFUL
;
467 CPortWavePci::GetDescriptor(
468 IN SUBDEVICE_DESCRIPTOR
** Descriptor
)
470 DPRINT("ISubDevice_GetDescriptor this %p\n", this);
471 *Descriptor
= m_SubDeviceDescriptor
;
472 return STATUS_SUCCESS
;
477 CPortWavePci::DataRangeIntersection(
479 IN PKSDATARANGE DataRange
,
480 IN PKSDATARANGE MatchingDataRange
,
481 IN ULONG OutputBufferLength
,
482 OUT PVOID ResultantFormat OPTIONAL
,
483 OUT PULONG ResultantFormatLength
)
485 DPRINT("ISubDevice_DataRangeIntersection this %p\n", this);
489 return m_Miniport
->DataRangeIntersection (PinId
, DataRange
, MatchingDataRange
, OutputBufferLength
, ResultantFormat
, ResultantFormatLength
);
492 return STATUS_UNSUCCESSFUL
;
497 CPortWavePci::PowerChangeNotify(
498 IN POWER_STATE PowerState
)
502 m_pPowerNotify
->PowerChangeNotify(PowerState
);
505 return STATUS_SUCCESS
;
510 CPortWavePci::PinCount(
512 IN OUT PULONG FilterNecessary
,
513 IN OUT PULONG FilterCurrent
,
514 IN OUT PULONG FilterPossible
,
515 IN OUT PULONG GlobalCurrent
,
516 IN OUT PULONG GlobalPossible
)
520 m_pPinCount
->PinCount(PinId
, FilterNecessary
, FilterCurrent
, FilterPossible
, GlobalCurrent
, GlobalPossible
);
521 return STATUS_SUCCESS
;
525 // scan filter descriptor
527 return STATUS_UNSUCCESSFUL
;
538 Port
= new(NonPagedPool
, TAG_PORTCLASS
) CPortWavePci(NULL
);
540 return STATUS_INSUFFICIENT_RESOURCES
;
542 Status
= Port
->QueryInterface(IID_IPort
, (PVOID
*)OutPort
);
544 if (!NT_SUCCESS(Status
))
549 DPRINT("NewPortWavePci %p Status %u\n", Port
, Status
);
556 GetDeviceObjectFromPortWavePci(
559 CPortWavePci
* This
= (CPortWavePci
*)iface
;
560 return This
->m_pDeviceObject
;
567 CPortWavePci
* This
= (CPortWavePci
*)iface
;
568 return This
->m_Miniport
;