- Revert to pre-38722 to unbreak build
[reactos.git] / reactos / drivers / wdm / audio / backpln / portcls / port_wavepci.c
1 #include "private.h"
2
3 typedef struct
4 {
5 IPortWavePciVtbl *lpVtbl;
6 IServiceSinkVtbl *lpVtblServiceSink;
7
8 #if 0
9 IUnregisterSubdevice *lpVtblUnregisterSubDevice;
10 #endif
11 LONG ref;
12
13 PMINIPORTWAVEPCI Miniport;
14 PDEVICE_OBJECT pDeviceObject;
15 KDPC Dpc;
16 BOOL bInitialized;
17 PRESOURCELIST pResourceList;
18 PSERVICEGROUP ServiceGroup;
19 }IPortWavePciImpl;
20
21
22 const GUID IID_IPortWavePci;
23 const GUID IID_IMiniportWavePci;
24
25 //---------------------------------------------------------------
26 // IServiceSink
27 //
28
29 static
30 NTSTATUS
31 NTAPI
32 IServiceSink_fnQueryInterface(
33 IServiceSink* iface,
34 IN REFIID refiid,
35 OUT PVOID* Output)
36 {
37 IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblServiceSink);
38
39 if (IsEqualGUIDAligned(refiid, &IID_IServiceSink))
40 {
41 *Output = &This->lpVtblServiceSink;
42 InterlockedIncrement(&This->ref);
43 return STATUS_SUCCESS;
44 }
45 return STATUS_UNSUCCESSFUL;
46 }
47
48 static
49 ULONG
50 NTAPI
51 IServiceSink_fnAddRef(
52 IServiceSink* iface)
53 {
54 IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblServiceSink);
55
56 return InterlockedIncrement(&This->ref);
57 }
58
59 static
60 ULONG
61 NTAPI
62 IServiceSink_fnRelease(
63 IServiceSink* iface)
64 {
65 IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblServiceSink);
66
67 InterlockedDecrement(&This->ref);
68
69 if (This->ref == 0)
70 {
71 ExFreePoolWithTag(This, TAG_PORTCLASS);
72 return 0;
73 }
74 /* Return new reference count */
75 return This->ref;
76 }
77
78 static
79 VOID
80 NTAPI
81 IServiceSink_fnRequestService(
82 IServiceSink* iface)
83 {
84 IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblServiceSink);
85
86 if (This->Miniport)
87 {
88 This->Miniport->lpVtbl->Service(This->Miniport);
89 }
90 }
91
92 static IServiceSinkVtbl vt_IServiceSink =
93 {
94 IServiceSink_fnQueryInterface,
95 IServiceSink_fnAddRef,
96 IServiceSink_fnRelease,
97 IServiceSink_fnRequestService
98 };
99
100 //---------------------------------------------------------------
101 // IPortWavePci
102 //
103
104 static
105 NTSTATUS
106 NTAPI
107 IPortWavePci_fnQueryInterface(
108 IPortWavePci* iface,
109 IN REFIID refiid,
110 OUT PVOID* Output)
111 {
112 IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
113
114 if (IsEqualGUIDAligned(refiid, &IID_IPortWavePci))
115 {
116 *Output = &This->lpVtbl;
117 InterlockedIncrement(&This->ref);
118 return STATUS_SUCCESS;
119 }
120 else if (IsEqualGUIDAligned(refiid, &IID_IServiceSink))
121 {
122 *Output = &This->lpVtbl;
123 InterlockedIncrement(&This->ref);
124 return STATUS_SUCCESS;
125 }
126 else if (IsEqualGUIDAligned(refiid, &IID_IPortClsVersion))
127 {
128 return NewPortClsVersion((PPORTCLSVERSION*)Output);
129 }
130 return STATUS_UNSUCCESSFUL;
131 }
132
133 static
134 ULONG
135 NTAPI
136 IPortWavePci_fnAddRef(
137 IPortWavePci* iface)
138 {
139 IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
140 return InterlockedIncrement(&This->ref);
141 }
142
143 static
144 ULONG
145 NTAPI
146 IPortWavePci_fnRelease(
147 IPortWavePci* iface)
148 {
149 IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
150
151 InterlockedDecrement(&This->ref);
152
153 if (This->ref == 0)
154 {
155 ExFreePoolWithTag(This, TAG_PORTCLASS);
156 return 0;
157 }
158 /* Return new reference count */
159 return This->ref;
160 }
161
162 VOID
163 NTAPI
164 ServiceNotifyRoutine(
165 IN struct _KDPC *Dpc,
166 IN PVOID DeferredContext,
167 IN PVOID SystemArgument1,
168 IN PVOID SystemArgument2)
169 {
170 IPortWavePciImpl * This = (IPortWavePciImpl*)DeferredContext;
171 if (This->ServiceGroup)
172 {
173 This->ServiceGroup->lpVtbl->RequestService(This->ServiceGroup);
174 }
175 }
176
177
178
179 NTSTATUS
180 NTAPI
181 IPortWavePci_fnInit(
182 IN IPortWavePci * iface,
183 IN PDEVICE_OBJECT DeviceObject,
184 IN PIRP Irp,
185 IN PUNKNOWN UnknownMiniport,
186 IN PUNKNOWN UnknownAdapter OPTIONAL,
187 IN PRESOURCELIST ResourceList)
188 {
189 IMiniportWavePci * Miniport;
190 PSERVICEGROUP ServiceGroup;
191 NTSTATUS Status;
192 IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
193
194 if (This->bInitialized)
195 {
196 DPRINT("IPortWaveCyclic_Init called again\n");
197 return STATUS_SUCCESS;
198 }
199
200 Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IMiniportWavePci, (PVOID*)&Miniport);
201 if (!NT_SUCCESS(Status))
202 {
203 DPRINT("IPortWaveCyclic_Init called with invalid IMiniport adapter\n");
204 return STATUS_INVALID_PARAMETER;
205 }
206
207 Status = Miniport->lpVtbl->Init(Miniport, UnknownAdapter, ResourceList, iface, &ServiceGroup);
208 if (!NT_SUCCESS(Status))
209 {
210 DPRINT("IMiniportWaveCyclic_Init failed with %x\n", Status);
211 return Status;
212 }
213
214 /* Initialize port object */
215 This->Miniport = Miniport;
216 This->pDeviceObject = DeviceObject;
217 This->bInitialized = TRUE;
218 This->pResourceList = ResourceList;
219 This->ServiceGroup = ServiceGroup;
220
221 /* initialize the dpc */
222 KeInitializeDpc(&This->Dpc, ServiceNotifyRoutine, (PVOID)This);
223
224 /* increment reference on miniport adapter */
225 Miniport->lpVtbl->AddRef(Miniport);
226 /* increment reference on resource list */
227 ResourceList->lpVtbl->AddRef(ResourceList);
228
229 /* add ourselves to service group which is called when miniport receives an isr */
230 ServiceGroup->lpVtbl->AddMember(ServiceGroup, (PSERVICESINK)&This->lpVtblServiceSink);
231
232 /* increment reference on service group */
233 ServiceGroup->lpVtbl->AddRef(ServiceGroup);
234
235 return STATUS_SUCCESS;
236 }
237
238 NTSTATUS
239 NTAPI
240 IPortWavePci_fnNewRegistryKey(
241 IN IPortWavePci * iface,
242 OUT PREGISTRYKEY *OutRegistryKey,
243 IN PUNKNOWN OuterUnknown OPTIONAL,
244 IN ULONG RegistryKeyType,
245 IN ACCESS_MASK DesiredAccess,
246 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
247 IN ULONG CreateOptions OPTIONAL,
248 OUT PULONG Disposition OPTIONAL)
249 {
250 return STATUS_UNSUCCESSFUL;
251 }
252
253 NTSTATUS
254 NTAPI
255 IPortWavePci_fnGetDeviceProperty(
256 IN IPortWavePci * iface,
257 IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty,
258 IN ULONG BufferLength,
259 OUT PVOID PropertyBuffer,
260 OUT PULONG ReturnLength)
261 {
262 IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
263
264 if (!This->bInitialized)
265 {
266 DPRINT("IPortWaveCyclic_fnNewRegistryKey called w/o initiazed\n");
267 return STATUS_UNSUCCESSFUL;
268 }
269
270 return IoGetDeviceProperty(This->pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength);
271 }
272
273 NTSTATUS
274 NTAPI
275 IPortWavePci_fnNewMasterDmaChannel(
276 IN IPortWavePci * iface,
277 OUT PDMACHANNEL *DmaChannel,
278 IN PUNKNOWN OuterUnknown OPTIONAL,
279 IN POOL_TYPE PoolType,
280 IN PRESOURCELIST ResourceList OPTIONAL,
281 IN BOOLEAN ScatterGather,
282 IN BOOLEAN Dma32BitAddresses,
283 IN BOOLEAN Dma64BitAddresses,
284 IN BOOLEAN IgnoreCount,
285 IN DMA_WIDTH DmaWidth,
286 IN DMA_SPEED DmaSpeed,
287 IN ULONG MaximumLength,
288 IN ULONG DmaPort)
289 {
290 NTSTATUS Status;
291 DEVICE_DESCRIPTION DeviceDescription;
292 IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
293
294 Status = PcDmaMasterDescription(ResourceList, ScatterGather, Dma32BitAddresses, IgnoreCount, Dma64BitAddresses, DmaWidth, DmaSpeed, MaximumLength, DmaPort, &DeviceDescription);
295 if (NT_SUCCESS(Status))
296 {
297 return PcNewDmaChannel(DmaChannel, OuterUnknown, PoolType, &DeviceDescription, This->pDeviceObject);
298 }
299
300 return Status;
301 }
302
303 VOID
304 NTAPI
305 IPortWavePci_fnNotify(
306 IN IPortWavePci * iface,
307 IN PSERVICEGROUP ServiceGroup)
308 {
309 IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
310 KeInsertQueueDpc(&This->Dpc, NULL, NULL);
311 }
312
313 static IPortWavePciVtbl vt_IPortWavePci =
314 {
315 /* IUnknown methods */
316 IPortWavePci_fnQueryInterface,
317 IPortWavePci_fnAddRef,
318 IPortWavePci_fnRelease,
319 /* IPort methods */
320 IPortWavePci_fnInit,
321 IPortWavePci_fnGetDeviceProperty,
322 IPortWavePci_fnNewRegistryKey,
323 /* IPortWavePci methods */
324 IPortWavePci_fnNewMasterDmaChannel,
325 IPortWavePci_fnNotify
326 };
327
328
329 NTSTATUS
330 NewPortWavePci(
331 OUT PPORT* OutPort)
332 {
333 IPortWavePciImpl * This;
334
335 This = ExAllocatePoolWithTag(NonPagedPool, sizeof(IPortWavePciImpl), TAG_PORTCLASS);
336 if (!This)
337 return STATUS_INSUFFICIENT_RESOURCES;
338
339 RtlZeroMemory(This, sizeof(IPortWavePciImpl));
340 This->lpVtblServiceSink = &vt_IServiceSink;
341 This->lpVtbl = &vt_IPortWavePci;
342 This->ref = 1;
343
344 *OutPort = (PPORT)&This->lpVtbl;
345 return STATUS_SUCCESS;
346 }