https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b39ae9f32b4f3691b24cce...
commit b39ae9f32b4f3691b24ccecfc4293b98b63d7a1d Author: Hervé Poussineau hpoussin@reactos.org AuthorDate: Sun Nov 7 12:18:04 2021 +0100 Commit: Hervé Poussineau hpoussin@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