diff --git a/hal/halx86/generic/dma.c b/hal/halx86/generic/dma.c index ad34e0f363e..ad0f761e509 100644 --- a/hal/halx86/generic/dma.c +++ b/hal/halx86/generic/dma.c @@ -77,9 +77,6 @@ #define NDEBUG #include -// FIXME: This value needs to be calculated at runtime -#define MAX_SG_ELEMENTS 0x20 - #ifndef _MINIHAL_ static KEVENT HalpDmaLock; static KSPIN_LOCK HalpDmaAdapterListLock; @@ -983,6 +980,8 @@ typedef struct _SCATTER_GATHER_CONTEXT { WAIT_CONTEXT_BLOCK Wcb; } SCATTER_GATHER_CONTEXT, *PSCATTER_GATHER_CONTEXT; +// FIXME: This value needs to be calculated at runtime +#define MAX_SG_ELEMENTS 0x30 IO_ALLOCATION_ACTION NTAPI @@ -997,6 +996,10 @@ HalpScatterGatherAdapterControl(IN PDEVICE_OBJECT DeviceObject, PSCATTER_GATHER_ELEMENT TempElements; ULONG ElementCount = 0, RemainingLength = AdapterControlContext->Length; PUCHAR CurrentVa = AdapterControlContext->CurrentVa; + // RemainingLength / PAGE_SIZE + 1 for the remainder of our division + // + 1 for a safety cushion gives a good safe value. Using the + // min function with MAX_SG_ELEMENTS keeps us from getting too large. + ULONG Est_SG_Elements = min(RemainingLength / PAGE_SIZE + 2, MAX_SG_ELEMENTS); /* Store the map register base for later in HalPutScatterGatherList */ AdapterControlContext->MapRegisterBase = MapRegisterBase; @@ -1004,7 +1007,7 @@ HalpScatterGatherAdapterControl(IN PDEVICE_OBJECT DeviceObject, // FIXME: HACK Allocate TempElements from pool to minimize stack usage. // A more efficient algorithm should be found to avoid allocations during S/G I/O operations. TempElements = ExAllocatePoolUninitialized(NonPagedPool, - sizeof(*TempElements) * MAX_SG_ELEMENTS, + sizeof(*TempElements) * Est_SG_Elements, TAG_DMA); if (!TempElements) { @@ -1034,6 +1037,9 @@ HalpScatterGatherAdapterControl(IN PDEVICE_OBJECT DeviceObject, ElementCount++; } + DPRINT("Est_SG_Elements %d\n", Est_SG_Elements); + DPRINT("ElementCount is %d\n", ElementCount); + if (RemainingLength > 0) { DPRINT1("Scatter/gather list construction failed!\n");