[CMAKE]
[reactos.git] / drivers / video / videoprt / dma.c
1 /*
2 * PROJECT: ReactOS Videoport
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/video/videoprt/dma.c
5 * PURPOSE: Videoport Direct Memory Access Support
6 * PROGRAMMERS: ...
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <videoprt.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 typedef struct
16 {
17 LIST_ENTRY Entry;
18 PDMA_ADAPTER Adapter;
19 ULONG MapRegisters;
20 PVOID HwDeviceExtension;
21
22 }VIP_DMA_ADAPTER, *PVIP_DMA_ADAPTER;
23
24 typedef struct
25 {
26 PVOID HwDeviceExtension;
27 PSCATTER_GATHER_LIST ScatterGatherList;
28 PEXECUTE_DMA ExecuteDmaRoutine;
29 PVOID Context;
30 PVP_DMA_ADAPTER VpDmaAdapter;
31
32 }DMA_START_CONTEXT, *PDMA_START_CONTEXT;
33
34
35 /* PUBLIC FUNCTIONS ***********************************************************/
36
37 /*
38 * @implemented
39 */
40 PVOID
41 NTAPI
42 VideoPortAllocateCommonBuffer(IN PVOID HwDeviceExtension,
43 IN PVP_DMA_ADAPTER VpDmaAdapter,
44 IN ULONG DesiredLength,
45 OUT PPHYSICAL_ADDRESS LogicalAddress,
46 IN BOOLEAN CacheEnabled,
47 PVOID Reserved)
48 {
49 PVIP_DMA_ADAPTER Adapter = (PVIP_DMA_ADAPTER)VpDmaAdapter;
50
51 /* check for valid arguments */
52 if (!Adapter || !Adapter->Adapter)
53 {
54 /* invalid parameter */
55 return NULL;
56 }
57
58 /* allocate common buffer */
59 return Adapter->Adapter->DmaOperations->AllocateCommonBuffer(Adapter->Adapter, DesiredLength, LogicalAddress, CacheEnabled);
60 }
61
62 /*
63 * @implemented
64 */
65 VOID
66 NTAPI
67 VideoPortReleaseCommonBuffer(IN PVOID HwDeviceExtension,
68 IN PVP_DMA_ADAPTER VpDmaAdapter,
69 IN ULONG Length,
70 IN PHYSICAL_ADDRESS LogicalAddress,
71 IN PVOID VirtualAddress,
72 IN BOOLEAN CacheEnabled)
73 {
74 PVIP_DMA_ADAPTER Adapter = (PVIP_DMA_ADAPTER)VpDmaAdapter;
75
76 /* check for valid arguments */
77 if (!Adapter || !Adapter->Adapter)
78 {
79 /* invalid parameter */
80 return;
81 }
82
83 /* release common buffer */
84 Adapter->Adapter->DmaOperations->FreeCommonBuffer(Adapter->Adapter, Length, LogicalAddress, VirtualAddress, CacheEnabled);
85 }
86
87 /*
88 * @implemented
89 */
90 VOID
91 NTAPI
92 VideoPortPutDmaAdapter(IN PVOID HwDeviceExtension,
93 IN PVP_DMA_ADAPTER VpDmaAdapter)
94 {
95 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
96 PVIP_DMA_ADAPTER Adapter = (PVIP_DMA_ADAPTER)VpDmaAdapter;
97
98 /* get hw device extension */
99 DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
100
101 /* sanity check */
102 ASSERT(!IsListEmpty(&DeviceExtension->DmaAdapterList));
103
104 /* remove dma adapter from list */
105 RemoveEntryList(&Adapter->Entry);
106
107 /* release dma adapter */
108 Adapter->Adapter->DmaOperations->PutDmaAdapter(Adapter->Adapter);
109
110 /* free memory */
111 ExFreePool(Adapter);
112 }
113
114 /*
115 * @implemented
116 */
117 PVP_DMA_ADAPTER
118 NTAPI
119 VideoPortGetDmaAdapter(IN PVOID HwDeviceExtension,
120 IN PVP_DEVICE_DESCRIPTION VpDeviceExtension)
121 {
122 DEVICE_DESCRIPTION DeviceDescription;
123 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
124 ULONG NumberOfMapRegisters;
125 PVIP_DMA_ADAPTER Adapter;
126 PDMA_ADAPTER DmaAdapter;
127
128 /* allocate private adapter structure */
129 Adapter = ExAllocatePool(NonPagedPool, sizeof(VIP_DMA_ADAPTER));
130 if (!Adapter)
131 {
132 /* failed to allocate adapter structure */
133 return NULL;
134 }
135
136 /* Zero the structure */
137 RtlZeroMemory(&DeviceDescription,
138 sizeof(DEVICE_DESCRIPTION));
139
140 /* Initialize the structure */
141 DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
142 DeviceDescription.Master = TRUE;
143 DeviceDescription.DmaWidth = Width8Bits;
144 DeviceDescription.DmaSpeed = Compatible;
145
146 /* Copy data from caller's device extension */
147 DeviceDescription.ScatterGather = VpDeviceExtension->ScatterGather;
148 DeviceDescription.Dma32BitAddresses = VpDeviceExtension->Dma32BitAddresses;
149 DeviceDescription.Dma64BitAddresses = VpDeviceExtension->Dma64BitAddresses;
150 DeviceDescription.MaximumLength = VpDeviceExtension->MaximumLength;
151
152 /* Copy data from the internal device extension */
153 DeviceDescription.BusNumber = DeviceExtension->SystemIoBusNumber;
154 DeviceDescription.InterfaceType = DeviceExtension->AdapterInterfaceType;
155
156 /* acquire dma adapter */
157 DmaAdapter = IoGetDmaAdapter(DeviceExtension->PhysicalDeviceObject, &DeviceDescription, &NumberOfMapRegisters);
158 if (!DmaAdapter)
159 {
160 /* failed to acquire dma */
161 ExFreePool(Adapter);
162 return NULL;
163 }
164
165 /* store dma adapter */
166 Adapter->Adapter = DmaAdapter;
167
168 /* store map register count */
169 Adapter->MapRegisters = NumberOfMapRegisters;
170
171 /* store hw device extension */
172 Adapter->HwDeviceExtension = HwDeviceExtension;
173
174 /* store in dma adapter list */
175 InsertTailList(&DeviceExtension->DmaAdapterList, &Adapter->Entry);
176
177 /* return result */
178 return (PVP_DMA_ADAPTER)Adapter;
179 }
180
181 /*
182 * @implemented
183 */
184 VOID
185 NTAPI
186 VideoPortFreeCommonBuffer(IN PVOID HwDeviceExtension,
187 IN ULONG Length,
188 IN PVOID VirtualAddress,
189 IN PHYSICAL_ADDRESS LogicalAddress,
190 IN BOOLEAN CacheEnabled)
191 {
192 PVIP_DMA_ADAPTER VpDmaAdapter;
193 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
194
195 /* sanity check */
196 ASSERT(!IsListEmpty(&DeviceExtension->DmaAdapterList));
197
198 /* grab first dma adapter */
199 VpDmaAdapter = (PVIP_DMA_ADAPTER)CONTAINING_RECORD(DeviceExtension->DmaAdapterList.Flink, VIP_DMA_ADAPTER, Entry);
200
201 /* sanity checks */
202 ASSERT(VpDmaAdapter->HwDeviceExtension == HwDeviceExtension);
203 ASSERT(VpDmaAdapter->Adapter != NULL);
204 ASSERT(VpDmaAdapter->MapRegisters != 0);
205
206 return VideoPortReleaseCommonBuffer(HwDeviceExtension, (PVP_DMA_ADAPTER)VpDmaAdapter, Length, LogicalAddress, VirtualAddress, CacheEnabled);
207
208 }
209
210 /*
211 * @implemented
212 */
213 PVOID
214 NTAPI
215 VideoPortGetCommonBuffer(IN PVOID HwDeviceExtension,
216 IN ULONG DesiredLength,
217 IN ULONG Alignment,
218 OUT PPHYSICAL_ADDRESS LogicalAddress,
219 OUT PULONG pActualLength,
220 IN BOOLEAN CacheEnabled)
221 {
222 PVOID Result;
223 PVIP_DMA_ADAPTER VpDmaAdapter;
224 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
225
226 /* maximum palette size */
227 if (DesiredLength > 262144)
228 {
229 /* size exceeded */
230 return NULL;
231 }
232
233 /* sanity check */
234 ASSERT(!IsListEmpty(&DeviceExtension->DmaAdapterList));
235
236 /* grab first dma adapter */
237 VpDmaAdapter = (PVIP_DMA_ADAPTER)CONTAINING_RECORD(DeviceExtension->DmaAdapterList.Flink, VIP_DMA_ADAPTER, Entry);
238
239 /* sanity checks */
240 ASSERT(VpDmaAdapter->HwDeviceExtension == HwDeviceExtension);
241 ASSERT(VpDmaAdapter->Adapter != NULL);
242 ASSERT(VpDmaAdapter->MapRegisters != 0);
243
244
245 /* allocate common buffer */
246 Result = VideoPortAllocateCommonBuffer(HwDeviceExtension, (PVP_DMA_ADAPTER)VpDmaAdapter, DesiredLength, LogicalAddress, CacheEnabled, NULL);
247
248 if (Result)
249 {
250 /* store length */
251 *pActualLength = DesiredLength;
252 }
253 else
254 {
255 /* failed to allocate common buffer */
256 *pActualLength = 0;
257 }
258
259 return Result;
260 }
261
262 /*
263 * @implemented
264 */
265 BOOLEAN
266 NTAPI
267 VideoPortUnmapDmaMemory(
268 PVOID HwDeviceExtension,
269 PVOID VirtualAddress,
270 HANDLE ProcessHandle,
271 PDMA BoardMemoryHandle)
272 {
273 /* Deprecated */
274 return FALSE;
275 }
276
277 /*
278 * @implemented
279 */
280 PDMA
281 NTAPI
282 VideoPortMapDmaMemory(IN PVOID HwDeviceExtension,
283 IN PVIDEO_REQUEST_PACKET pVrp,
284 IN PHYSICAL_ADDRESS BoardAddress,
285 IN PULONG Length,
286 IN PULONG InIoSpace,
287 IN PVOID MappedUserEvent,
288 IN PVOID DisplayDriverEvent,
289 IN OUT PVOID *VirtualAddress)
290 {
291 /* Deprecated */
292 return NULL;
293 }
294
295 /*
296 * @implemented
297 */
298 VOID
299 NTAPI
300 VideoPortSetDmaContext(IN PVOID HwDeviceExtension,
301 OUT PDMA pDma,
302 IN PVOID InstanceContext)
303 {
304 /* Deprecated */
305 return;
306 }
307
308 /*
309 * @implemented
310 */
311 BOOLEAN
312 NTAPI
313 VideoPortSignalDmaComplete(IN PVOID HwDeviceExtension,
314 IN PDMA pDmaHandle)
315 {
316 /* Deprecated */
317 return FALSE;
318 }
319
320
321 BOOLEAN
322 NTAPI
323 SyncScatterRoutine(
324 IN PVOID Context)
325 {
326 PDMA_START_CONTEXT StartContext = (PDMA_START_CONTEXT)Context;
327
328 StartContext->ExecuteDmaRoutine(StartContext->HwDeviceExtension, StartContext->VpDmaAdapter, (PVP_SCATTER_GATHER_LIST)StartContext->ScatterGatherList, StartContext->Context);
329 return TRUE;
330 }
331
332 VOID
333 NTAPI
334 ScatterAdapterControl(
335 IN PDEVICE_OBJECT *DeviceObject,
336 IN PIRP *Irp,
337 IN PSCATTER_GATHER_LIST ScatterGather,
338 IN PVOID Context)
339 {
340 PDMA_START_CONTEXT StartContext = (PDMA_START_CONTEXT)Context;
341
342 StartContext->ScatterGatherList = ScatterGather;
343
344 VideoPortSynchronizeExecution(StartContext->HwDeviceExtension, VpMediumPriority, SyncScatterRoutine, StartContext);
345 ExFreePool(StartContext);
346 }
347
348 /*
349 * @implemented
350 */
351 VP_STATUS
352 NTAPI
353 VideoPortStartDma(IN PVOID HwDeviceExtension,
354 IN PVP_DMA_ADAPTER VpDmaAdapter,
355 IN PVOID Mdl,
356 IN ULONG Offset,
357 IN OUT PULONG pLength,
358 IN PEXECUTE_DMA ExecuteDmaRoutine,
359 IN PVOID Context,
360 IN BOOLEAN WriteToDevice)
361 {
362 NTSTATUS Status;
363 KIRQL OldIrql;
364 PDMA_START_CONTEXT StartContext;
365 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
366 PVIP_DMA_ADAPTER Adapter = (PVIP_DMA_ADAPTER)VpDmaAdapter;
367
368 StartContext = ExAllocatePool(NonPagedPool, sizeof(DMA_START_CONTEXT));
369 if (!StartContext)
370 {
371 return ERROR_NOT_ENOUGH_MEMORY;
372 }
373
374 StartContext->Context = Context;
375 StartContext->ExecuteDmaRoutine = ExecuteDmaRoutine;
376 StartContext->HwDeviceExtension = HwDeviceExtension;
377 StartContext->VpDmaAdapter = VpDmaAdapter;
378
379 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
380
381 Status = Adapter->Adapter->DmaOperations->GetScatterGatherList(Adapter->Adapter,
382 DeviceExtension->PhysicalDeviceObject,
383 Mdl,
384 MmGetSystemAddressForMdl((PMDL)Mdl),
385 MmGetMdlByteCount((PMDL)Mdl),
386 (PDRIVER_LIST_CONTROL)ScatterAdapterControl,
387 StartContext,
388 WriteToDevice);
389
390 KeLowerIrql(OldIrql);
391
392 if (!NT_SUCCESS(Status))
393 {
394 *pLength = 0;
395 ExFreePool(StartContext);
396 Status = ERROR_NOT_ENOUGH_MEMORY;
397 }
398 else
399 {
400 Status = NO_ERROR;
401 }
402
403 /* Return status */
404 return Status;
405 }
406
407 /*
408 * @implemented
409 */
410 PVOID
411 NTAPI
412 VideoPortGetDmaContext(IN PVOID HwDeviceExtension,
413 IN PDMA pDma)
414 {
415 /* Deprecated */
416 return NULL;
417 }
418
419 /*
420 * @implemented
421 */
422 PDMA
423 NTAPI
424 VideoPortDoDma(IN PVOID HwDeviceExtension,
425 IN PDMA pDma,
426 IN DMA_FLAGS DmaFlags)
427 {
428 /* Deprecated */
429 return NULL;
430 }
431
432 /*
433 * @implemented
434 */
435 PDMA
436 NTAPI
437 VideoPortAssociateEventsWithDmaHandle(IN PVOID HwDeviceExtension,
438 IN OUT PVIDEO_REQUEST_PACKET pVrp,
439 IN PVOID MappedUserEvent,
440 IN PVOID DisplayDriverEvent)
441 {
442 /* Deprecated */
443 return NULL;
444 }
445
446 /*
447 * @implemented
448 */
449 VP_STATUS
450 NTAPI
451 VideoPortCompleteDma(IN PVOID HwDeviceExtension,
452 IN PVP_DMA_ADAPTER VpDmaAdapter,
453 IN PVP_SCATTER_GATHER_LIST VpScatterGather,
454 IN BOOLEAN WriteToDevice)
455 {
456 KIRQL OldIrql;
457 PVIP_DMA_ADAPTER Adapter = (PVIP_DMA_ADAPTER)VpDmaAdapter;
458
459 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
460 Adapter->Adapter->DmaOperations->PutScatterGatherList(Adapter->Adapter, (PSCATTER_GATHER_LIST)VpScatterGather, WriteToDevice);
461 KeLowerIrql(OldIrql);
462
463 return NO_ERROR;
464 }