https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b39ae9f32b4f3691b24cc…
commit b39ae9f32b4f3691b24ccecfc4293b98b63d7a1d
Author: Hervé Poussineau <hpoussin(a)reactos.org>
AuthorDate: Sun Nov 7 12:18:04 2021 +0100
Commit: Hervé Poussineau <hpoussin(a)reactos.org>
CommitDate: Sun Nov 7 14:07:57 2021 +0100
[HALX86] Implement HalBuildScatterGatherList
Make HalGetScatterGatherList a wrapper around it.
---
hal/halx86/generic/dma.c | 161 ++++++++++++++++++++++++++++++++++++-----------
1 file changed, 125 insertions(+), 36 deletions(-)
diff --git a/hal/halx86/generic/dma.c b/hal/halx86/generic/dma.c
index f14bbf59fb6..19d70517b5f 100644
--- a/hal/halx86/generic/dma.c
+++ b/hal/halx86/generic/dma.c
@@ -974,6 +974,7 @@ HalFreeCommonBuffer(IN PADAPTER_OBJECT AdapterObject,
}
typedef struct _SCATTER_GATHER_CONTEXT {
+ BOOLEAN UsingUserBuffer;
PADAPTER_OBJECT AdapterObject;
PMDL Mdl;
PUCHAR CurrentVa;
@@ -1076,7 +1077,7 @@ HalpScatterGatherAdapterControl(IN PDEVICE_OBJECT DeviceObject,
*
* @return The status of the operation.
*
- * @see HalPutScatterGatherList
+ * @see HalBuildScatterGatherList
*
* @implemented
*/
@@ -1084,41 +1085,29 @@ HalpScatterGatherAdapterControl(IN PDEVICE_OBJECT DeviceObject,
NTAPI
HalGetScatterGatherList(IN PADAPTER_OBJECT AdapterObject,
IN PDEVICE_OBJECT DeviceObject,
- IN PMDL Mdl,
- IN PVOID CurrentVa,
- IN ULONG Length,
- IN PDRIVER_LIST_CONTROL ExecutionRoutine,
- IN PVOID Context,
- IN BOOLEAN WriteToDevice)
+ IN PMDL Mdl,
+ IN PVOID CurrentVa,
+ IN ULONG Length,
+ IN PDRIVER_LIST_CONTROL ExecutionRoutine,
+ IN PVOID Context,
+ IN BOOLEAN WriteToDevice)
{
- PSCATTER_GATHER_CONTEXT AdapterControlContext;
-
- AdapterControlContext = ExAllocatePoolWithTag(NonPagedPool,
sizeof(SCATTER_GATHER_CONTEXT), TAG_DMA);
- if (!AdapterControlContext) return STATUS_INSUFFICIENT_RESOURCES;
-
- AdapterControlContext->AdapterObject = AdapterObject;
- AdapterControlContext->Mdl = Mdl;
- AdapterControlContext->CurrentVa = CurrentVa;
- AdapterControlContext->Length = Length;
- AdapterControlContext->MapRegisterCount = PAGE_ROUND_UP(Length) >> PAGE_SHIFT;
- AdapterControlContext->AdapterListControlRoutine = ExecutionRoutine;
- AdapterControlContext->AdapterListControlContext = Context;
- AdapterControlContext->WriteToDevice = WriteToDevice;
-
- AdapterControlContext->Wcb.DeviceObject = DeviceObject;
- AdapterControlContext->Wcb.DeviceContext = AdapterControlContext;
- AdapterControlContext->Wcb.CurrentIrp = DeviceObject->CurrentIrp;
-
- return HalAllocateAdapterChannel(AdapterObject,
- &AdapterControlContext->Wcb,
- AdapterControlContext->MapRegisterCount,
- HalpScatterGatherAdapterControl);
+ return HalBuildScatterGatherList(AdapterObject,
+ DeviceObject,
+ Mdl,
+ CurrentVa,
+ Length,
+ ExecutionRoutine,
+ Context,
+ WriteToDevice,
+ NULL,
+ 0);
}
/**
* @name HalPutScatterGatherList
*
- * Frees a scatter-gather list allocated from HalGetScatterGatherList
+ * Frees a scatter-gather list allocated from HalBuildScatterGatherList
*
* @param AdapterObject
* Adapter object representing the bus master or system dma controller.
@@ -1129,7 +1118,7 @@ HalpScatterGatherAdapterControl(IN PDEVICE_OBJECT DeviceObject,
*
* @return None
*
- * @see HalGetScatterGatherList
+ * @see HalBuildScatterGatherList
*
* @implemented
*/
@@ -1157,10 +1146,14 @@ HalpScatterGatherAdapterControl(IN PDEVICE_OBJECT DeviceObject,
AdapterControlContext->MapRegisterBase,
AdapterControlContext->MapRegisterCount);
- DPRINT("S/G DMA has finished!\n");
- ExFreePoolWithTag(AdapterControlContext, TAG_DMA);
ExFreePoolWithTag(ScatterGather, TAG_DMA);
+
+ /* If this is our buffer, release it */
+ if (!AdapterControlContext->UsingUserBuffer)
+ ExFreePoolWithTag(AdapterControlContext, TAG_DMA);
+
+ DPRINT("S/G DMA has finished!\n");
}
NTSTATUS
@@ -1187,6 +1180,40 @@ HalCalculateScatterGatherListSize(
return STATUS_SUCCESS;
}
+/**
+ * @name HalBuildScatterGatherList
+ *
+ * Creates a scatter-gather list to be using in scatter/gather DMA
+ *
+ * @param AdapterObject
+ * Adapter object representing the bus master or system dma controller.
+ * @param DeviceObject
+ * The device target for DMA.
+ * @param Mdl
+ * The MDL that describes the buffer to be mapped.
+ * @param CurrentVa
+ * The current VA in the buffer to be mapped for transfer.
+ * @param Length
+ * Specifies the length of data in bytes to be mapped.
+ * @param ExecutionRoutine
+ * A caller supplied AdapterListControl routine to be called when DMA is
available.
+ * @param Context
+ * Context passed to the AdapterListControl routine.
+ * @param WriteToDevice
+ * Indicates direction of DMA operation.
+ *
+ * @param ScatterGatherBuffer
+ * User buffer for the scatter-gather list
+ *
+ * @param ScatterGatherBufferLength
+ * Buffer length
+ *
+ * @return The status of the operation.
+ *
+ * @see HalPutScatterGatherList
+ *
+ * @implemented
+ */
NTSTATUS
NTAPI
HalBuildScatterGatherList(
@@ -1199,10 +1226,72 @@ HalBuildScatterGatherList(
IN PVOID Context,
IN BOOLEAN WriteToDevice,
IN PVOID ScatterGatherBuffer,
- IN ULONG ScatterGatherLength)
+ IN ULONG ScatterGatherBufferLength)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+ ULONG SgSize, NumberOfMapRegisters;
+ PSCATTER_GATHER_CONTEXT ScatterGatherContext;
+ BOOLEAN UsingUserBuffer;
+
+ Status = HalCalculateScatterGatherListSize(AdapterObject,
+ Mdl,
+ CurrentVa,
+ Length,
+ &SgSize,
+ &NumberOfMapRegisters);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ if (ScatterGatherBuffer)
+ {
+ /* Checking if user buffer is enough */
+ if (ScatterGatherBufferLength < SgSize)
+ {
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+ UsingUserBuffer = TRUE;
+ }
+ else
+ {
+ ScatterGatherBuffer = ExAllocatePoolWithTag(NonPagedPool, SgSize, TAG_DMA);
+ if (!ScatterGatherBuffer)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ UsingUserBuffer = FALSE;
+ }
+
+ {
+ ScatterGatherContext = (PSCATTER_GATHER_CONTEXT)ScatterGatherBuffer;
+
+ /* Fill the scatter-gather context */
+ ScatterGatherContext->UsingUserBuffer = UsingUserBuffer;
+ ScatterGatherContext->AdapterObject = AdapterObject;
+ ScatterGatherContext->Mdl = Mdl;
+ ScatterGatherContext->CurrentVa = CurrentVa;
+ ScatterGatherContext->Length = Length;
+ ScatterGatherContext->MapRegisterCount = NumberOfMapRegisters;
+ ScatterGatherContext->AdapterListControlRoutine = ExecutionRoutine;
+ ScatterGatherContext->AdapterListControlContext = Context;
+ ScatterGatherContext->WriteToDevice = WriteToDevice;
+
+ ScatterGatherContext->Wcb.DeviceObject = DeviceObject;
+ ScatterGatherContext->Wcb.DeviceContext = (PVOID)ScatterGatherContext;
+ ScatterGatherContext->Wcb.CurrentIrp = DeviceObject->CurrentIrp;
+
+ Status = HalAllocateAdapterChannel(AdapterObject,
+ &ScatterGatherContext->Wcb,
+ NumberOfMapRegisters,
+ HalpScatterGatherAdapterControl);
+
+ if (!NT_SUCCESS(Status))
+ {
+ if (!UsingUserBuffer)
+ ExFreePoolWithTag(ScatterGatherBuffer, TAG_DMA);
+ return Status;
+ }
+ }
+
+ return STATUS_SUCCESS;
}
NTSTATUS