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 ******************************************************************/
21 PVOID HwDeviceExtension
;
23 }VIP_DMA_ADAPTER
, *PVIP_DMA_ADAPTER
;
27 PVOID HwDeviceExtension
;
28 PSCATTER_GATHER_LIST ScatterGatherList
;
29 PEXECUTE_DMA ExecuteDmaRoutine
;
31 PVP_DMA_ADAPTER VpDmaAdapter
;
33 }DMA_START_CONTEXT
, *PDMA_START_CONTEXT
;
36 /* PUBLIC FUNCTIONS ***********************************************************/
43 VideoPortAllocateCommonBuffer(IN PVOID HwDeviceExtension
,
44 IN PVP_DMA_ADAPTER VpDmaAdapter
,
45 IN ULONG DesiredLength
,
46 OUT PPHYSICAL_ADDRESS LogicalAddress
,
47 IN BOOLEAN CacheEnabled
,
50 PVIP_DMA_ADAPTER Adapter
= (PVIP_DMA_ADAPTER
)VpDmaAdapter
;
52 /* check for valid arguments */
53 if (!Adapter
|| !Adapter
->Adapter
)
55 /* invalid parameter */
59 /* allocate common buffer */
60 return Adapter
->Adapter
->DmaOperations
->AllocateCommonBuffer(Adapter
->Adapter
, DesiredLength
, LogicalAddress
, CacheEnabled
);
68 VideoPortReleaseCommonBuffer(IN PVOID HwDeviceExtension
,
69 IN PVP_DMA_ADAPTER VpDmaAdapter
,
71 IN PHYSICAL_ADDRESS LogicalAddress
,
72 IN PVOID VirtualAddress
,
73 IN BOOLEAN CacheEnabled
)
75 PVIP_DMA_ADAPTER Adapter
= (PVIP_DMA_ADAPTER
)VpDmaAdapter
;
77 /* check for valid arguments */
78 if (!Adapter
|| !Adapter
->Adapter
)
80 /* invalid parameter */
84 /* release common buffer */
85 Adapter
->Adapter
->DmaOperations
->FreeCommonBuffer(Adapter
->Adapter
, Length
, LogicalAddress
, VirtualAddress
, CacheEnabled
);
93 VideoPortPutDmaAdapter(IN PVOID HwDeviceExtension
,
94 IN PVP_DMA_ADAPTER VpDmaAdapter
)
96 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
97 PVIP_DMA_ADAPTER Adapter
= (PVIP_DMA_ADAPTER
)VpDmaAdapter
;
99 /* get hw device extension */
100 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
103 ASSERT(!IsListEmpty(&DeviceExtension
->DmaAdapterList
));
105 /* remove dma adapter from list */
106 RemoveEntryList(&Adapter
->Entry
);
108 /* release dma adapter */
109 Adapter
->Adapter
->DmaOperations
->PutDmaAdapter(Adapter
->Adapter
);
120 VideoPortGetDmaAdapter(IN PVOID HwDeviceExtension
,
121 IN PVP_DEVICE_DESCRIPTION VpDeviceExtension
)
123 DEVICE_DESCRIPTION DeviceDescription
;
124 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
125 ULONG NumberOfMapRegisters
;
126 PVIP_DMA_ADAPTER Adapter
;
127 PDMA_ADAPTER DmaAdapter
;
129 /* allocate private adapter structure */
130 Adapter
= ExAllocatePool(NonPagedPool
, sizeof(VIP_DMA_ADAPTER
));
133 /* failed to allocate adapter structure */
137 /* Zero the structure */
138 RtlZeroMemory(&DeviceDescription
,
139 sizeof(DEVICE_DESCRIPTION
));
141 /* Initialize the structure */
142 DeviceDescription
.Version
= DEVICE_DESCRIPTION_VERSION
;
143 DeviceDescription
.Master
= TRUE
;
144 DeviceDescription
.DmaWidth
= Width8Bits
;
145 DeviceDescription
.DmaSpeed
= Compatible
;
147 /* Copy data from caller's device extension */
148 DeviceDescription
.ScatterGather
= VpDeviceExtension
->ScatterGather
;
149 DeviceDescription
.Dma32BitAddresses
= VpDeviceExtension
->Dma32BitAddresses
;
150 DeviceDescription
.Dma64BitAddresses
= VpDeviceExtension
->Dma64BitAddresses
;
151 DeviceDescription
.MaximumLength
= VpDeviceExtension
->MaximumLength
;
153 /* Copy data from the internal device extension */
154 DeviceDescription
.BusNumber
= DeviceExtension
->SystemIoBusNumber
;
155 DeviceDescription
.InterfaceType
= DeviceExtension
->AdapterInterfaceType
;
157 /* acquire dma adapter */
158 DmaAdapter
= IoGetDmaAdapter(DeviceExtension
->PhysicalDeviceObject
, &DeviceDescription
, &NumberOfMapRegisters
);
161 /* failed to acquire dma */
166 /* store dma adapter */
167 Adapter
->Adapter
= DmaAdapter
;
169 /* store map register count */
170 Adapter
->MapRegisters
= NumberOfMapRegisters
;
172 /* store hw device extension */
173 Adapter
->HwDeviceExtension
= HwDeviceExtension
;
175 /* store in dma adapter list */
176 InsertTailList(&DeviceExtension
->DmaAdapterList
, &Adapter
->Entry
);
179 return (PVP_DMA_ADAPTER
)Adapter
;
187 VideoPortFreeCommonBuffer(IN PVOID HwDeviceExtension
,
189 IN PVOID VirtualAddress
,
190 IN PHYSICAL_ADDRESS LogicalAddress
,
191 IN BOOLEAN CacheEnabled
)
193 PVIP_DMA_ADAPTER VpDmaAdapter
;
194 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
197 ASSERT(!IsListEmpty(&DeviceExtension
->DmaAdapterList
));
199 /* grab first dma adapter */
200 VpDmaAdapter
= (PVIP_DMA_ADAPTER
)CONTAINING_RECORD(DeviceExtension
->DmaAdapterList
.Flink
, VIP_DMA_ADAPTER
, Entry
);
203 ASSERT(VpDmaAdapter
->HwDeviceExtension
== HwDeviceExtension
);
204 ASSERT(VpDmaAdapter
->Adapter
!= NULL
);
205 ASSERT(VpDmaAdapter
->MapRegisters
!= 0);
207 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)
233 if (IsListEmpty(&DeviceExtension
->DmaAdapterList
))
235 /* no adapter available */
239 /* grab first dma adapter */
240 VpDmaAdapter
= (PVIP_DMA_ADAPTER
)CONTAINING_RECORD(DeviceExtension
->DmaAdapterList
.Flink
, VIP_DMA_ADAPTER
, Entry
);
243 ASSERT(VpDmaAdapter
->HwDeviceExtension
== HwDeviceExtension
);
244 ASSERT(VpDmaAdapter
->Adapter
!= NULL
);
245 ASSERT(VpDmaAdapter
->MapRegisters
!= 0);
247 /* allocate common buffer */
248 Result
= VideoPortAllocateCommonBuffer(HwDeviceExtension
, (PVP_DMA_ADAPTER
)VpDmaAdapter
, DesiredLength
, LogicalAddress
, CacheEnabled
, NULL
);
253 *pActualLength
= DesiredLength
;
257 /* failed to allocate common buffer */
269 VideoPortUnmapDmaMemory(
270 PVOID HwDeviceExtension
,
271 PVOID VirtualAddress
,
272 HANDLE ProcessHandle
,
273 PDMA BoardMemoryHandle
)
284 VideoPortMapDmaMemory(IN PVOID HwDeviceExtension
,
285 IN PVIDEO_REQUEST_PACKET pVrp
,
286 IN PHYSICAL_ADDRESS BoardAddress
,
289 IN PVOID MappedUserEvent
,
290 IN PVOID DisplayDriverEvent
,
291 IN OUT PVOID
*VirtualAddress
)
302 VideoPortSetDmaContext(IN PVOID HwDeviceExtension
,
304 IN PVOID InstanceContext
)
315 VideoPortSignalDmaComplete(IN PVOID HwDeviceExtension
,
328 PDMA_START_CONTEXT StartContext
= (PDMA_START_CONTEXT
)Context
;
330 StartContext
->ExecuteDmaRoutine(StartContext
->HwDeviceExtension
, StartContext
->VpDmaAdapter
, (PVP_SCATTER_GATHER_LIST
)StartContext
->ScatterGatherList
, StartContext
->Context
);
336 ScatterAdapterControl(
337 IN PDEVICE_OBJECT
*DeviceObject
,
339 IN PSCATTER_GATHER_LIST ScatterGather
,
342 PDMA_START_CONTEXT StartContext
= (PDMA_START_CONTEXT
)Context
;
344 StartContext
->ScatterGatherList
= ScatterGather
;
346 VideoPortSynchronizeExecution(StartContext
->HwDeviceExtension
, VpMediumPriority
, SyncScatterRoutine
, StartContext
);
347 ExFreePool(StartContext
);
355 VideoPortStartDma(IN PVOID HwDeviceExtension
,
356 IN PVP_DMA_ADAPTER VpDmaAdapter
,
359 IN OUT PULONG pLength
,
360 IN PEXECUTE_DMA ExecuteDmaRoutine
,
362 IN BOOLEAN WriteToDevice
)
366 PDMA_START_CONTEXT StartContext
;
367 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
368 PVIP_DMA_ADAPTER Adapter
= (PVIP_DMA_ADAPTER
)VpDmaAdapter
;
370 StartContext
= ExAllocatePool(NonPagedPool
, sizeof(DMA_START_CONTEXT
));
373 return ERROR_NOT_ENOUGH_MEMORY
;
376 StartContext
->Context
= Context
;
377 StartContext
->ExecuteDmaRoutine
= ExecuteDmaRoutine
;
378 StartContext
->HwDeviceExtension
= HwDeviceExtension
;
379 StartContext
->VpDmaAdapter
= VpDmaAdapter
;
381 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
383 Status
= Adapter
->Adapter
->DmaOperations
->GetScatterGatherList(Adapter
->Adapter
,
384 DeviceExtension
->PhysicalDeviceObject
,
386 MmGetSystemAddressForMdl((PMDL
)Mdl
),
387 MmGetMdlByteCount((PMDL
)Mdl
),
388 (PDRIVER_LIST_CONTROL
)ScatterAdapterControl
,
392 KeLowerIrql(OldIrql
);
394 if (!NT_SUCCESS(Status
))
397 ExFreePool(StartContext
);
398 Status
= ERROR_NOT_ENOUGH_MEMORY
;
414 VideoPortGetDmaContext(IN PVOID HwDeviceExtension
,
426 VideoPortDoDma(IN PVOID HwDeviceExtension
,
428 IN DMA_FLAGS DmaFlags
)
439 VideoPortAssociateEventsWithDmaHandle(IN PVOID HwDeviceExtension
,
440 IN OUT PVIDEO_REQUEST_PACKET pVrp
,
441 IN PVOID MappedUserEvent
,
442 IN PVOID DisplayDriverEvent
)
453 VideoPortCompleteDma(IN PVOID HwDeviceExtension
,
454 IN PVP_DMA_ADAPTER VpDmaAdapter
,
455 IN PVP_SCATTER_GATHER_LIST VpScatterGather
,
456 IN BOOLEAN WriteToDevice
)
459 PVIP_DMA_ADAPTER Adapter
= (PVIP_DMA_ADAPTER
)VpDmaAdapter
;
461 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
462 Adapter
->Adapter
->DmaOperations
->PutScatterGatherList(Adapter
->Adapter
, (PSCATTER_GATHER_LIST
)VpScatterGather
, WriteToDevice
);
463 KeLowerIrql(OldIrql
);