HalpDmaNextContiguousPieceV3
VOID __fastcall HalpDmaNextContiguousPieceV3(
_ADAPTER_OBJECT *ChildAdapter,
_MDL *Mdl,
_HALP_DMA_TRANSLATION_ENTRY *TranslationBase,
VOID *CurrentVa,
UINT8 WriteToDevice,
UINT64 Length){
unsigned __int8 DmaCanCross64K;
_HALP_DMA_TRANSLATION_ENTRY *v7;
unsigned __int64 QuadPart;
int v9;
unsigned __int64 v10;
bool v12;
unsigned int v13;
unsigned int v14;
__int64 v15;
unsigned int v16;
_MDL **v17;
_MDL **v18;
unsigned int v19;
_MDL **v20;
unsigned __int64 v21;
_MDL *v22;
unsigned int v23;
int v24;
NTSTATUS AdapterCacheAlignment;
unsigned __int64 *v26;
unsigned int i;
_HALP_DMA_TRANSLATION_ENTRY *NextMapping;
unsigned __int64 v29;
unsigned __int64 v30;
_MDL **v31;
unsigned __int8 v32;
unsigned int v33;
_LARGE_INTEGER MaximumPhysicalAddress;
DmaCanCross64K = ChildAdapter->AdapterObject.DmaCanCross64K;
v7 = TranslationBase;
v9 = (int)CurrentVa;
MaximumPhysicalAddress = ChildAdapter->AdapterObject.MaximumPhysicalAddress;
QuadPart = MaximumPhysicalAddress.QuadPart;
v10 = (unsigned __int64)MaximumPhysicalAddress.QuadPart >> 12;
v32 = DmaCanCross64K;
v12 = !WriteToDevice && !ChildAdapter->CacheCoherent;
v13 = Length;
v14 = 4096 - ((unsigned __int16)CurrentVa & 0xFFF);
v15 = (unsigned int)(((unsigned __int64)CurrentVa - (unsigned __int64)Mdl->StartVa) >> 12) + 6i64;
v33 = v14;
v16 = v14;
v17 = &Mdl->Next + v15;
v18 = v17;
v31 = v17;
if( (unsigned __int64)*v17 > v10 )
goto LABEL_33;
if( v12 )
{
if( ((HalpDmaGetAdapterCacheAlignment(ChildAdapter) - 1) & v9) == 0 )
{
QuadPart = MaximumPhysicalAddress.QuadPart;
goto LABEL_9;
}
LABEL_33:
v16 = 0;
goto LABEL_34;
}
LABEL_9:
if( v14 < v13 )
{
v19 = 4096;
while( 1 )
{
v20 = v18 + 1;
v21 = (unsigned __int64)v18[1];
if( v21 > v10 )
break;
v22 = *v18;
if( (_MDL **)((char *)&(*v18)->Next + 1) != (_MDL **)v21 )
break;
v23 = v13 - v16;
if( v13 - v16 > v19 )
v23 = v19;
if( QuadPart < v23 + (v21 << 12) - 1 && ChildAdapter->TranslationType != ExtTranslationTypeTranslate )
{
LABEL_27:
DmaCanCross64K = v32;
break;
}
if( !ChildAdapter->CacheCoherent && !WriteToDevice )
{
v24 = HalpDmaGetAdapterCacheAlignment(ChildAdapter) - 1;
if( (v24 & ((_DWORD)v21 << 12)) != 0 || (v24 & v23) != 0 )
goto LABEL_27;
QuadPart = MaximumPhysicalAddress.QuadPart;
}
DmaCanCross64K = v32;
if( (((unsigned __int64)v22 ^ v21) & 0xFFFFFFFFFFF00000ui64) == 0
&& (v32 == 1 || (((unsigned __int64)v22 ^ v21) & 0xFFFFFFFFFFFFFFF0ui64) == 0) )
{
v16 += v19;
v18 = v20;
if( v16 < v13 )
continue;
}
break;
}
v14 = v33;
v17 = v31;
v7 = TranslationBase;
}
if( v16 > v13 )
{
v16 = v13;
if( v12 )
{
AdapterCacheAlignment = HalpDmaGetAdapterCacheAlignment(ChildAdapter);
if( ((AdapterCacheAlignment - 1) & v13) != 0 )
v16 &= 0xFFFFF000;
}
}
LABEL_34:
if( ChildAdapter->ScatterGather && v13 && !v16 )
{
v26 = (unsigned __int64 *)(v17 + 1);
for( i = v14; i < v13; ++v26 )
{
if( *v26 <= v10 )
break;
i += 4096;
}
NextMapping = v7->NextMapping;
if( i > v13 )
i = v13;
if( NextMapping )
{
v29 = NextMapping->PhysicalAddress >> 12;
while( 1 )
{
NextMapping = NextMapping->Next;
if( v14 >= i )
break;
if( !NextMapping )
break;
v30 = NextMapping->PhysicalAddress >> 12;
if( v30 != v29 + 1
|| ((v29 ^ v30) & 0xFFFFFFFFFFF00000ui64) != 0
|| DmaCanCross64K != 1 && ((v29 ^ v30) & 0xFFFFFFFFFFFFFFF0ui64) != 0 )
{
break;
}
v29 = NextMapping->PhysicalAddress >> 12;
v14 += 4096;
}
}
}
}Referenced by:
HalpDmaNextContiguousPiece