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_IPortClsVersion
))
192 return NewPortClsVersion((PPORTCLSVERSION
*)Output
);
194 else if (IsEqualGUIDAligned(refiid
, IID_IUnregisterSubdevice
))
196 return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE
*)Output
);
198 else if (IsEqualGUIDAligned(refiid
, IID_IUnregisterPhysicalConnection
))
200 return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION
*)Output
);
203 if (RtlStringFromGUID(refiid
, &GuidString
) == STATUS_SUCCESS
)
205 DPRINT("IPortWavePci_fnQueryInterface no interface!!! iface %S\n", GuidString
.Buffer
);
206 RtlFreeUnicodeString(&GuidString
);
209 return STATUS_UNSUCCESSFUL
;
215 IN PDEVICE_OBJECT DeviceObject
,
217 IN PUNKNOWN UnknownMiniport
,
218 IN PUNKNOWN UnknownAdapter OPTIONAL
,
219 IN PRESOURCELIST ResourceList
)
221 IMiniportWavePci
* Miniport
;
222 PSERVICEGROUP ServiceGroup
;
225 PPOWERNOTIFY PowerNotify
;
227 DPRINT("IPortWavePci_fnInit entered with This %p, DeviceObject %p Irp %p UnknownMiniport %p, UnknownAdapter %p ResourceList %p\n",
228 this, DeviceObject
, Irp
, UnknownMiniport
, UnknownAdapter
, ResourceList
);
229 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
233 DPRINT("IPortWavePci_fnInit called again\n");
234 return STATUS_SUCCESS
;
237 Status
= UnknownMiniport
->QueryInterface(IID_IMiniportWavePci
, (PVOID
*)&Miniport
);
238 if (!NT_SUCCESS(Status
))
240 DPRINT("IPortWavePci_fnInit called with invalid IMiniport adapter\n");
241 return STATUS_INVALID_PARAMETER
;
244 // Initialize port object
245 m_Miniport
= Miniport
;
246 m_pDeviceObject
= DeviceObject
;
247 m_bInitialized
= TRUE
;
248 m_pResourceList
= ResourceList
;
249 InitializeListHead(&m_EventList
);
250 KeInitializeSpinLock(&m_EventListLock
);
252 // increment reference on miniport adapter
254 // increment reference on resource list
255 ResourceList
->AddRef();
257 Status
= Miniport
->Init(UnknownAdapter
, ResourceList
, this, &ServiceGroup
);
258 if (!NT_SUCCESS(Status
))
260 DPRINT("IPortWavePci_fnInit failed with %x\n", Status
);
261 m_bInitialized
= FALSE
;
262 // release reference on miniport adapter
264 // increment reference on resource list
265 ResourceList
->Release();
269 // check if the miniport adapter provides a valid device descriptor
270 Status
= Miniport
->GetDescription(&m_pDescriptor
);
271 if (!NT_SUCCESS(Status
))
273 DPRINT("failed to get description\n");
275 m_bInitialized
= FALSE
;
279 // create the subdevice descriptor
280 Status
= PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor
,
296 if (!NT_SUCCESS(Status
))
298 DPRINT("PcCreateSubdeviceDescriptor failed with %x\n", Status
);
300 m_bInitialized
= FALSE
;
304 // did we get a service group
307 // store service group in context
308 m_ServiceGroup
= ServiceGroup
;
310 // add ourselves to service group which is called when miniport receives an isr
311 m_ServiceGroup
->AddMember(PSERVICESINK(this));
313 // increment reference on service group
314 m_ServiceGroup
->AddRef();
317 // check if it supports IPinCount interface
318 Status
= UnknownMiniport
->QueryInterface(IID_IPinCount
, (PVOID
*)&PinCount
);
319 if (NT_SUCCESS(Status
))
321 // store IPinCount interface
322 m_pPinCount
= PinCount
;
325 // does the Miniport adapter support IPowerNotify interface*/
326 Status
= UnknownMiniport
->QueryInterface(IID_IPowerNotify
, (PVOID
*)&PowerNotify
);
327 if (NT_SUCCESS(Status
))
330 m_pPowerNotify
= PowerNotify
;
333 DPRINT("IPortWavePci_Init sucessfully initialized\n");
334 return STATUS_SUCCESS
;
339 CPortWavePci::NewRegistryKey(
340 OUT PREGISTRYKEY
*OutRegistryKey
,
341 IN PUNKNOWN OuterUnknown OPTIONAL
,
342 IN ULONG RegistryKeyType
,
343 IN ACCESS_MASK DesiredAccess
,
344 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
345 IN ULONG CreateOptions OPTIONAL
,
346 OUT PULONG Disposition OPTIONAL
)
348 DPRINT("IPortWavePci_fnNewRegistryKey entered\n");
349 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
353 DPRINT("IPortWavePci_fnNewRegistryKey called w/o initiazed\n");
354 return STATUS_UNSUCCESSFUL
;
357 return PcNewRegistryKey(OutRegistryKey
,
370 CPortWavePci::GetDeviceProperty(
371 IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty
,
372 IN ULONG BufferLength
,
373 OUT PVOID PropertyBuffer
,
374 OUT PULONG ReturnLength
)
376 DPRINT("IPortWavePci_fnGetDeviceProperty entered\n");
377 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
381 DPRINT("IPortWavePci_fnNewRegistryKey called w/o initiazed\n");
382 return STATUS_UNSUCCESSFUL
;
385 return IoGetDeviceProperty(m_pDeviceObject
, DeviceRegistryProperty
, BufferLength
, PropertyBuffer
, ReturnLength
);
390 CPortWavePci::NewMasterDmaChannel(
391 OUT PDMACHANNEL
*DmaChannel
,
392 IN PUNKNOWN OuterUnknown OPTIONAL
,
393 IN POOL_TYPE PoolType
,
394 IN PRESOURCELIST ResourceList OPTIONAL
,
395 IN BOOLEAN ScatterGather
,
396 IN BOOLEAN Dma32BitAddresses
,
397 IN BOOLEAN Dma64BitAddresses
,
398 IN BOOLEAN IgnoreCount
,
399 IN DMA_WIDTH DmaWidth
,
400 IN DMA_SPEED DmaSpeed
,
401 IN ULONG MaximumLength
,
405 DEVICE_DESCRIPTION DeviceDescription
;
407 DPRINT("IPortWavePci_fnNewMasterDmaChannel This %p entered\n", this);
408 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
410 Status
= PcDmaMasterDescription(ResourceList
, ScatterGather
, Dma32BitAddresses
, IgnoreCount
, Dma64BitAddresses
, DmaWidth
, DmaSpeed
, MaximumLength
, DmaPort
, &DeviceDescription
);
411 if (NT_SUCCESS(Status
))
413 return PcNewDmaChannel(DmaChannel
, OuterUnknown
, PoolType
, &DeviceDescription
, m_pDeviceObject
);
421 CPortWavePci::Notify(
422 IN PSERVICEGROUP ServiceGroup
)
424 //IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
426 //DPRINT("IPortWavePci_fnNotify entered %p, ServiceGroup %p\n", This, ServiceGroup);
430 ServiceGroup
->RequestService ();
434 //---------------------------------------------------------------
435 // ISubdevice interface
440 CPortWavePci::NewIrpTarget(
441 OUT
struct IIrpTarget
**OutTarget
,
444 IN POOL_TYPE PoolType
,
445 IN PDEVICE_OBJECT DeviceObject
,
447 IN KSOBJECT_CREATE
*CreateObject
)
450 IPortFilterWavePci
* Filter
;
452 DPRINT("ISubDevice_NewIrpTarget this %p\n", this);
456 *OutTarget
= (IIrpTarget
*)m_Filter
;
457 return STATUS_SUCCESS
;
460 Status
= NewPortFilterWavePci(&Filter
);
461 if (!NT_SUCCESS(Status
))
466 Status
= Filter
->Init((IPortWavePci
*)this);
467 if (!NT_SUCCESS(Status
))
473 *OutTarget
= (IIrpTarget
*)Filter
;
480 CPortWavePci::ReleaseChildren()
482 //IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice);
485 return STATUS_UNSUCCESSFUL
;
490 CPortWavePci::GetDescriptor(
491 IN SUBDEVICE_DESCRIPTOR
** Descriptor
)
493 DPRINT("ISubDevice_GetDescriptor this %p\n", this);
494 *Descriptor
= m_SubDeviceDescriptor
;
495 return STATUS_SUCCESS
;
500 CPortWavePci::DataRangeIntersection(
502 IN PKSDATARANGE DataRange
,
503 IN PKSDATARANGE MatchingDataRange
,
504 IN ULONG OutputBufferLength
,
505 OUT PVOID ResultantFormat OPTIONAL
,
506 OUT PULONG ResultantFormatLength
)
508 DPRINT("ISubDevice_DataRangeIntersection this %p\n", this);
512 return m_Miniport
->DataRangeIntersection (PinId
, DataRange
, MatchingDataRange
, OutputBufferLength
, ResultantFormat
, ResultantFormatLength
);
515 return STATUS_UNSUCCESSFUL
;
520 CPortWavePci::PowerChangeNotify(
521 IN POWER_STATE PowerState
)
525 m_pPowerNotify
->PowerChangeNotify(PowerState
);
528 return STATUS_SUCCESS
;
533 CPortWavePci::PinCount(
535 IN OUT PULONG FilterNecessary
,
536 IN OUT PULONG FilterCurrent
,
537 IN OUT PULONG FilterPossible
,
538 IN OUT PULONG GlobalCurrent
,
539 IN OUT PULONG GlobalPossible
)
543 m_pPinCount
->PinCount(PinId
, FilterNecessary
, FilterCurrent
, FilterPossible
, GlobalCurrent
, GlobalPossible
);
544 return STATUS_SUCCESS
;
548 // scan filter descriptor
550 return STATUS_UNSUCCESSFUL
;
561 Port
= new(NonPagedPool
, TAG_PORTCLASS
) CPortWavePci(NULL
);
563 return STATUS_INSUFFICIENT_RESOURCES
;
565 Status
= Port
->QueryInterface(IID_IPort
, (PVOID
*)OutPort
);
567 if (!NT_SUCCESS(Status
))
572 DPRINT("NewPortWavePci %p Status %u\n", Port
, Status
);
579 GetDeviceObjectFromPortWavePci(
582 CPortWavePci
* This
= (CPortWavePci
*)iface
;
583 return This
->m_pDeviceObject
;
590 CPortWavePci
* This
= (CPortWavePci
*)iface
;
591 return This
->m_Miniport
;