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
;
47 PRESOURCELIST m_pResourceList
;
48 PSERVICEGROUP m_ServiceGroup
;
49 PPINCOUNT m_pPinCount
;
50 PPOWERNOTIFY m_pPowerNotify
;
51 PPCFILTER_DESCRIPTOR m_pDescriptor
;
52 PSUBDEVICE_DESCRIPTOR m_SubDeviceDescriptor
;
53 IPortFilterWavePci
* m_Filter
;
55 LIST_ENTRY m_EventList
;
56 KSPIN_LOCK m_EventListLock
;
60 friend PDEVICE_OBJECT
GetDeviceObjectFromPortWavePci(IPortWavePci
* iface
);
61 friend PMINIPORTWAVEPCI
GetWavePciMiniport(PPORTWAVEPCI iface
);
65 static GUID InterfaceGuids
[3] =
69 0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
73 0x65E8773EL
, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
76 /// KSCATEGORY_CAPTURE
77 0x65E8773DL
, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
81 DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterWavePciTopologySet
, TopologyPropertyHandler
);
82 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterWavePciPinSet
, PinPropertyHandler
, PinPropertyHandler
, PinPropertyHandler
);
84 KSPROPERTY_SET WavePciPropertySet
[] =
87 &KSPROPSETID_Topology
,
88 sizeof(PortFilterWavePciTopologySet
) / sizeof(KSPROPERTY_ITEM
),
89 (const KSPROPERTY_ITEM
*)&PortFilterWavePciTopologySet
,
95 sizeof(PortFilterWavePciPinSet
) / sizeof(KSPROPERTY_ITEM
),
96 (const KSPROPERTY_ITEM
*)&PortFilterWavePciPinSet
,
103 //---------------------------------------------------------------
109 CPortWavePci::AddEventToEventList(
110 IN PKSEVENT_ENTRY EventEntry
)
114 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
116 KeAcquireSpinLock(&m_EventListLock
, &OldIrql
);
117 InsertTailList(&m_EventList
, &EventEntry
->ListEntry
);
118 KeReleaseSpinLock(&m_EventListLock
, OldIrql
);
125 CPortWavePci::GenerateEventList(
126 IN GUID
* Set OPTIONAL
,
135 //---------------------------------------------------------------
141 CPortWavePci::RequestService()
143 //DPRINT("IServiceSink_fnRequestService entered\n");
146 m_Miniport
->Service();
150 //---------------------------------------------------------------
156 CPortWavePci::QueryInterface(
160 UNICODE_STRING GuidString
;
162 DPRINT("IPortWavePci_fnQueryInterface entered\n");
164 if (IsEqualGUIDAligned(refiid
, IID_IPortWavePci
) ||
165 IsEqualGUIDAligned(refiid
, IID_IUnknown
) ||
166 IsEqualGUIDAligned(refiid
, IID_IPort
))
168 *Output
= PVOID(PPORTWAVEPCI(this));
169 PUNKNOWN(*Output
)->AddRef();
170 return STATUS_SUCCESS
;
172 else if (IsEqualGUIDAligned(refiid
, IID_IServiceSink
))
174 *Output
= PVOID(PSERVICESINK(this));
175 PUNKNOWN(*Output
)->AddRef();
176 return STATUS_SUCCESS
;
178 else if (IsEqualGUIDAligned(refiid
, IID_IPortEvents
))
180 *Output
= PVOID(PPORTEVENTS(this));
181 PUNKNOWN(*Output
)->AddRef();
182 return STATUS_SUCCESS
;
184 else if (IsEqualGUIDAligned(refiid
, IID_ISubdevice
))
186 *Output
= PVOID(PSUBDEVICE(this));
187 PUNKNOWN(*Output
)->AddRef();
188 return STATUS_SUCCESS
;
190 else if (IsEqualGUIDAligned(refiid
, IID_IDrmPort
) ||
191 IsEqualGUIDAligned(refiid
, IID_IDrmPort2
))
193 return NewIDrmPort((PDRMPORT2
*)Output
);
195 else if (IsEqualGUIDAligned(refiid
, IID_IPortClsVersion
))
197 return NewPortClsVersion((PPORTCLSVERSION
*)Output
);
199 else if (IsEqualGUIDAligned(refiid
, IID_IUnregisterSubdevice
))
201 return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE
*)Output
);
203 else if (IsEqualGUIDAligned(refiid
, IID_IUnregisterPhysicalConnection
))
205 return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION
*)Output
);
208 if (RtlStringFromGUID(refiid
, &GuidString
) == STATUS_SUCCESS
)
210 DPRINT("IPortWavePci_fnQueryInterface no interface!!! iface %S\n", GuidString
.Buffer
);
211 RtlFreeUnicodeString(&GuidString
);
214 return STATUS_UNSUCCESSFUL
;
220 IN PDEVICE_OBJECT DeviceObject
,
222 IN PUNKNOWN UnknownMiniport
,
223 IN PUNKNOWN UnknownAdapter OPTIONAL
,
224 IN PRESOURCELIST ResourceList
)
226 IMiniportWavePci
* Miniport
;
227 PSERVICEGROUP ServiceGroup
;
230 PPOWERNOTIFY PowerNotify
;
232 DPRINT("IPortWavePci_fnInit entered with This %p, DeviceObject %p Irp %p UnknownMiniport %p, UnknownAdapter %p ResourceList %p\n",
233 this, DeviceObject
, Irp
, UnknownMiniport
, UnknownAdapter
, ResourceList
);
234 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
238 DPRINT("IPortWavePci_fnInit called again\n");
239 return STATUS_SUCCESS
;
242 Status
= UnknownMiniport
->QueryInterface(IID_IMiniportWavePci
, (PVOID
*)&Miniport
);
243 if (!NT_SUCCESS(Status
))
245 DPRINT("IPortWavePci_fnInit called with invalid IMiniport adapter\n");
246 return STATUS_INVALID_PARAMETER
;
249 // Initialize port object
250 m_Miniport
= Miniport
;
251 m_pDeviceObject
= DeviceObject
;
252 m_bInitialized
= TRUE
;
253 m_pResourceList
= ResourceList
;
254 InitializeListHead(&m_EventList
);
255 KeInitializeSpinLock(&m_EventListLock
);
257 // increment reference on miniport adapter
263 // increment reference on resource list
264 ResourceList
->AddRef();
267 Status
= Miniport
->Init(UnknownAdapter
, ResourceList
, this, &ServiceGroup
);
268 if (!NT_SUCCESS(Status
))
270 DPRINT("IPortWavePci_fnInit failed with %x\n", Status
);
271 m_bInitialized
= FALSE
;
272 // release reference on miniport adapter
274 // increment reference on resource list
275 ResourceList
->Release();
279 // check if the miniport adapter provides a valid device descriptor
280 Status
= Miniport
->GetDescription(&m_pDescriptor
);
281 if (!NT_SUCCESS(Status
))
283 DPRINT("failed to get description\n");
285 m_bInitialized
= FALSE
;
289 // create the subdevice descriptor
290 Status
= PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor
,
306 if (!NT_SUCCESS(Status
))
308 DPRINT("PcCreateSubdeviceDescriptor failed with %x\n", Status
);
310 m_bInitialized
= FALSE
;
314 // did we get a service group
317 // store service group in context
318 m_ServiceGroup
= ServiceGroup
;
320 // add ourselves to service group which is called when miniport receives an isr
321 m_ServiceGroup
->AddMember(PSERVICESINK(this));
323 // increment reference on service group
324 m_ServiceGroup
->AddRef();
327 // store for node property requests
328 m_SubDeviceDescriptor
->UnknownMiniport
= UnknownMiniport
;
330 // check if it supports IPinCount interface
331 Status
= UnknownMiniport
->QueryInterface(IID_IPinCount
, (PVOID
*)&PinCount
);
332 if (NT_SUCCESS(Status
))
334 // store IPinCount interface
335 m_pPinCount
= PinCount
;
338 // does the Miniport adapter support IPowerNotify interface*/
339 Status
= UnknownMiniport
->QueryInterface(IID_IPowerNotify
, (PVOID
*)&PowerNotify
);
340 if (NT_SUCCESS(Status
))
343 m_pPowerNotify
= PowerNotify
;
346 DPRINT("IPortWavePci_Init sucessfully initialized\n");
347 return STATUS_SUCCESS
;
352 CPortWavePci::NewRegistryKey(
353 OUT PREGISTRYKEY
*OutRegistryKey
,
354 IN PUNKNOWN OuterUnknown OPTIONAL
,
355 IN ULONG RegistryKeyType
,
356 IN ACCESS_MASK DesiredAccess
,
357 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
358 IN ULONG CreateOptions OPTIONAL
,
359 OUT PULONG Disposition OPTIONAL
)
361 DPRINT("IPortWavePci_fnNewRegistryKey entered\n");
362 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
366 DPRINT("IPortWavePci_fnNewRegistryKey called w/o initiazed\n");
367 return STATUS_UNSUCCESSFUL
;
370 return PcNewRegistryKey(OutRegistryKey
,
383 CPortWavePci::GetDeviceProperty(
384 IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty
,
385 IN ULONG BufferLength
,
386 OUT PVOID PropertyBuffer
,
387 OUT PULONG ReturnLength
)
389 DPRINT("IPortWavePci_fnGetDeviceProperty entered\n");
390 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
394 DPRINT("IPortWavePci_fnNewRegistryKey called w/o initiazed\n");
395 return STATUS_UNSUCCESSFUL
;
398 return IoGetDeviceProperty(m_pDeviceObject
, DeviceRegistryProperty
, BufferLength
, PropertyBuffer
, ReturnLength
);
403 CPortWavePci::NewMasterDmaChannel(
404 OUT PDMACHANNEL
*DmaChannel
,
405 IN PUNKNOWN OuterUnknown OPTIONAL
,
406 IN POOL_TYPE PoolType
,
407 IN PRESOURCELIST ResourceList OPTIONAL
,
408 IN BOOLEAN ScatterGather
,
409 IN BOOLEAN Dma32BitAddresses
,
410 IN BOOLEAN Dma64BitAddresses
,
411 IN BOOLEAN IgnoreCount
,
412 IN DMA_WIDTH DmaWidth
,
413 IN DMA_SPEED DmaSpeed
,
414 IN ULONG MaximumLength
,
418 DEVICE_DESCRIPTION DeviceDescription
;
420 DPRINT("IPortWavePci_fnNewMasterDmaChannel This %p entered\n", this);
421 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
423 Status
= PcDmaMasterDescription(ResourceList
, ScatterGather
, Dma32BitAddresses
, IgnoreCount
, Dma64BitAddresses
, DmaWidth
, DmaSpeed
, MaximumLength
, DmaPort
, &DeviceDescription
);
424 if (NT_SUCCESS(Status
))
426 return PcNewDmaChannel(DmaChannel
, OuterUnknown
, PoolType
, &DeviceDescription
, m_pDeviceObject
);
434 CPortWavePci::Notify(
435 IN PSERVICEGROUP ServiceGroup
)
437 //IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
439 //DPRINT("IPortWavePci_fnNotify entered %p, ServiceGroup %p\n", This, ServiceGroup);
443 ServiceGroup
->RequestService ();
447 //---------------------------------------------------------------
448 // ISubdevice interface
453 CPortWavePci::NewIrpTarget(
454 OUT
struct IIrpTarget
**OutTarget
,
457 IN POOL_TYPE PoolType
,
458 IN PDEVICE_OBJECT DeviceObject
,
460 IN KSOBJECT_CREATE
*CreateObject
)
463 IPortFilterWavePci
* Filter
;
465 DPRINT("ISubDevice_NewIrpTarget this %p\n", this);
469 *OutTarget
= (IIrpTarget
*)m_Filter
;
470 return STATUS_SUCCESS
;
473 Status
= NewPortFilterWavePci(&Filter
);
474 if (!NT_SUCCESS(Status
))
479 Status
= Filter
->Init((IPortWavePci
*)this);
480 if (!NT_SUCCESS(Status
))
486 *OutTarget
= (IIrpTarget
*)Filter
;
493 CPortWavePci::ReleaseChildren()
495 //IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice);
498 return STATUS_UNSUCCESSFUL
;
503 CPortWavePci::GetDescriptor(
504 IN SUBDEVICE_DESCRIPTOR
** Descriptor
)
506 DPRINT("ISubDevice_GetDescriptor this %p\n", this);
507 *Descriptor
= m_SubDeviceDescriptor
;
508 return STATUS_SUCCESS
;
513 CPortWavePci::DataRangeIntersection(
515 IN PKSDATARANGE DataRange
,
516 IN PKSDATARANGE MatchingDataRange
,
517 IN ULONG OutputBufferLength
,
518 OUT PVOID ResultantFormat OPTIONAL
,
519 OUT PULONG ResultantFormatLength
)
521 DPRINT("ISubDevice_DataRangeIntersection this %p\n", this);
525 return m_Miniport
->DataRangeIntersection (PinId
, DataRange
, MatchingDataRange
, OutputBufferLength
, ResultantFormat
, ResultantFormatLength
);
528 return STATUS_UNSUCCESSFUL
;
533 CPortWavePci::PowerChangeNotify(
534 IN POWER_STATE PowerState
)
538 m_pPowerNotify
->PowerChangeNotify(PowerState
);
541 return STATUS_SUCCESS
;
546 CPortWavePci::PinCount(
548 IN OUT PULONG FilterNecessary
,
549 IN OUT PULONG FilterCurrent
,
550 IN OUT PULONG FilterPossible
,
551 IN OUT PULONG GlobalCurrent
,
552 IN OUT PULONG GlobalPossible
)
556 m_pPinCount
->PinCount(PinId
, FilterNecessary
, FilterCurrent
, FilterPossible
, GlobalCurrent
, GlobalPossible
);
557 return STATUS_SUCCESS
;
561 // scan filter descriptor
563 return STATUS_UNSUCCESSFUL
;
574 Port
= new(NonPagedPool
, TAG_PORTCLASS
) CPortWavePci(NULL
);
576 return STATUS_INSUFFICIENT_RESOURCES
;
578 Status
= Port
->QueryInterface(IID_IPort
, (PVOID
*)OutPort
);
580 if (!NT_SUCCESS(Status
))
585 DPRINT("NewPortWavePci %p Status %u\n", Port
, Status
);
592 GetDeviceObjectFromPortWavePci(
595 CPortWavePci
* This
= (CPortWavePci
*)iface
;
596 return This
->m_pDeviceObject
;
603 CPortWavePci
* This
= (CPortWavePci
*)iface
;
604 return This
->m_Miniport
;