[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 { typedef struct _SCATTER_GATHER_CONTEXT {
BOOLEAN UsingUserBuffer;
PADAPTER_OBJECT AdapterObject; PADAPTER_OBJECT AdapterObject;
PMDL Mdl; PMDL Mdl;
PUCHAR CurrentVa; PUCHAR CurrentVa;
@ -1076,7 +1077,7 @@ HalpScatterGatherAdapterControl(IN PDEVICE_OBJECT DeviceObject,
* *
* @return The status of the operation. * @return The status of the operation.
* *
* @see HalPutScatterGatherList * @see HalBuildScatterGatherList
* *
* @implemented * @implemented
*/ */
@ -1084,41 +1085,29 @@ HalpScatterGatherAdapterControl(IN PDEVICE_OBJECT DeviceObject,
NTAPI NTAPI
HalGetScatterGatherList(IN PADAPTER_OBJECT AdapterObject, HalGetScatterGatherList(IN PADAPTER_OBJECT AdapterObject,
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PMDL Mdl, IN PMDL Mdl,
IN PVOID CurrentVa, IN PVOID CurrentVa,
IN ULONG Length, IN ULONG Length,
IN PDRIVER_LIST_CONTROL ExecutionRoutine, IN PDRIVER_LIST_CONTROL ExecutionRoutine,
IN PVOID Context, IN PVOID Context,
IN BOOLEAN WriteToDevice) IN BOOLEAN WriteToDevice)
{ {
PSCATTER_GATHER_CONTEXT AdapterControlContext; return HalBuildScatterGatherList(AdapterObject,
DeviceObject,
AdapterControlContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(SCATTER_GATHER_CONTEXT), TAG_DMA); Mdl,
if (!AdapterControlContext) return STATUS_INSUFFICIENT_RESOURCES; CurrentVa,
Length,
AdapterControlContext->AdapterObject = AdapterObject; ExecutionRoutine,
AdapterControlContext->Mdl = Mdl; Context,
AdapterControlContext->CurrentVa = CurrentVa; WriteToDevice,
AdapterControlContext->Length = Length; NULL,
AdapterControlContext->MapRegisterCount = PAGE_ROUND_UP(Length) >> PAGE_SHIFT; 0);
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);
} }
/** /**
* @name HalPutScatterGatherList * @name HalPutScatterGatherList
* *
* Frees a scatter-gather list allocated from HalGetScatterGatherList * Frees a scatter-gather list allocated from HalBuildScatterGatherList
* *
* @param AdapterObject * @param AdapterObject
* Adapter object representing the bus master or system dma controller. * Adapter object representing the bus master or system dma controller.
@ -1129,7 +1118,7 @@ HalpScatterGatherAdapterControl(IN PDEVICE_OBJECT DeviceObject,
* *
* @return None * @return None
* *
* @see HalGetScatterGatherList * @see HalBuildScatterGatherList
* *
* @implemented * @implemented
*/ */
@ -1157,10 +1146,14 @@ HalpScatterGatherAdapterControl(IN PDEVICE_OBJECT DeviceObject,
AdapterControlContext->MapRegisterBase, AdapterControlContext->MapRegisterBase,
AdapterControlContext->MapRegisterCount); AdapterControlContext->MapRegisterCount);
DPRINT("S/G DMA has finished!\n");
ExFreePoolWithTag(AdapterControlContext, TAG_DMA);
ExFreePoolWithTag(ScatterGather, 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 NTSTATUS
@ -1187,6 +1180,40 @@ HalCalculateScatterGatherListSize(
return STATUS_SUCCESS; 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 NTSTATUS
NTAPI NTAPI
HalBuildScatterGatherList( HalBuildScatterGatherList(
@ -1199,10 +1226,72 @@ HalBuildScatterGatherList(
IN PVOID Context, IN PVOID Context,
IN BOOLEAN WriteToDevice, IN BOOLEAN WriteToDevice,
IN PVOID ScatterGatherBuffer, IN PVOID ScatterGatherBuffer,
IN ULONG ScatterGatherLength) IN ULONG ScatterGatherBufferLength)
{ {
UNIMPLEMENTED; NTSTATUS Status;
return STATUS_NOT_IMPLEMENTED; 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 NTSTATUS