HalpIommuCreateDevice

INT64 __stdcall HalpIommuCreateDevice(PVOID Src){
  unsigned int v1; 
  __int64 *v2; 
  _BYTE *v3; 
  PVOID v4; 
  __int64 v5; 
  _BYTE *v6; 
  __int64 *v7; 
  struct _KDEVICE_QUEUE *v8; 
  __int64 v9; 
  __int64 i; 
  __int64 v11; 
  __int64 v12; 
  __int64 v13; 
  int AcpiDeviceMapping; 
  __int64 v15; 
  __int64 v16; 
  __int64 v17; 
  __int64 v18; 
  VOID *v19; 
  UINT64 v20; 
  UINT8 v21; 
  char v22; 
  __int64 *v23; 
  __int64 v24; 
  __int64 v25; 
  UINT8 a5; 
  __int64 a2; 
  __int64 a3; 
  INT64 a4; 
  __int128 Srca; 
  __int64 v32; 
  unsigned int v34; 
  __int64 *v35; 
  PVOID v36; 
  v35 = v2;
  v34 = v1;
  v4 = 0i64;
  a4 = 0i64;
  v5 = 0i64;
  a3 = 0i64;
  v32 = 0i64;
  v6 = v3;
  v36 = 0i64;
  v7 = v2;
  a2 = 0i64;
  v8 = (struct _KDEVICE_QUEUE *)Src;
  Srca = 0i64;
  if( v3 )
    *v3 = 0;
  ExAcquirePushLockExclusiveEx((UINT64)&HalpIommuDeviceCreatedListPushLock, 0i64);
  for( i = HalpIommuDeviceCreatedList; (__int64 *)i != &HalpIommuDeviceCreatedList; i = *(_QWORD *)v11 )
  {
    if( IidAreIdsStrictlyEqual(*(INT64 **)(i + 16), (INT64)v8) )
    {
      ++*(_DWORD *)(v11 + 32);
      *v7 = *(_QWORD *)(v11 + 24);
      AcpiDeviceMapping = 0;
      goto LABEL_34;
    }
  }
  v12 = HalpMmAllocCtxAlloc(v9, 40i64);
  v13 = v12;
  if( !v12 )
  {
    AcpiDeviceMapping = -1073741670;
    goto LABEL_34;
  }
  *(_OWORD *)v12 = 0i64;
  *(_OWORD *)(v12 + 16) = 0i64;
  *(_QWORD *)(v12 + 32) = 0i64;
  AcpiDeviceMapping = HalpIommuCloneDeviceId(v8);
  if( AcpiDeviceMapping < 0 )
    goto LABEL_30;
  v16 = HalpMmAllocCtxAlloc(v15, 216i64);
  v17 = v16;
  if( !v16 )
  {
    AcpiDeviceMapping = -1073741670;
LABEL_30:
    v24 = *(_QWORD *)(v13 + 16);
    if( v24 )
      HalpMmAllocCtxFree(v15, v24);
    HalpMmAllocCtxFree(v15, v13);
    if( v4 )
      HalpMmAllocCtxFree(v25, (__int64)v4);
    goto LABEL_34;
  }
  *(_QWORD *)(v13 + 24) = v16;
  memset(v16, 0i64);
  if( HalpHvIommu )
  {
    if( *(_DWORD *)&v8->Type == 2 )
    {
      AcpiDeviceMapping = (unsigned int)HalpIommuQueryAcpiDeviceMapping(v8, (ULONG)&Srca);
      if( AcpiDeviceMapping < 0 )
        goto LABEL_29;
      AcpiDeviceMapping = HalpIommuCloneDeviceId(&Srca);
      if( AcpiDeviceMapping < 0 )
        goto LABEL_29;
      v8 = (struct _KDEVICE_QUEUE *)Src;
      v4 = Src;
      v36 = Src;
    }
    AcpiDeviceMapping = IommupHvRegisterDeviceId((INT64)v8, &a2);
    if( AcpiDeviceMapping >= 0 )
    {
      v5 = a2;
      goto LABEL_21;
    }
LABEL_29:
    HalpMmAllocCtxFree(v18, v17);
    goto LABEL_30;
  }
  AcpiDeviceMapping = HalpIommuCreateDeviceInternal((INT64)v8, v34, &a3, &a4, v6);
  if( AcpiDeviceMapping < 0 )
    goto LABEL_29;
LABEL_21:
  if( HalpHvIommu )
  {
    *(_QWORD *)(v17 + 24) = v5;
  }
  else
  {
    *(_QWORD *)v17 = a3;
    *(_QWORD *)(v17 + 8) = a4;
  }
  if( !v4 )
  {
    v4 = v36;
    AcpiDeviceMapping = HalpIommuCloneDeviceId(v8);
    if( AcpiDeviceMapping < 0 )
      goto LABEL_29;
  }
  *(_QWORD *)(v17 + 32) = v4;
  HalpIommuCheckDpptException((MDL *)v8, v19, v20, v21, a5);
  *(_BYTE *)(v17 + 16) = v22;
  *v35 = v17;
  *(_DWORD *)(v13 + 32) = 1;
  v23 = (__int64 *)qword_140C49BB8;
  if( *(__int64 **)qword_140C49BB8 != &HalpIommuDeviceCreatedList )
    __fastfail(3u);
  *(_QWORD *)v13 = &HalpIommuDeviceCreatedList;
  *(_QWORD *)(v13 + 8) = v23;
  *v23 = v13;
  qword_140C49BB8 = v13;
LABEL_34:
  if( (_InterlockedExchangeAdd64(
          (volatile signed __int64 *)&HalpIommuDeviceCreatedListPushLock,
          0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock((volatile INT64 *)&HalpIommuDeviceCreatedListPushLock);
  KeAbPostRelease(&HalpIommuDeviceCreatedListPushLock);
  return(unsigned int)AcpiDeviceMapping;
}

Referenced by:

HalpDmaAllocateChildAdapterV3
HalpIommuUnblockDevice
IommuDomainAttachDevice