[HALX86] Implement HalBuildScatterGatherList

Make HalGetScatterGatherList a wrapper around it.
This commit is contained in:
Hervé Poussineau 2021-11-07 12:18:04 +01:00
parent eb283043d5
commit b39ae9f32b

View file

@ -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