HalpDmaAllocateMapRegisters

_HALP_DMA_TRANSLATION_ENTRY *__stdcall HalpDmaAllocateMapRegisters(
        _ADAPTER_OBJECT *ChildAdapter,
        UINT64 NumberOfMapRegisters){
  INT64 v2; 
  __int64 v3; 
  unsigned int v4; 
  unsigned int v5; 
  _HALP_DMA_TRANSLATION_ENTRY *v7; 
  _HALP_DMA_TRANSLATION_ENTRY *result; 
  _HALP_DMA_MASTER_ADAPTER_OBJECT *MasterAdapter; 
  _HALP_ALLOC_CONTEXT *v10; 
  _HALP_DMA_TRANSLATION_ENTRY *v11; 
  _ADAPTER_OBJECT *v12; 
  _HALP_DMA_TRANSLATION_ENTRY *v13; 
  _HALP_DMA_TRANSLATION_ENTRY *v14; 
  _HALP_DMA_TRANSLATION_ENTRY *v15; 
  unsigned int v16; 
  VOID *v17; 
  UINT64 v18; 
  INT64 v19; 
  _MDL *v20; 
  unsigned int v21; 
  __int64 v22; 
  UINT8 *v23; 
  _HALP_ALLOC_CONTEXT *v24; 
  VOID **v25; 
  _QWORD *v26; 
  UINT8 *v27; 
  int v28; 
  _HALP_DMA_TRANSLATION_ENTRY *TranslationEntries; 
  VOID **v30; 
  __int64 v31; 
  _HALP_DMA_TRANSLATION_ENTRY *Next; 
  _HALP_DMA_TRANSLATION_ENTRY *v33; 
  _HALP_DMA_TRANSLATION_ENTRY *v34; 
  UINT64 *v35; 
  __int64 v36; 
  UINT64 v37; 
  __int64 v38; 
  _HALP_ALLOC_CONTEXT *v39; 
  INT64 ForLocalPool; 
  INT64 ForLocalPoola; 
  VOID *VirtualAddressOut; 
  _MDL *MdlOut; 
  _KLOCK_QUEUE_HANDLE LockHandle; 
  UINT64 PagesAllocated; 
  UINT64 v46; 
  UINT64 PhysicalAddressOut; 

  LODWORD(v3) = 0;
  v4 = 0;
  v5 = NumberOfMapRegisters;
  LODWORD(PagesAllocated) = 0;
  LODWORD(v46) = 0;
  v7 = 0i64;
  VirtualAddressOut = 0i64;
  PhysicalAddressOut = 0i64;
  MdlOut = 0i64;
  memset(&LockHandle, 0, sizeof(LockHandle));
  if( !ChildAdapter->NoLocalPool )
  {
    LOBYTE(ForLocalPool) = 0;
    if( ChildAdapter->ScatterGather )
    {
      result = HalpDmaAllocateScatterPagesFromScatterPool(
                 ChildAdapter,
                 &ChildAdapter->AdapterObject,
                 (unsigned int)NumberOfMapRegisters,
                 0,
                 0,
                 &PagesAllocated);
      v4 = PagesAllocated;
      v7 = result;
      if( (_DWORD)PagesAllocated == v5 )
        return result;
    }
    else
    {
      LOBYTE(v2) = 1;
      result = HalpDmaAllocateContiguousPagesFromContiguousPool(
                 ChildAdapter,
                 &ChildAdapter->AdapterObject,
                 (unsigned int)NumberOfMapRegisters,
                 v2,
                 ForLocalPool,
                 &PagesAllocated);
      v7 = result;
      if( result )
        return result;
      v4 = PagesAllocated;
    }
  }
  MasterAdapter = ChildAdapter->MasterAdapter;
  if( ChildAdapter->ScatterGather )
  {
    v11 = HalpDmaAllocateScatterPagesFromScatterPool(ChildAdapter, &MasterAdapter->AdapterObject, v5 - v4, 0, 0, &v46);
    if( v11 )
    {
      v13 = HalpDmaPrependTranslations(v11, (_HALP_DMA_TRANSLATION_ENTRY *)(unsigned int)v46);
      v4 += v46;
      v7 = v13;
      LODWORD(PagesAllocated) = v4;
    }
    if( v4 == v5 )
      return v7;
    v14 = HalpDmaAllocateScatterPagesFromContiguousPool(
            v12,
            &ChildAdapter->MasterAdapter->AdapterObject,
            v5 - v4,
            0,
            0,
            &v46);
    if( v14 )
    {
      v15 = HalpDmaPrependTranslations(v14, (_HALP_DMA_TRANSLATION_ENTRY *)(unsigned int)v46);
      v4 += v46;
      v7 = v15;
      LODWORD(PagesAllocated) = v4;
    }
    if( v4 == v5 )
      return v7;
  }
  else
  {
    LOBYTE(v2) = 1;
    LOBYTE(ForLocalPool) = 0;
    result = HalpDmaAllocateContiguousPagesFromContiguousPool(
               ChildAdapter,
               &MasterAdapter->AdapterObject,
               v5,
               v2,
               ForLocalPool,
               &PagesAllocated);
    v7 = result;
    if( result )
      return result;
    v4 = PagesAllocated;
  }
  if( !ChildAdapter->ScatterGather )
  {
    v16 = HalpDmaAllocateContiguousMemory(
            &ChildAdapter->AdapterObject,
            v5,
            &VirtualAddressOut,
            &PhysicalAddressOut,
            &MdlOut);
    LODWORD(PagesAllocated) = v16;
    if( v16 )
    {
      v17 = VirtualAddressOut;
      if( HalpDmaCommitContiguousMapBuffers(
             &ChildAdapter->MasterAdapter->AdapterObject,
             VirtualAddressOut,
             PhysicalAddressOut,
             v16) )
      {
        LOBYTE(v19) = 1;
        LOBYTE(ForLocalPoola) = 0;
        result = HalpDmaAllocateContiguousPagesFromContiguousPool(
                   ChildAdapter,
                   &ChildAdapter->MasterAdapter->AdapterObject,
                   v5,
                   v19,
                   ForLocalPoola,
                   &PagesAllocated);
        if( result )
          return result;
      }
      else
      {
        v20 = MdlOut;
        if( MdlOut )
        {
          if( v17 )
            MmUnmapLockedPages(v17, MdlOut);
          MiFreePagesFromMdl(v20, 0i64, v18);
          ExFreePoolWithTag(v20, 0);
        }
        else
        {
          MmFreeContiguousMemory(v17);
        }
      }
    }
    return 0i64;
  }
  v21 = v5 - v4;
  v22 = v21;
  v23 = HalpMmAllocCtxAlloc(v10, 8i64 * v21);
  v25 = (VOID **)v23;
  if( !v23 )
  {
LABEL_38:
    if( v4 )
    {
      v31 = v4;
      do
      {
        Next = v7->Next;
        HalpDmaReturnPageToOwner(ChildAdapter, ChildAdapter->MasterAdapter, v7);
        v7 = Next;
        --v31;
      }
      while( v31 );
    }
    return 0i64;
  }
  if( v21 )
  {
    v26 = v23;
    while( 1 )
    {
      v27 = HalpMmAllocCtxAlloc(v24, 0x1000ui64);
      *v26 = v27;
      if( !v27 )
        goto LABEL_34;
      MmGetPhysicalAddress((UINT64)v27);
      if( v28 )
        goto LABEL_34;
      LODWORD(v3) = v3 + 1;
      ++v26;
      if( (unsigned int)v3 >= v21 )
      {
        v22 = v21;
        break;
      }
    }
  }
  TranslationEntries = HalpDmaGetTranslationEntries(
                         &ChildAdapter->MasterAdapter->AdapterObject,
                         HalpDmaNonContiguousMapBuffer,
                         v21);
  if( !TranslationEntries )
  {
LABEL_34:
    if( (_DWORD)v3 )
    {
      v30 = v25;
      v3 = (unsigned int)v3;
      do
      {
        HalpMmAllocCtxFree(v24, *v30++);
        --v3;
      }
      while( v3 );
    }
    HalpMmAllocCtxFree(v24, v25);
    goto LABEL_38;
  }
  v33 = HalpDmaPrependTranslations(TranslationEntries, (_HALP_DMA_TRANSLATION_ENTRY *)v21);
  v34 = v33;
  if( v21 )
  {
    v35 = (UINT64 *)v25;
    do
    {
      v34->PhysicalAddress = (unsigned int)MmGetPhysicalAddress(*v35);
      v36 = 1i64;
      v37 = *v35;
      v38 = 2i64;
      do
      {
        v37 |= v36++;
        --v38;
      }
      while( v38 );
      ++v35;
      v34->u.VirtualAddress = (void *)(v37 | 0xC);
      v34 = v34->Next;
      --v22;
    }
    while( v22 );
  }
  KeAcquireInStackQueuedSpinLock(&ChildAdapter->MasterAdapter->AdapterObject.SpinLock, &LockHandle);
  ChildAdapter->MasterAdapter->ScatterPageCount += v21;
  KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
  __writecr8(LockHandle.OldIrql);
  HalpMmAllocCtxFree(v39, v25);
  return v33;
}

Referenced by:

HalAllocateAdapterChannelV2
HalDmaAllocateCrashDumpRegistersEx
HalpAllocateDmaResourcesInternal
HalpAllocateMapRegisters
HalpDmaProcessMapRegisterQueueV2
IoFreeAdapterChannelV2