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 return VideoPortReleaseCommonBuffer(HwDeviceExtension
, (PVP_DMA_ADAPTER
)VpDmaAdapter
, Length
, LogicalAddress
, VirtualAddress
, CacheEnabled
);
215 VideoPortGetCommonBuffer(IN PVOID HwDeviceExtension
,
216 IN ULONG DesiredLength
,
218 OUT PPHYSICAL_ADDRESS LogicalAddress
,
219 OUT PULONG pActualLength
,
220 IN BOOLEAN CacheEnabled
)
223 PVIP_DMA_ADAPTER VpDmaAdapter
;
224 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
226 /* maximum palette size */
227 if (DesiredLength
> 262144)
234 ASSERT(!IsListEmpty(&DeviceExtension
->DmaAdapterList
));
236 /* grab first dma adapter */
237 VpDmaAdapter
= (PVIP_DMA_ADAPTER
)CONTAINING_RECORD(DeviceExtension
->DmaAdapterList
.Flink
, VIP_DMA_ADAPTER
, Entry
);
240 ASSERT(VpDmaAdapter
->HwDeviceExtension
== HwDeviceExtension
);
241 ASSERT(VpDmaAdapter
->Adapter
!= NULL
);
242 ASSERT(VpDmaAdapter
->MapRegisters
!= 0);
245 /* allocate common buffer */
246 Result
= VideoPortAllocateCommonBuffer(HwDeviceExtension
, (PVP_DMA_ADAPTER
)VpDmaAdapter
, DesiredLength
, LogicalAddress
, CacheEnabled
, NULL
);
251 *pActualLength
= DesiredLength
;
255 /* failed to allocate common buffer */
267 VideoPortUnmapDmaMemory(
268 PVOID HwDeviceExtension
,
269 PVOID VirtualAddress
,
270 HANDLE ProcessHandle
,
271 PDMA BoardMemoryHandle
)
282 VideoPortMapDmaMemory(IN PVOID HwDeviceExtension
,
283 IN PVIDEO_REQUEST_PACKET pVrp
,
284 IN PHYSICAL_ADDRESS BoardAddress
,
287 IN PVOID MappedUserEvent
,
288 IN PVOID DisplayDriverEvent
,
289 IN OUT PVOID
*VirtualAddress
)
300 VideoPortSetDmaContext(IN PVOID HwDeviceExtension
,
302 IN PVOID InstanceContext
)
313 VideoPortSignalDmaComplete(IN PVOID HwDeviceExtension
,
326 PDMA_START_CONTEXT StartContext
= (PDMA_START_CONTEXT
)Context
;
328 StartContext
->ExecuteDmaRoutine(StartContext
->HwDeviceExtension
, StartContext
->VpDmaAdapter
, (PVP_SCATTER_GATHER_LIST
)StartContext
->ScatterGatherList
, StartContext
->Context
);
334 ScatterAdapterControl(
335 IN PDEVICE_OBJECT
*DeviceObject
,
337 IN PSCATTER_GATHER_LIST ScatterGather
,
340 PDMA_START_CONTEXT StartContext
= (PDMA_START_CONTEXT
)Context
;
342 StartContext
->ScatterGatherList
= ScatterGather
;
344 VideoPortSynchronizeExecution(StartContext
->HwDeviceExtension
, VpMediumPriority
, SyncScatterRoutine
, StartContext
);
345 ExFreePool(StartContext
);
353 VideoPortStartDma(IN PVOID HwDeviceExtension
,
354 IN PVP_DMA_ADAPTER VpDmaAdapter
,
357 IN OUT PULONG pLength
,
358 IN PEXECUTE_DMA ExecuteDmaRoutine
,
360 IN BOOLEAN WriteToDevice
)
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
;
368 StartContext
= ExAllocatePool(NonPagedPool
, sizeof(DMA_START_CONTEXT
));
371 return ERROR_NOT_ENOUGH_MEMORY
;
374 StartContext
->Context
= Context
;
375 StartContext
->ExecuteDmaRoutine
= ExecuteDmaRoutine
;
376 StartContext
->HwDeviceExtension
= HwDeviceExtension
;
377 StartContext
->VpDmaAdapter
= VpDmaAdapter
;
379 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
381 Status
= Adapter
->Adapter
->DmaOperations
->GetScatterGatherList(Adapter
->Adapter
,
382 DeviceExtension
->PhysicalDeviceObject
,
384 MmGetSystemAddressForMdl((PMDL
)Mdl
),
385 MmGetMdlByteCount((PMDL
)Mdl
),
386 (PDRIVER_LIST_CONTROL
)ScatterAdapterControl
,
390 KeLowerIrql(OldIrql
);
392 if (!NT_SUCCESS(Status
))
395 ExFreePool(StartContext
);
396 Status
= ERROR_NOT_ENOUGH_MEMORY
;
412 VideoPortGetDmaContext(IN PVOID HwDeviceExtension
,
424 VideoPortDoDma(IN PVOID HwDeviceExtension
,
426 IN DMA_FLAGS DmaFlags
)
437 VideoPortAssociateEventsWithDmaHandle(IN PVOID HwDeviceExtension
,
438 IN OUT PVIDEO_REQUEST_PACKET pVrp
,
439 IN PVOID MappedUserEvent
,
440 IN PVOID DisplayDriverEvent
)
451 VideoPortCompleteDma(IN PVOID HwDeviceExtension
,
452 IN PVP_DMA_ADAPTER VpDmaAdapter
,
453 IN PVP_SCATTER_GATHER_LIST VpScatterGather
,
454 IN BOOLEAN WriteToDevice
)
457 PVIP_DMA_ADAPTER Adapter
= (PVIP_DMA_ADAPTER
)VpDmaAdapter
;
459 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
460 Adapter
->Adapter
->DmaOperations
->PutScatterGatherList(Adapter
->Adapter
, (PSCATTER_GATHER_LIST
)VpScatterGather
, WriteToDevice
);
461 KeLowerIrql(OldIrql
);