HalDmaAllocateCrashDumpRegistersEx

NTSTATUS __stdcall HalDmaAllocateCrashDumpRegistersEx(
        _ADAPTER_OBJECT *ChildAdapter,
        UINT64 NumberOfMapRegisters,
        _HAL_DMA_CRASH_DUMP_REGISTER_TYPE Type,
        VOID **MapRegisterBase,
        UINT64 *MapRegistersAvailable){
  _ADAPTER_OBJECT *v5; 
  __int64 v6; 
  UINT64 *v9; 
  __int64 v10; 
  __int64 *i; 
  NTSTATUS result; 
  _LIST_ENTRY *v13; 
  _LIST_ENTRY *p_AdapterCrashDumpList; 
  unsigned int v15; 
  _HALP_DMA_TRANSLATION_ENTRY *MapRegisters; 
  INT64 v17; 
  _HALP_DMA_TRANSLATION_ENTRY *v18; 
  _HALP_DMA_DOMAIN_OBJECT *DomainPointer; 
  NTSTATUS v20; 
  UINT64 LogicalAddress; 
  int v22; 
  UINT64 NextLogicalAddress; 
  UINT64 *p_PhysicalAddress; 
  _HALP_DMA_TRANSLATION_ENTRY *v25; 
  _HALP_DMA_TRANSLATION_ENTRY *v26; 
  UINT64 v27; 
  unsigned int v28; 
  _QWORD *v29; 
  __int64 v30; 
  int v31; 
  _HALP_DMA_TRANSLATION_ENTRY *v32; 
  UINT64 a3; 

  v5 = 0i64;
  v6 = (unsigned int)NumberOfMapRegisters;
  if( !ChildAdapter )
    return -1073741811;
  if( !(_DWORD)NumberOfMapRegisters )
    return -1073741811;
  if( !MapRegisterBase )
    return -1073741811;
  v9 = MapRegistersAvailable;
  if( !MapRegistersAvailable || (unsigned int)Type > HalDmaCrashDumpRegisterSet2 )
    return -1073741811;
  if( !ChildAdapter->NeedsMapRegisters && ChildAdapter->CacheCoherent )
  {
    *MapRegisterBase = 0i64;
    *(_DWORD *)v9 = NumberOfMapRegisters;
    v10 = Type;
    ChildAdapter->MapRegisterBase = 0i64;
    ChildAdapter->NumberOfMapRegisters = 0;
    ChildAdapter->CrashDumpRegisterBase[Type] = 0i64;
    ChildAdapter->NumberOfCrashDumpRegisters[Type] = 0;
    goto LABEL_9;
  }
  v10 = Type;
  v15 = ChildAdapter->NumberOfCrashDumpRegisters[Type];
  if( (unsigned int)NumberOfMapRegisters <= v15 )
  {
    *(_DWORD *)MapRegistersAvailable = NumberOfMapRegisters;
    *MapRegisterBase = ChildAdapter->CrashDumpRegisterBase[Type];
    goto LABEL_9;
  }
  if( (unsigned int)NumberOfMapRegisters > ChildAdapter->MapRegistersPerChannel )
    return -1073741811;
  if( KeGetCurrentIrql() )
  {
    if( ChildAdapter == (_ADAPTER_OBJECT *)-264i64 || ChildAdapter->ScatterGather )
    {
      if( HalpDmaHibernateRegisterPhase != 1 )
      {
        LODWORD(a3) = NumberOfMapRegisters - v15;
        v25 = HalpDmaAllocateMapRegistersAtHighLevel((_HALP_DMA_TRANSLATION_ENTRY *)ChildAdapter, &a3);
        v26 = v25;
        if( v25 )
        {
          v27 = (unsigned int)a3;
          if( (_DWORD)a3 == (_DWORD)v6 - v15 )
          {
            if( ChildAdapter->CrashDumpRegisterBase[v10] )
            {
              _mm_lfence();
              v28 = ChildAdapter->NumberOfCrashDumpRegisters[v10];
              v29 = ChildAdapter->CrashDumpRegisterBase[v10];
              if( v28 > 1 )
              {
                v30 = v28 - 1;
                do
                {
                  v29 = (_QWORD *)v29[1];
                  --v30;
                }
                while( v30 );
              }
              v31 = a3;
              v29[1] = v26;
              ChildAdapter->NumberOfCrashDumpRegisters[v10] += v31;
              ChildAdapter->NumberOfMapRegisters = v6;
            }
            else
            {
              ChildAdapter->MapRegisterBase = v25;
              ChildAdapter->NumberOfMapRegisters = v6;
              ChildAdapter->CrashDumpRegisterBase[v10] = v25;
              ChildAdapter->NumberOfCrashDumpRegisters[v10] = v6;
            }
            *MapRegisterBase = ChildAdapter->CrashDumpRegisterBase[v10];
            *(_DWORD *)v9 = v6;
            goto LABEL_9;
          }
          v22 = a3 + v15;
          *MapRegisterBase = 0i64;
          *(_DWORD *)v9 = v22;
          HalpDmaFreeMapRegisters(ChildAdapter, v26, v27);
        }
        else
        {
          *MapRegisterBase = 0i64;
          *(_DWORD *)v9 = v15;
        }
        return -1073741670;
      }
      result = -1073741637;
    }
    else
    {
      result = -1073741670;
    }
    *MapRegisterBase = 0i64;
    *(_DWORD *)v9 = ChildAdapter->NumberOfCrashDumpRegisters[Type];
    return result;
  }
  MapRegisters = HalpDmaAllocateMapRegisters(ChildAdapter, (unsigned int)NumberOfMapRegisters);
  v18 = MapRegisters;
  if( !MapRegisters )
    return -1073741670;
  ChildAdapter->CrashDumpRegisterBase[v10] = MapRegisters;
  ChildAdapter->NumberOfCrashDumpRegisters[v10] = v6;
  if( ChildAdapter->TranslationType == ExtTranslationTypeTranslate )
  {
    DomainPointer = ChildAdapter->DomainPointer;
    LODWORD(a3) = HalpDomainLaAllocate(
                    (INT64)DomainPointer,
                    (PDUMPWRITER_FILL_HEADERS *)(unsigned int)((_DWORD)v6 << 12),
                    v17,
                    0i64,
                    0i64,
                    (INT64)&MapRegisters->LogicalAddress);
    if( (a3 & 0x80000000) != 0i64 )
    {
LABEL_37:
      HalpDmaFreeMapRegisters(ChildAdapter, v18, (unsigned int)v6);
      return a3;
    }
    v20 = HalpIommuDomainMapLogicalRange(
            (INT64)DomainPointer->IommuDomainPointer,
            0i64,
            0i64,
            v6 << 12,
            v18->LogicalAddress);
    LogicalAddress = v18->LogicalAddress;
    LODWORD(a3) = v20;
    if( v20 < 0 )
    {
      HalpDomainLaDelete((INT64)DomainPointer, LogicalAddress);
      goto LABEL_37;
    }
    v18->NextLogicalAddress = LogicalAddress;
    if( HalpIsHvPresent() )
    {
      NextLogicalAddress = v18->NextLogicalAddress;
      p_PhysicalAddress = &v18->PhysicalAddress;
      v32 = v18;
      v18->LogicalMappedLength = 0i64;
      while( 1 )
      {
        LODWORD(a3) = HalpIommuDomainMapLogicalRange(
                        (INT64)DomainPointer->IommuDomainPointer,
                        3i64,
                        *p_PhysicalAddress,
                        4096i64,
                        NextLogicalAddress);
        if( (a3 & 0x80000000) != 0i64 )
          break;
        v18->NextLogicalAddress += 4096i64;
        v18->LogicalMappedLength += 4096i64;
        NextLogicalAddress = v18->NextLogicalAddress;
        p_PhysicalAddress = &v32->Next->PhysicalAddress;
        v32 = (_HALP_DMA_TRANSLATION_ENTRY *)p_PhysicalAddress;
        if( !p_PhysicalAddress )
        {
          v18->NextLogicalAddress = v18->LogicalAddress;
          v18->LogicalBounceBufferPremapped = 1;
          goto LABEL_35;
        }
      }
      HalpIommuDomainUnmapLogicalRange(DomainPointer->IommuDomainPointer, (PVOID)v18->LogicalAddress);
      goto LABEL_37;
    }
  }
LABEL_35:
  *(_DWORD *)v9 = v6;
  *MapRegisterBase = ChildAdapter->CrashDumpRegisterBase[v10];
LABEL_9:
  if( *MapRegisterBase )
    *((_QWORD *)*MapRegisterBase + 7) = *MapRegisterBase;
  ++ChildAdapter->CrashDumpRegisterRefCount[v10];
  for( i = (__int64 *)HalpDmaHibernateAdapters; i != &HalpDmaHibernateAdapters; i = (__int64 *)*i )
  {
    v5 = (_ADAPTER_OBJECT *)(i - 35);
    if( i - 35 == (__int64 *)ChildAdapter )
      return 0;
  }
  if( v5 != ChildAdapter )
  {
    v13 = (_LIST_ENTRY *)qword_140C4BC48;
    p_AdapterCrashDumpList = &ChildAdapter->AdapterCrashDumpList;
    if( *(__int64 **)qword_140C4BC48 != &HalpDmaHibernateAdapters )
      __fastfail(3u);
    p_AdapterCrashDumpList->Flink = (_LIST_ENTRY *)&HalpDmaHibernateAdapters;
    p_AdapterCrashDumpList->Blink = v13;
    v13->Flink = p_AdapterCrashDumpList;
    qword_140C4BC48 = (__int64)p_AdapterCrashDumpList;
  }
  return 0;
}

Referenced by:

No references.