Sync with trunk (r48123)
[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 PDMA_ADAPTER Adapter;
18 ULONG MapRegisters;
19
20 }VIP_DMA_ADAPTER, *PVIP_DMA_ADAPTER;
21
22 typedef struct
23 {
24 PVOID HwDeviceExtension;
25 PSCATTER_GATHER_LIST ScatterGatherList;
26 PEXECUTE_DMA ExecuteDmaRoutine;
27 PVOID Context;
28 PVP_DMA_ADAPTER VpDmaAdapter;
29
30 }DMA_START_CONTEXT, *PDMA_START_CONTEXT;
31
32
33 /* PUBLIC FUNCTIONS ***********************************************************/
34
35 /*
36 * @implemented
37 */
38 PVOID
39 NTAPI
40 VideoPortAllocateCommonBuffer(IN PVOID HwDeviceExtension,
41 IN PVP_DMA_ADAPTER VpDmaAdapter,
42 IN ULONG DesiredLength,
43 OUT PPHYSICAL_ADDRESS LogicalAddress,
44 IN BOOLEAN CacheEnabled,
45 PVOID Reserved)
46 {
47 PVIP_DMA_ADAPTER Adapter = (PVIP_DMA_ADAPTER)VpDmaAdapter;
48
49
50 return Adapter->Adapter->DmaOperations->AllocateCommonBuffer(Adapter->Adapter, DesiredLength, LogicalAddress, CacheEnabled);
51 }
52
53 /*
54 * @implemented
55 */
56 VOID
57 NTAPI
58 VideoPortReleaseCommonBuffer(IN PVOID HwDeviceExtension,
59 IN PVP_DMA_ADAPTER VpDmaAdapter,
60 IN ULONG Length,
61 IN PHYSICAL_ADDRESS LogicalAddress,
62 IN PVOID VirtualAddress,
63 IN BOOLEAN CacheEnabled)
64 {
65 PVIP_DMA_ADAPTER Adapter = (PVIP_DMA_ADAPTER)VpDmaAdapter;
66
67 Adapter->Adapter->DmaOperations->FreeCommonBuffer(Adapter->Adapter, Length, LogicalAddress, VirtualAddress, CacheEnabled);
68 }
69
70 /*
71 * @implemented
72 */
73 VOID
74 NTAPI
75 VideoPortPutDmaAdapter(IN PVOID HwDeviceExtension,
76 IN PVP_DMA_ADAPTER VpDmaAdapter)
77 {
78 PVIP_DMA_ADAPTER Adapter = (PVIP_DMA_ADAPTER)VpDmaAdapter;
79
80 Adapter->Adapter->DmaOperations->PutDmaAdapter(Adapter->Adapter);
81 ExFreePool(Adapter);
82 }
83
84 /*
85 * @implemented
86 */
87 PVP_DMA_ADAPTER
88 NTAPI
89 VideoPortGetDmaAdapter(IN PVOID HwDeviceExtension,
90 IN PVP_DEVICE_DESCRIPTION VpDeviceExtension)
91 {
92 DEVICE_DESCRIPTION DeviceDescription;
93 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
94 ULONG NumberOfMapRegisters;
95 PVIP_DMA_ADAPTER Adapter;
96 PDMA_ADAPTER DmaAdapter;
97
98 /* Zero the structure */
99 RtlZeroMemory(&DeviceDescription,
100 sizeof(DEVICE_DESCRIPTION));
101
102 /* Initialize the structure */
103 DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
104 DeviceDescription.Master = TRUE /* ?? */;
105 DeviceDescription.DmaWidth = Width8Bits;
106 DeviceDescription.DmaSpeed = Compatible;
107
108 /* Copy data from caller's device extension */
109 DeviceDescription.ScatterGather = VpDeviceExtension->ScatterGather;
110 DeviceDescription.Dma32BitAddresses = VpDeviceExtension->Dma32BitAddresses;
111 DeviceDescription.Dma64BitAddresses = VpDeviceExtension->Dma64BitAddresses;
112 DeviceDescription.MaximumLength = VpDeviceExtension->MaximumLength;
113
114 /* Copy data from the internal device extension */
115 DeviceDescription.BusNumber = DeviceExtension->SystemIoBusNumber;
116 DeviceDescription.InterfaceType = DeviceExtension->AdapterInterfaceType;
117
118 Adapter = ExAllocatePool(NonPagedPool, sizeof(VIP_DMA_ADAPTER));
119 if (!Adapter)
120 return NULL;
121
122
123 DmaAdapter = IoGetDmaAdapter(DeviceExtension->PhysicalDeviceObject, &DeviceDescription, &NumberOfMapRegisters);
124 if (!DmaAdapter)
125 {
126 ExFreePool(Adapter);
127 return NULL;
128 }
129
130 Adapter->Adapter = DmaAdapter;
131 Adapter->MapRegisters = NumberOfMapRegisters;
132
133 return (PVP_DMA_ADAPTER)Adapter;
134 }
135
136 /*
137 * @implemented
138 */
139 VOID
140 NTAPI
141 VideoPortFreeCommonBuffer(IN PVOID HwDeviceExtension,
142 IN ULONG Length,
143 IN PVOID VirtualAddress,
144 IN PHYSICAL_ADDRESS LogicalAddress,
145 IN BOOLEAN CacheEnabled)
146 {
147 DEVICE_DESCRIPTION DeviceDescription;
148 PVP_DMA_ADAPTER VpDmaAdapter;
149
150 /* FIXME: Broken code*/
151 VpDmaAdapter = VideoPortGetDmaAdapter(HwDeviceExtension,
152 (PVP_DEVICE_DESCRIPTION)&DeviceDescription);
153 HalFreeCommonBuffer((PADAPTER_OBJECT)VpDmaAdapter,
154 Length,
155 LogicalAddress,
156 VirtualAddress,
157 CacheEnabled);
158 }
159
160 /*
161 * @unimplemented
162 */
163 PVOID
164 NTAPI
165 VideoPortGetCommonBuffer(IN PVOID HwDeviceExtension,
166 IN ULONG DesiredLength,
167 IN ULONG Alignment,
168 OUT PPHYSICAL_ADDRESS LogicalAddress,
169 OUT PULONG pActualLength,
170 IN BOOLEAN CacheEnabled)
171 {
172 UNIMPLEMENTED;
173 return NULL;
174 }
175
176 /*
177 * @implemented
178 */
179 BOOLEAN
180 NTAPI
181 VideoPortUnmapDmaMemory(
182 PVOID HwDeviceExtension,
183 PVOID VirtualAddress,
184 HANDLE ProcessHandle,
185 PDMA BoardMemoryHandle)
186 {
187 /* Deprecated */
188 return FALSE;
189 }
190
191 /*
192 * @implemented
193 */
194 PDMA
195 NTAPI
196 VideoPortMapDmaMemory(IN PVOID HwDeviceExtension,
197 IN PVIDEO_REQUEST_PACKET pVrp,
198 IN PHYSICAL_ADDRESS BoardAddress,
199 IN PULONG Length,
200 IN PULONG InIoSpace,
201 IN PVOID MappedUserEvent,
202 IN PVOID DisplayDriverEvent,
203 IN OUT PVOID *VirtualAddress)
204 {
205 /* Deprecated */
206 return NULL;
207 }
208
209 /*
210 * @implemented
211 */
212 VOID
213 NTAPI
214 VideoPortSetDmaContext(IN PVOID HwDeviceExtension,
215 OUT PDMA pDma,
216 IN PVOID InstanceContext)
217 {
218 /* Deprecated */
219 return;
220 }
221
222 /*
223 * @implemented
224 */
225 BOOLEAN
226 NTAPI
227 VideoPortSignalDmaComplete(IN PVOID HwDeviceExtension,
228 IN PDMA pDmaHandle)
229 {
230 /* Deprecated */
231 return FALSE;
232 }
233
234
235 BOOLEAN
236 NTAPI
237 SyncScatterRoutine(
238 IN PVOID Context)
239 {
240 PDMA_START_CONTEXT StartContext = (PDMA_START_CONTEXT)Context;
241
242 StartContext->ExecuteDmaRoutine(StartContext->HwDeviceExtension, StartContext->VpDmaAdapter, (PVP_SCATTER_GATHER_LIST)StartContext->ScatterGatherList, StartContext->Context);
243 return TRUE;
244 }
245
246 VOID
247 NTAPI
248 ScatterAdapterControl(
249 IN PDEVICE_OBJECT *DeviceObject,
250 IN PIRP *Irp,
251 IN PSCATTER_GATHER_LIST ScatterGather,
252 IN PVOID Context)
253 {
254 PDMA_START_CONTEXT StartContext = (PDMA_START_CONTEXT)Context;
255
256 StartContext->ScatterGatherList = ScatterGather;
257
258 VideoPortSynchronizeExecution(StartContext->HwDeviceExtension, VpMediumPriority, SyncScatterRoutine, StartContext);
259 ExFreePool(StartContext);
260 }
261
262 /*
263 * @implemented
264 */
265 VP_STATUS
266 NTAPI
267 VideoPortStartDma(IN PVOID HwDeviceExtension,
268 IN PVP_DMA_ADAPTER VpDmaAdapter,
269 IN PVOID Mdl,
270 IN ULONG Offset,
271 IN OUT PULONG pLength,
272 IN PEXECUTE_DMA ExecuteDmaRoutine,
273 IN PVOID Context,
274 IN BOOLEAN WriteToDevice)
275 {
276 NTSTATUS Status;
277 KIRQL OldIrql;
278 PDMA_START_CONTEXT StartContext;
279 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
280 PVIP_DMA_ADAPTER Adapter = (PVIP_DMA_ADAPTER)VpDmaAdapter;
281
282 StartContext = ExAllocatePool(NonPagedPool, sizeof(DMA_START_CONTEXT));
283 if (!StartContext)
284 {
285 return ERROR_NOT_ENOUGH_MEMORY;
286 }
287
288 StartContext->Context = Context;
289 StartContext->ExecuteDmaRoutine = ExecuteDmaRoutine;
290 StartContext->HwDeviceExtension = HwDeviceExtension;
291 StartContext->VpDmaAdapter = VpDmaAdapter;
292
293 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
294
295 Status = Adapter->Adapter->DmaOperations->GetScatterGatherList(Adapter->Adapter,
296 DeviceExtension->PhysicalDeviceObject,
297 Mdl,
298 MmGetSystemAddressForMdl((PMDL)Mdl),
299 MmGetMdlByteCount((PMDL)Mdl),
300 (PDRIVER_LIST_CONTROL)ScatterAdapterControl,
301 StartContext,
302 WriteToDevice);
303
304 KeLowerIrql(OldIrql);
305
306 if (!NT_SUCCESS(Status))
307 {
308 *pLength = 0;
309 ExFreePool(StartContext);
310 Status = ERROR_NOT_ENOUGH_MEMORY;
311 }
312 else
313 {
314 Status = NO_ERROR;
315 }
316
317 /* Return status */
318 return Status;
319 }
320
321 /*
322 * @implemented
323 */
324 PVOID
325 NTAPI
326 VideoPortGetDmaContext(IN PVOID HwDeviceExtension,
327 IN PDMA pDma)
328 {
329 /* Deprecated */
330 return NULL;
331 }
332
333 /*
334 * @implemented
335 */
336 PDMA
337 NTAPI
338 VideoPortDoDma(IN PVOID HwDeviceExtension,
339 IN PDMA pDma,
340 IN DMA_FLAGS DmaFlags)
341 {
342 /* Deprecated */
343 return NULL;
344 }
345
346 /*
347 * @unimplemented
348 */
349 PDMA
350 NTAPI
351 VideoPortAssociateEventsWithDmaHandle(IN PVOID HwDeviceExtension,
352 IN OUT PVIDEO_REQUEST_PACKET pVrp,
353 IN PVOID MappedUserEvent,
354 IN PVOID DisplayDriverEvent)
355 {
356 UNIMPLEMENTED;
357 return NULL;
358 }
359
360 /*
361 * @implemented
362 */
363 VP_STATUS
364 NTAPI
365 VideoPortCompleteDma(IN PVOID HwDeviceExtension,
366 IN PVP_DMA_ADAPTER VpDmaAdapter,
367 IN PVP_SCATTER_GATHER_LIST VpScatterGather,
368 IN BOOLEAN WriteToDevice)
369 {
370 KIRQL OldIrql;
371 PVIP_DMA_ADAPTER Adapter = (PVIP_DMA_ADAPTER)VpDmaAdapter;
372
373 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
374 Adapter->Adapter->DmaOperations->PutScatterGatherList(Adapter->Adapter, (PSCATTER_GATHER_LIST)VpScatterGather, WriteToDevice);
375 KeLowerIrql(OldIrql);
376
377 return NO_ERROR;
378 }