https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b39ae9f32b4f3691b24ccecfc4293b98b63d7a1d

commit b39ae9f32b4f3691b24ccecfc4293b98b63d7a1d
Author:     Hervé Poussineau <[email protected]>
AuthorDate: Sun Nov 7 12:18:04 2021 +0100
Commit:     Hervé Poussineau <[email protected]>
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

Reply via email to