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 0x65E8773EL
, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
72 /// KSCATEGORY_CAPTURE
73 0x65E8773DL
, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
77 0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 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
))
167 *Output
= PVOID(PPORTWAVEPCI(this));
168 PUNKNOWN(*Output
)->AddRef();
169 return STATUS_SUCCESS
;
171 else if (IsEqualGUIDAligned(refiid
, IID_IServiceSink
))
173 *Output
= PVOID(PSERVICESINK(this));
174 PUNKNOWN(*Output
)->AddRef();
175 return STATUS_SUCCESS
;
177 else if (IsEqualGUIDAligned(refiid
, IID_IPortEvents
))
179 *Output
= PVOID(PPORTEVENTS(this));
180 PUNKNOWN(*Output
)->AddRef();
181 return STATUS_SUCCESS
;
183 else if (IsEqualGUIDAligned(refiid
, IID_ISubdevice
))
185 *Output
= PVOID(PSUBDEVICE(this));
186 PUNKNOWN(*Output
)->AddRef();
187 return STATUS_SUCCESS
;
189 else if (IsEqualGUIDAligned(refiid
, IID_IPortClsVersion
))
191 return NewPortClsVersion((PPORTCLSVERSION
*)Output
);
193 else if (IsEqualGUIDAligned(refiid
, IID_IUnregisterSubdevice
))
195 return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE
*)Output
);
197 else if (IsEqualGUIDAligned(refiid
, IID_IUnregisterPhysicalConnection
))
199 return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION
*)Output
);
202 if (RtlStringFromGUID(refiid
, &GuidString
) == STATUS_SUCCESS
)
204 DPRINT1("IPortWavePci_fnQueryInterface no interface!!! iface %S\n", GuidString
.Buffer
);
205 RtlFreeUnicodeString(&GuidString
);
208 return STATUS_UNSUCCESSFUL
;
214 IN PDEVICE_OBJECT DeviceObject
,
216 IN PUNKNOWN UnknownMiniport
,
217 IN PUNKNOWN UnknownAdapter OPTIONAL
,
218 IN PRESOURCELIST ResourceList
)
220 IMiniportWavePci
* Miniport
;
221 PSERVICEGROUP ServiceGroup
;
224 PPOWERNOTIFY PowerNotify
;
226 DPRINT("IPortWavePci_fnInit entered with This %p, DeviceObject %p Irp %p UnknownMiniport %p, UnknownAdapter %p ResourceList %p\n",
227 this, DeviceObject
, Irp
, UnknownMiniport
, UnknownAdapter
, ResourceList
);
228 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
232 DPRINT("IPortWavePci_fnInit called again\n");
233 return STATUS_SUCCESS
;
236 Status
= UnknownMiniport
->QueryInterface(IID_IMiniportWavePci
, (PVOID
*)&Miniport
);
237 if (!NT_SUCCESS(Status
))
239 DPRINT("IPortWavePci_fnInit called with invalid IMiniport adapter\n");
240 return STATUS_INVALID_PARAMETER
;
243 // Initialize port object
244 m_Miniport
= Miniport
;
245 m_pDeviceObject
= DeviceObject
;
246 m_bInitialized
= TRUE
;
247 m_pResourceList
= ResourceList
;
248 InitializeListHead(&m_EventList
);
249 KeInitializeSpinLock(&m_EventListLock
);
251 // increment reference on miniport adapter
253 // increment reference on resource list
254 ResourceList
->AddRef();
256 Status
= Miniport
->Init(UnknownAdapter
, ResourceList
, this, &ServiceGroup
);
257 if (!NT_SUCCESS(Status
))
259 DPRINT("IPortWavePci_fnInit failed with %x\n", Status
);
260 m_bInitialized
= FALSE
;
261 // release reference on miniport adapter
263 // increment reference on resource list
264 ResourceList
->Release();
268 // check if the miniport adapter provides a valid device descriptor
269 Status
= Miniport
->GetDescription(&m_pDescriptor
);
270 if (!NT_SUCCESS(Status
))
272 DPRINT1("failed to get description\n");
274 m_bInitialized
= FALSE
;
278 // create the subdevice descriptor
279 Status
= PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor
,
295 if (!NT_SUCCESS(Status
))
297 DPRINT1("PcCreateSubdeviceDescriptor failed with %x\n", Status
);
299 m_bInitialized
= FALSE
;
303 // did we get a service group
306 // store service group in context
307 m_ServiceGroup
= ServiceGroup
;
309 // add ourselves to service group which is called when miniport receives an isr
310 m_ServiceGroup
->AddMember(PSERVICESINK(this));
312 // increment reference on service group
313 m_ServiceGroup
->AddRef();
316 // check if it supports IPinCount interface
317 Status
= UnknownMiniport
->QueryInterface(IID_IPinCount
, (PVOID
*)&PinCount
);
318 if (NT_SUCCESS(Status
))
320 // store IPinCount interface
321 m_pPinCount
= PinCount
;
324 // does the Miniport adapter support IPowerNotify interface*/
325 Status
= UnknownMiniport
->QueryInterface(IID_IPowerNotify
, (PVOID
*)&PowerNotify
);
326 if (NT_SUCCESS(Status
))
329 m_pPowerNotify
= PowerNotify
;
332 DPRINT("IPortWavePci_Init sucessfully initialized\n");
333 return STATUS_SUCCESS
;
338 CPortWavePci::NewRegistryKey(
339 OUT PREGISTRYKEY
*OutRegistryKey
,
340 IN PUNKNOWN OuterUnknown OPTIONAL
,
341 IN ULONG RegistryKeyType
,
342 IN ACCESS_MASK DesiredAccess
,
343 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
344 IN ULONG CreateOptions OPTIONAL
,
345 OUT PULONG Disposition OPTIONAL
)
347 DPRINT("IPortWavePci_fnNewRegistryKey entered\n");
348 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
352 DPRINT("IPortWavePci_fnNewRegistryKey called w/o initiazed\n");
353 return STATUS_UNSUCCESSFUL
;
356 return PcNewRegistryKey(OutRegistryKey
,
369 CPortWavePci::GetDeviceProperty(
370 IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty
,
371 IN ULONG BufferLength
,
372 OUT PVOID PropertyBuffer
,
373 OUT PULONG ReturnLength
)
375 DPRINT("IPortWavePci_fnGetDeviceProperty entered\n");
376 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
380 DPRINT("IPortWavePci_fnNewRegistryKey called w/o initiazed\n");
381 return STATUS_UNSUCCESSFUL
;
384 return IoGetDeviceProperty(m_pDeviceObject
, DeviceRegistryProperty
, BufferLength
, PropertyBuffer
, ReturnLength
);
389 CPortWavePci::NewMasterDmaChannel(
390 OUT PDMACHANNEL
*DmaChannel
,
391 IN PUNKNOWN OuterUnknown OPTIONAL
,
392 IN POOL_TYPE PoolType
,
393 IN PRESOURCELIST ResourceList OPTIONAL
,
394 IN BOOLEAN ScatterGather
,
395 IN BOOLEAN Dma32BitAddresses
,
396 IN BOOLEAN Dma64BitAddresses
,
397 IN BOOLEAN IgnoreCount
,
398 IN DMA_WIDTH DmaWidth
,
399 IN DMA_SPEED DmaSpeed
,
400 IN ULONG MaximumLength
,
404 DEVICE_DESCRIPTION DeviceDescription
;
406 DPRINT("IPortWavePci_fnNewMasterDmaChannel This %p entered\n", this);
407 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
409 Status
= PcDmaMasterDescription(ResourceList
, ScatterGather
, Dma32BitAddresses
, IgnoreCount
, Dma64BitAddresses
, DmaWidth
, DmaSpeed
, MaximumLength
, DmaPort
, &DeviceDescription
);
410 if (NT_SUCCESS(Status
))
412 return PcNewDmaChannel(DmaChannel
, OuterUnknown
, PoolType
, &DeviceDescription
, m_pDeviceObject
);
420 CPortWavePci::Notify(
421 IN PSERVICEGROUP ServiceGroup
)
423 //IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
425 //DPRINT("IPortWavePci_fnNotify entered %p, ServiceGroup %p\n", This, ServiceGroup);
429 ServiceGroup
->RequestService ();
433 //---------------------------------------------------------------
434 // ISubdevice interface
439 CPortWavePci::NewIrpTarget(
440 OUT
struct IIrpTarget
**OutTarget
,
443 IN POOL_TYPE PoolType
,
444 IN PDEVICE_OBJECT DeviceObject
,
446 IN KSOBJECT_CREATE
*CreateObject
)
449 IPortFilterWavePci
* Filter
;
451 DPRINT("ISubDevice_NewIrpTarget this %p\n", this);
455 *OutTarget
= (IIrpTarget
*)m_Filter
;
456 return STATUS_SUCCESS
;
459 Status
= NewPortFilterWavePci(&Filter
);
460 if (!NT_SUCCESS(Status
))
465 Status
= Filter
->Init((IPortWavePci
*)this);
466 if (!NT_SUCCESS(Status
))
472 *OutTarget
= (IIrpTarget
*)Filter
;
479 CPortWavePci::ReleaseChildren()
481 //IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice);
484 return STATUS_UNSUCCESSFUL
;
489 CPortWavePci::GetDescriptor(
490 IN SUBDEVICE_DESCRIPTOR
** Descriptor
)
492 DPRINT1("ISubDevice_GetDescriptor this %p\n", this);
493 *Descriptor
= m_SubDeviceDescriptor
;
494 return STATUS_SUCCESS
;
499 CPortWavePci::DataRangeIntersection(
501 IN PKSDATARANGE DataRange
,
502 IN PKSDATARANGE MatchingDataRange
,
503 IN ULONG OutputBufferLength
,
504 OUT PVOID ResultantFormat OPTIONAL
,
505 OUT PULONG ResultantFormatLength
)
507 DPRINT("ISubDevice_DataRangeIntersection this %p\n", this);
511 return m_Miniport
->DataRangeIntersection (PinId
, DataRange
, MatchingDataRange
, OutputBufferLength
, ResultantFormat
, ResultantFormatLength
);
514 return STATUS_UNSUCCESSFUL
;
519 CPortWavePci::PowerChangeNotify(
520 IN POWER_STATE PowerState
)
524 m_pPowerNotify
->PowerChangeNotify(PowerState
);
527 return STATUS_SUCCESS
;
532 CPortWavePci::PinCount(
534 IN OUT PULONG FilterNecessary
,
535 IN OUT PULONG FilterCurrent
,
536 IN OUT PULONG FilterPossible
,
537 IN OUT PULONG GlobalCurrent
,
538 IN OUT PULONG GlobalPossible
)
542 m_pPinCount
->PinCount(PinId
, FilterNecessary
, FilterCurrent
, FilterPossible
, GlobalCurrent
, GlobalPossible
);
543 return STATUS_SUCCESS
;
547 // scan filter descriptor
549 return STATUS_UNSUCCESSFUL
;
560 Port
= new(NonPagedPool
, TAG_PORTCLASS
) CPortWavePci(NULL
);
562 return STATUS_INSUFFICIENT_RESOURCES
;
564 Status
= Port
->QueryInterface(IID_IPort
, (PVOID
*)OutPort
);
566 if (!NT_SUCCESS(Status
))
571 DPRINT("NewPortWavePci %p Status %u\n", Port
, Status
);
578 GetDeviceObjectFromPortWavePci(
581 CPortWavePci
* This
= (CPortWavePci
*)iface
;
582 return This
->m_pDeviceObject
;
589 CPortWavePci
* This
= (CPortWavePci
*)iface
;
590 return This
->m_Miniport
;