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
258 // increment reference on resource list
259 ResourceList
->AddRef();
262 Status
= Miniport
->Init(UnknownAdapter
, ResourceList
, this, &ServiceGroup
);
263 if (!NT_SUCCESS(Status
))
265 DPRINT("IPortWavePci_fnInit failed with %x\n", Status
);
266 m_bInitialized
= FALSE
;
267 // release reference on miniport adapter
269 // increment reference on resource list
270 ResourceList
->Release();
274 // check if the miniport adapter provides a valid device descriptor
275 Status
= Miniport
->GetDescription(&m_pDescriptor
);
276 if (!NT_SUCCESS(Status
))
278 DPRINT("failed to get description\n");
280 m_bInitialized
= FALSE
;
284 // create the subdevice descriptor
285 Status
= PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor
,
301 if (!NT_SUCCESS(Status
))
303 DPRINT("PcCreateSubdeviceDescriptor failed with %x\n", Status
);
305 m_bInitialized
= FALSE
;
309 // did we get a service group
312 // store service group in context
313 m_ServiceGroup
= ServiceGroup
;
315 // add ourselves to service group which is called when miniport receives an isr
316 m_ServiceGroup
->AddMember(PSERVICESINK(this));
318 // increment reference on service group
319 m_ServiceGroup
->AddRef();
322 // check if it supports IPinCount interface
323 Status
= UnknownMiniport
->QueryInterface(IID_IPinCount
, (PVOID
*)&PinCount
);
324 if (NT_SUCCESS(Status
))
326 // store IPinCount interface
327 m_pPinCount
= PinCount
;
330 // does the Miniport adapter support IPowerNotify interface*/
331 Status
= UnknownMiniport
->QueryInterface(IID_IPowerNotify
, (PVOID
*)&PowerNotify
);
332 if (NT_SUCCESS(Status
))
335 m_pPowerNotify
= PowerNotify
;
338 DPRINT("IPortWavePci_Init sucessfully initialized\n");
339 return STATUS_SUCCESS
;
344 CPortWavePci::NewRegistryKey(
345 OUT PREGISTRYKEY
*OutRegistryKey
,
346 IN PUNKNOWN OuterUnknown OPTIONAL
,
347 IN ULONG RegistryKeyType
,
348 IN ACCESS_MASK DesiredAccess
,
349 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
350 IN ULONG CreateOptions OPTIONAL
,
351 OUT PULONG Disposition OPTIONAL
)
353 DPRINT("IPortWavePci_fnNewRegistryKey entered\n");
354 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
358 DPRINT("IPortWavePci_fnNewRegistryKey called w/o initiazed\n");
359 return STATUS_UNSUCCESSFUL
;
362 return PcNewRegistryKey(OutRegistryKey
,
375 CPortWavePci::GetDeviceProperty(
376 IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty
,
377 IN ULONG BufferLength
,
378 OUT PVOID PropertyBuffer
,
379 OUT PULONG ReturnLength
)
381 DPRINT("IPortWavePci_fnGetDeviceProperty entered\n");
382 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
386 DPRINT("IPortWavePci_fnNewRegistryKey called w/o initiazed\n");
387 return STATUS_UNSUCCESSFUL
;
390 return IoGetDeviceProperty(m_pDeviceObject
, DeviceRegistryProperty
, BufferLength
, PropertyBuffer
, ReturnLength
);
395 CPortWavePci::NewMasterDmaChannel(
396 OUT PDMACHANNEL
*DmaChannel
,
397 IN PUNKNOWN OuterUnknown OPTIONAL
,
398 IN POOL_TYPE PoolType
,
399 IN PRESOURCELIST ResourceList OPTIONAL
,
400 IN BOOLEAN ScatterGather
,
401 IN BOOLEAN Dma32BitAddresses
,
402 IN BOOLEAN Dma64BitAddresses
,
403 IN BOOLEAN IgnoreCount
,
404 IN DMA_WIDTH DmaWidth
,
405 IN DMA_SPEED DmaSpeed
,
406 IN ULONG MaximumLength
,
410 DEVICE_DESCRIPTION DeviceDescription
;
412 DPRINT("IPortWavePci_fnNewMasterDmaChannel This %p entered\n", this);
413 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
415 Status
= PcDmaMasterDescription(ResourceList
, ScatterGather
, Dma32BitAddresses
, IgnoreCount
, Dma64BitAddresses
, DmaWidth
, DmaSpeed
, MaximumLength
, DmaPort
, &DeviceDescription
);
416 if (NT_SUCCESS(Status
))
418 return PcNewDmaChannel(DmaChannel
, OuterUnknown
, PoolType
, &DeviceDescription
, m_pDeviceObject
);
426 CPortWavePci::Notify(
427 IN PSERVICEGROUP ServiceGroup
)
429 //IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
431 //DPRINT("IPortWavePci_fnNotify entered %p, ServiceGroup %p\n", This, ServiceGroup);
435 ServiceGroup
->RequestService ();
439 //---------------------------------------------------------------
440 // ISubdevice interface
445 CPortWavePci::NewIrpTarget(
446 OUT
struct IIrpTarget
**OutTarget
,
449 IN POOL_TYPE PoolType
,
450 IN PDEVICE_OBJECT DeviceObject
,
452 IN KSOBJECT_CREATE
*CreateObject
)
455 IPortFilterWavePci
* Filter
;
457 DPRINT("ISubDevice_NewIrpTarget this %p\n", this);
461 *OutTarget
= (IIrpTarget
*)m_Filter
;
462 return STATUS_SUCCESS
;
465 Status
= NewPortFilterWavePci(&Filter
);
466 if (!NT_SUCCESS(Status
))
471 Status
= Filter
->Init((IPortWavePci
*)this);
472 if (!NT_SUCCESS(Status
))
478 *OutTarget
= (IIrpTarget
*)Filter
;
485 CPortWavePci::ReleaseChildren()
487 //IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice);
490 return STATUS_UNSUCCESSFUL
;
495 CPortWavePci::GetDescriptor(
496 IN SUBDEVICE_DESCRIPTOR
** Descriptor
)
498 DPRINT("ISubDevice_GetDescriptor this %p\n", this);
499 *Descriptor
= m_SubDeviceDescriptor
;
500 return STATUS_SUCCESS
;
505 CPortWavePci::DataRangeIntersection(
507 IN PKSDATARANGE DataRange
,
508 IN PKSDATARANGE MatchingDataRange
,
509 IN ULONG OutputBufferLength
,
510 OUT PVOID ResultantFormat OPTIONAL
,
511 OUT PULONG ResultantFormatLength
)
513 DPRINT("ISubDevice_DataRangeIntersection this %p\n", this);
517 return m_Miniport
->DataRangeIntersection (PinId
, DataRange
, MatchingDataRange
, OutputBufferLength
, ResultantFormat
, ResultantFormatLength
);
520 return STATUS_UNSUCCESSFUL
;
525 CPortWavePci::PowerChangeNotify(
526 IN POWER_STATE PowerState
)
530 m_pPowerNotify
->PowerChangeNotify(PowerState
);
533 return STATUS_SUCCESS
;
538 CPortWavePci::PinCount(
540 IN OUT PULONG FilterNecessary
,
541 IN OUT PULONG FilterCurrent
,
542 IN OUT PULONG FilterPossible
,
543 IN OUT PULONG GlobalCurrent
,
544 IN OUT PULONG GlobalPossible
)
548 m_pPinCount
->PinCount(PinId
, FilterNecessary
, FilterCurrent
, FilterPossible
, GlobalCurrent
, GlobalPossible
);
549 return STATUS_SUCCESS
;
553 // scan filter descriptor
555 return STATUS_UNSUCCESSFUL
;
566 Port
= new(NonPagedPool
, TAG_PORTCLASS
) CPortWavePci(NULL
);
568 return STATUS_INSUFFICIENT_RESOURCES
;
570 Status
= Port
->QueryInterface(IID_IPort
, (PVOID
*)OutPort
);
572 if (!NT_SUCCESS(Status
))
577 DPRINT("NewPortWavePci %p Status %u\n", Port
, Status
);
584 GetDeviceObjectFromPortWavePci(
587 CPortWavePci
* This
= (CPortWavePci
*)iface
;
588 return This
->m_pDeviceObject
;
595 CPortWavePci
* This
= (CPortWavePci
*)iface
;
596 return This
->m_Miniport
;