HalpDmaGetTranslationEntries

_HALP_DMA_TRANSLATION_ENTRY *__stdcall HalpDmaGetTranslationEntries(
        _HALP_DMA_ADAPTER_OBJECT *Adapter,
        _HALP_DMA_MAP_BUFFER_TYPE Type,
        UINT64 EntriesNeeded){
  _HALP_DMA_TRANSLATION_ENTRY *result; 
  __int64 v4; 
  _HALP_DMA_ADAPTER_OBJECT *v6; 
  __int64 v7; 
  _HALP_DMA_TRANSLATION_BUFFER *v8; 
  _HALP_DMA_TRANSLATION_BUFFER **p_Next; 
  unsigned int v10; 
  _HALP_DMA_TRANSLATION_BUFFER *i; 
  unsigned int v12; 
  _HALP_DMA_TRANSLATION_ENTRY *v13; 
  _HALP_DMA_TRANSLATION_ENTRY *v14; 
  _HALP_DMA_TRANSLATION_ENTRY *v15; 
  unsigned int EntryCount; 
  _HALP_DMA_TRANSLATION_ENTRY *Entries; 
  unsigned __int64 OldIrql; 
  _HALP_DMA_TRANSLATION_BUFFER *NewTranslationBuffer; 
  _KLOCK_QUEUE_HANDLE LockHandle; 

  result = 0i64;
  v4 = (unsigned int)EntriesNeeded;
  v6 = Adapter;
  memset(&LockHandle, 0, sizeof(LockHandle));
  if( Type == HalpDmaContiguousMapBuffer )
  {
    v7 = 56i64;
    goto LABEL_3;
  }
  if( Type == HalpDmaNonContiguousMapBuffer )
  {
    v7 = 72i64;
LABEL_3:
    KeAcquireInStackQueuedSpinLock(&Adapter->GrowLock, &LockHandle);
    v8 = *(_HALP_DMA_TRANSLATION_BUFFER **)((char *)&v6->DmaHeader.Version + v7);
    if( v8 )
    {
      p_Next = *(_HALP_DMA_TRANSLATION_BUFFER ***)((char *)&v6->DmaHeader.Version + v7);
      v10 = v8->EntryCount - *(_DWORD *)((char *)&v6->DmaHeader.DmaOperations + v7);
      for( i = v8->Next; i; i = i->Next )
      {
        v10 += i->EntryCount;
        p_Next = &i->Next;
      }
      if( v10 >= (unsigned int)v4 )
        goto LABEL_7;
    }
    else
    {
      v10 = 0;
      p_Next = 0i64;
    }
    NewTranslationBuffer = HalpDmaAllocateNewTranslationBuffer(v6, (unsigned int)v4 - v10);
    if( !NewTranslationBuffer )
    {
      KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
      OldIrql = LockHandle.OldIrql;
      result = 0i64;
LABEL_16:
      __writecr8(OldIrql);
      return result;
    }
    if( p_Next )
    {
      *p_Next = NewTranslationBuffer;
    }
    else
    {
      v8 = NewTranslationBuffer;
      if( Type )
        v6->ScatterTranslations = NewTranslationBuffer;
      else
        v6->ContiguousTranslations = NewTranslationBuffer;
    }
LABEL_7:
    v12 = *(_DWORD *)((char *)&v6->DmaHeader.DmaOperations + v7);
    v13 = 0i64;
    v14 = 0i64;
    v15 = 0i64;
    if( (_DWORD)v4 )
    {
      EntryCount = v8->EntryCount;
      do
      {
        if( v12 >= EntryCount )
        {
          v8 = v8->Next;
          v12 = 0;
          EntryCount = v8->EntryCount;
        }
        Entries = v8->Entries;
        v15 = &Entries[v12];
        if( v13 )
          v14->Next = v15;
        else
          v13 = &Entries[v12];
        memset(&Entries[v12++], 0i64, sizeof(_HALP_DMA_TRANSLATION_ENTRY));
        v15->NextMapping = v15;
        v14 = v15;
        --v4;
      }
      while( v4 );
      v6 = Adapter;
    }
    *(_QWORD *)((char *)&v6->DmaHeader.Version + v7) = v8;
    *(_DWORD *)((char *)&v6->DmaHeader.DmaOperations + v7) = v12;
    v15->Next = 0i64;
    KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
    OldIrql = LockHandle.OldIrql;
    result = v13;
    goto LABEL_16;
  }
  return result;
}

Referenced by:

HalpDmaAllocateMapRegisters
HalpDmaCommitContiguousMapBuffers
HalpDmaCommitScatterMapBuffers