- Implement IPortEvents interface for IPortTopology
[reactos.git] / reactos / drivers / wdm / audio / backpln / portcls / port_wavepci.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/port_wavepci.c
5 * PURPOSE: Wave PCI Port driver
6 * PROGRAMMER: Johannes Anderwald
7 */
8
9 #include "private.h"
10
11 typedef struct
12 {
13 IPortWavePciVtbl *lpVtbl;
14 IServiceSinkVtbl *lpVtblServiceSink;
15 IPortEventsVtbl *lpVtblPortEvents;
16 ISubdeviceVtbl *lpVtblSubDevice;
17
18 #if 0
19 IUnregisterSubdevice *lpVtblUnregisterSubDevice;
20 #endif
21 LONG ref;
22
23 PMINIPORTWAVEPCI Miniport;
24 PDEVICE_OBJECT pDeviceObject;
25 BOOL bInitialized;
26 PRESOURCELIST pResourceList;
27 PSERVICEGROUP ServiceGroup;
28 PPINCOUNT pPinCount;
29 PPOWERNOTIFY pPowerNotify;
30 PPCFILTER_DESCRIPTOR pDescriptor;
31 PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
32 IPortFilterWavePci * Filter;
33
34 LIST_ENTRY EventList;
35 KSPIN_LOCK EventListLock;
36
37 }IPortWavePciImpl;
38
39 static GUID InterfaceGuids[3] =
40 {
41 {
42 /// KSCATEGORY_RENDER
43 0x65E8773EL, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
44 },
45 {
46 /// KSCATEGORY_CAPTURE
47 0x65E8773DL, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
48 },
49 {
50 /// KS_CATEGORY_AUDIO
51 0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
52 }
53 };
54
55 DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterWavePciTopologySet, TopologyPropertyHandler);
56 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterWavePciPinSet, PinPropertyHandler, PinPropertyHandler, PinPropertyHandler);
57
58 KSPROPERTY_SET WavePciPropertySet[] =
59 {
60 {
61 &KSPROPSETID_Topology,
62 sizeof(PortFilterWavePciTopologySet) / sizeof(KSPROPERTY_ITEM),
63 (const KSPROPERTY_ITEM*)&PortFilterWavePciTopologySet,
64 0,
65 NULL
66 },
67 {
68 &KSPROPSETID_Pin,
69 sizeof(PortFilterWavePciPinSet) / sizeof(KSPROPERTY_ITEM),
70 (const KSPROPERTY_ITEM*)&PortFilterWavePciPinSet,
71 0,
72 NULL
73 }
74 };
75
76
77 //---------------------------------------------------------------
78 // IPortEvents
79 //
80
81 static
82 NTSTATUS
83 NTAPI
84 IPortEvents_fnQueryInterface(
85 IPortEvents* iface,
86 IN REFIID refiid,
87 OUT PVOID* Output)
88 {
89 IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblPortEvents);
90
91 DPRINT("IPortEvents_fnQueryInterface entered\n");
92
93 if (IsEqualGUIDAligned(refiid, &IID_IPortEvents) ||
94 IsEqualGUIDAligned(refiid, &IID_IUnknown))
95 {
96 *Output = &This->lpVtblPortEvents;
97 InterlockedIncrement(&This->ref);
98 return STATUS_SUCCESS;
99 }
100 return STATUS_UNSUCCESSFUL;
101 }
102
103 static
104 ULONG
105 NTAPI
106 IPortEvents_fnAddRef(
107 IPortEvents* iface)
108 {
109 IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblPortEvents);
110 DPRINT("IPortEvents_fnAddRef entered\n");
111 return InterlockedIncrement(&This->ref);
112 }
113
114 static
115 ULONG
116 NTAPI
117 IPortEvents_fnRelease(
118 IPortEvents* iface)
119 {
120 IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblPortEvents);
121 DPRINT("IPortEvents_fnRelease entered\n");
122 InterlockedDecrement(&This->ref);
123
124 if (This->ref == 0)
125 {
126 FreeItem(This, TAG_PORTCLASS);
127 return 0;
128 }
129 /* Return new reference count */
130 return This->ref;
131 }
132
133 static
134 void
135 NTAPI
136 IPortEvents_fnAddEventToEventList(
137 IPortEvents* iface,
138 IN PKSEVENT_ENTRY EventEntry)
139 {
140 KIRQL OldIrql;
141 IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblPortEvents);
142
143 ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
144
145 KeAcquireSpinLock(&This->EventListLock, &OldIrql);
146 InsertTailList(&This->EventList, &EventEntry->ListEntry);
147 KeReleaseSpinLock(&This->EventListLock, OldIrql);
148 }
149
150
151 static
152 void
153 NTAPI
154 IPortEvents_fnGenerateEventList(
155 IPortEvents* iface,
156 IN GUID* Set OPTIONAL,
157 IN ULONG EventId,
158 IN BOOL PinEvent,
159 IN ULONG PinId,
160 IN BOOL NodeEvent,
161 IN ULONG NodeId)
162 {
163 UNIMPLEMENTED
164 }
165
166 static IPortEventsVtbl vt_IPortEvents =
167 {
168 IPortEvents_fnQueryInterface,
169 IPortEvents_fnAddRef,
170 IPortEvents_fnRelease,
171 IPortEvents_fnAddEventToEventList,
172 IPortEvents_fnGenerateEventList
173 };
174
175 //---------------------------------------------------------------
176 // IServiceSink
177 //
178
179 static
180 NTSTATUS
181 NTAPI
182 IServiceSink_fnQueryInterface(
183 IServiceSink* iface,
184 IN REFIID refiid,
185 OUT PVOID* Output)
186 {
187 IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblServiceSink);
188
189 DPRINT("IServiceSink_fnQueryInterface entered\n");
190
191 if (IsEqualGUIDAligned(refiid, &IID_IServiceSink) ||
192 IsEqualGUIDAligned(refiid, &IID_IUnknown))
193 {
194 *Output = &This->lpVtblServiceSink;
195 InterlockedIncrement(&This->ref);
196 return STATUS_SUCCESS;
197 }
198 return STATUS_UNSUCCESSFUL;
199 }
200
201 static
202 ULONG
203 NTAPI
204 IServiceSink_fnAddRef(
205 IServiceSink* iface)
206 {
207 IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblServiceSink);
208 DPRINT("IServiceSink_fnAddRef entered\n");
209 return InterlockedIncrement(&This->ref);
210 }
211
212 static
213 ULONG
214 NTAPI
215 IServiceSink_fnRelease(
216 IServiceSink* iface)
217 {
218 IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblServiceSink);
219 DPRINT("IServiceSink_fnRelease entered\n");
220 InterlockedDecrement(&This->ref);
221
222 if (This->ref == 0)
223 {
224 FreeItem(This, TAG_PORTCLASS);
225 return 0;
226 }
227 /* Return new reference count */
228 return This->ref;
229 }
230
231 static
232 VOID
233 NTAPI
234 IServiceSink_fnRequestService(
235 IServiceSink* iface)
236 {
237 IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblServiceSink);
238 //DPRINT("IServiceSink_fnRequestService entered\n");
239 if (This->Miniport)
240 {
241 This->Miniport->lpVtbl->Service(This->Miniport);
242 }
243 }
244
245 static IServiceSinkVtbl vt_IServiceSink =
246 {
247 IServiceSink_fnQueryInterface,
248 IServiceSink_fnAddRef,
249 IServiceSink_fnRelease,
250 IServiceSink_fnRequestService
251 };
252
253 //---------------------------------------------------------------
254 // IPortWavePci
255 //
256
257 static
258 NTSTATUS
259 NTAPI
260 IPortWavePci_fnQueryInterface(
261 IPortWavePci* iface,
262 IN REFIID refiid,
263 OUT PVOID* Output)
264 {
265 UNICODE_STRING GuidString;
266 IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
267
268 DPRINT("IPortWavePci_fnQueryInterface entered\n");
269
270 if (IsEqualGUIDAligned(refiid, &IID_IPortWavePci) ||
271 IsEqualGUIDAligned(refiid, &IID_IUnknown))
272 {
273 *Output = &This->lpVtbl;
274 InterlockedIncrement(&This->ref);
275 return STATUS_SUCCESS;
276 }
277 else if (IsEqualGUIDAligned(refiid, &IID_IServiceSink))
278 {
279 *Output = &This->lpVtblServiceSink;
280 InterlockedIncrement(&This->ref);
281 return STATUS_SUCCESS;
282 }
283 else if (IsEqualGUIDAligned(refiid, &IID_IPortEvents))
284 {
285 *Output = &This->lpVtblPortEvents;
286 InterlockedIncrement(&This->ref);
287 return STATUS_SUCCESS;
288 }
289 else if (IsEqualGUIDAligned(refiid, &IID_ISubdevice))
290 {
291 *Output = &This->lpVtblSubDevice;
292 InterlockedIncrement(&This->ref);
293 return STATUS_SUCCESS;
294 }
295 else if (IsEqualGUIDAligned(refiid, &IID_IPortClsVersion))
296 {
297 return NewPortClsVersion((PPORTCLSVERSION*)Output);
298 }
299 else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice))
300 {
301 return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output);
302 }
303 else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterPhysicalConnection))
304 {
305 return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output);
306 }
307
308 if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
309 {
310 DPRINT1("IPortWavePci_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer);
311 RtlFreeUnicodeString(&GuidString);
312 }
313
314 return STATUS_UNSUCCESSFUL;
315 }
316
317 static
318 ULONG
319 NTAPI
320 IPortWavePci_fnAddRef(
321 IPortWavePci* iface)
322 {
323 IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
324
325 DPRINT("IPortWavePci_fnAddRef entered\n");
326
327 return InterlockedIncrement(&This->ref);
328 }
329
330 static
331 ULONG
332 NTAPI
333 IPortWavePci_fnRelease(
334 IPortWavePci* iface)
335 {
336 IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
337
338 DPRINT("IPortWavePci_fnRelease entered\n");
339
340 InterlockedDecrement(&This->ref);
341
342 if (This->ref == 0)
343 {
344 FreeItem(This, TAG_PORTCLASS);
345 return 0;
346 }
347 /* Return new reference count */
348 return This->ref;
349 }
350
351 NTSTATUS
352 NTAPI
353 IPortWavePci_fnInit(
354 IN IPortWavePci * iface,
355 IN PDEVICE_OBJECT DeviceObject,
356 IN PIRP Irp,
357 IN PUNKNOWN UnknownMiniport,
358 IN PUNKNOWN UnknownAdapter OPTIONAL,
359 IN PRESOURCELIST ResourceList)
360 {
361 IMiniportWavePci * Miniport;
362 PSERVICEGROUP ServiceGroup;
363 NTSTATUS Status;
364 PPINCOUNT PinCount;
365 PPOWERNOTIFY PowerNotify;
366 IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
367
368 DPRINT("IPortWavePci_fnInit entered with This %p, DeviceObject %p Irp %p UnknownMiniport %p, UnknownAdapter %p ResourceList %p\n",
369 This, DeviceObject, Irp, UnknownMiniport, UnknownAdapter, ResourceList);
370 ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
371
372 if (This->bInitialized)
373 {
374 DPRINT("IPortWavePci_fnInit called again\n");
375 return STATUS_SUCCESS;
376 }
377
378 Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IMiniportWavePci, (PVOID*)&Miniport);
379 if (!NT_SUCCESS(Status))
380 {
381 DPRINT("IPortWavePci_fnInit called with invalid IMiniport adapter\n");
382 return STATUS_INVALID_PARAMETER;
383 }
384
385 /* Initialize port object */
386 This->Miniport = Miniport;
387 This->pDeviceObject = DeviceObject;
388 This->bInitialized = TRUE;
389 This->pResourceList = ResourceList;
390 InitializeListHead(&This->EventList);
391 KeInitializeSpinLock(&This->EventListLock);
392
393 /* increment reference on miniport adapter */
394 Miniport->lpVtbl->AddRef(Miniport);
395 /* increment reference on resource list */
396 ResourceList->lpVtbl->AddRef(ResourceList);
397
398 Status = Miniport->lpVtbl->Init(Miniport, UnknownAdapter, ResourceList, iface, &ServiceGroup);
399 if (!NT_SUCCESS(Status))
400 {
401 DPRINT("IPortWavePci_fnInit failed with %x\n", Status);
402 This->bInitialized = FALSE;
403 /* release reference on miniport adapter */
404 Miniport->lpVtbl->Release(Miniport);
405 /* increment reference on resource list */
406 ResourceList->lpVtbl->Release(ResourceList);
407 return Status;
408 }
409
410 /* check if the miniport adapter provides a valid device descriptor */
411 Status = Miniport->lpVtbl->GetDescription(Miniport, &This->pDescriptor);
412 if (!NT_SUCCESS(Status))
413 {
414 DPRINT1("failed to get description\n");
415 Miniport->lpVtbl->Release(Miniport);
416 This->bInitialized = FALSE;
417 return Status;
418 }
419
420 /* create the subdevice descriptor */
421 Status = PcCreateSubdeviceDescriptor(&This->SubDeviceDescriptor,
422 3,
423 InterfaceGuids,
424 0,
425 NULL,
426 2,
427 WavePciPropertySet,
428 0,
429 0,
430 0,
431 NULL,
432 0,
433 NULL,
434 This->pDescriptor);
435
436
437 if (!NT_SUCCESS(Status))
438 {
439 DPRINT1("PcCreateSubdeviceDescriptor failed with %x\n", Status);
440 Miniport->lpVtbl->Release(Miniport);
441 This->bInitialized = FALSE;
442 return Status;
443 }
444
445 /* did we get a service group */
446 if (ServiceGroup)
447 {
448 /* store service group in context */
449 This->ServiceGroup = ServiceGroup;
450
451 /* add ourselves to service group which is called when miniport receives an isr */
452 ServiceGroup->lpVtbl->AddMember(ServiceGroup, (PSERVICESINK)&This->lpVtblServiceSink);
453
454 /* increment reference on service group */
455 ServiceGroup->lpVtbl->AddRef(ServiceGroup);
456 }
457
458 /* check if it supports IPinCount interface */
459 Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IPinCount, (PVOID*)&PinCount);
460 if (NT_SUCCESS(Status))
461 {
462 /* store IPinCount interface */
463 This->pPinCount = PinCount;
464 }
465
466 /* does the Miniport adapter support IPowerNotify interface*/
467 Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IPowerNotify, (PVOID*)&PowerNotify);
468 if (NT_SUCCESS(Status))
469 {
470 /* store reference */
471 This->pPowerNotify = PowerNotify;
472 }
473
474 DPRINT("IPortWavePci_Init sucessfully initialized\n");
475 return STATUS_SUCCESS;
476 }
477
478 NTSTATUS
479 NTAPI
480 IPortWavePci_fnNewRegistryKey(
481 IN IPortWavePci * iface,
482 OUT PREGISTRYKEY *OutRegistryKey,
483 IN PUNKNOWN OuterUnknown OPTIONAL,
484 IN ULONG RegistryKeyType,
485 IN ACCESS_MASK DesiredAccess,
486 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
487 IN ULONG CreateOptions OPTIONAL,
488 OUT PULONG Disposition OPTIONAL)
489 {
490 IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
491
492 DPRINT("IPortWavePci_fnNewRegistryKey entered\n");
493 ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
494
495 if (!This->bInitialized)
496 {
497 DPRINT("IPortWavePci_fnNewRegistryKey called w/o initiazed\n");
498 return STATUS_UNSUCCESSFUL;
499 }
500
501 return PcNewRegistryKey(OutRegistryKey,
502 OuterUnknown,
503 RegistryKeyType,
504 DesiredAccess,
505 This->pDeviceObject,
506 NULL,//FIXME
507 ObjectAttributes,
508 CreateOptions,
509 Disposition);
510 }
511
512 NTSTATUS
513 NTAPI
514 IPortWavePci_fnGetDeviceProperty(
515 IN IPortWavePci * iface,
516 IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty,
517 IN ULONG BufferLength,
518 OUT PVOID PropertyBuffer,
519 OUT PULONG ReturnLength)
520 {
521 IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
522
523 DPRINT("IPortWavePci_fnGetDeviceProperty entered\n");
524 ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
525
526 if (!This->bInitialized)
527 {
528 DPRINT("IPortWavePci_fnNewRegistryKey called w/o initiazed\n");
529 return STATUS_UNSUCCESSFUL;
530 }
531
532 return IoGetDeviceProperty(This->pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength);
533 }
534
535 NTSTATUS
536 NTAPI
537 IPortWavePci_fnNewMasterDmaChannel(
538 IN IPortWavePci * iface,
539 OUT PDMACHANNEL *DmaChannel,
540 IN PUNKNOWN OuterUnknown OPTIONAL,
541 IN POOL_TYPE PoolType,
542 IN PRESOURCELIST ResourceList OPTIONAL,
543 IN BOOLEAN ScatterGather,
544 IN BOOLEAN Dma32BitAddresses,
545 IN BOOLEAN Dma64BitAddresses,
546 IN BOOLEAN IgnoreCount,
547 IN DMA_WIDTH DmaWidth,
548 IN DMA_SPEED DmaSpeed,
549 IN ULONG MaximumLength,
550 IN ULONG DmaPort)
551 {
552 NTSTATUS Status;
553 DEVICE_DESCRIPTION DeviceDescription;
554 IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
555
556 DPRINT("IPortWavePci_fnNewMasterDmaChannel This %p entered\n", This);
557 ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
558
559 Status = PcDmaMasterDescription(ResourceList, ScatterGather, Dma32BitAddresses, IgnoreCount, Dma64BitAddresses, DmaWidth, DmaSpeed, MaximumLength, DmaPort, &DeviceDescription);
560 if (NT_SUCCESS(Status))
561 {
562 return PcNewDmaChannel(DmaChannel, OuterUnknown, PoolType, &DeviceDescription, This->pDeviceObject);
563 }
564
565 return Status;
566 }
567
568 VOID
569 NTAPI
570 IPortWavePci_fnNotify(
571 IN IPortWavePci * iface,
572 IN PSERVICEGROUP ServiceGroup)
573 {
574 //IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
575
576 //DPRINT("IPortWavePci_fnNotify entered %p, ServiceGroup %p\n", This, ServiceGroup);
577
578 if (ServiceGroup)
579 {
580 ServiceGroup->lpVtbl->RequestService (ServiceGroup);
581 }
582 }
583
584 static IPortWavePciVtbl vt_IPortWavePci =
585 {
586 /* IUnknown methods */
587 IPortWavePci_fnQueryInterface,
588 IPortWavePci_fnAddRef,
589 IPortWavePci_fnRelease,
590 /* IPort methods */
591 IPortWavePci_fnInit,
592 IPortWavePci_fnGetDeviceProperty,
593 IPortWavePci_fnNewRegistryKey,
594 /* IPortWavePci methods */
595 IPortWavePci_fnNotify,
596 IPortWavePci_fnNewMasterDmaChannel,
597 };
598
599 //---------------------------------------------------------------
600 // ISubdevice interface
601 //
602
603 static
604 NTSTATUS
605 NTAPI
606 ISubDevice_fnQueryInterface(
607 IN ISubdevice *iface,
608 IN REFIID InterfaceId,
609 IN PVOID* Interface)
610 {
611 IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice);
612
613 return IPortWavePci_fnQueryInterface((IPortWavePci*)This, InterfaceId, Interface);
614 }
615
616 static
617 ULONG
618 NTAPI
619 ISubDevice_fnAddRef(
620 IN ISubdevice *iface)
621 {
622 IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice);
623
624 return IPortWavePci_fnAddRef((IPortWavePci*)This);
625 }
626
627 static
628 ULONG
629 NTAPI
630 ISubDevice_fnRelease(
631 IN ISubdevice *iface)
632 {
633 IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice);
634
635 return IPortWavePci_fnRelease((IPortWavePci*)This);
636 }
637
638 static
639 NTSTATUS
640 NTAPI
641 ISubDevice_fnNewIrpTarget(
642 IN ISubdevice *iface,
643 OUT struct IIrpTarget **OutTarget,
644 IN WCHAR * Name,
645 IN PUNKNOWN Unknown,
646 IN POOL_TYPE PoolType,
647 IN PDEVICE_OBJECT DeviceObject,
648 IN PIRP Irp,
649 IN KSOBJECT_CREATE *CreateObject)
650 {
651 NTSTATUS Status;
652 IPortFilterWavePci * Filter;
653 IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice);
654
655 DPRINT("ISubDevice_NewIrpTarget this %p\n", This);
656
657 if (This->Filter)
658 {
659 *OutTarget = (IIrpTarget*)This->Filter;
660 return STATUS_SUCCESS;
661 }
662
663 Status = NewPortFilterWavePci(&Filter);
664 if (!NT_SUCCESS(Status))
665 {
666 return Status;
667 }
668
669 Status = Filter->lpVtbl->Init(Filter, (IPortWavePci*)This);
670 if (!NT_SUCCESS(Status))
671 {
672 Filter->lpVtbl->Release(Filter);
673 return Status;
674 }
675
676 *OutTarget = (IIrpTarget*)Filter;
677 This->Filter = Filter;
678 return Status;
679 }
680
681 static
682 NTSTATUS
683 NTAPI
684 ISubDevice_fnReleaseChildren(
685 IN ISubdevice *iface)
686 {
687 //IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice);
688
689 UNIMPLEMENTED
690 return STATUS_UNSUCCESSFUL;
691 }
692
693 static
694 NTSTATUS
695 NTAPI
696 ISubDevice_fnGetDescriptor(
697 IN ISubdevice *iface,
698 IN SUBDEVICE_DESCRIPTOR ** Descriptor)
699 {
700 IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice);
701
702 DPRINT1("ISubDevice_GetDescriptor this %p\n", This);
703 *Descriptor = This->SubDeviceDescriptor;
704 return STATUS_SUCCESS;
705 }
706
707 static
708 NTSTATUS
709 NTAPI
710 ISubDevice_fnDataRangeIntersection(
711 IN ISubdevice *iface,
712 IN ULONG PinId,
713 IN PKSDATARANGE DataRange,
714 IN PKSDATARANGE MatchingDataRange,
715 IN ULONG OutputBufferLength,
716 OUT PVOID ResultantFormat OPTIONAL,
717 OUT PULONG ResultantFormatLength)
718 {
719 IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice);
720
721 DPRINT("ISubDevice_DataRangeIntersection this %p\n", This);
722
723 if (This->Miniport)
724 {
725 return This->Miniport->lpVtbl->DataRangeIntersection (This->Miniport, PinId, DataRange, MatchingDataRange, OutputBufferLength, ResultantFormat, ResultantFormatLength);
726 }
727
728 return STATUS_UNSUCCESSFUL;
729 }
730
731 static
732 NTSTATUS
733 NTAPI
734 ISubDevice_fnPowerChangeNotify(
735 IN ISubdevice *iface,
736 IN POWER_STATE PowerState)
737 {
738 IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice);
739
740 if (This->pPowerNotify)
741 {
742 This->pPowerNotify->lpVtbl->PowerChangeNotify(This->pPowerNotify, PowerState);
743 }
744
745 return STATUS_SUCCESS;
746 }
747
748 static
749 NTSTATUS
750 NTAPI
751 ISubDevice_fnPinCount(
752 IN ISubdevice *iface,
753 IN ULONG PinId,
754 IN OUT PULONG FilterNecessary,
755 IN OUT PULONG FilterCurrent,
756 IN OUT PULONG FilterPossible,
757 IN OUT PULONG GlobalCurrent,
758 IN OUT PULONG GlobalPossible)
759 {
760 IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice);
761
762 if (This->pPinCount)
763 {
764 This->pPinCount->lpVtbl->PinCount(This->pPinCount, PinId, FilterNecessary, FilterCurrent, FilterPossible, GlobalCurrent, GlobalPossible);
765 return STATUS_SUCCESS;
766 }
767
768 /* FIXME
769 * scan filter descriptor
770 */
771 return STATUS_UNSUCCESSFUL;
772 }
773
774 static ISubdeviceVtbl vt_ISubdeviceVtbl =
775 {
776 ISubDevice_fnQueryInterface,
777 ISubDevice_fnAddRef,
778 ISubDevice_fnRelease,
779 ISubDevice_fnNewIrpTarget,
780 ISubDevice_fnReleaseChildren,
781 ISubDevice_fnGetDescriptor,
782 ISubDevice_fnDataRangeIntersection,
783 ISubDevice_fnPowerChangeNotify,
784 ISubDevice_fnPinCount
785 };
786
787 NTSTATUS
788 NewPortWavePci(
789 OUT PPORT* OutPort)
790 {
791 IPortWavePciImpl * This;
792
793 This = AllocateItem(NonPagedPool, sizeof(IPortWavePciImpl), TAG_PORTCLASS);
794 if (!This)
795 return STATUS_INSUFFICIENT_RESOURCES;
796
797 This->lpVtblServiceSink = &vt_IServiceSink;
798 This->lpVtbl = &vt_IPortWavePci;
799 This->lpVtblSubDevice = &vt_ISubdeviceVtbl;
800 This->lpVtblPortEvents = &vt_IPortEvents;
801 This->ref = 1;
802
803 *OutPort = (PPORT)&This->lpVtbl;
804 DPRINT("NewPortWavePci %p\n", *OutPort);
805 return STATUS_SUCCESS;
806 }
807
808 PDEVICE_OBJECT
809 GetDeviceObjectFromPortWavePci(
810 IPortWavePci* iface)
811 {
812 IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
813 return This->pDeviceObject;
814 }
815
816 PMINIPORTWAVEPCI
817 GetWavePciMiniport(
818 PPORTWAVEPCI iface)
819 {
820 IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
821 return This->Miniport;
822 }