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
9 /* INCLUDES ******************************************************************/
20 PVOID HwDeviceExtension
;
22 }VIP_DMA_ADAPTER
, *PVIP_DMA_ADAPTER
;
26 PVOID HwDeviceExtension
;
27 PSCATTER_GATHER_LIST ScatterGatherList
;
28 PEXECUTE_DMA ExecuteDmaRoutine
;
30 PVP_DMA_ADAPTER VpDmaAdapter
;
32 }DMA_START_CONTEXT
, *PDMA_START_CONTEXT
;
35 /* PUBLIC FUNCTIONS ***********************************************************/
42 VideoPortAllocateCommonBuffer(IN PVOID HwDeviceExtension
,
43 IN PVP_DMA_ADAPTER VpDmaAdapter
,
44 IN ULONG DesiredLength
,
45 OUT PPHYSICAL_ADDRESS LogicalAddress
,
46 IN BOOLEAN CacheEnabled
,
49 PVIP_DMA_ADAPTER Adapter
= (PVIP_DMA_ADAPTER
)VpDmaAdapter
;
51 /* check for valid arguments */
52 if (!Adapter
|| !Adapter
->Adapter
)
54 /* invalid parameter */
58 /* allocate common buffer */
59 return Adapter
->Adapter
->DmaOperations
->AllocateCommonBuffer(Adapter
->Adapter
, DesiredLength
, LogicalAddress
, CacheEnabled
);
67 VideoPortReleaseCommonBuffer(IN PVOID HwDeviceExtension
,
68 IN PVP_DMA_ADAPTER VpDmaAdapter
,
70 IN PHYSICAL_ADDRESS LogicalAddress
,
71 IN PVOID VirtualAddress
,
72 IN BOOLEAN CacheEnabled
)
74 PVIP_DMA_ADAPTER Adapter
= (PVIP_DMA_ADAPTER
)VpDmaAdapter
;
76 /* check for valid arguments */
77 if (!Adapter
|| !Adapter
->Adapter
)
79 /* invalid parameter */
83 /* release common buffer */
84 Adapter
->Adapter
->DmaOperations
->FreeCommonBuffer(Adapter
->Adapter
, Length
, LogicalAddress
, VirtualAddress
, CacheEnabled
);
92 VideoPortPutDmaAdapter(IN PVOID HwDeviceExtension
,
93 IN PVP_DMA_ADAPTER VpDmaAdapter
)
95 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
96 PVIP_DMA_ADAPTER Adapter
= (PVIP_DMA_ADAPTER
)VpDmaAdapter
;
98 /* get hw device extension */
99 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
102 ASSERT(!IsListEmpty(&DeviceExtension
->DmaAdapterList
));
104 /* remove dma adapter from list */
105 RemoveEntryList(&Adapter
->Entry
);
107 /* release dma adapter */
108 Adapter
->Adapter
->DmaOperations
->PutDmaAdapter(Adapter
->Adapter
);
119 VideoPortGetDmaAdapter(IN PVOID HwDeviceExtension
,
120 IN PVP_DEVICE_DESCRIPTION VpDeviceExtension
)
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
;
128 /* allocate private adapter structure */
129 Adapter
= ExAllocatePool(NonPagedPool
, sizeof(VIP_DMA_ADAPTER
));
132 /* failed to allocate adapter structure */
136 /* Zero the structure */
137 RtlZeroMemory(&DeviceDescription
,
138 sizeof(DEVICE_DESCRIPTION
));
140 /* Initialize the structure */
141 DeviceDescription
.Version
= DEVICE_DESCRIPTION_VERSION
;
142 DeviceDescription
.Master
= TRUE
;
143 DeviceDescription
.DmaWidth
= Width8Bits
;
144 DeviceDescription
.DmaSpeed
= Compatible
;
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
;
152 /* Copy data from the internal device extension */
153 DeviceDescription
.BusNumber
= DeviceExtension
->SystemIoBusNumber
;
154 DeviceDescription
.InterfaceType
= DeviceExtension
->AdapterInterfaceType
;
156 /* acquire dma adapter */
157 DmaAdapter
= IoGetDmaAdapter(DeviceExtension
->PhysicalDeviceObject
, &DeviceDescription
, &NumberOfMapRegisters
);
160 /* failed to acquire dma */
165 /* store dma adapter */
166 Adapter
->Adapter
= DmaAdapter
;
168 /* store map register count */
169 Adapter
->MapRegisters
= NumberOfMapRegisters
;
171 /* store hw device extension */
172 Adapter
->HwDeviceExtension
= HwDeviceExtension
;
174 /* store in dma adapter list */
175 InsertTailList(&DeviceExtension
->DmaAdapterList
, &Adapter
->Entry
);
178 return (PVP_DMA_ADAPTER
)Adapter
;
186 VideoPortFreeCommonBuffer(IN PVOID HwDeviceExtension
,
188 IN PVOID VirtualAddress
,
189 IN PHYSICAL_ADDRESS LogicalAddress
,
190 IN BOOLEAN CacheEnabled
)
192 PVIP_DMA_ADAPTER VpDmaAdapter
;
193 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
196 ASSERT(!IsListEmpty(&DeviceExtension
->DmaAdapterList
));
198 /* grab first dma adapter */
199 VpDmaAdapter
= (PVIP_DMA_ADAPTER
)CONTAINING_RECORD(DeviceExtension
->DmaAdapterList
.Flink
, VIP_DMA_ADAPTER
, Entry
);
202 ASSERT(VpDmaAdapter
->HwDeviceExtension
== HwDeviceExtension
);
203 ASSERT(VpDmaAdapter
->Adapter
!= NULL
);
204 ASSERT(VpDmaAdapter
->MapRegisters
!= 0);
206 VideoPortReleaseCommonBuffer(HwDeviceExtension
, (PVP_DMA_ADAPTER
)VpDmaAdapter
, Length
, LogicalAddress
, VirtualAddress
, CacheEnabled
);
214 VideoPortGetCommonBuffer(IN PVOID HwDeviceExtension
,
215 IN ULONG DesiredLength
,
217 OUT PPHYSICAL_ADDRESS LogicalAddress
,
218 OUT PULONG pActualLength
,
219 IN BOOLEAN CacheEnabled
)
222 PVIP_DMA_ADAPTER VpDmaAdapter
;
223 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
225 /* maximum palette size */
226 if (DesiredLength
> 262144)
233 ASSERT(!IsListEmpty(&DeviceExtension
->DmaAdapterList
));
235 /* grab first dma adapter */
236 VpDmaAdapter
= (PVIP_DMA_ADAPTER
)CONTAINING_RECORD(DeviceExtension
->DmaAdapterList
.Flink
, VIP_DMA_ADAPTER
, Entry
);
239 ASSERT(VpDmaAdapter
->HwDeviceExtension
== HwDeviceExtension
);
240 ASSERT(VpDmaAdapter
->Adapter
!= NULL
);
241 ASSERT(VpDmaAdapter
->MapRegisters
!= 0);
244 /* allocate common buffer */
245 Result
= VideoPortAllocateCommonBuffer(HwDeviceExtension
, (PVP_DMA_ADAPTER
)VpDmaAdapter
, DesiredLength
, LogicalAddress
, CacheEnabled
, NULL
);
250 *pActualLength
= DesiredLength
;
254 /* failed to allocate common buffer */
266 VideoPortUnmapDmaMemory(
267 PVOID HwDeviceExtension
,
268 PVOID VirtualAddress
,
269 HANDLE ProcessHandle
,
270 PDMA BoardMemoryHandle
)
281 VideoPortMapDmaMemory(IN PVOID HwDeviceExtension
,
282 IN PVIDEO_REQUEST_PACKET pVrp
,
283 IN PHYSICAL_ADDRESS BoardAddress
,
286 IN PVOID MappedUserEvent
,
287 IN PVOID DisplayDriverEvent
,
288 IN OUT PVOID
*VirtualAddress
)
299 VideoPortSetDmaContext(IN PVOID HwDeviceExtension
,
301 IN PVOID InstanceContext
)
312 VideoPortSignalDmaComplete(IN PVOID HwDeviceExtension
,
325 PDMA_START_CONTEXT StartContext
= (PDMA_START_CONTEXT
)Context
;
327 StartContext
->ExecuteDmaRoutine(StartContext
->HwDeviceExtension
, StartContext
->VpDmaAdapter
, (PVP_SCATTER_GATHER_LIST
)StartContext
->ScatterGatherList
, StartContext
->Context
);
333 ScatterAdapterControl(
334 IN PDEVICE_OBJECT
*DeviceObject
,
336 IN PSCATTER_GATHER_LIST ScatterGather
,
339 PDMA_START_CONTEXT StartContext
= (PDMA_START_CONTEXT
)Context
;
341 StartContext
->ScatterGatherList
= ScatterGather
;
343 VideoPortSynchronizeExecution(StartContext
->HwDeviceExtension
, VpMediumPriority
, SyncScatterRoutine
, StartContext
);
344 ExFreePool(StartContext
);
352 VideoPortStartDma(IN PVOID HwDeviceExtension
,
353 IN PVP_DMA_ADAPTER VpDmaAdapter
,
356 IN OUT PULONG pLength
,
357 IN PEXECUTE_DMA ExecuteDmaRoutine
,
359 IN BOOLEAN WriteToDevice
)
363 PDMA_START_CONTEXT StartContext
;
364 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
365 PVIP_DMA_ADAPTER Adapter
= (PVIP_DMA_ADAPTER
)VpDmaAdapter
;
367 StartContext
= ExAllocatePool(NonPagedPool
, sizeof(DMA_START_CONTEXT
));
370 return ERROR_NOT_ENOUGH_MEMORY
;
373 StartContext
->Context
= Context
;
374 StartContext
->ExecuteDmaRoutine
= ExecuteDmaRoutine
;
375 StartContext
->HwDeviceExtension
= HwDeviceExtension
;
376 StartContext
->VpDmaAdapter
= VpDmaAdapter
;
378 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
380 Status
= Adapter
->Adapter
->DmaOperations
->GetScatterGatherList(Adapter
->Adapter
,
381 DeviceExtension
->PhysicalDeviceObject
,
383 MmGetSystemAddressForMdl((PMDL
)Mdl
),
384 MmGetMdlByteCount((PMDL
)Mdl
),
385 (PDRIVER_LIST_CONTROL
)ScatterAdapterControl
,
389 KeLowerIrql(OldIrql
);
391 if (!NT_SUCCESS(Status
))
394 ExFreePool(StartContext
);
395 Status
= ERROR_NOT_ENOUGH_MEMORY
;
411 VideoPortGetDmaContext(IN PVOID HwDeviceExtension
,
423 VideoPortDoDma(IN PVOID HwDeviceExtension
,
425 IN DMA_FLAGS DmaFlags
)
436 VideoPortAssociateEventsWithDmaHandle(IN PVOID HwDeviceExtension
,
437 IN OUT PVIDEO_REQUEST_PACKET pVrp
,
438 IN PVOID MappedUserEvent
,
439 IN PVOID DisplayDriverEvent
)
450 VideoPortCompleteDma(IN PVOID HwDeviceExtension
,
451 IN PVP_DMA_ADAPTER VpDmaAdapter
,
452 IN PVP_SCATTER_GATHER_LIST VpScatterGather
,
453 IN BOOLEAN WriteToDevice
)
456 PVIP_DMA_ADAPTER Adapter
= (PVIP_DMA_ADAPTER
)VpDmaAdapter
;
458 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
459 Adapter
->Adapter
->DmaOperations
->PutScatterGatherList(Adapter
->Adapter
, (PSCATTER_GATHER_LIST
)VpScatterGather
, WriteToDevice
);
460 KeLowerIrql(OldIrql
);