- Convert portcls to a C++ driver
[reactos.git] / reactos / drivers / wdm / audio / backpln / portcls / api.cpp
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/api.cpp
5 * PURPOSE: Port api functions
6 * PROGRAMMER: Johannes Anderwald
7 */
8
9 #include "private.hpp"
10
11 NTSTATUS
12 NTAPI
13 PcGetDeviceProperty(
14 IN PVOID DeviceObject,
15 IN DEVICE_REGISTRY_PROPERTY DeviceProperty,
16 IN ULONG BufferLength,
17 OUT PVOID PropertyBuffer,
18 OUT PULONG ResultLength)
19 {
20 PPCLASS_DEVICE_EXTENSION DeviceExtension;
21
22 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
23
24 DeviceExtension = (PPCLASS_DEVICE_EXTENSION)((PDEVICE_OBJECT)DeviceObject)->DeviceExtension;
25
26 return IoGetDeviceProperty(DeviceExtension->PhysicalDeviceObject, DeviceProperty, BufferLength, PropertyBuffer, ResultLength);
27 }
28
29 ULONGLONG
30 NTAPI
31 PcGetTimeInterval(
32 IN ULONGLONG Since)
33 {
34 LARGE_INTEGER CurrentTime;
35
36 KeQuerySystemTime(&CurrentTime);
37
38 return (CurrentTime.QuadPart - Since);
39 }
40
41 VOID
42 NTAPI
43 PcIoTimerRoutine(
44 IN PDEVICE_OBJECT DeviceObject,
45 IN PVOID Context)
46 {
47 PPCLASS_DEVICE_EXTENSION DeviceExtension;
48 KIRQL OldIrql;
49 PLIST_ENTRY ListEntry;
50 PTIMER_CONTEXT CurContext;
51
52 if (!DeviceObject || !DeviceObject->DeviceExtension)
53 return;
54
55 DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
56
57 KeAcquireSpinLock(&DeviceExtension->TimerListLock, &OldIrql);
58
59 ListEntry = DeviceExtension->TimerList.Flink;
60 while(ListEntry != &DeviceExtension->TimerList)
61 {
62 CurContext = (PTIMER_CONTEXT)CONTAINING_RECORD(ListEntry, TIMER_CONTEXT, Entry);
63
64 CurContext->pTimerRoutine(DeviceObject, CurContext->Context);
65 ListEntry = ListEntry->Flink;
66 }
67
68 KeReleaseSpinLock(&DeviceExtension->TimerListLock, OldIrql);
69 }
70
71 NTSTATUS
72 NTAPI
73 PcRegisterIoTimeout(
74 IN PDEVICE_OBJECT pDeviceObject,
75 IN PIO_TIMER_ROUTINE pTimerRoutine,
76 IN PVOID pContext)
77 {
78 NTSTATUS Status = STATUS_SUCCESS;
79 PTIMER_CONTEXT TimerContext, CurContext;
80 KIRQL OldIrql;
81 PLIST_ENTRY ListEntry;
82 BOOLEAN bFound;
83 PPCLASS_DEVICE_EXTENSION DeviceExtension;
84
85 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
86
87 if (!pDeviceObject || !pDeviceObject->DeviceExtension)
88 return STATUS_INVALID_PARAMETER;
89
90 DeviceExtension = (PPCLASS_DEVICE_EXTENSION)pDeviceObject->DeviceExtension;
91
92 TimerContext = (PTIMER_CONTEXT)AllocateItem(NonPagedPool, sizeof(TIMER_CONTEXT), TAG_PORTCLASS);
93 if (!TimerContext)
94 {
95 DPRINT1("Failed to allocate memory\n");
96 return STATUS_INSUFFICIENT_RESOURCES;
97 }
98
99 KeAcquireSpinLock(&DeviceExtension->TimerListLock, &OldIrql);
100
101 ListEntry = DeviceExtension->TimerList.Flink;
102 bFound = FALSE;
103 while(ListEntry != &DeviceExtension->TimerList)
104 {
105 CurContext = (PTIMER_CONTEXT)CONTAINING_RECORD(ListEntry, TIMER_CONTEXT, Entry);
106
107 if (CurContext->Context == pContext && CurContext->pTimerRoutine == pTimerRoutine)
108 {
109 bFound = TRUE;
110 Status = STATUS_UNSUCCESSFUL;
111 ExFreePool(TimerContext);
112 break;
113 }
114 ListEntry = ListEntry->Flink;
115 }
116
117 if (!bFound)
118 {
119 TimerContext->Context = pContext;
120 TimerContext->pTimerRoutine = pTimerRoutine;
121 InsertTailList(&DeviceExtension->TimerList, &TimerContext->Entry);
122 }
123
124 KeReleaseSpinLock(&DeviceExtension->TimerListLock, OldIrql);
125
126 return Status;
127 }
128
129 NTSTATUS
130 NTAPI
131 PcUnregisterIoTimeout(
132 IN PDEVICE_OBJECT pDeviceObject,
133 IN PIO_TIMER_ROUTINE pTimerRoutine,
134 IN PVOID pContext)
135 {
136 PTIMER_CONTEXT CurContext;
137 KIRQL OldIrql;
138 PLIST_ENTRY ListEntry;
139 BOOLEAN bFound;
140 PPCLASS_DEVICE_EXTENSION DeviceExtension;
141
142 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
143
144 if (!pDeviceObject || !pDeviceObject->DeviceExtension)
145 return STATUS_INVALID_PARAMETER;
146
147
148 DeviceExtension = (PPCLASS_DEVICE_EXTENSION)pDeviceObject->DeviceExtension;
149
150
151 KeAcquireSpinLock(&DeviceExtension->TimerListLock, &OldIrql);
152
153 ListEntry = DeviceExtension->TimerList.Flink;
154 bFound = FALSE;
155
156 while(ListEntry != &DeviceExtension->TimerList)
157 {
158 CurContext = (PTIMER_CONTEXT)CONTAINING_RECORD(ListEntry, TIMER_CONTEXT, Entry);
159
160 if (CurContext->Context == pContext && CurContext->pTimerRoutine == pTimerRoutine)
161 {
162 bFound = TRUE;
163 RemoveEntryList(&CurContext->Entry);
164 ExFreePool(CurContext);
165 break;
166 }
167 ListEntry = ListEntry->Flink;
168 }
169
170 KeReleaseSpinLock(&DeviceExtension->TimerListLock, OldIrql);
171
172 if (bFound)
173 return STATUS_SUCCESS;
174 else
175 return STATUS_NOT_FOUND;
176 }
177
178
179
180 NTSTATUS
181 NTAPI
182 PcCompletePendingPropertyRequest(
183 IN PPCPROPERTY_REQUEST PropertyRequest,
184 IN NTSTATUS NtStatus)
185 {
186 // sanity checks
187 PC_ASSERT_IRQL(DISPATCH_LEVEL);
188
189 if (!PropertyRequest || !PropertyRequest->Irp || NtStatus == STATUS_PENDING)
190 return STATUS_INVALID_PARAMETER;
191
192 // set the final status code
193 PropertyRequest->Irp->IoStatus.Status = NtStatus;
194
195 // complete the irp
196 IoCompleteRequest(PropertyRequest->Irp, IO_SOUND_INCREMENT);
197
198 // free the property request
199 ExFreePool(PropertyRequest);
200
201 // return success
202 return STATUS_SUCCESS;
203 }
204
205 NTSTATUS
206 NTAPI
207 PcDmaMasterDescription(
208 IN PRESOURCELIST ResourceList OPTIONAL,
209 IN BOOLEAN ScatterGather,
210 IN BOOLEAN Dma32BitAddresses,
211 IN BOOLEAN IgnoreCount,
212 IN BOOLEAN Dma64BitAddresses,
213 IN DMA_WIDTH DmaWidth,
214 IN DMA_SPEED DmaSpeed,
215 IN ULONG MaximumLength,
216 IN ULONG DmaPort,
217 OUT PDEVICE_DESCRIPTION DeviceDescription)
218 {
219
220 RtlZeroMemory(DeviceDescription, sizeof(DEVICE_DESCRIPTION));
221
222 DeviceDescription->Master = TRUE;
223 DeviceDescription->Version = DEVICE_DESCRIPTION_VERSION1;
224 DeviceDescription->ScatterGather= ScatterGather;
225 DeviceDescription->Dma32BitAddresses = Dma32BitAddresses;
226 DeviceDescription->IgnoreCount = IgnoreCount;
227 DeviceDescription->Dma64BitAddresses = Dma64BitAddresses;
228 DeviceDescription->DmaWidth = DmaWidth;
229 DeviceDescription->DmaSpeed = DmaSpeed;
230 DeviceDescription->MaximumLength = MaximumLength;
231 DeviceDescription->DmaPort = DmaPort;
232
233 return STATUS_SUCCESS;
234 }
235
236 NTSTATUS
237 NTAPI
238 PcDmaSlaveDescription(
239 IN PRESOURCELIST ResourceList OPTIONAL,
240 IN ULONG DmaIndex,
241 IN BOOL DemandMode,
242 IN ULONG AutoInitialize,
243 IN DMA_SPEED DmaSpeed,
244 IN ULONG MaximumLength,
245 IN ULONG DmaPort,
246 OUT PDEVICE_DESCRIPTION DeviceDescription)
247 {
248
249 RtlZeroMemory(DeviceDescription, sizeof(DEVICE_DESCRIPTION));
250
251 DeviceDescription->Version = DEVICE_DESCRIPTION_VERSION1;
252 DeviceDescription->DemandMode = DemandMode;
253 DeviceDescription->AutoInitialize = AutoInitialize;
254 DeviceDescription->DmaSpeed = DmaSpeed;
255 DeviceDescription->MaximumLength = MaximumLength;
256 DeviceDescription->DmaPort = DmaPort;
257
258 return STATUS_SUCCESS;
259 }
260