Newer
Older
AMI-Aptio-BIOS-Reversed / AmiModulePkg / Usb / Pei / UsbPei / UsbPei.c
@Ajax Dong Ajax Dong 2 days ago 160 KB Restructure the repo
#include "UsbPei.h"

//
// UsbPei - UEFI Module (Regenerated from IDA)
// Total functions: 119
//

// Function: XhciGetPciCfg @ 0x260 (0x20 bytes)
// Index: 1/119

void *__cdecl XhciGetPciCfg(void *buf, unsigned int count)
{
  memset(buf, 0, count); /*0x277*/
  return buf; /*0x27e*/
}


// Function: XhciStall @ 0x280 (0x15 bytes)
// Index: 2/119

void *__cdecl XhciStall(void *buf, unsigned int count, char value)
{
  memset(buf, value, count); /*0x28d*/
  return buf; /*0x293*/
}


// Function: XhciAllocatePages @ 0x2a0 (0x1f bytes)
// Index: 3/119

int __cdecl XhciAllocatePages(int a1, int a2, int a3, int a4)
{
  do /*0x2b9*/
  {
    *(_DWORD *)(a1 + 8 * a2 - 8) = a3; /*0x2b1*/
    *(_DWORD *)(a1 + 8 * a2-- - 4) = a4; /*0x2b5*/
  }
  while ( a2 ); /*0x2b9*/
  return a1; /*0x2bd*/
}


// Function: XhciFreePages @ 0x2c0 (0x15 bytes)
// Index: 4/119

void *__cdecl XhciFreePages(void *buf, unsigned int count, int value)
{
  memset32(buf, value, count); /*0x2cd*/
  return buf; /*0x2d3*/
}


// Function: XhciReportStatusCode @ 0x2e0 (0x3f bytes)
// Index: 5/119

char *__cdecl XhciReportStatusCode(char *dst, char *src, unsigned int count)
{
  unsigned int count_1; // edx
  char *dst_1; // edi
  char *src_1; // esi

  count_1 = count; /*0x2ea*/
  if ( src < dst && &src[count - 1] >= dst ) /*0x2f8*/
  {
    src_1 = &src[count - 1]; /*0x30c*/
    dst_1 = &dst[count - 1]; /*0x30e*/
  }
  else
  {
    count_1 = count & 3; /*0x2fc*/
    qmemcpy(dst, src, 4 * (count >> 2)); /*0x305*/
    src_1 = &src[4 * (count >> 2)]; /*0x305*/
    dst_1 = &dst[4 * (count >> 2)]; /*0x305*/
  }
  qmemcpy(dst_1, src_1, count_1); /*0x315*/
  return dst; /*0x31c*/
}


// Function: _ModuleEntryPoint @ 0x31f (0x14 bytes)
// Index: 6/119

EFI_STATUS ModuleEntryPoint(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
  (*(void (__cdecl **)(EFI_SYSTEM_TABLE *, void *))(LODWORD(SystemTable->Hdr.Signature) + 36))(SystemTable, &unk_89A0); /*0x32b*/
  return 0; /*0x332*/
}


// Function: XhciSchedulePortProbe @ 0x333 (0xe3 bytes)
// Index: 7/119

int __cdecl XhciSchedulePortProbe(int a1)
{
  int result; // eax
  unsigned int n0x7F; // edi
  int v3; // ecx
  unsigned int i; // ebx
  char n3; // [esp+3h] [ebp-Dh]
  int v6; // [esp+4h] [ebp-Ch] BYREF
  int v7; // [esp+8h] [ebp-8h] BYREF
  _BYTE v8[4]; // [esp+Ch] [ebp-4h] BYREF

  n3 = 3; /*0x33d*/
  if ( byte_8AC9 == 1 ) /*0x342*/
    return 0; /*0x344*/
  n0x7F = 0; /*0x356*/
  byte_8AC9 = 1; /*0x358*/
  result = (*(int (__cdecl **)(int, void *, _DWORD, _DWORD, int *))(*(_DWORD *)a1 + 32))(a1, &unk_8930, 0, 0, &v7); /*0x369*/
  if ( result >= 0 ) /*0x371*/
  {
    while ( 1 ) /*0x380*/
    {
      XhciEnumerateHub(v3, a1); /*0x380*/
      for ( i = 0; i < 0x7F; ++i ) /*0x385*/
      {
        if ( (*(int (__cdecl **)(int, void *, unsigned int, _BYTE *, int *))(*(_DWORD *)a1 + 32))( /*0x39e*/
               a1,
               &unk_8990,
               i,
               v8,
               &v6) < 0 )
          break; /*0x39e*/
        if ( *(_BYTE *)(*(_DWORD *)(v6 + 72) + 5) == 9 ) /*0x3ae*/
          XhciCreateUsbDevice(a1, v6 - 4, (_BYTE *)(*(_DWORD *)(v6 + 60) + 52), 1); /*0x3bb*/
      }
      if ( !--n3 ) /*0x3cd*/
        break; /*0x3cd*/
      (*(void (__cdecl **)(int, int, int))(v7 + 4))(a1, v7, 500000); /*0x3da*/
    }
    do /*0x40b*/
    {
      if ( (*(int (__cdecl **)(int, void *, unsigned int, _BYTE *, int *))(*(_DWORD *)a1 + 32))( /*0x3fa*/
             a1,
             &unk_8990,
             n0x7F,
             v8,
             &v6) < 0 )
        break; /*0x3fa*/
      XhciInitUsb2Port(a1, v6); /*0x402*/
      ++n0x7F; /*0x407*/
    }
    while ( n0x7F < 0x7F ); /*0x40b*/
    return 0; /*0x40d*/
  }
  return result; /*0x412*/
}


// Function: UsbPeiEntry @ 0x416 (0x70 bytes)
// Index: 8/119

int __cdecl UsbPeiEntry(int a1)
{
  void (__cdecl **v1)(int); // ecx
  unsigned int i; // edi
  int v3; // ecx
  void (__cdecl **v5)(int); // [esp+0h] [ebp-4h] BYREF

  v5 = v1; /*0x419*/
  if ( byte_8AC8 != 1 ) /*0x421*/
  {
    byte_8AC8 = 1; /*0x42b*/
    for ( i = 0; i < 0x10; ++i ) /*0x432*/
    {
      if ( (*(int (__cdecl **)(int, void *, unsigned int, _DWORD, void (__cdecl ***)(int)))(*(_DWORD *)a1 + 32))( /*0x44a*/
             a1,
             &unk_89AC,
             i,
             0,
             &v5) < 0 )
        break; /*0x44a*/
      (*v5)(a1); /*0x450*/
    }
    XhciInit(0, a1); /*0x45b*/
    XhciEnumerateHub(v3, a1); /*0x462*/
    XhciSchedulePortProbe(a1); /*0x46a*/
    (*(void (__cdecl **)(int, void *))(*(_DWORD *)a1 + 36))(a1, &unk_89BC); /*0x477*/
  }
  return 0; /*0x484*/
}


// Function: UsbPeiEnumerateDevices @ 0x486 (0x94 bytes)
// Index: 9/119

int __cdecl UsbPeiEnumerateDevices(int a1)
{
  int v1; // esi
  unsigned __int8 v2; // bh
  int i; // eax
  unsigned __int8 v4; // bl
  void (__cdecl *v5)(int, int, int); // ecx
  int v6; // eax
  int v8; // [esp+14h] [ebp-8h] BYREF
  int v9; // [esp+18h] [ebp-4h]

  v1 = a1; /*0x48b*/
  v2 = 1; /*0x4a1*/
  for ( i = (*(int (__cdecl **)(int, void *, _DWORD, _DWORD, int *))(*(_DWORD *)a1 + 32))(a1, &unk_8980, 0, 0, &v8); /*0x4a3*/
        i >= 0;
        i = (*(int (__cdecl **)(int, void *, int, _DWORD, int *))(*(_DWORD *)v1 + 32))(v1, &unk_8980, v6, 0, &v8) )
  {
    (*(void (__cdecl **)(int, int, int *))(v8 + 8))(v1, v8, &a1); /*0x4b3*/
    v4 = 1; /*0x4b6*/
    for ( LOBYTE(v9) = 1; v4 <= (unsigned __int8)a1; LOBYTE(v9) = v4 ) /*0x4c3*/
    {
      (*(void (__cdecl **)(int, int, int, int))(v8 + 20))(v1, v8, v9, 1); /*0x4d1*/
      ++v4; /*0x4d7*/
    }
    v5 = *(void (__cdecl **)(int, int, int))(v8 + 32); /*0x4e7*/
    if ( v5 ) /*0x4ec*/
      v5(v1, v8, 1); /*0x4f2*/
    v6 = v2++; /*0x4fe*/
  }
  return 0; /*0x512*/
}


// Function: XhciInit @ 0x51a (0xaf0 bytes)
// Index: 10/119

int __cdecl XhciInit(int PeiServices, int XhcDev)
{
  int OpRegVal; // eax
  __int64 PciConfigAddr; // [esp-10h] [ebp-64h]
  int HcMemBase; // [esp+0h] [ebp-54h] BYREF
  __int64 PciFullAddr; // [esp+10h] [ebp-44h]
  int PciAttr; // [esp+18h] [ebp-3Ch] BYREF
  _DWORD NotifyProto[2]; // [esp+1Ch] [ebp-38h] BYREF
  int PageCount; // [esp+24h] [ebp-30h]
  int NotifyIndex; // [esp+28h] [ebp-2Ch]
  char PciSpeed; // [esp+2Ch] [ebp-28h]
  int BarBase; // [esp+30h] [ebp-24h] BYREF
  unsigned __int64 ProgIfInfo; // [esp+34h] [ebp-20h] BYREF
  int PciBar; // [esp+38h] [ebp-1Ch]
  int Status; // [esp+3Ch] [ebp-18h]
  int HcIndex; // [esp+40h] [ebp-14h]
  int HcMemBase_1; // [esp+44h] [ebp-10h]
  __int16 DeviceId; // [esp+48h] [ebp-Ch] BYREF
  _WORD Vid[2]; // [esp+4Ch] [ebp-8h] BYREF
  char CapRegVal; // [esp+51h] [ebp-3h] BYREF
  char MemRegVal; // [esp+52h] [ebp-2h]
  unsigned __int8 PciDevIdx; // [esp+53h] [ebp-1h]

  BarBase = -25165824; /*0x520*/
  CapRegVal = 6; /*0x527*/
  NotifyIndex = 0;... [13295 chars total]


// Function: XhciAllocPageTables @ 0x100a (0x179 bytes)
// Index: 11/119

int __cdecl XhciAllocPageTables(int XhcDev, int buf)
{
  int EntryIndex; // ecx
  int EntryAddr; // esi
  int PageTableBuf[2]; // [esp+4h] [ebp-20h] BYREF
  int EntryAddr_1; // [esp+Ch] [ebp-18h]
  int BufBase; // [esp+10h] [ebp-14h]
  BOOL Aligned; // [esp+14h] [ebp-10h]
  int Status; // [esp+18h] [ebp-Ch]
  unsigned __int16 EntryIdx; // [esp+1Ch] [ebp-8h]
  unsigned __int16 EntryIdx_1; // [esp+20h] [ebp-4h]

  EntryIdx_1 = ((unsigned __int8)HIBYTE(*(_DWORD *)(buf + 1151296)) >> 3) /*0x1034*/
             + 32 * ((*(_DWORD *)(buf + 1151296) >> 21) & 0x1F);
  if ( !EntryIdx_1 ) /*0x103e*/
    return 0; /*0x1040*/
  Aligned = ((8 * EntryIdx_1) & 0xFFF) != 0; /*0x1053*/
  Status = (*(int (__cdecl **)(int, int, unsigned int, int *))(*(_DWORD *)XhcDev + 72))( /*0x1084*/
             XhcDev,
             4,
             Aligned + ((8 * (unsigned int)EntryIdx_1) >> 12),
             PageTableBuf);
  if ( Status < 0 ) /*0x108b*/
    return -2147483639; /*0x108d*/
  ZeroMem(PageTableBuf[0], 8 * EntryIdx_1); /*0x10a1*/
  EntryAddr_1 = PageTableBuf[0]; /*0x10a9*/
  Status = (*(int (__cdecl **)(int, int, int, int *))(*(_DWORD *)XhcDev + 72))( /*0x10d0*/
             XhcDev,
             4,
             *(_DWORD *)(buf + 1118424) * (EntryIdx_1 + 1),
             PageTableBuf);
  if ( Status < 0 ) /*0x10d7*/
    return -2147483639; /*0x10d9*/
  ZeroMem(PageTableBuf[0], (EntryIdx_1 + 1) * (*(_DWORD *)(buf + 1118424) << 12)); /*0x10fa*/
  BufBase = (*(_DWORD *)(buf + 1118424) << 12) - 1; /*0x110c*/
  PageTableBuf[0] = ~BufBase & (BufBase + PageTableBuf[0]); /*0x111e*/
  PageTableBuf[1] = 0; /*0x1121*/
  for ( EntryIdx = 0; EntryIdx < (int)EntryIdx_1; ++EntryIdx ) /*0x1126*/
  {
    EntryIndex = EntryIdx; /*0x115c*/
    EntryAddr = EntryAddr_1; /*0x1162*/
    *(_DWORD *)(EntryAddr_1 + 8 * EntryIdx) = EntryIdx * (*(_DWORD *)(buf + 1118424) << 12) + PageTableBuf[0]; /*0x1165*/
    *(_DWORD *)(EntryAddr + 8 * EntryIndex + 4) = 0; /*0x1168*/
  }
  **(_DWORD **)(buf + 1151284) = EntryAddr_1; /*0x117a*/
  return 0; /*0x117e*/
}


// Function: XhciCoreInit @ 0x1183 (0x823 bytes)
// Index: 12/119

int __cdecl XhciCoreInit(int XhcDev, int XhcRegBase)
{
  int DcbaapVal; // [esp+0h] [ebp-20h]
  int PortScAddr; // [esp+4h] [ebp-1Ch]
  int PortRegVal; // [esp+8h] [ebp-18h] BYREF
  int DeciSecVal; // [esp+Ch] [ebp-14h] BYREF
  int PortRegBase; // [esp+10h] [ebp-10h]
  int TempVal; // [esp+14h] [ebp-Ch]
  unsigned int PortIdx; // [esp+18h] [ebp-8h]
  char MaxPorts; // [esp+1Dh] [ebp-3h]
  unsigned __int8 i; // [esp+1Eh] [ebp-2h]
  unsigned __int8 SlotNum; // [esp+1Fh] [ebp-1h]

  MaxPorts = 0; /*0x1189*/
  DcbaapVal = 0; /*0x118d*/
  PortRegVal = 0; /*0x1191*/
  for ( PortIdx = 0; PortIdx < 0x3E8 && (XhciReadOpReg(XhcRegBase, 4) & 0x800) != 0; ++PortIdx ) /*0x1195*/
    (*(void (__cdecl **)(_DWORD, _DWORD, int))(*(_DWORD *)(XhcRegBase + 1151667) + 4))( /*0x11dd*/
      *(_DWORD *)(XhcRegBase + 1151591),
      *(_DWORD *)(XhcRegBase + 1151667),
      100);
  if ( DebugEnabled() && (XhciReadOpReg(XhcRegBase, 4) & 0x800) != 0 ) /*0x1202*/
    DebugAssert( /*0x1213*/
      (int)"e:\\hs\\Am... [8239 chars total]


// Function: XhciInitDeviceContext @ 0x19a6 (0x5ad bytes)
// Index: 13/119

int __cdecl XhciInitDeviceContext(
        int PeiServices,
        int XhcRegBase,
        int UsbDevice,
        unsigned __int8 SlotId,
        unsigned __int8 RouteString)
{
  int EpCtx2; // eax
  int DcbaapPtr; // eax
  int SlotId_1; // ecx
  int Status; // [esp+4h] [ebp-44h]
  bool SetAddress; // [esp+8h] [ebp-40h]
  unsigned __int8 SlotIdBuf[4]; // [esp+Ch] [ebp-3Ch] BYREF
  _DWORD *InputCtxPtr; // [esp+10h] [ebp-38h]
  int DevCtxBase; // [esp+14h] [ebp-34h]
  int DevCtx0; // [esp+18h] [ebp-30h]
  int DevCtxEntry; // [esp+1Ch] [ebp-2Ch]
  int EpCtxCount; // [esp+20h] [ebp-28h]
  int CmdStatus; // [esp+24h] [ebp-24h]
  int TransferRing; // [esp+28h] [ebp-20h]
  int buf; // [esp+2Ch] [ebp-1Ch]
  char Speed; // [esp+30h] [ebp-18h]
  int EpCtx; // [esp+34h] [ebp-14h]
  _DWORD *ParentDevCtx; // [esp+38h] [ebp-10h]
  _DWORD *SlotCtx; // [esp+3Ch] [ebp-Ch]
  unsigned __int8 CmdParams[6]; // [esp+40h] [ebp-8h] BYREF
  bool SetAddress_1; // [esp+46h] [ebp-2h]
  unsigned __int8 EpIdx; // [esp+47h] [ebp-1h]

  DevCtx0 = 0; /*0x19ad*/
  SlotCtx = 0; /*0x19b1*/
  ParentDevCtx = 0; /*0x19b5*/
  EpCtx = 0; /*0x19b9*/
  InputCtxPtr = 0; /*0x19bd*/
  DevCtxBase = XhciGetDevCtxBase(XhcRegBase, SlotId); /*0x19ce*/
  buf = *(_DWORD *)(XhcRegBase + 1118436); /*0x19da*/
  TransferRing = 0; /*0x19dd*/
  *(_WORD *)CmdParams = 0; /*0x19e3*/
  SetAddress_1 = 0; /*0x19e7*/
  DevCtxEntry = XhciGetDevCtxEntry(XhcRegBase, DevCtxBase, 0); /*0x19fb*/
  if ( (unsigned __int8)((unsigned __int8)HIBYTE(*(_DWORD *)(DevCtxEntry + 12)) >> 3) >= 2u ) /*0x1a0d*/
    return -2147483641; /*0x1a0f*/
  ZeroMem(buf, 33 * *(unsigned __int8 *)(XhcRegBase + 1118428)); /*0x1a29*/
  DevCtx0 = XhciGetDevCtxEntry(XhcRegBase, buf, 0); /*0x1a3e*/
  *(_DWORD *)(DevCtx0 + 4) = 3; /*0x1a44*/
  SlotCtx = (_DWORD *)XhciGetDevCtxEntry(XhcRegBase, buf, 1u); /*0x1a5b*/
  *SlotCtx &= 0xFFF00000; /*0x1a6b*/
  *SlotCtx = *SlotCtx & 0x7FFFFFF | 0x8000000; /*0x1a7f*/
  if ( *(_WORD *)(UsbDevice + 144) ) /*0x1a84*/
  {
    CmdStatus = XhciLookupDeviceByRoute((_BYTE *)(XhcRegBase + 1151360), SlotIdBuf, *(_BYTE *)(UsbDevice + 144) & 0x7F); /*0x1ad7*/
    if ( DebugEnabled() && CmdStatus ) /*0x1aea*/
      DebugAssert((int)"e:\\hs\\AmiModulePkg\\Usb\\Pei\\PeiXhci.c", 675, (int)"Status == 0"); /*0x1afb*/
    Status = XhciGetDevCtxBase(XhcRegBase, SlotIdBuf[0]); /*0x1b12*/
    ParentDevCtx = (_DWORD *)XhciGetDevCtxEntry(XhcRegBase, Status, 0); /*0x1b25*/
    SlotCtx[1] = ((unsigned __int8)BYTE2(ParentDevCtx[1]) << 16) | SlotCtx[1] & 0xFF00FFFF; /*0x1b4f*/
  }
  else
  {
    SlotCtx[1] = (RouteString << 16) | SlotCtx[1] & 0xFF00FFFF; /*0x1aac*/
  }
  Speed = *(_BYTE *)(UsbDevice + 56); /*0x1b58*/
  switch ( Speed ) /*0x1b5f*/
  {
    case 1: /*0x1b5f*/
      *SlotCtx = *SlotCtx & 0xFF0FFFFF | 0x200000; /*0x1ba3*/
      break;
    case 2: /*0x1b5f*/
      *SlotCtx = *SlotCtx & 0xFF0FFFFF | 0x100000; /*0x1bb9*/
      break;
    case 3: /*0x1b5f*/
      *SlotCtx = *SlotCtx & 0xFF0FFFFF | 0x300000; /*0x1b8d*/
      break;
    case 4: /*0x1b5f*/
      *SlotCtx = *SlotCtx & 0xFF0FFFFF | 0x400000; /*0x1bcf*/
      break;
    case 5: /*0x1b5f*/
      *SlotCtx = *SlotCtx & 0xFF0FFFFF | 0x500000; /*0x1be5*/
      break;
  }
  InputCtxPtr = (_DWORD *)XhciGetDevCtxEntry(XhcRegBase, DevCtxBase, 1u); /*0x1bf7*/
  EpCtxCount = *InputCtxPtr & 7; /*0x1c02*/
  if ( EpCtxCount ) /*0x1c05*/
  {
    if ( EpCtxCount == 1 || EpCtxCount == 3 ) /*0x1c11*/
      TransferRing = XhciGetTransferRing(XhcRegBase, SlotId, 0); /*0x1c3a*/
  }
  else
  {
    TransferRing = XhciAllocTransferRing(XhcRegBase, SlotId, 0); /*0x1c25*/
  }
  EpCtx = XhciGetDevCtxEntry(XhcRegBase, buf, 2u); /*0x1c4d*/
  *(_DWORD *)(EpCtx + 4) = *(_DWORD *)(EpCtx + 4) & 0xFFFFFFC7 | 0x20; /*0x1c5f*/
  *(_DWORD *)(EpCtx + 4) = (*(unsigned __int16 *)(UsbDevice + 54) << 16) | (unsigned __int16)*(_DWORD *)(EpCtx + 4); /*0x1c82*/
  EpCtx2 = EpCtx; /*0x1c99*/
  *(_DWORD *)(EpCtx + 8) = *(unsigned __int8 *)(TransferRing + 16) | *(_DWORD *)(TransferRing + 12); /*0x1c9c*/
  *(_DWORD *)(EpCtx2 + 12) = 0; /*0x1c9f*/
  *(_WORD *)(EpCtx + 16) = 8; /*0x1ca8*/
  *(_DWORD *)(EpCtx + 4) |= 6u; /*0x1cb8*/
  if ( *(_WORD *)(UsbDevice + 144) ) /*0x1cbe*/
  {
    if ( ((*ParentDevCtx >> 20) & 0xF) == 4 || ((*ParentDevCtx >> 20) & 0xF) == 5 ) /*0x1ceb*/
    {
      for ( EpIdx = 0; EpIdx < 5u && (((*ParentDevCtx & 0xFFFFFu) >> (4 * EpIdx)) & 0xF) != 0; ++EpIdx ) /*0x1ced*/
        ; /*0x1cf8*/
      *SlotCtx = (RouteString << (4 * EpIdx)) & 0xFFFFF | *ParentDevCtx & 0xFFFFF | *SlotCtx & 0xFFF00000; /*0x1d4e*/
    }
    else if ( ((*SlotCtx >> 20) & 0xF) == 1 || ((*SlotCtx >> 20) & 0xF) == 2 ) /*0x1d73*/
    {
      if ( ((*ParentDevCtx >> 20) & 0xF) == 3 ) /*0x1d87*/
      {
        SlotCtx[2] = SlotIdBuf[0] | SlotCtx[2] & 0xFFFFFF00; /*0x1da3*/
        SlotCtx[2] = ((unsigned __int8)((int)*(unsigned __int16 *)(UsbDevice + 144) >> 7) << 8) /*0x1dcf*/
                   | SlotCtx[2] & 0xFFFF00FF;
      }
      else
      {
        SlotCtx[2] = (unsigned __int8)ParentDevCtx[2] | SlotCtx[2] & 0xFFFFFF00; /*0x1e18*/
        SlotCtx[2] = ((unsigned __int8)BYTE1(ParentDevCtx[2]) << 8) | SlotCtx[2] & 0xFFFF00FF; /*0x1e42*/
      }
      *SlotCtx = (((*ParentDevCtx & 0x2000000) != 0) << 25) | *SlotCtx & 0xFDFFFFFF; /*0x1df3*/
    }
  }
  SetAddress = ((*SlotCtx >> 20) & 0xF) != 4 /*0x1e9f*/
            && ((*SlotCtx >> 20) & 0xF) != 5
            && !((unsigned __int8)HIBYTE(*(_DWORD *)(DevCtxEntry + 12)) >> 3);
  SetAddress_1 = SetAddress; /*0x1ea6*/
  *(_WORD *)CmdParams = (SetAddress << 8) | SlotId; /*0x1eb6*/
  CmdStatus = XhciIssueCommand(PeiServices, XhcRegBase, 11, CmdParams); /*0x1ece*/
  if ( CmdStatus )
  {
    XhciIssueCommand(PeiServices, XhcRegBase, 10, &SlotId); /*0x1ee3*/
    DcbaapPtr = *(_DWORD *)(XhcRegBase + 1151284); /*0x1eee*/
    SlotId_1 = SlotId; /*0x1ef4*/
    *(_DWORD *)(DcbaapPtr + 8 * SlotId) = 0; /*0x1ef8*/
    *(_DWORD *)(DcbaapPtr + 8 * SlotId_1 + 4) = 0; /*0x1efc*/
    return CmdStatus; /*0x1f01*/
  }
  else
  {
    if ( !SetAddress_1 && DebugEnabled() )
    {
      if ( DebugLevelEnabled() )
        DebugPrint(64, (int)"PEI_XHCI: new device address %d\n", (unsigned __int8)*(_DWORD *)(DevCtxEntry + 12));
    }
    return 0; /*0x1f4c*/
  }
}


// Function: XhciEnableSlot @ 0x1f53 (0x14f bytes)
// Index: 14/119

int __cdecl XhciEnableSlot(int PeiServices, int UsbDevice, unsigned __int8 RouteString)
{
  int DevCtxPtr; // edx
  int SlotIdIdx; // esi
  int DevCtxBase; // [esp+4h] [ebp-14h]
  int Status; // [esp+8h] [ebp-10h]
  int SlotInited; // [esp+8h] [ebp-10h]
  unsigned __int8 SlotIdBuf[4]; // [esp+Ch] [ebp-Ch] BYREF
  int UsbDevicea; // [esp+10h] [ebp-8h]
  int XhcRegBase; // [esp+14h] [ebp-4h]

  UsbDevicea = UsbDevice; /*0x1f5d*/
  XhcRegBase = *(_DWORD *)(UsbDevice + 64) - 1151595; /*0x1f6b*/
  if ( *(_BYTE *)(UsbDevice + 56) == 3 || *(_BYTE *)(UsbDevicea + 56) == 2 || *(_BYTE *)(UsbDevicea + 56) == 1 ) /*0x1f90*/
    (*(void (__cdecl **)(_DWORD, _DWORD, int))(*(_DWORD *)(XhcRegBase + 1151667) + 4))( /*0x1fb2*/
      *(_DWORD *)(XhcRegBase + 1151591),
      *(_DWORD *)(XhcRegBase + 1151667),
      5000);
  Status = XhciIssueCommand(PeiServices, XhcRegBase, 9, SlotIdBuf); /*0x1fcc*/
  if ( Status ) /*0x1fd3*/
    return Status; /*0x1fd5*/
  *(_BYTE *)(UsbDevicea + 62) = SlotIdBuf[0]; /*0x1fe3*/
  DevCtxBase = XhciGetDevCtxBase(XhcRegBase, SlotIdBuf[0]); /*0x1ff3*/
  ZeroMem(DevCtxBase, 32 * *(unsigned __int8 *)(XhcRegBase + 1118428)); /*0x2006*/
  DevCtxPtr = *(_DWORD *)(XhcRegBase + 1151284); /*0x2013*/
  SlotIdIdx = SlotIdBuf[0]; /*0x2019*/
  *(_DWORD *)(DevCtxPtr + 8 * SlotIdBuf[0]) = DevCtxBase; /*0x201d*/
  *(_DWORD *)(DevCtxPtr + 8 * SlotIdIdx + 4) = 0; /*0x2020*/
  if ( DebugEnabled() && DebugLevelEnabled() )
    DebugPrint(64, (int)"PEI_XHCI: Slot[%d] enabled, device context at %x\n", SlotIdBuf[0], DevCtxBase);
  SlotInited = XhciInitDeviceContext(PeiServices, XhcRegBase, UsbDevicea, SlotIdBuf[0], RouteString); /*0x2075*/
  if ( !SlotInited ) /*0x207c*/
    XhciAddDeviceEntry(XhcRegBase + 1151360, SlotIdBuf[0], RouteString, UsbDevicea, 0); /*0x2092*/
  return SlotInited; /*0x209d*/
}


// Function: XhciAddDeviceEntry @ 0x20a2 (0x8f bytes)
// Index: 15/119

int __cdecl XhciAddDeviceEntry(int a1, char SlotIdOut, char RouteString, int UsbDevice, char a5)
{
  int v6; // [esp+0h] [ebp-8h]
  unsigned __int8 i; // [esp+7h] [ebp-1h]

  v6 = a1; /*0x20aa*/
  if ( a5 ) /*0x20b3*/
  {
    for ( i = 1; i < 0x21u; ++i ) /*0x20d5*/
    {
      if ( !*(_BYTE *)v6 ) /*0x20f8*/
      {
        *(_BYTE *)v6 = SlotIdOut; /*0x2105*/
        *(_BYTE *)(v6 + 1) = a5; /*0x210d*/
        *(_BYTE *)(v6 + 2) = RouteString; /*0x2116*/
        *(_DWORD *)(v6 + 3) = UsbDevice; /*0x211f*/
        return 0; /*0x2124*/
      }
      v6 += 7; /*0x20e9*/
    }
    return -2147483634; /*0x2128*/
  }
  else
  {
    *(_BYTE *)a1 = SlotIdOut; /*0x20bb*/
    *(_BYTE *)(a1 + 2) = RouteString; /*0x20c3*/
    *(_DWORD *)(a1 + 3) = UsbDevice; /*0x20cc*/
    return 0; /*0x20cf*/
  }
}


// Function: XhciLookupDeviceByRoute @ 0x2131 (0x53 bytes)
// Index: 16/119

int __cdecl XhciLookupDeviceByRoute(_BYTE *a1, _BYTE *p_SlotIdOut, unsigned __int8 DeviceAddress)
{
  unsigned __int8 i; // [esp+7h] [ebp-1h]

  for ( i = 1; i < 0x21u; ++i ) /*0x213c*/
  {
    if ( (unsigned __int8)a1[1] == DeviceAddress ) /*0x2169*/
    {
      *p_SlotIdOut = *a1; /*0x2173*/
      return 0; /*0x2177*/
    }
    a1 += 7; /*0x2150*/
  }
  return -2147483634; /*0x2180*/
}


// Function: XhciFreeEndpoint @ 0x2184 (0x65 bytes)
// Index: 17/119

char __cdecl XhciFreeEndpoint(int PeiServices, int XhcRegBase, unsigned __int8 SlotIdOut, unsigned __int8 EpIndex)
{
  int DevCtxBase; // eax
  char v6; // [esp+4h] [ebp-8h]
  unsigned __int8 v7[4]; // [esp+8h] [ebp-4h] BYREF

  v6 = 0; /*0x218a*/
  DevCtxBase = XhciGetDevCtxBase(XhcRegBase, SlotIdOut); /*0x2197*/
  if ( (*(_DWORD *)XhciGetDevCtxEntry(XhcRegBase, DevCtxBase, EpIndex) & 7) == 2 ) /*0x21b8*/
  {
    *(_WORD *)v7 = SlotIdOut + (EpIndex << 8); /*0x21c7*/
    return XhciIssueCommand(PeiServices, XhcRegBase, 14, v7); /*0x21df*/
  }
  return v6; /*0x21e5*/
}


// Function: XhciConfigureEndpoint @ 0x21e9 (0xf6 bytes)
// Index: 18/119

int __cdecl XhciConfigureEndpoint(int PeiServices, int XhcRegBase, unsigned __int8 SlotIdOut, unsigned __int8 EpIndex)
{
  int DevCtxBase; // eax
  unsigned __int8 EpCtxParams[4]; // [esp+0h] [ebp-20h] BYREF
  int EpCtx1; // [esp+4h] [ebp-1Ch]
  unsigned int MaxEsitVal; // [esp+Ch] [ebp-14h]
  int TransferRing; // [esp+10h] [ebp-10h]
  int EpCtx2; // [esp+14h] [ebp-Ch]
  _DWORD *DevCtxEntry; // [esp+18h] [ebp-8h]
  unsigned __int8 EpCtx3[4]; // [esp+1Ch] [ebp-4h] BYREF

  EpCtx2 = 0; /*0x21ef*/
  DevCtxBase = XhciGetDevCtxBase(XhcRegBase, SlotIdOut); /*0x21fc*/
  DevCtxEntry = (_DWORD *)XhciGetDevCtxEntry(XhcRegBase, DevCtxBase, EpIndex); /*0x220f*/
  if ( (*DevCtxEntry & 7) == 2 ) /*0x221d*/
  {
    *(_WORD *)EpCtx3 = SlotIdOut + (EpIndex << 8); /*0x222c*/
    EpCtx2 = XhciIssueCommand(PeiServices, XhcRegBase, 14, EpCtx3); /*0x2244*/
  }
  if ( (*DevCtxEntry & 7) == 3 || (*DevCtxEntry & 7) == 4 ) /*0x225f*/
  {
    TransferRing = XhciGetTransferRing(XhcRegBase, SlotIdOut, EpIndex - 1); /*0x2275*/
    *(_DWORD *)EpCtxParams = *(unsigned __int8 *)(TransferRing + 16) + *(_DWORD *)(TransferRing + 12); /*0x2289*/
    EpCtx1 = 0; /*0x228c*/
    MaxEsitVal = ((EpIndex & 0x1F) << 16) | MaxEsitVal & 0xFFE0FFFF; /*0x22a4*/
    MaxEsitVal = (SlotIdOut << 24) | MaxEsitVal & 0xFFFFFF; /*0x22be*/
    return XhciIssueCommand(PeiServices, XhcRegBase, 16, EpCtxParams); /*0x22d5*/
  }
  return EpCtx2; /*0x22db*/
}


// Function: XhciConfigureEndpointEx @ 0x22df (0x118 bytes)
// Index: 19/119

int __cdecl XhciConfigureEndpointEx(int PeiServices, int XhcRegBase, unsigned __int8 SlotIdOut, unsigned __int8 EpType)
{
  int DevCtxBase; // eax
  unsigned __int8 EpCtxParams[4]; // [esp+0h] [ebp-24h] BYREF
  int EpCtx1; // [esp+4h] [ebp-20h]
  unsigned int MaxEsitVal; // [esp+Ch] [ebp-18h]
  int TransferRing; // [esp+10h] [ebp-14h]
  int EpCtx2; // [esp+14h] [ebp-10h]
  _DWORD *DevCtxEntry; // [esp+18h] [ebp-Ch]
  int EpCtx3; // [esp+1Ch] [ebp-8h]
  unsigned __int8 EpCtx4[4]; // [esp+20h] [ebp-4h] BYREF

  EpCtx2 = 0; /*0x22e5*/
  if ( EpType ) /*0x22ef*/
    LOBYTE(EpCtx3) = ((int)EpType >> 7) + 2 * (EpType & 0xF); /*0x2302*/
  else
    LOBYTE(EpCtx3) = 1; /*0x2307*/
  DevCtxBase = XhciGetDevCtxBase(XhcRegBase, SlotIdOut); /*0x2314*/
  DevCtxEntry = (_DWORD *)XhciGetDevCtxEntry(XhcRegBase, DevCtxBase, EpCtx3); /*0x2327*/
  if ( (*DevCtxEntry & 7) == 1 ) /*0x2335*/
  {
    *(_WORD *)EpCtx4 = SlotIdOut + ((unsigned __int8)EpCtx3 << 8); /*0x2344*/
    EpCtx2 = XhciIssueCommand(PeiServices, XhcRegBase, 15, EpCtx4); /*0x235c*/
  }
  if ( (*DevCtxEntry & 7) == 3 || (*DevCtxEntry & 7) == 4 ) /*0x2377*/
  {
    TransferRing = XhciGetTransferRing(XhcRegBase, SlotIdOut, EpCtx3 - 1); /*0x238d*/
    *(_DWORD *)EpCtxParams = *(unsigned __int8 *)(TransferRing + 16) + *(_DWORD *)(TransferRing + 12); /*0x23a1*/
    EpCtx1 = 0; /*0x23a4*/
    MaxEsitVal = ((EpCtx3 & 0x1F) << 16) | MaxEsitVal & 0xFFE0FFFF; /*0x23bc*/
    MaxEsitVal = (SlotIdOut << 24) | MaxEsitVal & 0xFFFFFF; /*0x23d6*/
    return XhciIssueCommand(PeiServices, XhcRegBase, 16, EpCtxParams); /*0x23ed*/
  }
  return EpCtx2; /*0x23f3*/
}


// Function: XhciEvaluateEndpoint @ 0x23f7 (0xfb bytes)
// Index: 20/119

int __cdecl XhciEvaluateEndpoint(int PeiServices, int XhcRegBase, unsigned __int8 SlotIdOut, unsigned __int8 a4)
{
  int result; // eax
  int DevCtxBase; // [esp+8h] [ebp-8h]
  int DevCtxEntry; // [esp+Ch] [ebp-4h]

  DevCtxBase = XhciGetDevCtxBase(XhcRegBase, SlotIdOut); /*0x240a*/
  result = (*(_DWORD *)XhciGetDevCtxEntry(XhcRegBase, DevCtxBase, 0) >> 20) & 0xF; /*0x2428*/
  if ( result == 1 ) /*0x242e*/
  {
    result = (unsigned __int16)HIWORD(*(_DWORD *)(XhciGetDevCtxEntry(XhcRegBase, DevCtxBase, 1u) + 4)); /*0x2451*/
    if ( result != a4 ) /*0x245c*/
    {
      ZeroMem(*(_DWORD *)(XhcRegBase + 1118436), 33 * *(unsigned __int8 *)(XhcRegBase + 1118428)); /*0x2479*/
      *(_DWORD *)(XhciGetDevCtxEntry(XhcRegBase, *(_DWORD *)(XhcRegBase + 1118436), 0) + 4) = 2; /*0x249a*/
      DevCtxEntry = XhciGetDevCtxEntry(XhcRegBase, *(_DWORD *)(XhcRegBase + 1118436), 2u); /*0x24b7*/
      *(_DWORD *)(DevCtxEntry + 4) = (a4 << 16) | (unsigned __int16)*(_DWORD *)(DevCtxEntry + 4); /*0x24d7*/
      return XhciIssueCommand(PeiServices, XhcRegBase, 13, &SlotIdOut); /*0x24e6*/
    }
  }
  return result; /*0x24ee*/
}


// Function: XhciRingDoorbell @ 0x24f2 (0xbf bytes)
// Index: 21/119

int __cdecl XhciRingDoorbell(int PeiServices, int XhcRegBase, unsigned __int8 SlotIdOut, unsigned __int8 EpIndex)
{
  int DevCtxBase; // eax
  unsigned __int8 EpIndex_1; // [esp-4h] [ebp-10h]
  int DoorbellReg; // [esp+0h] [ebp-Ch]
  _DWORD *DevCtxEntry; // [esp+4h] [ebp-8h]
  unsigned int i; // [esp+8h] [ebp-4h]

  DoorbellReg = XhciGetDoorbellReg(XhcRegBase, SlotIdOut); /*0x2509*/
  XhciWriteMem(XhcRegBase, 2u, DoorbellReg, 1u, (int)&EpIndex); /*0x251a*/
  if ( !SlotIdOut ) /*0x2528*/
    return -2147483641; /*0x252a*/
  EpIndex_1 = EpIndex; /*0x2531*/
  DevCtxBase = XhciGetDevCtxBase(XhcRegBase, SlotIdOut); /*0x253a*/
  DevCtxEntry = (_DWORD *)XhciGetDevCtxEntry(XhcRegBase, DevCtxBase, EpIndex_1); /*0x254d*/
  for ( i = 0; i < 0x64 && (*DevCtxEntry & 7) != 1; ++i ) /*0x2550*/
    (*(void (__cdecl **)(_DWORD, _DWORD, int))(*(_DWORD *)(XhcRegBase + 1151667) + 4))( /*0x258f*/
      *(_DWORD *)(XhcRegBase + 1151591),
      *(_DWORD *)(XhcRegBase + 1151667),
      100);
  if ( (*DevCtxEntry & 7) == 1 ) /*0x25a2*/
    return 0; /*0x25ab*/
  else
    return -2147483641; /*0x25a4*/
}


// Function: XhciCreateTransfer @ 0x25b1 (0x4e0 bytes)
// Index: 22/119

int __cdecl XhciCreateTransfer(
        int PeiServices,
        int XhcFull,
        unsigned __int8 DeviceAddress,
        int EndpointAddr,
        int a5,
        int MaxPacketLength,
        unsigned __int8 *Request,
        int RequestLen,
        int DataBuffer,
        _WORD *DataLen,
        int Timeout,
        _DWORD *ResultFlags)
{
  unsigned int TrbFlags; // eax
  unsigned int TrbDataPtr; // edx
  int DevCtxBase; // [esp+0h] [ebp-2Ch]
  int DevCtxEntry; // [esp+8h] [ebp-24h]
  int TransferRing; // [esp+10h] [ebp-1Ch]
  int Status; // [esp+14h] [ebp-18h]
  int CmdStatus; // [esp+14h] [ebp-18h]
  int RingStatus; // [esp+14h] [ebp-18h]
  int DoorbellStatus; // [esp+14h] [ebp-18h]
  char SlotIdBuf[4]; // [esp+18h] [ebp-14h] BYREF
  int XhcRegBase; // [esp+1Ch] [ebp-10h]
  unsigned int TrbDataPtr_1; // [esp+20h] [ebp-Ch]
  __int16 RequestType; // [esp+24h] [ebp-8h]
  char CompletionCode; // [esp+2Bh] [ebp-1h] BYREF

  XhcRegBase = XhcFull - 1151595; /*0x25bf*/
  RequestType = *Request + (Request[1] << 8); /*0x25d4*/
  if ( DeviceAddress ) /*0x25e2*/
  {
    Status = XhciLookupDeviceByRoute((_BYTE *)(XhcRegBase + 1151360), SlotIdBuf, DeviceAddress); /*0x260a*/
    if ( DebugEnabled() && Status ) /*0x261d*/
      DebugAssert((int)"e:\\hs\\AmiModulePkg\\Usb\\Pei\\PeiXhci.c", 1186, (int)"Status == 0"); /*0x262e*/
  }
  else
  {
    SlotIdBuf[0] = *(_BYTE *)(XhcRegBase + 1151360); /*0x25ed*/
  }
  if ( !SlotIdBuf[0] ) /*0x263e*/
    return -2147483641; /*0x2645*/
  DevCtxBase = XhciGetDevCtxBase(XhcRegBase, SlotIdBuf[0]); /*0x2657*/
  DevCtxEntry = XhciGetDevCtxEntry(XhcRegBase, DevCtxBase, 0); /*0x266a*/
  if ( !*Request && Request[1] == 5 ) /*0x2685*/
  {
    if ( (unsigned __int8)HIBYTE(*(_DWORD *)(DevCtxEntry + 12)) >> 3 == 1 ) /*0x269a*/
      XhciInitDeviceContext( /*0x26b9*/
        PeiServices,
        XhcRegBase,
        *(_DWORD *)(XhcRegBase + 1151363),
        SlotIdBuf[0],
        *(_BYTE *)(XhcRegBase + 1151362));
    CmdStatus = XhciAddDeviceEntry( /*0x26f4*/
                  XhcRegBase + 1151360,
                  SlotIdBuf[0],
                  *(_BYTE *)(XhcRegBase + 1151362),
                  *(_DWORD *)(XhcRegBase + 1151363),
                  Request[2]);
    if ( DebugEnabled() ) /*0x26f7*/
    {
      if ( CmdStatus ) /*0x2707*/
        DebugAssert((int)"e:\\hs\\AmiModulePkg\\Usb\\Pei\\PeiXhci.c", 1207, (int)"Status == 0"); /*0x2718*/
    }
    return 0; /*0x2724*/
  }
  *ResultFlags = 0; /*0x272c*/
  TransferRing = XhciGetTransferRing(XhcRegBase, SlotIdBuf[0], 0); /*0x273f*/
  TrbDataPtr_1 = (unsigned int)XhciRingAllocTrb(TransferRing); /*0x274b*/
  *(_DWORD *)(TrbDataPtr_1 + 12) = *(_DWORD *)(TrbDataPtr_1 + 12) & 0xFFFF03FF | 0x800; /*0x2761*/
  *(_DWORD *)(TrbDataPtr_1 + 12) |= 0x40u; /*0x2770*/
  *(_WORD *)TrbDataPtr_1 = RequestType; /*0x277a*/
  *(_WORD *)(TrbDataPtr_1 + 2) = *((_WORD *)Request + 1); /*0x2787*/
  *(_WORD *)(TrbDataPtr_1 + 4) = *((_WORD *)Request + 2); /*0x2795*/
  *(_WORD *)(TrbDataPtr_1 + 6) = *DataLen; /*0x27a2*/
  *(_DWORD *)(TrbDataPtr_1 + 8) = *(_DWORD *)(TrbDataPtr_1 + 8) & 0xFFFE0000 | 8; /*0x27b7*/
  if ( *(unsigned __int16 *)(XhcRegBase + 1151290) >= 0x100u ) /*0x27c9*/
  {
    if ( *(_DWORD *)DataLen ) /*0x27ce*/
    {
      if ( (RequestType & 0x80) != 0 ) /*0x27dc*/
        TrbFlags = *(_DWORD *)(TrbDataPtr_1 + 12) | 0x30000; /*0x27e4*/
      else
        TrbFlags = *(_DWORD *)(TrbDataPtr_1 + 12) & 0xFFFCFFFF | 0x20000; /*0x27fc*/
      *(_DWORD *)(TrbDataPtr_1 + 12) = TrbFlags; /*0x27ec*/
    }
    else
    {
      *(_DWORD *)(TrbDataPtr_1 + 12) &= 0xFFFCFFFF; /*0x2817*/
    }
  }
  if ( *(_DWORD *)DataLen ) /*0x281d*/
  {
    TrbDataPtr_1 = (unsigned int)XhciRingAllocTrb(TransferRing); /*0x282f*/
    *(_DWORD *)(TrbDataPtr_1 + 12) = *(_DWORD *)(TrbDataPtr_1 + 12) & 0xFFFF03FF | 0xC00; /*0x2845*/
    *(_DWORD *)(TrbDataPtr_1 + 12) = (((RequestType & 0x80u) != 0) << 16) | *(_DWORD *)(TrbDataPtr_1 + 12) & 0xFFFEFFFF; /*0x287a*/
    *(_DWORD *)(TrbDataPtr_1 + 8) = *(_DWORD *)DataLen & 0x1FFFF | *(_DWORD *)(TrbDataPtr_1 + 8) & 0xFFFE0000; /*0x2898*/
    TrbDataPtr = TrbDataPtr_1; /*0x28a0*/
    *(_DWORD *)TrbDataPtr_1 = DataBuffer; /*0x28a3*/
    *(_DWORD *)(TrbDataPtr + 4) = 0; /*0x28a5*/
    *(_DWORD *)(TrbDataPtr_1 + 12) = *(_BYTE *)(TransferRing + 16) & 1 | *(_DWORD *)(TrbDataPtr_1 + 12) & 0xFFFFFFFE; /*0x28c0*/
  }
  TrbDataPtr_1 = (unsigned int)XhciRingAllocTrb(TransferRing); /*0x28cc*/
  *(_DWORD *)(TrbDataPtr_1 + 12) = *(_DWORD *)(TrbDataPtr_1 + 12) & 0xFFFF03FF | 0x1000; /*0x28e2*/
  *(_DWORD *)(TrbDataPtr_1 + 12) |= 0x20u; /*0x28f1*/
  if ( (RequestType & 0x80) == 0 ) /*0x28fd*/
    *(_DWORD *)(TrbDataPtr_1 + 12) |= 0x10000u; /*0x290d*/
  *(_DWORD *)(TrbDataPtr_1 + 12) = *(_BYTE *)(TransferRing + 16) & 1 | *(_DWORD *)(TrbDataPtr_1 + 12) & 0xFFFFFFFE; /*0x2928*/
  RingStatus = XhciRingDoorbell(PeiServices, XhcRegBase, SlotIdBuf[0], 1u); /*0x293e*/
  if ( RingStatus < 0 ) /*0x2945*/
    return RingStatus; /*0x294a*/
  DoorbellStatus = XhciWaitForCompletion( /*0x296d*/
                     PeiServices,
                     XhcRegBase,
                     TrbDataPtr_1 | 0x2000000000LL,
                     &CompletionCode,
                     2000,
                     0);
  if ( DoorbellStatus < 0 ) /*0x2974*/
  {
    if ( CompletionCode == 2 ) /*0x2984*/
    {
      *ResultFlags |= 4u; /*0x29ab*/
    }
    else
    {
      if ( CompletionCode == 3 ) /*0x298a*/
      {
        *ResultFlags |= 8u; /*0x29ba*/
      }
      else if ( CompletionCode != 4 ) /*0x2990*/
      {
        if ( CompletionCode == 6 ) /*0x2996*/
        {
          *ResultFlags |= 2u; /*0x29dc*/
          XhciConfigureEndpoint(PeiServices, XhcRegBase, SlotIdBuf[0], 1u); /*0x29e9*/
        }
        else if ( CompletionCode == -1 ) /*0x299c*/
        {
          *ResultFlags |= 0x40u; /*0x29fe*/
          XhciConfigureEndpointEx(PeiServices, XhcRegBase, SlotIdBuf[0], 0); /*0x2a0b*/
        }
        return DoorbellStatus; /*0x2a0b*/
      }
      XhciConfigureEndpoint(PeiServices, XhcRegBase, SlotIdBuf[0], 1u); /*0x29c7*/
    }
    return DoorbellStatus; /*0x2a16*/
  }
  if ( Request[1] == 6 && *(_DWORD *)DataLen == 8 ) /*0x2a2a*/
    XhciEvaluateEndpoint(PeiServices, XhcRegBase, SlotIdBuf[0], *(_BYTE *)(DataBuffer + 7)); /*0x2a3d*/
  if ( Request[1] == 1 && !*((_WORD *)Request + 1) && *Request == 2 && Request[4] ) /*0x2a6a*/
    XhciConfigureEndpointEx(PeiServices, XhcRegBase, SlotIdBuf[0], Request[4]); /*0x2a83*/
  return 0; /*0x2a8d*/
}


// Function: XhciCreateBulkTransfer @ 0x2a91 (0x450 bytes)
// Index: 23/119

int __cdecl XhciCreateBulkTransfer(
        int PeiServices,
        int XhcFull,
        unsigned __int8 DeviceAddress,
        char EndpointAddr,
        int DataBuffer,
        unsigned __int16 MaxPacket,
        int DataPhys,
        unsigned int DataLen,
        unsigned int *TransferLen,
        int HubAddr,
        int HubPort,
        _DWORD *ResultFlags)
{
  __int64 DataLen_1; // [esp+0h] [ebp-60h]
  int CompletedLen; // [esp+Ch] [ebp-54h] BYREF
  int MaxPktLen; // [esp+10h] [ebp-50h]
  int MaxPktLen_2; // [esp+14h] [ebp-4Ch]
  int TrbChunkSize; // [esp+18h] [ebp-48h]
  unsigned __int8 EpType[4]; // [esp+1Ch] [ebp-44h]
  unsigned int TrbChunkSize_5; // [esp+20h] [ebp-40h]
  int Status; // [esp+24h] [ebp-3Ch]
  unsigned int TrbTotalSize; // [esp+28h] [ebp-38h]
  unsigned int TrbChunkSize_1; // [esp+2Ch] [ebp-34h]
  unsigned int TrbChunkSize_2; // [esp+30h] [ebp-30h]
  unsigned __int8 SlotIdBuf[4]; // [esp+34h] [ebp-2Ch] BYREF
  char CompCode; // [esp+38h] [ebp-28h]
  unsigned __int8 EpIdx[4]; // [esp+3Ch] [ebp-24h]
  int TransferRing; // [esp+40h] [ebp-20h]
  int XhcRegBase; // [esp+44h] [ebp-1Ch]
  unsigned int TrbChunkSize_4; // [esp+48h] [ebp-18h]
  unsigned int TrbChunkSize_3; // [esp+4Ch] [ebp-14h]
  _DWORD *FirstTrbPtr; // [esp+50h] [ebp-10h]
  unsigned int MaxPktLen_1; // [esp+54h] [ebp-Ch]
  unsigned int FirstTrbPtr_1; // [esp+58h] [ebp-8h]
  char CompletionCode; // [esp+5Fh] [ebp-1h] BYREF

  XhcRegBase = XhcFull - 1151595; /*0x2a9f*/
  EpType[0] = EndpointAddr; /*0x2aa5*/
  EpIdx[0] = 2 * (EndpointAddr & 0xF); /*0x2ab1*/
  if ( EndpointAddr < 0 ) /*0x2abd*/
    ++EpIdx[0]; /*0x2ac4*/
  XhciLookupDeviceByRoute((_BYTE *)(XhcRegBase + 1151360), SlotIdBuf, DeviceAddress); /*0x2ad7*/
  TransferRing = XhciGetTransferRing(XhcRegBase, SlotIdBuf[0], EpIdx[0] - 1); /*0x2af3*/
  DataLen_1 = DataLen; /*0x2afb*/
  TrbChunkSize_1 = *TransferLen; /*0x2b06*/
  *ResultFlags = 0; /*0x2b0c*/
  TrbTotalSize = 0; /*0x2b0f*/
  while ( TrbTotalSize < *TransferLen ) /*0x2b1b*/
  {
    if ( TrbChunkSize_1 <= 0x80000 ) /*0x2b28*/
      TrbChunkSize = TrbChunkSize_1; /*0x2b36*/
    else
      TrbChunkSize = 0x80000; /*0x2b2a*/
    TrbChunkSize_2 = TrbChunkSize; /*0x2b3c*/
    TrbChunkSize_3 = TrbChunkSize; /*0x2b42*/
    FirstTrbPtr_1 = 0; /*0x2b53*/
    TrbChunkSize_5 = 0; /*0x2b57*/
    FirstTrbPtr = 0; /*0x2b5b*/
    while ( TrbChunkSize_5 < TrbChunkSize_2 ) /*0x2b65*/
    {
      FirstTrbPtr_1 = (unsigned int)XhciRingAllocTrb(TransferRing); /*0x2b74*/
      if ( !FirstTrbPtr ) /*0x2b7b*/
        FirstTrbPtr = (_DWORD *)FirstTrbPtr_1; /*0x2b80*/
      *(_DWORD *)(FirstTrbPtr_1 + 12) = *(_DWORD *)(FirstTrbPtr_1 + 12) & 0xFFFF03FF | 0x400; /*0x2b96*/
      *(_DWORD *)(FirstTrbPtr_1 + 12) |= 4u; /*0x2ba5*/
      *(_QWORD *)FirstTrbPtr_1 = DataLen_1; /*0x2bae*/
      if ( TrbChunkSize_3 <= 0x10000 ) /*0x2bbd*/
      {
        *(_DWORD *)(FirstTrbPtr_1 + 12) |= 0x20u; /*0x2be3*/
        TrbChunkSize_4 = TrbChunkSize_3; /*0x2be9*/
      }
      else
      {
        TrbChunkSize_4 = 0x10000; /*0x2bbf*/
        *(_DWORD *)(FirstTrbPtr_1 + 12) |= 0x10u; /*0x2bd2*/
      }
      if ( TrbChunkSize_4 > 0x10000 - (unsigned int)(unsigned __int16)DataLen_1 ) /*0x2c09*/
      {
        TrbChunkSize_4 = 0x10000 - (unsigned __int16)DataLen_1; /*0x2c25*/
        *(_DWORD *)(FirstTrbPtr_1 + 12) |= 0x10u; /*0x2c34*/
        *(_DWORD *)(FirstTrbPtr_1 + 12) &= ~0x20u; /*0x2c43*/
      }
      *(_DWORD *)(FirstTrbPtr_1 + 8) = TrbChunkSize_4 & 0x1FFFF | *(_DWORD *)(FirstTrbPtr_1 + 8) & 0xFFFE0000; /*0x2c5f*/
      TrbChunkSize_5 += TrbChunkSize_4; /*0x2c68*/
      DataLen_1 += TrbChunkSize_4; /*0x2c76*/
      TrbChunkSize_3 -= TrbChunkSize_4; /*0x2c82*/
      if ( *(unsigned __int16 *)(XhcRegBase + 1151290) < 0x100u ) /*0x2c94*/
      {
        MaxPktLen_1 = TrbChunkSize_4 + TrbChunkSize_3; /*0x2ce7*/
        if ( TrbChunkSize_4 + TrbChunkSize_3 >= 0x8000 ) /*0x2cf1*/
          MaxPktLen = 31; /*0x2cfe*/
        else
          MaxPktLen = MaxPktLen_1 >> 10; /*0x2cf9*/
        MaxPktLen_1 = MaxPktLen; /*0x2d08*/
      }
      else
      {
        MaxPktLen_1 = 0; /*0x2c96*/
        if ( TrbChunkSize_3 ) /*0x2c9e*/
        {
          MaxPktLen_1 = TrbChunkSize_3 / MaxPacket; /*0x2cab*/
          if ( TrbChunkSize_3 % MaxPacket ) /*0x2cb7*/
            ++MaxPktLen_1; /*0x2cc1*/
          if ( MaxPktLen_1 <= 0x1F ) /*0x2cc8*/
            MaxPktLen_2 = MaxPktLen_1; /*0x2cd6*/
          else
            MaxPktLen_2 = 31; /*0x2cca*/
          MaxPktLen_1 = MaxPktLen_2; /*0x2cdc*/
        }
      }
      *(_DWORD *)(FirstTrbPtr_1 + 8) = ((MaxPktLen_1 & 0x1F) << 17) | *(_DWORD *)(FirstTrbPtr_1 + 8) & 0xFFC1FFFF; /*0x2d25*/
      if ( (_DWORD *)FirstTrbPtr_1 != FirstTrbPtr ) /*0x2d2e*/
        *(_DWORD *)(FirstTrbPtr_1 + 12) = *(_BYTE *)(TransferRing + 16) & 1 /*0x2d48*/
                                        | *(_DWORD *)(FirstTrbPtr_1 + 12) & 0xFFFFFFFE;
    }
    if ( FirstTrbPtr_1 < (unsigned int)FirstTrbPtr ) /*0x2d56*/
      *(_DWORD *)(*(_DWORD *)(TransferRing + 8) + 12) |= 0x10u; /*0x2d6a*/
    FirstTrbPtr[3] = *(_BYTE *)(TransferRing + 16) & 1 | FirstTrbPtr[3] & 0xFFFFFFFE; /*0x2d85*/
    if ( FirstTrbPtr_1 < (unsigned int)FirstTrbPtr ) /*0x2d8e*/
      FirstTrbPtr[3] = !(FirstTrbPtr[3] & 1) | FirstTrbPtr[3] & 0xFFFFFFFE; /*0x2dad*/
    Status = XhciRingDoorbell(PeiServices, XhcRegBase, SlotIdBuf[0], EpIdx[0]); /*0x2dc4*/
    if ( Status < 0 ) /*0x2dcb*/
      break; /*0x2dcb*/
    Status = XhciWaitForCompletion( /*0x2df2*/
               PeiServices,
               XhcRegBase,
               FirstTrbPtr_1 | 0x2000000000LL,
               &CompletionCode,
               0x2710u,
               &CompletedLen);
    *(_DWORD *)(*(_DWORD *)(TransferRing + 8) + 12) &= ~0x10u; /*0x2e07*/
    if ( Status >= 0 ) /*0x2e0e*/
      goto LABEL_50; /*0x2e0e*/
    CompCode = CompletionCode; /*0x2e17*/
    if ( CompletionCode == 2 ) /*0x2e1e*/
    {
      *ResultFlags |= 4u; /*0x2e45*/
      goto LABEL_50; /*0x2e47*/
    }
    switch ( CompCode ) /*0x2e24*/
    {
      case 3: /*0x2e24*/
        *ResultFlags |= 8u; /*0x2e54*/
LABEL_47:
        XhciConfigureEndpoint(PeiServices, XhcRegBase, SlotIdBuf[0], EpIdx[0]); /*0x2e56*/
        break; /*0x2e6a*/
      case 4: /*0x2e24*/
        goto LABEL_47; /*0x2e2a*/
      case 6: /*0x2e24*/
        *ResultFlags |= 2u; /*0x2e77*/
        XhciFreeEndpoint(PeiServices, XhcRegBase, SlotIdBuf[0], EpIdx[0]); /*0x2e85*/
        break;
      case -1: /*0x2e24*/
        *ResultFlags |= 0x40u; /*0x2e9a*/
        XhciConfigureEndpointEx(PeiServices, XhcRegBase, SlotIdBuf[0], EpType[0]); /*0x2ea8*/
        break;
    }
LABEL_50:
    TrbTotalSize += TrbChunkSize_2 - CompletedLen; /*0x2eb0*/
    if ( CompletedLen ) /*0x2ec0*/
      break; /*0x2ec0*/
    TrbChunkSize_1 -= TrbChunkSize_2; /*0x2eca*/
  }
  *TransferLen = TrbTotalSize; /*0x2ed2*/
  return Status; /*0x2edd*/
}


// Function: XhciPollAndCheckTransfer @ 0x2ee1 (0x163 bytes)
// Index: 24/119

int __cdecl XhciPollAndCheckTransfer(
        int PeiServices,
        int XhcContext,
        unsigned __int8 DeviceAddress,
        char EndpointAddr,
        int DataBuffer,
        int DataLen,
        int Token,
        _BYTE *TrbData,
        int TrbDataLen,
        int HubAddr,
        unsigned int Timeout)
{
  _BYTE *SrcPtr; // [esp+0h] [ebp-18h]
  _BYTE *TrbData_1; // [esp+4h] [ebp-14h]
  int Status; // [esp+8h] [ebp-10h]
  unsigned int TimeoutMs; // [esp+Ch] [ebp-Ch]
  unsigned int PollCount; // [esp+Ch] [ebp-Ch]
  char SlotIdBuf; // [esp+16h] [ebp-2h] BYREF
  char EpIdx; // [esp+17h] [ebp-1h]

  if ( TrbData && TrbDataLen ) /*0x2efc*/
  {
    XhciLookupDeviceByRoute((_BYTE *)(XhcContext - 235), &SlotIdBuf, DeviceAddress); /*0x2f42*/
    EpIdx = 2 * (EndpointAddr & 0xF); /*0x2f53*/
    if ( EndpointAddr < 0 ) /*0x2f5f*/
      ++EpIdx; /*0x2f66*/
    if ( EpIdx == *(_BYTE *)(XhcContext + 80) && SlotIdBuf == *(_BYTE *)(XhcContext + 81) ) /*0x2f8b*/
    {
      TimeoutMs = 0; /*0x2f97*/
      Status = -2147483642; /*0x2f9b*/
      while ( TimeoutMs < Timeout ) /*0x2fb1*/
      {
        Status = XhciProcessEventRing(PeiServices, XhcContext - 1151595); /*0x2fc0*/
        if ( !Status ) /*0x2fc7*/
          break; /*0x2fc7*/
        (*(void (__cdecl **)(_DWORD, _DWORD, int))(*(_DWORD *)(XhcContext + 72) + 4))( /*0x2feb*/
          *(_DWORD *)(XhcContext - 4),
          *(_DWORD *)(XhcContext + 72),
          1000);
        ++TimeoutMs; /*0x2fa8*/
      }
      if ( Status >= 0 ) /*0x2ff7*/
      {
        SrcPtr = (_BYTE *)(XhcContext + 82); /*0x3008*/
        TrbData_1 = TrbData; /*0x300e*/
        for ( PollCount = 0; PollCount < 8; ++PollCount ) /*0x3011*/
          *TrbData_1++ = *SrcPtr++; /*0x302c*/
        return 0; /*0x303e*/
      }
      else
      {
        return -2147483630; /*0x2ff9*/
      }
    }
    else
    {
      return -2147483634; /*0x2f8d*/
    }
  }
  else
  {
    if ( DebugEnabled() ) /*0x2efe*/
      DebugAssert((int)"e:\\hs\\AmiModulePkg\\Usb\\Pei\\PeiXhci.c", 1563, (int)"((BOOLEAN)(0==1))"); /*0x2f1e*/
    return -2147483646; /*0x2f28*/
  }
}


// Function: XhciGetMaxPorts @ 0x3044 (0x2b bytes)
// Index: 25/119

int __cdecl XhciGetMaxPorts(int a1, int a2, _BYTE *a3)
{
  *a3 = HIBYTE(*(_DWORD *)(a2 - 303)); /*0x3067*/
  return 0; /*0x306b*/
}


// Function: XhciDecodePortSpeed @ 0x306f (0xbb bytes)
// Index: 26/119

char __cdecl XhciDecodePortSpeed(int PeiServices, unsigned __int8 a2, _WORD *PortStatus)
{
  __int16 SpeedVal; // ax

  LOBYTE(SpeedVal) = a2; /*0x3073*/
  if ( a2 > 1u )
  {
    switch ( a2 )
    {
      case 2u:
        SpeedVal = *PortStatus | 0x200; /*0x30aa*/
        *PortStatus = SpeedVal; /*0x30b2*/
        break;
      case 3u:
        SpeedVal = *PortStatus | 0x400; /*0x30bd*/
        *PortStatus = SpeedVal; /*0x30c5*/
        break;
      case 4u:
        SpeedVal = *PortStatus | 0x800; /*0x30d0*/
        *PortStatus = SpeedVal; /*0x30d8*/
        break;
      case 5u:
        SpeedVal = *PortStatus | 0x1000; /*0x30e3*/
        *PortStatus = SpeedVal; /*0x30eb*/
        break;
      default:
        if ( DebugEnabled() && DebugLevelEnabled() )
          DebugPrint(0x80000000, (int)"XHCI ERROR: unknown device speed.\n");
        LOBYTE(SpeedVal) = 0; /*0x3122*/
        break;
    }
  }
  return SpeedVal; /*0x3126*/
}


// Function: XhciGetPortStatus @ 0x312a (0x3ae bytes)
// Index: 27/119

int __cdecl XhciGetPortStatus(int PeiServices, int XhcFull, unsigned __int8 PortNumber, _WORD *PortStatus)
{
  int PortRegOff; // [esp+0h] [ebp-18h]
  int PortScReg; // [esp+4h] [ebp-14h]
  int OpRegVal; // [esp+8h] [ebp-10h] BYREF
  unsigned int PollCount; // [esp+Ch] [ebp-Ch]
  int *p_OpRegVal; // [esp+10h] [ebp-8h]
  int XhcRegBase; // [esp+14h] [ebp-4h]

  XhcRegBase = XhcFull - 1151595; /*0x3138*/
  PortScReg = 16 * (PortNumber - 1) + 1024; /*0x3148*/
  p_OpRegVal = &OpRegVal; /*0x314e*/
  OpRegVal = XhciReadOpReg(XhcFull - 1151595, PortScReg); /*0x315e*/
  if ( DebugEnabled() && DebugLevelEnabled() )
    DebugPrint(64, (int)"XHCI port[%d] status: %08x\n", PortNumber, OpRegVal);
  for ( PollCount = 0; PollCount < 0xC8 && (((unsigned int)*p_OpRegVal >> 4) & 1) != 0; ++PollCount ) /*0x319b*/
  {
    (*(void (__cdecl **)(_DWORD, _DWORD, int))(*(_DWORD *)(XhcRegBase + 1151667) + 4))( /*0x31e0*/
      *(_DWORD *)(XhcRegBase + 1151591),
      *(_DWORD *)(XhcRegBase + 1151667),
      1000);
    OpRegVal = XhciReadOpReg(XhcRegBase, PortScReg); /*0x31f3*/
  }
  PortRegOff = ((unsigned int)*p_OpRegVal >> 5) & 0xF; /*0x3203*/
  switch ( PortRegOff ) /*0x320a*/
  {
    case 6: /*0x320a*/
      for ( PollCount = 0; PollCount < 0xC; ++PollCount ) /*0x3325*/
      {
        (*(void (__cdecl **)(_DWORD, _DWORD, int))(*(_DWORD *)(XhcRegBase + 1151667) + 4))( /*0x3358*/
          *(_DWORD *)(XhcRegBase + 1151591),
          *(_DWORD *)(XhcRegBase + 1151667),
          1000);
        OpRegVal = XhciReadOpReg(XhcRegBase, PortScReg); /*0x336b*/
        if ( (((unsigned int)*p_OpRegVal >> 5) & 0xF) != 6 ) /*0x337c*/
          break; /*0x337c*/
      }
      break;
    case 7: /*0x320a*/
      if ( XhciIsUsb3Port(XhcRegBase, PortNumber) ) /*0x3291*/
      {
        for ( PollCount = 0; PollCount < 0x1F4; ++PollCount ) /*0x32a4*/
        {
          (*(void (__cdecl **)(_DWORD, _DWORD, int))(*(_DWORD *)(XhcRegBase + 1151667) + 4))( /*0x32da*/
            *(_DWORD *)(XhcRegBase + 1151591),
            *(_DWORD *)(XhcRegBase + 1151667),
            1000);
          OpRegVal = XhciReadOpReg(XhcRegBase, PortScReg); /*0x32ed*/
          if ( (((unsigned int)*p_OpRegVal >> 5) & 0xF) != 7 ) /*0x32fe*/
            break; /*0x32fe*/
        }
      }
      break;
    case 8: /*0x320a*/
      for ( PollCount = 0; PollCount < 0xC8; ++PollCount ) /*0x3226*/
      {
        (*(void (__cdecl **)(_DWORD, _DWORD, int))(*(_DWORD *)(XhcRegBase + 1151667) + 4))( /*0x325c*/
          *(_DWORD *)(XhcRegBase + 1151591),
          *(_DWORD *)(XhcRegBase + 1151667),
          1000);
        OpRegVal = XhciReadOpReg(XhcRegBase, PortScReg); /*0x326f*/
        if ( (((unsigned int)*p_OpRegVal >> 5) & 0xF) != 8 ) /*0x3280*/
          break; /*0x3280*/
      }
      break;
  }
  OpRegVal = XhciReadOpReg(XhcRegBase, PortScReg); /*0x338f*/
  *(_DWORD *)PortStatus = 0; /*0x3395*/
  if ( (*p_OpRegVal & 1) != 0 ) /*0x33a0*/
    *PortStatus |= 1u; /*0x33ae*/
  if ( (((unsigned int)*p_OpRegVal >> 1) & 1) != 0 ) /*0x33bb*/
    *PortStatus |= 2u; /*0x33c9*/
  if ( (((unsigned int)*p_OpRegVal >> 3) & 1) != 0 ) /*0x33d7*/
    *PortStatus |= 8u; /*0x33e5*/
  if ( (((unsigned int)*p_OpRegVal >> 4) & 1) != 0 ) /*0x33f3*/
    *PortStatus |= 0x10u; /*0x3401*/
  if ( (((unsigned int)*p_OpRegVal >> 9) & 1) != 0 ) /*0x340f*/
    *PortStatus |= 0x100u; /*0x341f*/
  if ( (((unsigned int)*p_OpRegVal >> 17) & 1) != 0 ) /*0x342d*/
    PortStatus[1] |= 1u; /*0x343c*/
  if ( (((unsigned int)*p_OpRegVal >> 18) & 1) != 0 ) /*0x344b*/
    PortStatus[1] |= 2u; /*0x345a*/
  if ( (((unsigned int)*p_OpRegVal >> 20) & 1) != 0 ) /*0x3469*/
    PortStatus[1] |= 8u; /*0x3478*/
  if ( (((unsigned int)*p_OpRegVal >> 21) & 1) != 0 || (((unsigned int)*p_OpRegVal >> 19) & 1) != 0 ) /*0x3494*/
  {
    PortStatus[1] |= 0x10u; /*0x34a3*/
    PortStatus[1] |= 1u; /*0x34b4*/
  }
  XhciDecodePortSpeed(PeiServices, ((unsigned int)*p_OpRegVal >> 10) & 0xF, PortStatus); /*0x34ca*/
  return 0; /*0x34d4*/
}


// Function: XhciSetPortPower @ 0x34d8 (0xb7 bytes)
// Index: 28/119

int __cdecl XhciSetPortPower(int a1, int a2, unsigned __int8 a3, int n8)
{
  int PortScReg; // [esp+0h] [ebp-10h]
  __int16 OpRegVal; // [esp+4h] [ebp-Ch]
  int v7; // [esp+8h] [ebp-8h]

  v7 = a2 - 1151595; /*0x34e6*/
  PortScReg = 16 * (a3 - 1) + 1024; /*0x34f6*/
  if ( a3 > (unsigned int)(unsigned __int8)HIBYTE(*(_DWORD *)(a2 - 303)) ) /*0x3511*/
    return -2147483646; /*0x3518*/
  OpRegVal = XhciReadOpReg(v7, PortScReg); /*0x3527*/
  if ( n8 <= 0 ) /*0x3534*/
    return -2147483646; /*0x3534*/
  if ( n8 > 2 ) /*0x353a*/
  {
    if ( n8 == 4 ) /*0x3540*/
    {
      XhciWriteOpReg(v7, PortScReg, OpRegVal & 0x200 | 0x10); /*0x3563*/
    }
    else
    {
      if ( n8 != 8 ) /*0x3546*/
        return -2147483646; /*0x3587*/
      XhciWriteOpReg(v7, PortScReg, 512); /*0x3578*/
    }
  }
  return 0; /*0x358b*/
}


// Function: XhciControlPort @ 0x358f (0x1f5 bytes)
// Index: 29/119

int __cdecl XhciControlPort(int a1, int a2, unsigned __int8 PortNumber, int n18)
{
  int PortScReg; // [esp+0h] [ebp-10h]
  int XhcRegBase; // [esp+4h] [ebp-Ch]
  __int16 OpRegVal; // [esp+Ch] [ebp-4h]
  int PortPmReg; // [esp+Ch] [ebp-4h]

  XhcRegBase = a2 - 1151595; /*0x359d*/
  PortScReg = 16 * (PortNumber - 1) + 1024; /*0x35ad*/
  if ( PortNumber > (unsigned int)(unsigned __int8)HIBYTE(*(_DWORD *)(a2 - 303)) ) /*0x35c8*/
    return -2147483646; /*0x35cf*/
  OpRegVal = XhciReadOpReg(XhcRegBase, PortScReg); /*0x35e1*/
  if ( n18 > 16 ) /*0x35ee*/
  {
    if ( n18 == 17 ) /*0x3631*/
    {
      XhciWriteOpReg(XhcRegBase, PortScReg, OpRegVal & 0x200 | 0x40000); /*0x3720*/
    }
    else if ( n18 != 18 ) /*0x363b*/
    {
      if ( n18 == 19 ) /*0x3645*/
      {
        XhciWriteOpReg(XhcRegBase, PortScReg, OpRegVal & 0x200 | 0x100000); /*0x3745*/
      }
      else
      {
        if ( n18 != 20 ) /*0x364f*/
          return -2147483646; /*0x364f*/
        XhciWriteOpReg(XhcRegBase, PortScReg, OpRegVal & 0x200 | 0x280000); /*0x376d*/
      }
    }
  }
  else if ( n18 == 16 ) /*0x35f4*/
  {
    XhciWriteOpReg(XhcRegBase, PortScReg, OpRegVal & 0x200 | 0x2A0000); /*0x36fd*/
  }
  else if ( n18 == 1 ) /*0x35fe*/
  {
    if ( (OpRegVal & 2) != 0 ) /*0x3660*/
    {
      if ( XhciIsUsb3Port(XhcRegBase, PortNumber) ) /*0x3668*/
        PortPmReg = OpRegVal & 0x200 | 0x10; /*0x3681*/
      else
        PortPmReg = OpRegVal & 0x200 | 2; /*0x3691*/
      XhciWriteOpReg(XhcRegBase, PortScReg, PortPmReg); /*0x369d*/
    }
  }
  else if ( n18 != 2 && n18 != 4 ) /*0x360e*/
  {
    if ( n18 == 8 ) /*0x3618*/
    {
      XhciWriteOpReg(XhcRegBase, PortScReg, 0); /*0x36c8*/
    }
    else if ( n18 != 13 ) /*0x3622*/
    {
      return -2147483646; /*0x377c*/
    }
  }
  return 0; /*0x3780*/
}


// Function: XhciDestroyDevice @ 0x3784 (0x599 bytes)
// Index: 30/119

int __cdecl XhciDestroyDevice(int PeiServices, int XhcFull, unsigned __int16 Index)
{
  int DcbaapPtr; // eax
  int DcbaapIdx; // ecx
  __int64 PciConfigAddr; // [esp-Ch] [ebp-64h]
  _DWORD Params[2]; // [esp+4h] [ebp-54h] BYREF
  __int64 RouteString; // [esp+Ch] [ebp-4Ch]
  int PortSc; // [esp+14h] [ebp-44h] BYREF
  int *TransferRing; // [esp+18h] [ebp-40h]
  _DWORD *DevCtxEntry; // [esp+1Ch] [ebp-3Ch]
  int SlotIdx; // [esp+20h] [ebp-38h]
  int OpRegVal; // [esp+24h] [ebp-34h]
  int EpCtx; // [esp+28h] [ebp-30h]
  int EpCtx2; // [esp+2Ch] [ebp-2Ch]
  int DevSlotBase; // [esp+30h] [ebp-28h]
  unsigned int EpLoopIdx; // [esp+34h] [ebp-24h]
  int PciBar; // [esp+38h] [ebp-20h]
  char Speed; // [esp+3Ch] [ebp-1Ch]
  unsigned __int8 SlotIdBuf[4]; // [esp+40h] [ebp-18h] BYREF
  int EpIdx; // [esp+44h] [ebp-14h]
  unsigned int SlotLoopIdx; // [esp+48h] [ebp-10h]
  int XhcRegBase; // [esp+4Ch] [ebp-Ch]
  unsigned __int8 CmdParamBuf[7]; // [esp+50h] [ebp-8h] BYREF
  unsigned __int8 i; // [esp+57h] [ebp-1h]

  XhcRegBase = XhcFull - 1151595; /*0x3793*/
  OpRegVal = 0; /*0x3796*/
  SlotIdx = Index; /*0x379e*/
  if ( Index != 1 ) /*0x37a5*/
    return -2147483645; /*0x3d0f*/
  for ( SlotLoopIdx = 0; SlotLoopIdx <= 0x20; ++SlotLoopIdx ) /*0x37ac*/
  {
    DevSlotBase = *(_DWORD *)(XhcRegBase + 1151284); /*0x37cf*/
    EpLoopIdx = SlotLoopIdx; /*0x37d2*/
    if ( *(_QWORD *)(DevSlotBase + 8 * SlotLoopIdx + 8) ) /*0x37e1*/
    {
      SlotIdBuf[0] = SlotLoopIdx + 1; /*0x37f3*/
      DevCtxEntry = (_DWORD *)XhciGetDevCtxEntry( /*0x3813*/
                                XhcRegBase,
                                *(_DWORD *)(*(_DWORD *)(XhcRegBase + 1151284) + 8 * SlotLoopIdx + 8),
                                0);
      LOBYTE(EpIdx) = 1; /*0x3816*/
      while ( (unsigned __int8)EpIdx <= (unsigned int)((unsigned __int8)HIBYTE(*DevCtxEntry) >> 3) ) /*0x3835*/
      {
        EpCtx = XhciGetDevCtxEntry( /*0x3859*/
                  XhcRegBase,
                  *(_DWORD *)(*(_DWORD *)(XhcRegBase + 1151284) + 8 * SlotLoopIdx + 8),
                  EpIdx);
        EpCtx2 = EpCtx; /*0x385f*/
        if ( *(_QWORD *)(EpCtx + 8) ) /*0x3868*/
        {
          if ( (*(_DWORD *)EpCtx & 7) == 1 ) /*0x387b*/
          {
            *(_WORD *)CmdParamBuf = SlotIdBuf[0] + ((unsigned __int8)EpIdx << 8); /*0x388a*/
            XhciIssueCommand(PeiServices, XhcRegBase, 15, CmdParamBuf); /*0x389a*/
          }
          TransferRing = (int *)XhciGetTransferRing(XhcRegBase, SlotIdBuf[0], EpIdx - 1); /*0x38b6*/
          ZeroMem(*TransferRing, 0x400u); /*0x38c3*/
        }
        LOBYTE(EpIdx) = EpIdx + 1; /*0x3821*/
      }
      XhciIssueCommand(PeiServices, XhcRegBase, 10, SlotIdBuf); /*0x38d9*/
      DcbaapPtr = *(_DWORD *)(XhcRegBase + 1151284); /*0x38e4*/
      DcbaapIdx = SlotIdBuf[0]; /*0x38ea*/
      *(_DWORD *)(DcbaapPtr + 8 * SlotIdBuf[0]) = 0; /*0x38ee*/
      *(_DWORD *)(DcbaapPtr + 8 * DcbaapIdx + 4) = 0; /*0x38f2*/
    }
  }
  OpRegVal = XhciReadOpReg(XhcRegBase, 0); /*0x3908*/
  XhciClearOpRegBits(XhcRegBase, 0, 4); /*0x3912*/
  XhciClearOpRegBitsAt(XhcRegBase, *(_DWORD *)(XhcRegBase + 1151324) + 32 - *(_DWORD *)(XhcRegBase + 1118420), 2); /*0x3935*/
  XhciClearOpRegBits(XhcRegBase, 0, 1); /*0x3944*/
  for ( SlotLoopIdx = 0; SlotLoopIdx < 0x140 && (XhciReadOpReg(XhcRegBase, 4) & 1) == 0; ++SlotLoopIdx ) /*0x394c*/
    (*(void (__cdecl **)(_DWORD, _DWORD, int))(*(_DWORD *)(XhcRegBase + 1151667) + 4))( /*0x3992*/
      *(_DWORD *)(XhcRegBase + 1151591),
      *(_DWORD *)(XhcRegBase + 1151667),
      100);
  if ( DebugEnabled() && (XhciReadOpReg(XhcRegBase, 4) & 1) == 0 ) /*0x39b5*/
    DebugAssert( /*0x39c6*/
      (int)"e:\\hs\\AmiModulePkg\\Usb\\Pei\\PeiXhci.c",
      1981,
      (int)"XhciReadOpReg(Usb3Hc, 0x0004) & 0x00000001");
  if ( !*(_DWORD *)(XhcRegBase + 1151356) /*0x3a04*/
    || (XhciReadMem(XhcRegBase, 2u, *(_DWORD *)(XhcRegBase + 1151356) + 32, 1u, (int)&PortSc), PortSc >= 0) )
  {
    XhciSetOpRegBits(XhcRegBase, 0, 2); /*0x3a12*/
    (*(void (__cdecl **)(_DWORD, _DWORD, int))(*(_DWORD *)(XhcRegBase + 1151667) + 4))( /*0x3a3a*/
      *(_DWORD *)(XhcRegBase + 1151591),
      *(_DWORD *)(XhcRegBase + 1151667),
      1000);
    for ( SlotLoopIdx = 0; SlotLoopIdx < 0x1F40 && (XhciReadOpReg(XhcRegBase, 0) & 2) != 0; ++SlotLoopIdx ) /*0x3a40*/
      (*(void (__cdecl **)(_DWORD, _DWORD, int))(*(_DWORD *)(XhcRegBase + 1151667) + 4))( /*0x3a86*/
        *(_DWORD *)(XhcRegBase + 1151591),
        *(_DWORD *)(XhcRegBase + 1151667),
        100);
    if ( DebugEnabled() && (XhciReadOpReg(XhcRegBase, 0) & 2) != 0 ) /*0x3aa9*/
      DebugAssert( /*0x3aba*/
        (int)"e:\\hs\\AmiModulePkg\\Usb\\Pei\\PeiXhci.c",
        2005,
        (int)"!(XhciReadOpReg(Usb3Hc, 0x0000) & 0x00000002)");
    if ( (OpRegVal & 8) != 0 ) /*0x3aca*/
      XhciSetOpRegBits(XhcRegBase, 0, 8); /*0x3ad3*/
    Params[0] = 0; /*0x3adb*/
    Params[1] = 0; /*0x3adf*/
    if ( *(_BYTE *)(XhcRegBase + 1151686) == 1 ) /*0x3af0*/
    {
      (*(void (__cdecl **)(int, _DWORD, int, int, _DWORD, _DWORD *))(*(_DWORD *)(*(_DWORD *)PeiServices + 100) + 4))( /*0x3b5f*/
        PeiServices,
        *(_DWORD *)(*(_DWORD *)PeiServices + 100),
        2,
        ((unsigned __int8)byte_89CE[3 * *(unsigned __int8 *)(XhcRegBase + 1151685)] << 8)
      | ((unsigned __int8)byte_89CD[3 * *(unsigned __int8 *)(XhcRegBase + 1151685)] << 16)
      | ((unsigned __int8)byte_89CC[3 * *(unsigned __int8 *)(XhcRegBase + 1151685)] << 24)
      | 0x10,
        0,
        Params);
      (*(void (__cdecl **)(int, _DWORD, _DWORD, int, _DWORD, _DWORD *))(*(_DWORD *)(*(_DWORD *)PeiServices + 100) + 4))( /*0x3bce*/
        PeiServices,
        *(_DWORD *)(*(_DWORD *)PeiServices + 100),
        0,
        ((unsigned __int8)byte_89CE[3 * *(unsigned __int8 *)(XhcRegBase + 1151685)] << 8)
      | ((unsigned __int8)byte_89CD[3 * *(unsigned __int8 *)(XhcRegBase + 1151685)] << 16)
      | ((unsigned __int8)byte_89CC[3 * *(unsigned __int8 *)(XhcRegBase + 1151685)] << 24)
      | 4,
        0,
        Params);
    }
    if ( *(unsigned __int8 *)(XhcRegBase + 1151685) == (unsigned __int16)word_89E4 - 1 ) /*0x3be8*/
    {
      for ( i = 0; ; ++i ) /*0x3bee*/
      {
        if ( i >= (int)(unsigned __int16)word_89C8 ) /*0x3c09*/
          return 0; /*0x3c09*/
        Speed = byte_89EF[16 * i]; /*0x3c1c*/
        switch ( Speed ) /*0x3c23*/
        {
          case 8: /*0x3c23*/
            PciBar = 0; /*0x3c39*/
            break;
          case 16: /*0x3c23*/
            PciBar = 1; /*0x3c3f*/
            break;
          case 32: /*0x3c23*/
            PciBar = 2; /*0x3c48*/
            break;
          case 64: /*0x3c23*/
            PciBar = 3; /*0x3c51*/
            break;
          default:
            continue; /*0x3c35*/
        }
        if ( (unsigned int)dword_89EB[4 * i] >= 0x100 ) /*0x3c6d*/
          RouteString = XhciSetConfig((unsigned int)dword_89EB[4 * i]); /*0x3ca1*/
        else
          RouteString = (unsigned int)dword_89EB[4 * i]; /*0x3c7e*/
        PciConfigAddr = RouteString /*0x3ceb*/
                      | ((unsigned __int8)byte_89EA[16 * i] << 8)
                      | ((unsigned __int8)byte_89E9[16 * i] << 16)
                      | ((unsigned __int8)byte_89E8[16 * i] << 24);
        (*(void (__cdecl **)(int, _DWORD, int, _DWORD, _DWORD, _DWORD *))(*(_DWORD *)(*(_DWORD *)PeiServices + 100) + 4))( /*0x3d02*/
          PeiServices,
          *(_DWORD *)(*(_DWORD *)PeiServices + 100),
          PciBar,
          PciConfigAddr,
          HIDWORD(PciConfigAddr),
          Params);
      }
    }
  }
  return 0; /*0x3d18*/
}


// Function: XhciReadMem64 @ 0x3d1d (0x2f bytes)
// Index: 31/119

__int64 __cdecl XhciReadMem64(int buf, int a2)
{
  int LocalBuf[2]; // [esp+0h] [ebp-8h] BYREF

  XhciReadMem(buf, 2u, a2 - *(_DWORD *)(buf + 1118420), 2u, (int)LocalBuf); /*0x3d3a*/
  return *(_QWORD *)LocalBuf; /*0x3d48*/
}


// Function: XhciWriteMem64 @ 0x3d4c (0x25 bytes)
// Index: 32/119

int XhciWriteMem64(int buf, int a2, ...)
{
  va_list va; // [esp+10h] [ebp+10h] BYREF

  va_start(va, a2);
  return XhciWriteMem(buf, 2u, a2 - *(_DWORD *)(buf + 1118420), 2u, (int)va); /*0x3d6f*/
}


// Function: XhciInitRing @ 0x3d71 (0xb2 bytes)
// Index: 33/119

int __cdecl XhciInitRing(int a1, _BYTE *a2, int n64, char a4)
{
  _DWORD *v4; // edx
  _BYTE *v6; // [esp+0h] [ebp-Ch]
  unsigned int RingIdx; // [esp+4h] [ebp-8h]

  *(_DWORD *)a1 = a2; /*0x3d7d*/
  *(_DWORD *)(a1 + 4) = n64; /*0x3d85*/
  *(_DWORD *)(a1 + 8) = *(_DWORD *)a1 + 16 * n64 - 16; /*0x3d9a*/
  *(_BYTE *)(a1 + 16) = 1; /*0x3da0*/
  *(_DWORD *)(a1 + 12) = a2; /*0x3daa*/
  v6 = a2; /*0x3db0*/
  for ( RingIdx = 0; RingIdx < 16 * n64; ++RingIdx ) /*0x3db3*/
    *v6++ = 0; /*0x3dd5*/
  if ( a4 ) /*0x3de0*/
  {
    v4 = *(_DWORD **)(a1 + 8); /*0x3df0*/
    *v4 = a2; /*0x3df3*/
    v4[1] = 0; /*0x3df5*/
    v4[3] |= 2u; /*0x3e04*/
    v4[3] = v4[3] & 0xFFFF03FF | 0x1800; /*0x3e1a*/
  }
  return 0; /*0x3e1f*/
}


// Function: XhciRingAllocTrb @ 0x3e23 (0xc2 bytes)
// Index: 34/119

_DWORD *__cdecl XhciRingAllocTrb(int a1)
{
  _DWORD *RingSegPtr; // [esp+0h] [ebp-Ch]
  _DWORD *RingSegPtr_1; // [esp+4h] [ebp-8h]
  unsigned __int8 TrbIdx; // [esp+Bh] [ebp-1h]

  RingSegPtr_1 = *(_DWORD **)(a1 + 12); /*0x3e2f*/
  if ( (unsigned __int8)HIBYTE(*((_WORD *)RingSegPtr_1 + 6)) >> 2 == 6 ) /*0x3e41*/
  {
    RingSegPtr_1[3] = *(_BYTE *)(a1 + 16) & 1 | RingSegPtr_1[3] & 0xFFFFFFFE; /*0x3e5b*/
    *(_BYTE *)(a1 + 16) ^= 1u; /*0x3e6b*/
    *(_DWORD *)(a1 + 12) = *(_DWORD *)a1; /*0x3e76*/
    RingSegPtr_1 = *(_DWORD **)(a1 + 12); /*0x3e7f*/
  }
  RingSegPtr = RingSegPtr_1; /*0x3e85*/
  for ( TrbIdx = 0; TrbIdx < 4u; ++TrbIdx ) /*0x3e8c*/
    *RingSegPtr++ = 0; /*0x3ea6*/
  RingSegPtr_1[3] = *(_BYTE *)(a1 + 16) & 1 | RingSegPtr_1[3] & 0xFFFFFFFE; /*0x3ecc*/
  *(_DWORD *)(a1 + 12) += 16; /*0x3edb*/
  return RingSegPtr_1; /*0x3ee1*/
}


// Function: XhciSendCommandTrb @ 0x3ee5 (0x1a0 bytes)
// Index: 35/119

int __cdecl XhciSendCommandTrb(int PeiServices, int buf, int a3, int a4, unsigned __int8 SlotIdOut, unsigned __int8 a6)
{
  _DWORD *v7; // eax
  int DoorbellReg; // [esp+0h] [ebp-10h]
  int TransferRing; // [esp+4h] [ebp-Ch]
  unsigned __int8 TrbIdx; // [esp+Fh] [ebp-1h]

  if ( *(unsigned __int8 *)(buf + 1151675) != a6 || *(unsigned __int8 *)(buf + 1151676) != SlotIdOut ) /*0x3f13*/
    return -2147483642; /*0x3f15*/
  if ( DebugEnabled() && DebugLevelEnabled() )
    DebugPrint(64, (int)"buf: ");
  for ( TrbIdx = 0; TrbIdx < 8u; ++TrbIdx ) /*0x3f50*/
  {
    if ( DebugEnabled() ) /*0x3f67*/
    {
      if ( DebugLevelEnabled() ) /*0x3f76*/
        DebugPrint(64, (int)"%x", *(unsigned __int8 *)(buf + TrbIdx + 1151677)); /*0x3f99*/
    }
  }
  if ( DebugEnabled() && DebugLevelEnabled() ) /*0x3fba*/
    DebugPrint(64, (int)"\n"); /*0x3fcd*/
  TransferRing = XhciGetTransferRing(buf, SlotIdOut, a6 - 1); /*0x3ff0*/
  v7 = XhciRingAllocTrb(TransferRing); /*0x3ff6*/
  v7[3] = v7[3] & 0xFFFF03FF | 0x400; /*0x4012*/
  *v7 = buf + 1151677; /*0x4022*/
  v7[1] = 0; /*0x4024*/
  v7[2] = v7[2] & 0xFFFE0000 | 8; /*0x4038*/
  v7[3] |= 4u; /*0x4047*/
  v7[3] |= 0x20u; /*0x4056*/
  DoorbellReg = XhciGetDoorbellReg(buf, SlotIdOut); /*0x4066*/
  XhciWriteMem(buf, 2u, DoorbellReg, 1u, (int)&a6); /*0x4077*/
  return 0; /*0x4081*/
}


// Function: XhciProcessEventRing @ 0x4085 (0x498 bytes)
// Index: 36/119

int __cdecl XhciProcessEventRing(int PeiServices, int buf)
{
  int EventTrbAddr; // [esp+18h] [ebp-Ch]
  int EventStatus; // [esp+1Ch] [ebp-8h]
  int *EventTrbPtr; // [esp+20h] [ebp-4h]

  if ( XhciReadMem64(buf, *(_DWORD *)(buf + 1151320) + 48) != *(_DWORD *)(buf + 1151284) ) /*0x40c7*/
    return -2147483642; /*0x40d1*/
  if ( (XhciReadOpReg(buf, 4) & 8) != 0 ) /*0x40e8*/
  {
    XhciWriteOpReg(buf, 4, 8); /*0x40f1*/
    XhciSetOpRegBitsAt(buf, *(_DWORD *)(buf + 1151324) + 32 - *(_DWORD *)(buf + 1118420), 1); /*0x411b*/
  }
  if ( (*(_DWORD *)(*(_DWORD *)(buf + 1118484) + 12) & 1) != *(_BYTE *)(buf + 1118488) ) /*0x413e*/
    return -2147483642; /*0x4140*/
  EventTrbAddr = 0; /*0x4148*/
  while ( 1 )
  {
    EventTrbPtr = *(int **)(buf + 1118484); /*0x4155*/
    if ( (EventTrbPtr[3] & 1) != *(_BYTE *)(buf + 1118488) ) /*0x416d*/
      break; /*0x416d*/
    if ( *(_DWORD *)(buf + 1118484) == *(_DWORD *)(buf + 1118480) ) /*0x4186*/
    {
      *(_DWORD *)(buf + 1118484) = *(_DWORD *)(buf + 1118472); /*0x4194*/
      *(_BYTE *)(buf + 1118488) ^= 1u; /*0x41aa*/
    }
    else
    {
      *(_DWORD *)(buf + 1118484) += 16; /*0x41c1*/
    }
    if ( HIBYTE(EventTrbPtr[2]) == 13 && DebugEnabled() && DebugLevelEnabled() )
      DebugPrint(64, (int)"PEI_XHCI: short packet detected.");
    if ( HIBYTE(EventTrbPtr[2]) == 6 && DebugEnabled() && DebugLevelEnabled() )
      DebugPrint(0x80000000, (int)"PEI_XHCI: device STALLs.");
    if ( HIBYTE(EventTrbPtr[2]) != 1
      && HIBYTE(EventTrbPtr[2]) != 6
      && HIBYTE(EventTrbPtr[2]) != 13
      && DebugEnabled()
      && DebugLevelEnabled() )
    {
      DebugPrint(0x80000000, (int)"Trb completion code: %d\n", HIBYTE(EventTrbPtr[2]));
    }
    EventStatus = (unsigned __int8)HIBYTE(*((_WORD *)EventTrbPtr + 6)) >> 2; /*0x42e5*/
    switch ( EventStatus ) /*0x42ec*/
    {
      case ' ': /*0x42ec*/
        EventTrbAddr = XhciSendCommandTrb( /*0x435d*/
                         PeiServices,
                         buf,
                         *EventTrbPtr,
                         EventTrbPtr[1],
                         HIBYTE(EventTrbPtr[3]),
                         HIWORD(EventTrbPtr[3]) & 0x1F);
        break;
      case '!': /*0x42ec*/
        if ( DebugEnabled() && DebugLevelEnabled() ) /*0x4374*/
          DebugPrint(64, (int)"CmdCompleteEvt\n"); /*0x4387*/
        break;
      case '"': /*0x42ec*/
        if ( DebugEnabled() && DebugLevelEnabled() ) /*0x43aa*/
          DebugPrint(64, (int)"PortStatusChgEvt, port #%d\n", HIBYTE(*EventTrbPtr)); /*0x43cb*/
        break;
      case '$': /*0x42ec*/
        if ( DebugEnabled() && DebugLevelEnabled() ) /*0x43ef*/
          DebugPrint(64, (int)"DoorbellEvt\n"); /*0x4402*/
        break;
      case '%': /*0x42ec*/
        if ( DebugEnabled() && DebugLevelEnabled() ) /*0x4425*/
          DebugPrint(64, (int)"HostControllerEvt\n"); /*0x4438*/
        break;
      case '&': /*0x42ec*/
        if ( DebugEnabled() && DebugLevelEnabled() ) /*0x445b*/
          DebugPrint(64, (int)"DevNotificationEvt\n"); /*0x446e*/
        break;
      case '\'': /*0x42ec*/
        if ( DebugEnabled() && DebugLevelEnabled() ) /*0x448e*/
          DebugPrint(64, (int)"MfIndexWrapEvt\n"); /*0x44a1*/
        break;
      default:
        if ( DebugEnabled() ) /*0x44b2*/
        {
          if ( DebugLevelEnabled() ) /*0x44c3*/
            DebugPrint(0x80000000, (int)"UNKNOWN EVENT\n"); /*0x44d9*/
        }
        break;
    }
  }
  XhciWriteMem64(buf, *(_DWORD *)(buf + 1151324) + 56, *(_DWORD *)(buf + 1118484) | 8, 0); /*0x450d*/
  return EventTrbAddr; /*0x4518*/
}


// Function: XhciWaitForCompletion @ 0x451d (0x362 bytes)
// Index: 37/119

int __cdecl XhciWaitForCompletion(
        int PeiServices,
        int XhcRegBase,
        __int64 a3,
        char *p_n6,
        __int16 n2000,
        _BYTE *p_CompletedLen)
{
  int CompCode; // [esp+4h] [ebp-18h]
  unsigned int PollCount; // [esp+8h] [ebp-14h]
  int CompCode_1; // [esp+Ch] [ebp-10h]
  _DWORD *ErstEntryPtr; // [esp+10h] [ebp-Ch]
  _DWORD *EvtTrbPtr; // [esp+14h] [ebp-8h]
  char CompCodeByte; // [esp+1Bh] [ebp-1h]

  PollCount = 0; /*0x452f*/
LABEL_2:
  if ( PollCount >= (unsigned int)(unsigned __int16)n2000 + 1 )
  {
    if ( DebugEnabled() && DebugLevelEnabled() )
      DebugPrint(0x80000000, (int)"PEI_XHCI: execution time-out.\n");
    *p_n6 = -1; /*0x4861*/
    CompCode_1 = -2147483641; /*0x4864*/
  }
  else
  {
    EvtTrbPtr = *(_DWORD **)(XhcRegBase + 1118484); /*0x4551*/
    CompCodeByte = *(_BYTE *)(XhcRegBase + 1118488); /*0x455d*/
    while ( 1 )
    {
      if ( (EvtTrbPtr[3] & 1) != CompCodeByte ) /*0x456f*/
        goto LABEL_40; /*0x456f*/
      *p_n6 = HIBYTE(EvtTrbPtr[2]); /*0x4587*/
      if ( (unsigned __int8)HIBYTE(EvtTrbPtr[2]) == 6 || (unsigned __int8)HIBYTE(EvtTrbPtr[2]) == 4 ) /*0x45ad*/
      {
        CompCode_1 = -2147483641; /*0x45af*/
        goto LABEL_45; /*0x45b6*/
      }
      if ( __PAIR64__((unsigned __int8)HIBYTE(*((_WORD *)EvtTrbPtr + 6)) >> 2, *EvtTrbPtr) == a3 ) /*0x45ca*/
        break; /*0x45ca*/
      if ( EvtTrbPtr == *(_DWORD **)(XhcRegBase + 1118480) ) /*0x4758*/
      {
        EvtTrbPtr = *(_DWORD **)(XhcRegBase + 1118472); /*0x4763*/
        CompCodeByte ^= 1u; /*0x476d*/
      }
      else
      {
        EvtTrbPtr += 4; /*0x4778*/
      }
      if ( EvtTrbPtr == *(_DWORD **)(XhcRegBase + 1118484) )
      {
        if ( DebugEnabled() && DebugLevelEnabled() )
          DebugPrint(0x80000000, (int)"PEI_XHCI: Event Ring is full...\n");
        if ( DebugEnabled() ) /*0x47bf*/
          DebugAssert((int)"e:\\hs\\AmiModulePkg\\Usb\\Pei\\PeiXhci.c", 2445, (int)"((BOOLEAN)(0==1))"); /*0x47df*/
        *p_n6 = 21; /*0x47ec*/
LABEL_40:
        (*(void (__cdecl **)(_DWORD, _DWORD, int))(*(_DWORD *)(XhcRegBase + 1151667) + 4))( /*0x47fd*/
          *(_DWORD *)(XhcRegBase + 1151591),
          *(_DWORD *)(XhcRegBase + 1151667),
          1000);
        ++PollCount; /*0x4539*/
        goto LABEL_2; /*0x4823*/
      }
    }
    if ( (unsigned __int8)HIBYTE(EvtTrbPtr[2]) != 1
      && (unsigned __int8)HIBYTE(EvtTrbPtr[2]) != 13
      && DebugEnabled()
      && DebugLevelEnabled() )
    {
      DebugPrint(0x80000000, (int)"TRB Completion Error: %d\n", HIBYTE(EvtTrbPtr[2]));
    }
    if ( HIDWORD(a3) == 33 ) /*0x464e*/
      *p_CompletedLen = HIBYTE(EvtTrbPtr[3]); /*0x4661*/
    if ( HIDWORD(a3) == 32 ) /*0x4667*/
    {
      if ( p_CompletedLen ) /*0x4671*/
      {
        *(_DWORD *)p_CompletedLen = EvtTrbPtr[2] & 0xFFFFFF; /*0x4685*/
        if ( (unsigned __int8)HIBYTE(EvtTrbPtr[2]) == 13 ) /*0x4698*/
        {
          for ( ErstEntryPtr = (_DWORD *)*EvtTrbPtr; ; *(_DWORD *)p_CompletedLen += ErstEntryPtr[2] & 0x1FFFF ) /*0x469f*/
          {
            ErstEntryPtr[3] &= ~4u; /*0x46b3*/
            ErstEntryPtr[3] &= ~0x20u; /*0x46c2*/
            if ( ((ErstEntryPtr[3] >> 4) & 1) == 0 ) /*0x46d1*/
              break; /*0x46d1*/
            ErstEntryPtr += 4; /*0x46db*/
            if ( (unsigned __int8)HIBYTE(*((_WORD *)ErstEntryPtr + 6)) >> 2 == 6 ) /*0x46ed*/
              ErstEntryPtr = (_DWORD *)*ErstEntryPtr; /*0x46f4*/
          }
        }
      }
    }
    if ( (unsigned __int8)HIBYTE(EvtTrbPtr[2]) == 1 || (unsigned __int8)HIBYTE(EvtTrbPtr[2]) == 13 ) /*0x4732*/
      CompCode = 0; /*0x473d*/
    else
      CompCode = -2147483641; /*0x4734*/
    CompCode_1 = CompCode; /*0x4744*/
  }
LABEL_45:
  XhciProcessEventRing(PeiServices, XhcRegBase); /*0x486b*/
  return CompCode_1; /*0x487b*/
}


// Function: XhciIssueCommand @ 0x487f (0x509 bytes)
// Index: 38/119

int __cdecl XhciIssueCommand(int PeiServices, int XhcRegBase, int n10, unsigned __int8 *a4)
{
  unsigned int TrbAddrLow; // edx
  unsigned int TrbAddrLow_2; // edx
  unsigned int TrbAddrLow_3; // eax
  int CmdCompletionVal; // [esp+0h] [ebp-18h] BYREF
  int CmdStatus; // [esp+4h] [ebp-14h]
  int CmdParamCopy; // [esp+8h] [ebp-10h]
  int CmdParam2; // [esp+Ch] [ebp-Ch]
  unsigned int TrbAddrLow_1; // [esp+10h] [ebp-8h]
  unsigned __int8 CompCode; // [esp+16h] [ebp-2h] BYREF
  unsigned __int8 CompletedLen; // [esp+17h] [ebp-1h] BYREF

  TrbAddrLow_1 = (unsigned int)XhciRingAllocTrb(XhcRegBase + 1118440); /*0x4894*/
  *(_DWORD *)(TrbAddrLow_1 + 12) = ((n10 & 0x3F) << 10) | *(_DWORD *)(TrbAddrLow_1 + 12) & 0xFFFF03FF; /*0x48b1*/
  CmdParam2 = n10; /*0x48b7*/
  if ( n10 == 10 ) /*0x48be*/
  {
    *(_DWORD *)(TrbAddrLow_1 + 12) = (*a4 << 24) | *(_DWORD *)(TrbAddrLow_1 + 12) & 0xFFFFFF; /*0x4a7d*/
  }
  else if ( CmdParam2 == 11 ) /*0x48c8*/
  {
    TrbAddrLow = TrbAddrLow_1; /*0x4908*/
    *(_DWORD *)TrbAddrLow_1 = *(_DWORD *)(XhcRegBase + 1118436); /*0x490b*/
    *(_DWORD *)(TrbAddrLow + 4) = 0; /*0x490d*/
    *(_DWORD *)(TrbAddrLow_1 + 12) = (*a4 << 24) | *(_DWORD *)(TrbAddrLow_1 + 12) & 0xFFFFFF; /*0x492f*/
    *(_DWORD *)(TrbAddrLow_1 + 12) = ((a4[1] & 1) << 9) | *(_DWORD *)(TrbAddrLow_1 + 12) & 0xFFFFFDFF; /*0x4950*/
  }
  else if ( CmdParam2 > 11 ) /*0x48ce*/
  {
    if ( CmdParam2 <= 13 ) /*0x48d8*/
    {
      TrbAddrLow_2 = TrbAddrLow_1; /*0x4963*/
      *(_DWORD *)TrbAddrLow_1 = *(_DWORD *)(XhcRegBase + 1118436); /*0x4966*/
      *(_DWORD *)(TrbAddrLow_2 + 4) = 0; /*0x4968*/
      *(_DWORD *)(TrbAddrLow_1 + 12) = (*a4 << 24) | *(_DWORD *)(TrbAddrLow_1 + 12) & 0xFFFFFF; /*0x498a*/
      *(_DWORD *)(TrbAddrLow_1 + 12) &= ~0x200u; /*0x499b*/
    }
    else
    {
      switch ( CmdParam2 ) /*0x48de*/
      {
        case 14: /*0x48de*/
          *(_DWORD *)(TrbAddrLow_1 + 12) &= ~0x200u; /*0x49b1*/
          *(_DWORD *)(TrbAddrLow_1 + 12) = (*a4 << 24) | *(_DWORD *)(TrbAddrLow_1 + 12) & 0xFFFFFF; /*0x49d3*/
          *(_DWORD *)(TrbAddrLow_1 + 12) = ((a4[1] & 0x1F) << 16) | *(_DWORD *)(TrbAddrLow_1 + 12) & 0xFFE0FFFF; /*0x49f4*/
          break;
        case 15: /*0x48de*/
          *(_DWORD *)(TrbAddrLow_1 + 12) = (*a4 << 24) | *(_DWORD *)(TrbAddrLow_1 + 12) & 0xFFFFFF; /*0x4aa1*/
          *(_DWORD *)(TrbAddrLow_1 + 12) = ((a4[1] & 0x1F) << 16) | *(_DWORD *)(TrbAddrLow_1 + 12) & 0xFFE0FFFF; /*0x4ac2*/
          break;
        case 16: /*0x48de*/
          TrbAddrLow_3 = TrbAddrLow_1; /*0x49fc*/
          *(_DWORD *)TrbAddrLow_1 = *(_DWORD *)a4; /*0x4a04*/
          *(_DWORD *)(TrbAddrLow_3 + 4) = *((_DWORD *)a4 + 1); /*0x4a09*/
          *(_DWORD *)(TrbAddrLow_1 + 12) = ((HIWORD(*((_DWORD *)a4 + 3)) & 0x1F) << 16) /*0x4a2f*/
                                         | *(_DWORD *)(TrbAddrLow_1 + 12) & 0xFFE0FFFF;
          *(_DWORD *)(TrbAddrLow_1 + 12) = ((unsigned __int8)HIBYTE(*((_DWORD *)a4 + 3)) << 24) /*0x4a59*/
                                         | *(_DWORD *)(TrbAddrLow_1 + 12) & 0xFFFFFF;
          break;
      }
    }
  }
  *(_DWORD *)(TrbAddrLow_1 + 12) = *(_BYTE *)(XhcRegBase + 1118456) & 1 | *(_DWORD *)(TrbAddrLow_1 + 12) & 0xFFFFFFFE; /*0x4ae0*/
  CmdCompletionVal = 0; /*0x4ae3*/
  XhciWriteMem(XhcRegBase, 2u, *(_DWORD *)(XhcRegBase + 1151308), 1u, (int)&CmdCompletionVal); /*0x4afb*/
  CmdStatus = XhciWaitForCompletion( /*0x4b23*/
                PeiServices,
                XhcRegBase,
                TrbAddrLow_1 | 0x2100000000LL,
                (char *)&CompCode,
                0x1F4u,
                &CompletedLen);
  if ( CmdStatus == -2147483641 )
  {
    if ( DebugEnabled() )
    {
      if ( DebugLevelEnabled() )
        DebugPrint(0x80000000, (int)"XHCI command[%d] completion error code: %d\n", n10, CompCode);
    }
    return CmdStatus; /*0x4b6e*/
  }
  else
  {
    CmdParamCopy = n10; /*0x4b79*/
    if ( n10 == 9 )
    {
      if ( DebugEnabled() && DebugLevelEnabled() )
        DebugPrint(64, (int)"PEI_XHCI: Enable Slot command complete, SlotID %d\n", CompletedLen);
      *a4 = CompletedLen; /*0x4bfc*/
    }
    else
    {
      switch ( CmdParamCopy )
      {
        case 10:
          if ( DebugEnabled() && DebugLevelEnabled() )
            DebugPrint(64, (int)"PEI_XHCI: DisableSlot command complete.\n");
          break;
        case 12:
          if ( DebugEnabled() && DebugLevelEnabled() )
            DebugPrint(64, (int)"PEI_XHCI: Configure Endpoint command complete.\n");
          break;
        case 13:
          if ( DebugEnabled() && DebugLevelEnabled() )
            DebugPrint(64, (int)"PEI_XHCI: Evaluate Context command complete.\n");
          break;
        case 14:
          if ( DebugEnabled() && DebugLevelEnabled() )
            DebugPrint(64, (int)"PEI_XHCI: Reset Endpoint command complete (slot#%x dci#%x).\n", *a4, a4[1]);
          (*(void (__cdecl **)(_DWORD, _DWORD, int))(*(_DWORD *)(XhcRegBase + 1151667) + 4))( /*0x4cd0*/
            *(_DWORD *)(XhcRegBase + 1151591),
            *(_DWORD *)(XhcRegBase + 1151667),
            10000);
          break;
        case 15:
          if ( DebugEnabled() && DebugLevelEnabled() )
            DebugPrint(64, (int)"XHCI: Stop Endpoint command complete (slot#%x dci#%x).\n", *a4, a4[1]);
          break;
        default:
          if ( CmdParamCopy == 16 && DebugEnabled() && DebugLevelEnabled() )
            DebugPrint(64, (int)"PEI_XHCI: Set TR pointer command complete.\n");
          break;
      }
    }
    return 0; /*0x4d82*/
  }
}


// Function: XhciAllocTransferRing @ 0x4d88 (0x60 bytes)
// Index: 39/119

int __cdecl XhciAllocTransferRing(int XhcRegBase, unsigned __int8 SlotId, unsigned __int8 a3)
{
  int v4; // [esp+4h] [ebp-4h]

  v4 = 32 * a3 + ((SlotId - 1) << 10) + *(_DWORD *)(XhcRegBase + 1151272); /*0x4dac*/
  XhciInitRing(v4, (_BYTE *)(*(_DWORD *)(XhcRegBase + 1151276) + ((a3 + 32 * (SlotId - 1)) << 10)), 64, 1); /*0x4dd9*/
  return v4; /*0x4de4*/
}


// Function: XhciContextSize @ 0x4de8 (0x85 bytes)
// Index: 40/119

unsigned __int8 __cdecl XhciContextSize(char n4, char n3, unsigned __int8 a3)
{
  char v4; // [esp+0h] [ebp-2h]
  unsigned __int8 v5; // [esp+1h] [ebp-1h]

  if ( n4 == 4 || n4 == 2 || n4 == 6 ) /*0x4e05*/
  {
    if ( n3 == 3 ) /*0x4e0e*/
      return a3; /*0x4e10*/
    else
      return 0; /*0x4e17*/
  }
  else if ( n3 == 5 || n3 == 4 || n3 == 3 ) /*0x4e34*/
  {
    return a3 - 1; /*0x4e3a*/
  }
  else
  {
    v5 = a3; /*0x4e40*/
    v4 = 0; /*0x4e43*/
    while ( v5 ) /*0x4e57*/
    {
      v5 >>= 1; /*0x4e5e*/
      ++v4; /*0x4e4e*/
    }
    return v4 + 2; /*0x4e68*/
  }
}


// Function: XhciControlTransfer @ 0x4e6d (0x47f bytes)
// Index: 41/119

int __cdecl XhciControlTransfer(int PeiServices, int a2, unsigned __int8 DeviceAddress, int a4)
{
  _BYTE v5[12]; // [esp+0h] [ebp-68h] BYREF
  __int16 SetupPkt; // [esp+Ch] [ebp-5Ch] BYREF
  __int16 SetupPkt2; // [esp+Eh] [ebp-5Ah]
  __int16 SetupPkt3; // [esp+10h] [ebp-58h]
  __int16 SetupPkt4; // [esp+12h] [ebp-56h]
  int TrbAddr; // [esp+14h] [ebp-54h] BYREF
  int StatusVal; // [esp+18h] [ebp-50h]
  int DescBufPtr; // [esp+1Ch] [ebp-4Ch] BYREF
  int TimeoutMs; // [esp+20h] [ebp-48h]
  unsigned int *TrbRingPtr; // [esp+24h] [ebp-44h]
  int DevCtxBase; // [esp+28h] [ebp-40h]
  BOOL v16; // [esp+2Ch] [ebp-3Ch]
  int SlotCtx; // [esp+30h] [ebp-38h]
  unsigned __int8 *DataBufPtr; // [esp+34h] [ebp-34h]
  unsigned __int8 SlotIdBuf[4]; // [esp+38h] [ebp-30h] BYREF
  int RouteString; // [esp+3Ch] [ebp-2Ch]
  int EpCtx; // [esp+40h] [ebp-28h]
  char RouteString_1; // [esp+44h] [ebp-24h]
  int EpType; // [esp+48h] [ebp-20h]
  unsigned __int8 *DataBufPtr_1; // [esp+4Ch] [ebp-1Ch]
  int *DevCtxEntry; // [esp+50h] [ebp-18h]
  int EpCtxEntry; // [esp+54h] [ebp-14h]
  int XhcRegBase; // [esp+58h] [ebp-10h]
  unsigned __int16 MaxPktSize; // [esp+5Ch] [ebp-Ch]
  unsigned __int16 DescIdx; // [esp+60h] [ebp-8h]
  bool v30; // [esp+64h] [ebp-4h]
  unsigned __int8 HubPortCnt; // [esp+65h] [ebp-3h]
  char DevSpeed; // [esp+66h] [ebp-2h]
  unsigned __int8 EpCount; // [esp+67h] [ebp-1h]

  XhcRegBase = a2 - 1151595; /*0x4e7b*/
  if ( !DeviceAddress ) /*0x4e84*/
    return -2147483646; /*0x4e86*/
  DevSpeed = XhciLookupDeviceByRoute((_BYTE *)(XhcRegBase + 1151360), SlotIdBuf, DeviceAddress); /*0x4ea8*/
  if ( !SlotIdBuf[0] ) /*0x4ec3*/
    return -2147483641; /*0x4ec5*/
  DevCtxBase = XhciGetDevCtxBase(XhcRegBase, SlotIdBuf[0]); /*0x4edc*/
  if ( *(_BYTE *)(a4 + 1) != 2 ) /*0x4ee9*/
    return -2147483641; /*0x4eeb*/
  DevCtxEntry = (int *)XhciGetDevCtxEntry(XhcRegBase, DevCtxBase, 0); /*0x4f05*/
  LOBYTE(RouteString) = ((unsigned int)*DevCtxEntry >> 20) & 0xF; /*0x4f13*/
  ZeroMem(*(_DWORD *)(XhcRegBase + 1118436), 33 * *(unsigned __int8 *)(XhcRegBase + 1118428)); /*0x4f2c*/
  SlotCtx = XhciGetDevCtxEntry(XhcRegBase, *(_DWORD *)(XhcRegBase + 1118436), 0); /*0x4f47*/
  *(_DWORD *)(SlotCtx + 4) = 1; /*0x4f4d*/
  DevCtxEntry = (int *)XhciGetDevCtxEntry(XhcRegBase, *(_DWORD *)(XhcRegBase + 1118436), 1u); /*0x4f6a*/
  MaxPktSize = *(_WORD *)(a4 + 2); /*0x4f74*/
  if ( MaxPktSize > 0x1FFu ) /*0x4f81*/
    MaxPktSize = 511; /*0x4f88*/
  for ( DescIdx = 0; DescIdx < (int)MaxPktSize; DescIdx += *DataBufPtr_1 ) /*0x4f8e*/
  {
    DataBufPtr = (unsigned __int8 *)(a4 + DescIdx); /*0x4fbb*/
    DataBufPtr_1 = DataBufPtr; /*0x4fc1*/
    if ( DataBufPtr[1] == 4 ) /*0x4fce*/
    {
      v16 = DataBufPtr[5] == 9; /*0x4fda*/
      v30 = v16; /*0x4fec*/
    }
    else if ( DataBufPtr_1[1] == 5 ) /*0x4ffb*/
    {
      if ( (DataBufPtr_1[3] & 3) != 0 ) /*0x5009*/
      {
        EpCount = 2 * (DataBufPtr_1[2] & 0xF); /*0x502e*/
        LOBYTE(EpType) = DataBufPtr_1[3] & 3; /*0x503b*/
        if ( (DataBufPtr_1[2] & 0x80) != 0 ) /*0x504a*/
        {
          ++EpCount; /*0x5051*/
          LOBYTE(EpType) = EpType + 4; /*0x505b*/
        }
      }
      else
      {
        EpCount = 2 * (DataBufPtr_1[2] & 0xF) + 1; /*0x5019*/
        LOBYTE(EpType) = 4; /*0x501c*/
      }
      if ( EpCount > (unsigned int)((unsigned __int8)HIBYTE(*DevCtxEntry) >> 3) ) /*0x506f*/
        *DevCtxEntry = ((EpCount & 0x1F) << 27) | *DevCtxEntry & 0x7FFFFFF; /*0x508b*/
      EpCtxEntry = XhciGetDevCtxEntry(XhcRegBase, *(_DWORD *)(XhcRegBase + 1118436), EpCount + 1); /*0x50a7*/
      *(_DWORD *)(EpCtxEntry + 4) = (8 * (EpType & 7)) | *(_DWORD *)(EpCtxEntry + 4) & 0xFFFFFFC7; /*0x50c2*/
      *(_DWORD *)(EpCtxEntry + 4) = ((*((_WORD *)DataBufPtr_1 + 2) & 0x7FF) << 16) /*0x50ea*/
                                  | (unsigned __int16)*(_DWORD *)(EpCtxEntry + 4);
      *(_DWORD *)(EpCtxEntry + 4) |= 6u; /*0x50f9*/
      HubPortCnt = XhciContextSize(EpType, RouteString, DataBufPtr_1[6]); /*0x5112*/
      *(_DWORD *)EpCtxEntry = (HubPortCnt << 16) | *(_DWORD *)EpCtxEntry & 0xFF00FFFF; /*0x5131*/
      TrbRingPtr = (unsigned int *)XhciAllocTransferRing(XhcRegBase, SlotIdBuf[0], EpCount - 1); /*0x5147*/
      *(_QWORD *)(EpCtxEntry + 8) = *TrbRingPtr + 1LL; /*0x515a*/
      *(_DWORD *)(SlotCtx + 4) |= 1 << EpCount; /*0x5172*/
    }
  }
  if ( v30 ) /*0x5180*/
  {
    DescBufPtr = 12; /*0x5186*/
    ZeroMem((int)&SetupPkt, 8u); /*0x5193*/
    SetupPkt = 1696; /*0x5198*/
    if ( (unsigned __int8)RouteString == 4 || (unsigned __int8)RouteString == 5 ) /*0x51b0*/
      SetupPkt2 = 10752; /*0x51b7*/
    else
      SetupPkt2 = 10496; /*0x51c2*/
    SetupPkt3 = 0; /*0x51c8*/
    SetupPkt4 = 12; /*0x51cf*/
    TimeoutMs = 3000; /*0x51d3*/
    RouteString_1 = RouteString; /*0x51dd*/
    if ( (_BYTE)RouteString == 1 ) /*0x51e4*/
    {
      LOBYTE(EpCtx) = 2; /*0x520c*/
    }
    else
    {
      switch ( RouteString_1 ) /*0x51ea*/
      {
        case 2: /*0x51ea*/
          LOBYTE(EpCtx) = 1; /*0x5206*/
          break;
        case 3: /*0x51ea*/
          LOBYTE(EpCtx) = 3; /*0x5200*/
          break;
        case 4: /*0x51ea*/
          LOBYTE(EpCtx) = 4; /*0x5212*/
          break;
        case 5: /*0x51ea*/
          LOBYTE(EpCtx) = 5; /*0x5218*/
          break;
      }
    }
    EpCtxEntry = XhciGetDevCtxEntry(XhcRegBase, DevCtxBase, 1u); /*0x522c*/
    StatusVal = XhciCreateTransfer( /*0x5268*/
                  PeiServices,
                  a2,
                  0,
                  EpCtx,
                  (unsigned __int16)HIWORD(*(_DWORD *)(EpCtxEntry + 4)),
                  0,
                  (unsigned __int8 *)&SetupPkt,
                  0,
                  (int)v5,
                  &DescBufPtr,
                  TimeoutMs,
                  &TrbAddr);
    if ( StatusVal >= 0 ) /*0x526f*/
    {
      *DevCtxEntry |= 0x4000000u; /*0x527e*/
      DevCtxEntry[1] = (v5[2] << 24) | DevCtxEntry[1] & 0xFFFFFF; /*0x529d*/
      if ( (unsigned __int8)RouteString == 3 ) /*0x52a7*/
        DevCtxEntry[2] = ((((int)*(unsigned __int16 *)&v5[3] >> 5) & 3) << 16) | DevCtxEntry[2] & 0xFFFCFFFF; /*0x52ca*/
    }
  }
  return (unsigned __int8)XhciIssueCommand(PeiServices, XhcRegBase, 12, SlotIdBuf); /*0x52e8*/
}


// Function: XhciGetDeviceDescriptor @ 0x52ec (0xfc bytes)
// Index: 42/119

int __cdecl XhciGetDeviceDescriptor(int a1, int a2)
{
  _DWORD *v2; // eax
  int DoorbellReg; // [esp+0h] [ebp-18h]
  int TransferRing; // [esp+4h] [ebp-14h]
  int XhcRegBase; // [esp+Ch] [ebp-Ch]
  char v7; // [esp+17h] [ebp-1h] BYREF

  XhcRegBase = *(_DWORD *)(a2 + 64) - 1151595; /*0x5303*/
  v7 = 2 * (*(_BYTE *)(a2 + 146) & 0xF) + 1; /*0x5317*/
  TransferRing = XhciGetTransferRing(XhcRegBase, *(_BYTE *)(a2 + 62), v7 - 1); /*0x5333*/
  v2 = XhciRingAllocTrb(TransferRing); /*0x5339*/
  v2[3] = v2[3] & 0xFFFF03FF | 0x400; /*0x5355*/
  *v2 = XhcRegBase + 1151677; /*0x5365*/
  v2[1] = 0; /*0x5367*/
  v2[2] = v2[2] & 0xFFFE0000 | 8; /*0x537b*/
  v2[3] |= 4u; /*0x538a*/
  v2[3] |= 0x20u; /*0x5399*/
  *(_BYTE *)(XhcRegBase + 1151675) = v7; /*0x53a2*/
  *(_BYTE *)(XhcRegBase + 1151676) = *(_BYTE *)(a2 + 62); /*0x53b1*/
  DoorbellReg = XhciGetDoorbellReg(XhcRegBase, *(_BYTE *)(a2 + 62)); /*0x53c9*/
  XhciWriteMem(XhcRegBase, 2u, DoorbellReg, 1u, (int)&v7); /*0x53da*/
  return 0; /*0x53e4*/
}


// Function: XhciGetTransferRing @ 0x53e8 (0x24 bytes)
// Index: 43/119

int __cdecl XhciGetTransferRing(int a1, unsigned __int8 a2, unsigned __int8 a3)
{
  return ((a2 - 1) << 10) + *(_DWORD *)(a1 + 1151272) + 32 * a3; /*0x540a*/
}


// Function: XhciGetDoorbellReg @ 0x540c (0x15 bytes)
// Index: 44/119

int __cdecl XhciGetDoorbellReg(int XhcRegBase, unsigned __int8 SlotIdOut)
{
  return *(_DWORD *)(XhcRegBase + 1151308) + 4 * SlotIdOut; /*0x541f*/
}


// Function: XhciGetDevCtxBase @ 0x5421 (0x2a bytes)
// Index: 45/119

int __cdecl XhciGetDevCtxBase(int a1, unsigned __int8 a2)
{
  return *(_DWORD *)(a1 + 1151280) + 32 * *(unsigned __int8 *)(a1 + 1118428) * (a2 - 1); /*0x5447*/
}


// Function: XhciGetDevCtxEntry @ 0x544b (0x19 bytes)
// Index: 46/119

int __cdecl XhciGetDevCtxEntry(int a1, int a2, unsigned __int8 a3)
{
  return a2 + *(unsigned __int8 *)(a1 + 1118428) * a3; /*0x5462*/
}


// Function: XhciIsUsb3Port @ 0x5464 (0xfb bytes)
// Index: 47/119

char __cdecl XhciIsUsb3Port(int XhcRegBase, unsigned __int8 PortNumber)
{
  int PortScReg; // [esp+0h] [ebp-8h]
  unsigned __int8 PortIdx; // [esp+7h] [ebp-1h]

  if ( BYTE1(*(_DWORD *)(XhcRegBase + 1151348)) /*0x54bc*/
    && PortNumber >= (unsigned int)(unsigned __int8)*(_DWORD *)(XhcRegBase + 1151348)
    && PortNumber < (unsigned __int8)BYTE1(*(_DWORD *)(XhcRegBase + 1151348))
                  + (unsigned int)(unsigned __int8)*(_DWORD *)(XhcRegBase + 1151348) )
  {
    return 1; /*0x54be*/
  }
  if ( *(_BYTE *)(XhcRegBase + 1151687) ) /*0x54c8*/
  {
    for ( PortIdx = 0; PortIdx < (int)*(unsigned __int8 *)(XhcRegBase + 1151687); ++PortIdx ) /*0x54d7*/
    {
      PortScReg = *(_DWORD *)(XhcRegBase + 1151352) + 12 * PortIdx; /*0x5507*/
      if ( BYTE1(*(_DWORD *)(PortScReg + 8)) /*0x5551*/
        && PortNumber >= (unsigned int)(unsigned __int8)*(_DWORD *)(PortScReg + 8)
        && PortNumber < (unsigned __int8)BYTE1(*(_DWORD *)(PortScReg + 8))
                      + (unsigned int)(unsigned __int8)*(_DWORD *)(PortScReg + 8) )
      {
        return 1; /*0x5555*/
      }
    }
  }
  return 0; /*0x555b*/
}


// Function: XhciResetPortsOnInit @ 0x555f (0x13e bytes)
// Index: 48/119

int __cdecl XhciResetPortsOnInit(int XhcDev, _DWORD *buf)
{
  int DevIdx_1; // eax
  int OpRegVal; // [esp+0h] [ebp-14h] BYREF
  int *p_OpRegVal; // [esp+4h] [ebp-10h]
  unsigned int PortIdx; // [esp+8h] [ebp-Ch]
  int PortScReg; // [esp+Ch] [ebp-8h]
  unsigned __int8 PortConnStatus; // [esp+12h] [ebp-2h]
  unsigned __int8 DevIdx; // [esp+13h] [ebp-1h]

  p_OpRegVal = &OpRegVal; /*0x5568*/
  DevIdx_1 = (unsigned __int8)BYTE1(buf[287834]); /*0x5577*/
  if ( BYTE1(buf[287834]) ) /*0x5577*/
  {
    for ( DevIdx = 0; ; ++DevIdx ) /*0x5582*/
    {
      DevIdx_1 = DevIdx; /*0x5590*/
      if ( DevIdx >= (unsigned int)(unsigned __int8)BYTE1(buf[287834]) ) /*0x55a8*/
        break; /*0x55a8*/
      PortConnStatus = buf[287834] + DevIdx; /*0x55c3*/
      PortScReg = 16 * (PortConnStatus - 1) + 1024; /*0x55d3*/
      OpRegVal = XhciReadOpReg((int)buf, PortScReg); /*0x55e3*/
      if ( (*p_OpRegVal & 1) != 0 && (((unsigned int)*p_OpRegVal >> 1) & 1) == 0 ) /*0x55fe*/
      {
        XhciWriteOpReg((int)buf, PortScReg, 528); /*0x560f*/
        OpRegVal = XhciReadOpReg((int)buf, PortScReg); /*0x5624*/
        for ( PortIdx = 0; PortIdx < 0x7D0 && (((unsigned int)*p_OpRegVal >> 21) & 1) == 0; ++PortIdx ) /*0x5627*/
        {
          (*(void (__cdecl **)(_DWORD, _DWORD, int))(*(_DWORD *)((char *)buf + 1151667) + 4))( /*0x5669*/
            *(_DWORD *)((char *)buf + 1151591),
            *(_DWORD *)((char *)buf + 1151667),
            100);
          OpRegVal = XhciReadOpReg((int)buf, PortScReg); /*0x567c*/
        }
        XhciWriteOpReg((int)buf, PortScReg, 2621952); /*0x568c*/
      }
    }
  }
  return DevIdx_1; /*0x5699*/
}


// Function: XhciParseUsb3Cap @ 0x569d (0x148 bytes)
// Index: 49/119

int __cdecl XhciParseUsb3Cap(int XhcDev, int buf)
{
  int CapEntryBuf; // [esp+0h] [ebp-24h] BYREF
  char CapId; // [esp+8h] [ebp-1Ch] BYREF
  int CapOffset; // [esp+Ch] [ebp-18h]
  int CapId_1; // [esp+10h] [ebp-14h]
  unsigned int CapValue; // [esp+14h] [ebp-10h]
  int CapIdx; // [esp+18h] [ebp-Ch]
  int p_CapId; // [esp+1Ch] [ebp-8h]
  unsigned __int8 CapType; // [esp+23h] [ebp-1h]

  p_CapId = (int)&CapId; /*0x56a6*/
  CapType = 0; /*0x56a9*/
  if ( !HIWORD(*(_DWORD *)(buf + 1151304)) ) /*0x56b9*/
    return 0; /*0x56c2*/
  for ( CapIdx = 4 * (unsigned __int16)HIWORD(*(_DWORD *)(buf + 1151304)); /*0x56db*/
        ;
        CapIdx += 4 * (unsigned __int8)BYTE1(*(_DWORD *)p_CapId) )
  {
    XhciReadMem(buf, 2u, CapIdx, 1u, p_CapId); /*0x56eb*/
    CapId_1 = (unsigned __int8)*(_DWORD *)p_CapId; /*0x56fd*/
    if ( CapId_1 == 2 && (unsigned __int8)HIBYTE(*(_DWORD *)p_CapId) == 3 ) /*0x5718*/
    {
      if ( (unsigned __int8)BYTE2(*(_DWORD *)p_CapId) == 1 ) /*0x572a*/
      {
        ++CapType; /*0x5731*/
      }
      else if ( (unsigned __int8)BYTE2(*(_DWORD *)p_CapId) == 16 ) /*0x5746*/
      {
        ++CapType; /*0x574d*/
      }
    }
    if ( !BYTE1(*(_DWORD *)p_CapId) ) /*0x5758*/
      break; /*0x5758*/
  }
  if ( CapType ) /*0x5782*/
  {
    CapValue = ((12 * (unsigned int)CapType) >> 12) + 1; /*0x578f*/
    CapOffset = (*(int (__cdecl **)(int, int, unsigned int, int *))(*(_DWORD *)XhcDev + 72))( /*0x57a9*/
                  XhcDev,
                  4,
                  CapValue,
                  &CapEntryBuf);
    if ( CapOffset < 0 ) /*0x57b0*/
      return -2147483639; /*0x57b7*/
    ZeroMem(CapEntryBuf, CapValue << 12); /*0x57c2*/
    *(_BYTE *)(buf + 1151687) = CapType; /*0x57cd*/
    *(_DWORD *)(buf + 1151352) = CapEntryBuf; /*0x57d9*/
  }
  return 0; /*0x57e1*/
}


// Function: XhciParseExtendedCap @ 0x57e5 (0x41c bytes)
// Index: 50/119

int __cdecl XhciParseExtendedCap(int XhcDev, int buf)
{
  char CapId; // [esp+0h] [ebp-18h] BYREF
  int CapId_1; // [esp+4h] [ebp-14h]
  int CapEntry; // [esp+8h] [ebp-10h]
  int p_CapId; // [esp+Ch] [ebp-Ch]
  int CapIdx; // [esp+10h] [ebp-8h]
  unsigned __int8 CapCount; // [esp+17h] [ebp-1h]

  p_CapId = (int)&CapId; /*0x57ee*/
  CapCount = 0; /*0x57f1*/
  if ( !HIWORD(*(_DWORD *)(buf + 1151304)) ) /*0x5801*/
    return 0; /*0x5808*/
  for ( CapIdx = 4 * (unsigned __int16)HIWORD(*(_DWORD *)(buf + 1151304));
        ;
        CapIdx += 4 * (unsigned __int8)BYTE1(*(_DWORD *)p_CapId) )
  {
    XhciReadMem(buf, 2u, CapIdx, 1u, p_CapId); /*0x5833*/
    CapId_1 = (unsigned __int8)*(_DWORD *)p_CapId; /*0x5845*/
    if ( CapId_1 == 2 )
    {
      if ( DebugEnabled() && DebugLevelEnabled() )
        DebugPrint(
          64,
          (int)"XHCI: CAP supported : MajorRev %x MinorRev %x\n",
          HIBYTE(*(_DWORD *)p_CapId),
          (unsigned __int8)BYTE2(*(_DWORD *)p_CapId));
      if ( (unsigned __int8)HIBYTE(*(_DWORD *)p_CapId) == 2 )
      {
        XhciReadMem(buf, 2u, CapIdx, 3u, buf + 1151328); /*0x58d9*/
        if ( DebugEnabled() && DebugLevelEnabled() )
          DebugPrint(
            64,
            (int)"XHCI: USB2 Support Protocol %x, PortOffset %x PortCount %x\n",
            CapIdx + *(_DWORD *)(buf + 1118420),
            (unsigned __int8)*(_DWORD *)(buf + 1151336),
            BYTE1(*(_DWORD *)(buf + 1151336)));
      }
      else if ( (unsigned __int8)HIBYTE(*(_DWORD *)p_CapId) == 3 )
      {
        if ( (unsigned __int8)BYTE2(*(_DWORD *)p_CapId) )
        {
          if ( (unsigned __int8)BYTE2(*(_DWORD *)p_CapId) == 1 )
          {
            if ( *(_BYTE *)(buf + 1151687) && CapCount < (int)*(unsigned __int8 *)(buf + 1151687) )
            {
              CapEntry = *(_DWORD *)(buf + 1151352) + 12 * CapCount; /*0x5a3d*/
              XhciReadMem(buf, 2u, CapIdx, 3u, CapEntry); /*0x5a4d*/
              if ( DebugEnabled() && DebugLevelEnabled() )
                DebugPrint(
                  64,
                  (int)"XHCI: USB3.1 Support Protocol %x, PortOffset %x PortCount %x\n",
                  CapIdx + *(_DWORD *)(buf + 1118420),
                  (unsigned __int8)*(_DWORD *)(CapEntry + 8),
                  BYTE1(*(_DWORD *)(CapEntry + 8)));
              ++CapCount; /*0x5ab4*/
            }
          }
          else if ( (unsigned __int8)BYTE2(*(_DWORD *)p_CapId) == 16
                 && *(_BYTE *)(buf + 1151687)
                 && CapCount < (int)*(unsigned __int8 *)(buf + 1151687) )
          {
            CapEntry = *(_DWORD *)(buf + 1151352) + 12 * CapCount; /*0x5b0a*/
            XhciReadMem(buf, 2u, CapIdx, 3u, CapEntry); /*0x5b1a*/
            if ( DebugEnabled() && DebugLevelEnabled() )
              DebugPrint(
                64,
                (int)"XHCI: USB3.1 Support Protocol %x, PortOffset %x PortCount %x\n",
                CapIdx + *(_DWORD *)(buf + 1118420),
                (unsigned __int8)*(_DWORD *)(CapEntry + 8),
                BYTE1(*(_DWORD *)(CapEntry + 8)));
            ++CapCount; /*0x5b81*/
          }
        }
        else
        {
          XhciReadMem(buf, 2u, CapIdx, 3u, buf + 1151340); /*0x5982*/
          if ( DebugEnabled() && DebugLevelEnabled() )
            DebugPrint(
              64,
              (int)"XHCI: USB3.0 Support Protocol %x, PortOffset %x PortCount %x\n",
              CapIdx + *(_DWORD *)(buf + 1118420),
              (unsigned __int8)*(_DWORD *)(buf + 1151348),
              BYTE1(*(_DWORD *)(buf + 1151348)));
        }
      }
    }
    else if ( CapId_1 == 10 )
    {
      *(_DWORD *)(buf + 1151356) = CapIdx; /*0x5b8e*/
      if ( DebugEnabled() )
      {
        if ( DebugLevelEnabled() )
          DebugPrint(64, (int)"XHCI: USB Debug Capability Ptr %x\n", *(_DWORD *)(buf + 1151356));
      }
    }
    if ( !BYTE1(*(_DWORD *)p_CapId) ) /*0x5bd7*/
      break; /*0x5bd7*/
  }
  return 0; /*0x5bfd*/
}


// Function: XhciReadMem @ 0x5c01 (0x114 bytes)
// Index: 51/119

int __cdecl XhciReadMem(int a1, unsigned int n4, int a3, unsigned int i, int a5)
{
  unsigned int j; // [esp+8h] [ebp-4h]

  if ( n4 >= 4 ) /*0x5c0b*/
    return -2147483646; /*0x5c13*/
  if ( !i ) /*0x5c21*/
    return -2147483646; /*0x5c23*/
  if ( !a5 ) /*0x5c31*/
    return -2147483646; /*0x5c33*/
  for ( j = 0; j < i; ++j ) /*0x5c3d*/
  {
    if ( n4 ) /*0x5c60*/
    {
      if ( n4 == 1 ) /*0x5c66*/
      {
        *(_WORD *)(a5 + 2 * j) = MmioRead16((unsigned __int16 *)(a3 + *(_DWORD *)(a1 + 1118420) + 2 * j)); /*0x5cb4*/
      }
      else if ( n4 == 2 ) /*0x5c6c*/
      {
        *(_DWORD *)(a5 + 4 * j) = MmioRead32((void *)(a3 + *(_DWORD *)(a1 + 1118420) + 4 * j)); /*0x5cd7*/
      }
      else
      {
        *(_QWORD *)(a5 + 8 * j) = MmioRead64(a3 + *(_DWORD *)(a1 + 1118420) + 8 * j); /*0x5cf9*/
      }
    }
    else
    {
      *(_BYTE *)(j + a5) = MmioRead8((void *)(j + a3 + *(_DWORD *)(a1 + 1118420))); /*0x5c93*/
    }
  }
  return 0; /*0x5d10*/
}


// Function: XhciWriteMem @ 0x5d15 (0x114 bytes)
// Index: 52/119

int __cdecl XhciWriteMem(int a1, unsigned int n4, int a3, unsigned int i, int a5)
{
  unsigned int j; // [esp+4h] [ebp-4h]

  if ( n4 >= 4 ) /*0x5d1e*/
    return -2147483646; /*0x5d26*/
  if ( !i ) /*0x5d34*/
    return -2147483646; /*0x5d36*/
  if ( !a5 ) /*0x5d44*/
    return -2147483646; /*0x5d46*/
  for ( j = 0; j < i; ++j ) /*0x5d50*/
  {
    if ( n4 ) /*0x5d73*/
    {
      if ( n4 == 1 ) /*0x5d79*/
      {
        MmioWrite16((_WORD *)(a3 + *(_DWORD *)(a1 + 1118420) + 2 * j), *(_WORD *)(a5 + 2 * j)); /*0x5dc6*/
      }
      else if ( n4 == 2 ) /*0x5d7f*/
      {
        MmioWrite32((_DWORD *)(a3 + *(_DWORD *)(a1 + 1118420) + 4 * j), *(_DWORD *)(a5 + 4 * j)); /*0x5de8*/
      }
      else
      {
        MmioWrite64(*(_DWORD *)(a5 + 8 * j), *(_DWORD *)(a5 + 8 * j + 4)); /*0x5e0e*/
      }
    }
    else
    {
      MmioWrite8((_BYTE *)(j + a3 + *(_DWORD *)(a1 + 1118420)), *(_BYTE *)(j + a5)); /*0x5da3*/
    }
  }
  return 0; /*0x5e25*/
}


// Function: XhciSetOpRegBitsAt @ 0x5e29 (0x3d bytes)
// Index: 53/119

int __cdecl XhciSetOpRegBitsAt(int buf, int a2, int n2)
{
  int v3; // ecx
  int v5; // [esp+0h] [ebp-4h] BYREF

  v5 = v3; /*0x5e2c*/
  XhciReadMem(buf, 2u, a2, 1u, (int)&v5); /*0x5e3b*/
  v5 |= n2; /*0x5e49*/
  return XhciWriteMem(buf, 2u, a2, 1u, (int)&v5); /*0x5e64*/
}


// Function: XhciClearOpRegBitsAt @ 0x5e66 (0x3f bytes)
// Index: 54/119

int __cdecl XhciClearOpRegBitsAt(int buf, int a2, int n2)
{
  int v3; // ecx
  int v5; // [esp+0h] [ebp-4h] BYREF

  v5 = v3; /*0x5e69*/
  XhciReadMem(buf, 2u, a2, 1u, (int)&v5); /*0x5e78*/
  v5 &= ~n2; /*0x5e88*/
  return XhciWriteMem(buf, 2u, a2, 1u, (int)&v5); /*0x5ea3*/
}


// Function: XhciReadOpReg @ 0x5ea5 (0x2c bytes)
// Index: 55/119

int __cdecl XhciReadOpReg(int a1, int a2)
{
  int v2; // ecx
  int v4; // [esp+0h] [ebp-4h] BYREF

  v4 = v2; /*0x5ea8*/
  XhciReadMem(a1, 2u, a2 + *(unsigned __int8 *)(a1 + 1151288), 1u, (int)&v4); /*0x5ec2*/
  return v4; /*0x5ecf*/
}


// Function: XhciWriteOpReg @ 0x5ed1 (0x26 bytes)
// Index: 56/119

int XhciWriteOpReg(int a2, int a3, ...)
{
  va_list va; // [esp+10h] [ebp+10h] BYREF

  va_start(va, a3);
  return XhciWriteMem(a2, 2u, a3 + *(unsigned __int8 *)(a2 + 1151288), 1u, (int)va); /*0x5ef5*/
}


// Function: XhciSetOpRegBits @ 0x5ef7 (0x2c bytes)
// Index: 57/119

int __cdecl XhciSetOpRegBits(int a1, int a2, int a3)
{
  int v4; // [esp+0h] [ebp-4h]

  v4 = a3 | XhciReadOpReg(a1, a2); /*0x5f0b*/
  return XhciWriteOpReg(a1, a2, v4); /*0x5f21*/
}


// Function: XhciClearOpRegBits @ 0x5f23 (0x30 bytes)
// Index: 58/119

int __cdecl XhciClearOpRegBits(int buf, int a2, int n4)
{
  int v4; // [esp+0h] [ebp-4h]

  v4 = ~n4 & XhciReadOpReg(buf, a2); /*0x5f3b*/
  return XhciWriteOpReg(buf, a2, v4); /*0x5f51*/
}


// Function: XhciEnumerateHub @ 0x5f53 (0x3f bytes)
// Index: 59/119

int __fastcall XhciEnumerateHub(int a1, int a2)
{
  int v2; // edi
  int i; // eax
  int v6; // [esp+Ch] [ebp-4h] BYREF

  v2 = 0; /*0x5f5b*/
  for ( i = (*(int (__cdecl **)(int, void *, _DWORD, _DWORD, int *))(*(_DWORD *)a2 + 32))(a2, &unk_8980, 0, 0, &v6); /*0x5f67*/
        i >= 0;
        i = (*(int (__cdecl **)(int, void *, int, _DWORD, int *))(*(_DWORD *)a2 + 32))(a2, &unk_8980, v2, 0, &v6) )
  {
    XhciConnectUsbDevice(a2, v6); /*0x5f6f*/
    ++v2; /*0x5f78*/
  }
  return 0; /*0x5f8b*/
}


// Function: XhciCreateUsbDevice @ 0x5f92 (0x2fa bytes)
// Index: 60/119

int __fastcall XhciCreateUsbDevice(int a1, int a2, _BYTE *a3, char a4)
{
  int v5; // esi
  int (__cdecl **v6)(int, _DWORD, _WORD *, int, int, _DWORD, _DWORD, _BYTE *); // edi
  int v7; // ebx
  __int16 v8; // ax
  __int16 v9; // cx
  __int16 v10; // ax
  char n2; // al
  int v12; // edi
  bool v13; // sf
  int v14; // eax
  bool v15; // sf
  int v16; // eax
  _BYTE *v17; // ecx
  int result; // eax
  int v19; // [esp+10h] [ebp-18h]
  int v20; // [esp+14h] [ebp-14h] BYREF
  int v21; // [esp+18h] [ebp-10h]
  int v22; // [esp+1Ch] [ebp-Ch] BYREF
  int v23; // [esp+20h] [ebp-8h]
  _BYTE v24[4]; // [esp+24h] [ebp-4h] BYREF

  v5 = a2; /*0x5f9b*/
  v23 = a2; /*0x5fa1*/
  v6 = (int (__cdecl **)(int, _DWORD, _WORD *, int, int, _DWORD, _DWORD, _BYTE *))(a2 + 4); /*0x5fab*/
  (*(void (__cdecl **)(int, void *, _DWORD, _DWORD, _BYTE *))(*(_DWORD *)a1 + 32))(a1, &unk_8930, 0, 0, v24); /*0x5fb6*/
  LOBYTE(v19) = 1; /*0x5fbc*/
  if ( !*(_BYTE *)(v5 + 59) ) /*0x5fc5*/
    return 0; /*0x6277*/
  while ( 1 ) /*0x5fcb*/
  {
    if ( XhciReadPortStatus(a1, (int)v6, v19, &v20) < 0 ) /*0x5fe2*/
      goto LABEL_47; /*0x5fe2*/
    if ( (v20 & 0x10000) != 0 ) /*0x5fed*/
    {
      XhciWritePortStatus(a1, v6, v19, 16); /*0x5ff6*/
    }
    else if ( a4 == 1 ) /*0x6004*/
    {
      goto LABEL_47; /*0x6004*/
    }
    v21 = v20; /*0x600e*/
    if ( (v20 & 1) == 0 ) /*0x6014*/
      goto LABEL_47; /*0x6014*/
    if ( (v20 & 2) == 0 ) /*0x601e*/
    {
      XhciResetPort(a1, v6, v19); /*0x6025*/
      XhciReadPortStatus(a1, (int)v6, v19, &v20); /*0x6034*/
      v21 = v20; /*0x6040*/
      if ( (v20 & 1) == 0 || (v20 & 2) == 0 ) /*0x6050*/
        goto LABEL_47; /*0x6050*/
    }
    if ( (*(int (__cdecl **)(int, int, int *))(*(_DWORD *)a1 + 76))(a1, 152, &v22) < 0 ) /*0x606d*/
      return -2147483639; /*0x6279*/
    v7 = v22; /*0x6076*/
    (*(void (__cdecl **)(int, int, _DWORD))(*(_DWORD *)a1 + 84))(v22, 152, 0); /*0x607e*/
    *(_DWORD *)v7 = 1147302741; /*0x6084*/
    *(_BYTE *)(v7 + 52) = 0; /*0x6091*/
    *(_BYTE *)(v7 + 57) = 0; /*0x6094*/
    *(_WORD *)(v7 + 54) = 8; /*0x609a*/
    qmemcpy((void *)(v7 + 4), &src_, 0x18u); /*0x60a6*/
    *(_DWORD *)(v7 + 28) = unk_8598; /*0x60b5*/
    *(_DWORD *)(v7 + 32) = &unk_8990; /*0x60b6*/
    *(_DWORD *)(v7 + 36) = unk_85A0; /*0x60b7*/
    *(_DWORD *)(v7 + 36) = v7 + 4; /*0x60bd*/
    *(_DWORD *)(v7 + 40) = unk_85BC; /*0x60c3*/
    *(_DWORD *)(v7 + 44) = &unk_8960; /*0x60c4*/
    *(_DWORD *)(v7 + 48) = 0; /*0x60c5*/
    v5 = v23; /*0x60c6*/
    *(_DWORD *)(v7 + 48) = v7 + 4; /*0x60ca*/
    *(_DWORD *)(v7 + 64) = *(_DWORD *)(v5 + 64); /*0x60d0*/
    *(_WORD *)(v7 + 58) = 0; /*0x60db*/
    *(_BYTE *)(v7 + 56) = 2; /*0x60df*/
    v8 = *(unsigned __int8 *)(v5 + 52); /*0x60e3*/
    *(_BYTE *)(v7 + 150) = 0; /*0x60e7*/
    v9 = v8 + ((unsigned __int8)v19 << 7); /*0x60ee*/
    v10 = v21; /*0x60f1*/
    *(_WORD *)(v7 + 144) = v9; /*0x60f5*/
    if ( (v10 & 0x200) != 0 ) /*0x6103*/
      *(_BYTE *)(v7 + 56) = 1; /*0x6105*/
    if ( (v10 & 0x400) != 0 ) /*0x610f*/
    {
      *(_BYTE *)(v7 + 56) = 3; /*0x6114*/
      *(_WORD *)(v7 + 54) = 64; /*0x6118*/
    }
    if ( (v10 & 0x800) != 0 ) /*0x6128*/
    {
      *(_BYTE *)(v7 + 56) = 4; /*0x612a*/
      *(_WORD *)(v7 + 54) = 512; /*0x612e*/
    }
    if ( (v10 & 0x1000) != 0 ) /*0x6137*/
    {
      *(_BYTE *)(v7 + 56) = 5; /*0x6139*/
      *(_WORD *)(v7 + 54) = 512; /*0x613d*/
    }
    n2 = *(_BYTE *)(v5 + 56); /*0x6141*/
    if ( n2 == 1 || n2 == 2 ) /*0x614a*/
      *(_WORD *)(v7 + 144) = *(_WORD *)(v5 + 144); /*0x6153*/
    if ( XhciProcessHubPort(a1, v7, v19, a3) >= 0 ) /*0x616f*/
    {
      v12 = (*(int (__cdecl **)(int, int))(*(_DWORD *)a1 + 24))(a1, v7 + 28); /*0x6195*/
      v13 = v12 < 0; /*0x6199*/
      if ( v12 ) /*0x619b*/
      {
        v14 = DebugPrintUsbStatus(); /*0x619d*/
        if ( v14 ) /*0x61a4*/
          (*(void (__cdecl **)(const char *, int, const char *))(v14 + 4))( /*0x61b5*/
            "e:\\hs\\AmiModulePkg\\Usb\\Pei\\UsbPeim.c",
            268,
            "Status == 0");
        v13 = v12 < 0; /*0x61bb*/
      }
      if ( v13 ) /*0x61bd*/
        return v12; /*0x61bd*/
      v12 = (*(int (__cdecl **)(int, int))(*(_DWORD *)a1 + 24))(a1, v7 + 40); /*0x61ce*/
      v15 = v12 < 0; /*0x61d2*/
      if ( v12 ) /*0x61d4*/
      {
        v16 = DebugPrintUsbStatus(); /*0x61d6*/
        if ( v16 ) /*0x61dd*/
          (*(void (__cdecl **)(const char *, int, const char *))(v16 + 4))( /*0x61ee*/
            "e:\\hs\\AmiModulePkg\\Usb\\Pei\\UsbPeim.c",
            275,
            "Status == 0");
        v15 = v12 < 0; /*0x61f4*/
      }
      if ( v15 ) /*0x61f6*/
        return v12; /*0x6283*/
      v17 = *(_BYTE **)(v7 + 76); /*0x61fc*/
      if ( v17[5] == 8 && v17[7] == 80 ) /*0x6209*/
        *(_BYTE *)(v7 + 58) = 4; /*0x620b*/
      if ( v17[5] == 9 ) /*0x6213*/
      {
        *(_BYTE *)(v7 + 58) = 3; /*0x6215*/
        *(_BYTE *)(v7 + 150) = *(_BYTE *)(v5 + 150) + 1; /*0x6221*/
      }
      if ( v17[5] == 3 && v17[6] == 1 && v17[7] == 1 ) /*0x6237*/
        *(_BYTE *)(v7 + 58) = 1; /*0x6239*/
      if ( *(_BYTE *)(v7 + 58) == 3 ) /*0x6241*/
      {
        result = XhciControlTransferLow(a1, v7); /*0x6247*/
        if ( result < 0 ) /*0x624e*/
          return result; /*0x624e*/
        XhciCreateUsbDevice(a1, v7, a3, 0); /*0x625a*/
      }
      v6 = (int (__cdecl **)(int, _DWORD, _WORD *, int, int, _DWORD, _DWORD, _BYTE *))(v5 + 4); /*0x6261*/
    }
    else
    {
      v6 = (int (__cdecl **)(int, _DWORD, _WORD *, int, int, _DWORD, _DWORD, _BYTE *))(v5 + 4); /*0x6177*/
      XhciWritePortStatus( /*0x617e*/
        a1,
        (int (__cdecl **)(int, _DWORD, _WORD *, int, int, _DWORD, _DWORD, _BYTE *))(v5 + 4),
        v19,
        1);
    }
LABEL_47:
    LOBYTE(v19) = v19 + 1; /*0x6264*/
    if ( (unsigned __int8)v19 > *(_BYTE *)(v5 + 59) ) /*0x6271*/
      return 0; /*0x6271*/
  }
}


// Function: XhciConnectUsbDevice @ 0x628c (0x29b bytes)
// Index: 61/119

int __fastcall XhciConnectUsbDevice(int a1, int a2)
{
  int v3; // esi
  int v4; // ebp
  int v5; // ebp
  __int16 v6; // ax
  int v7; // edi
  bool v8; // sf
  int v9; // eax
  bool v10; // sf
  int v11; // eax
  _BYTE *v12; // eax
  int result; // eax
  unsigned __int8 v14; // [esp+13h] [ebp-15h] BYREF
  __int16 v15; // [esp+14h] [ebp-14h] BYREF
  char v16; // [esp+16h] [ebp-12h]
  int v17; // [esp+18h] [ebp-10h]
  int v18; // [esp+1Ch] [ebp-Ch] BYREF
  int v19; // [esp+20h] [ebp-8h]
  _BYTE v20[4]; // [esp+24h] [ebp-4h] BYREF

  v3 = a2; /*0x6295*/
  v19 = a2; /*0x629b*/
  (*(void (__cdecl **)(int, void *, _DWORD, _DWORD, _BYTE *))(*(_DWORD *)a1 + 32))(a1, &unk_8930, 0, 0, v20); /*0x62ac*/
  (*(void (__cdecl **)(int, int, unsigned __int8 *))(v3 + 8))(a1, v3, &v14); /*0x62b6*/
  LOBYTE(v17) = 1; /*0x62bc*/
  if ( v14 ) /*0x62c6*/
  {
    do /*0x62cc*/
    {
      v4 = v17; /*0x62cc*/
      (*(void (__cdecl **)(int, int, int, __int16 *))(v3 + 12))(a1, v3, v17, &v15); /*0x62d8*/
      if ( (v16 & 1) != 0 ) /*0x62e3*/
      {
        (*(void (__cdecl **)(int, int, int, int))(v3 + 20))(a1, v3, v4, 16); /*0x62ee*/
        if ( (v15 & 1) != 0 ) /*0x62fa*/
        {
          if ( (v15 & 2) != 0 /*0x632e*/
            || (XhciGetHubDescriptor(a1, (void (__cdecl **)(_DWORD, _DWORD, _DWORD, _DWORD))v3, v4),
                (*(void (__cdecl **)(int, int, int, __int16 *))(v3 + 12))(a1, v3, v4, &v15),
                (v15 & 1) != 0)
            && (v15 & 2) != 0 )
          {
            if ( (*(int (__cdecl **)(int, int, int *))(*(_DWORD *)a1 + 76))(a1, 152, &v18) < 0 ) /*0x634a*/
              return -2147483639; /*0x6520*/
            v5 = v18; /*0x6352*/
            (*(void (__cdecl **)(int, int, _DWORD))(*(_DWORD *)a1 + 84))(v18, 152, 0); /*0x635a*/
            *(_DWORD *)v5 = 1147302741; /*0x6360*/
            *(_DWORD *)(v5 + 56) = 2; /*0x636c*/
            *(_BYTE *)(v5 + 52) = 0; /*0x6375*/
            *(_WORD *)(v5 + 54) = 8; /*0x637b*/
            *(_BYTE *)(v5 + 150) = 0; /*0x6386*/
            qmemcpy((void *)(v5 + 4), &src_, 0x18u); /*0x638d*/
            *(_DWORD *)(v5 + 28) = unk_8598; /*0x6398*/
            *(_DWORD *)(v5 + 32) = &unk_8990; /*0x6399*/
            *(_DWORD *)(v5 + 36) = unk_85A0; /*0x639a*/
            *(_DWORD *)(v5 + 36) = v5 + 4; /*0x63a0*/
            *(_DWORD *)(v5 + 40) = unk_85BC; /*0x63a6*/
            *(_DWORD *)(v5 + 44) = &unk_8960; /*0x63a7*/
            *(_DWORD *)(v5 + 48) = 0; /*0x63a8*/
            v3 = v19; /*0x63a9*/
            *(_DWORD *)(v5 + 48) = v5 + 4; /*0x63ad*/
            *(_DWORD *)(v5 + 64) = v3; /*0x63b2*/
            *(_WORD *)(v5 + 144) = 0; /*0x63b5*/
            v6 = v15; /*0x63bc*/
            if ( (v15 & 0x200) != 0 ) /*0x63c7*/
            {
              *(_BYTE *)(v5 + 56) = 1; /*0x63c9*/
              v6 = v15; /*0x63cc*/
            }
            if ( (v6 & 0x400) != 0 ) /*0x63d7*/
            {
              *(_BYTE *)(v5 + 56) = 3; /*0x63dc*/
              *(_WORD *)(v5 + 54) = 64; /*0x63e0*/
              v6 = v15; /*0x63e4*/
            }
            if ( (v6 & 0x800) != 0 ) /*0x63f4*/
            {
              *(_BYTE *)(v5 + 56) = 4; /*0x63f6*/
              *(_WORD *)(v5 + 54) = 512; /*0x63fa*/
              v6 = v15; /*0x63fe*/
            }
            if ( (v6 & 0x1000) != 0 ) /*0x6407*/
            {
              *(_BYTE *)(v5 + 56) = 5; /*0x6409*/
              *(_WORD *)(v5 + 54) = 512; /*0x640d*/
            }
            if ( XhciProcessHubPort(a1, v5, v17, (_BYTE *)(v3 + 52)) >= 0 ) /*0x6426*/
            {
              v7 = (*(int (__cdecl **)(int, int))(*(_DWORD *)a1 + 24))(a1, v5 + 28); /*0x6445*/
              v8 = v7 < 0; /*0x6449*/
              if ( v7 ) /*0x644b*/
              {
                v9 = DebugPrintUsbStatus(); /*0x644d*/
                if ( v9 ) /*0x6454*/
                  (*(void (__cdecl **)(const char *, int, const char *))(v9 + 4))( /*0x6465*/
                    "e:\\hs\\AmiModulePkg\\Usb\\Pei\\UsbPeim.c",
                    467,
                    "Status == 0");
                v8 = v7 < 0; /*0x646b*/
              }
              if ( v8 ) /*0x646d*/
                return v7; /*0x646d*/
              v7 = (*(int (__cdecl **)(int, int))(*(_DWORD *)a1 + 24))(a1, v5 + 40); /*0x647d*/
              v10 = v7 < 0; /*0x6481*/
              if ( v7 ) /*0x6483*/
              {
                v11 = DebugPrintUsbStatus(); /*0x6485*/
                if ( v11 ) /*0x648c*/
                  (*(void (__cdecl **)(const char *, int, const char *))(v11 + 4))( /*0x649d*/
                    "e:\\hs\\AmiModulePkg\\Usb\\Pei\\UsbPeim.c",
                    474,
                    "Status == 0");
                v10 = v7 < 0; /*0x64a3*/
              }
              if ( v10 ) /*0x64a5*/
                return v7; /*0x651e*/
              v12 = *(_BYTE **)(v5 + 76); /*0x64a7*/
              if ( v12[5] == 8 && v12[7] == 80 ) /*0x64b4*/
                *(_BYTE *)(v5 + 58) = 4; /*0x64b6*/
              if ( v12[5] == 9 ) /*0x64be*/
                *(_BYTE *)(v5 + 58) = 3; /*0x64c0*/
              if ( v12[5] == 3 && v12[6] == 1 && v12[7] == 1 ) /*0x64d4*/
                *(_BYTE *)(v5 + 58) = 1; /*0x64d6*/
              if ( *(_BYTE *)(v5 + 58) == 3 ) /*0x64de*/
              {
                result = XhciControlTransferLow(a1, v5); /*0x64e4*/
                if ( result < 0 ) /*0x64eb*/
                  return result; /*0x64eb*/
                XhciCreateUsbDevice(a1, v5, (_BYTE *)(v3 + 52), 0); /*0x64f7*/
              }
            }
            else
            {
              (*(void (__cdecl **)(int, int, int, int))(v3 + 20))(a1, v3, v17, 1); /*0x6430*/
            }
          }
        }
      }
      LOBYTE(v17) = v17 + 1; /*0x6504*/
    }
    while ( (unsigned __int8)v17 <= v14 ); /*0x62cc*/
  }
  return 0; /*0x6514*/
}


// Function: XhciProcessHubPort @ 0x6527 (0x166 bytes)
// Index: 62/119

int __fastcall XhciProcessHubPort(int a1, int a2, int a3, _BYTE *a4)
{
  char v5; // bl
  int (__cdecl *v7)(int, int, int); // eax
  int result; // eax
  int (__cdecl **v9)(int, _DWORD, _WORD *, _DWORD, int, _BYTE *, _DWORD, _BYTE *); // eax
  int v10; // eax
  int v11; // ebp
  __int16 n64; // ax
  char n2; // al
  _BYTE *v14; // ecx
  int v15; // [esp+Ch] [ebp-18h] BYREF
  _BYTE v16[2]; // [esp+10h] [ebp-14h] BYREF
  unsigned __int16 n0x300; // [esp+12h] [ebp-12h]
  unsigned __int8 n64_1; // [esp+17h] [ebp-Dh]

  v5 = 0; /*0x652f*/
  v15 = 0; /*0x6535*/
  (*(void (__cdecl **)(int, void *, _DWORD, _DWORD, int *))(*(_DWORD *)a1 + 32))(a1, &unk_8930, 0, 0, &v15); /*0x6546*/
  v7 = *(int (__cdecl **)(int, int, int))(*(_DWORD *)(a2 + 64) + 40); /*0x654f*/
  if ( !v7 || (result = v7(a1, a2, a3), result >= 0) ) /*0x6563*/
  {
    v9 = (int (__cdecl **)(int, _DWORD, _WORD *, _DWORD, int, _BYTE *, _DWORD, _BYTE *))(a2 + 4); /*0x6569*/
    while ( 1 ) /*0x657e*/
    {
      v10 = XhciShortPacketFix(a1, v9, 256, v16, 8, v16); /*0x657e*/
      v11 = v10; /*0x6583*/
      if ( v10 >= 0 ) /*0x658a*/
        break; /*0x658a*/
      if ( v10 != -2147483630 ) /*0x6592*/
      {
        (*(void (__cdecl **)(int, int, int))(v15 + 4))(a1, v15, 100000); /*0x659f*/
        v9 = (int (__cdecl **)(int, _DWORD, _WORD *, _DWORD, int, _BYTE *, _DWORD, _BYTE *))(a2 + 4); /*0x65a5*/
        if ( (unsigned __int8)++v5 < 5u ) /*0x65ad*/
          continue; /*0x65ad*/
      }
      return v11; /*0x65b1*/
    }
    if ( n0x300 < 0x300u ) /*0x65c0*/
    {
      if ( n64_1 ) /*0x65d4*/
        n64 = n64_1; /*0x65d6*/
      else
        n64 = 64; /*0x65dd*/
    }
    else
    {
      n64 = 1 << n64_1; /*0x65c9*/
    }
    *(_WORD *)(a2 + 54) = n64; /*0x65de*/
    n2 = *(_BYTE *)(a2 + 56); /*0x65e2*/
    if ( n2 == 1 || n2 == 2 || n2 == 3 ) /*0x65ef*/
      (*(void (__cdecl **)(int, int, int))(v15 + 4))(a1, v15, 10000); /*0x65fc*/
    result = XhciRecoveryPacket( /*0x6617*/
               a1,
               (int (__cdecl **)(int, _DWORD, _WORD *, int, int, _DWORD, _DWORD, _BYTE *))(a2 + 4),
               (unsigned __int8)++*a4);
    if ( result >= 0 ) /*0x661f*/
    {
      *(_BYTE *)(a2 + 52) = *a4; /*0x6624*/
      (*(void (__cdecl **)(int, int, int))(v15 + 4))(a1, v15, 2000); /*0x6632*/
      result = XhciShortPacketFix( /*0x6649*/
                 a1,
                 (int (__cdecl **)(int, _DWORD, _WORD *, _DWORD, int, _BYTE *, _DWORD, _BYTE *))(a2 + 4),
                 256,
                 v14,
                 18,
                 v16);
      if ( result >= 0 ) /*0x6653*/
      {
        result = XhciGetPortInfo(a1, a2); /*0x6659*/
        if ( result >= 0 ) /*0x6660*/
        {
          if ( *(_BYTE *)(a2 + 56) == 2 ) /*0x6666*/
            (*(void (__cdecl **)(int, int, int))(v15 + 4))(a1, v15, 100); /*0x6670*/
          result = XhciStopEndpoint( /*0x667a*/
                     a1,
                     (int (__cdecl **)(int, _DWORD, _WORD *, int, int, _DWORD, _DWORD, _BYTE *))(a2 + 4));
          if ( result >= 0 ) /*0x6681*/
            return 0; /*0x6683*/
        }
      }
    }
  }
  return result; /*0x6686*/
}


// Function: XhciGetPortInfo @ 0x668d (0x113 bytes)
// Index: 63/119

int __fastcall XhciGetPortInfo(int a1, int a2)
{
  unsigned int v4; // ebx
  int result; // eax
  _BYTE **v6; // ebp
  _BYTE *v7; // ecx
  int v8; // edx
  int v9; // ecx
  unsigned int v10; // ebp
  int v11; // eax
  unsigned __int8 *v12; // eax
  unsigned __int8 *v13; // eax
  unsigned __int8 *v14; // ecx
  unsigned __int8 **v15; // edx
  int (__cdecl *v16)(int, _DWORD, _DWORD, int); // [esp+Ch] [ebp-10h]
  char v17; // [esp+10h] [ebp-Ch] BYREF
  int v18; // [esp+11h] [ebp-Bh]
  int v19; // [esp+15h] [ebp-7h]

  v4 = 0; /*0x669b*/
  v17 = 0; /*0x66a4*/
  v18 = 0; /*0x66af*/
  v19 = 0; /*0x66b3*/
  result = XhciShortPacketFix( /*0x66b7*/
             a1,
             (int (__cdecl **)(int, _DWORD, _WORD *, _DWORD, int, _BYTE *, _DWORD, _BYTE *))(a2 + 4),
             512,
             &v17,
             9u,
             &v17);
  if ( result >= 0 ) /*0x66c1*/
  {
    v6 = (_BYTE **)(a2 + 68); /*0x66cf*/
    result = (*(int (__cdecl **)(int, _DWORD, int))(*(_DWORD *)a1 + 76))( /*0x66d5*/
               a1,
               *(unsigned __int16 *)((char *)&v18 + 1),
               a2 + 68);
    if ( result >= 0 ) /*0x66dd*/
    {
      result = XhciShortPacketFix( /*0x66f5*/
                 a1,
                 (int (__cdecl **)(int, _DWORD, _WORD *, _DWORD, int, _BYTE *, _DWORD, _BYTE *))(a2 + 4),
                 512,
                 v7,
                 *(unsigned __int16 *)((char *)&v18 + 1),
                 *v6);
      v8 = result; /*0x66fa*/
      if ( result >= 0 ) /*0x6701*/
      {
        v9 = (int)*v6; /*0x6707*/
        *(_DWORD *)(a2 + 72) = *v6; /*0x670a*/
        v10 = *(unsigned __int16 *)(v9 + 2) + v9 - 1; /*0x6714*/
        v16 = *(int (__cdecl **)(int, _DWORD, _DWORD, int))(*(_DWORD *)(a2 + 64) + 44); /*0x671c*/
        if ( !v16 /*0x6739*/
          || (result = v16(a1, *(_DWORD *)(a2 + 64), *(unsigned __int8 *)(a2 + 52), v9), v8 = result, result >= 0) )
        {
          v11 = *(_DWORD *)(a2 + 72) + **(unsigned __int8 **)(a2 + 72); /*0x6741*/
          for ( *(_DWORD *)(a2 + 76) = v11; *(_DWORD *)(a2 + 76) < v10; *(_DWORD *)(a2 + 76) += *v12 ) /*0x6748*/
          {
            v12 = *(unsigned __int8 **)(a2 + 76); /*0x674a*/
            if ( v12[1] == 4 ) /*0x6751*/
              break; /*0x6751*/
            if ( !*v12 ) /*0x6755*/
              return v8; /*0x679c*/
          }
          v13 = *(unsigned __int8 **)(a2 + 76); /*0x6762*/
          v14 = &v13[*v13]; /*0x6768*/
          if ( v13[4] ) /*0x676a*/
          {
            v15 = (unsigned __int8 **)(a2 + 80); /*0x676f*/
            do /*0x6790*/
            {
              if ( (unsigned int)v14 >= v10 ) /*0x6774*/
                break; /*0x6774*/
              if ( v14[1] == 5 ) /*0x677a*/
              {
                *v15 = v14; /*0x677c*/
                ++v4; /*0x677e*/
                ++v15; /*0x677f*/
              }
              v14 += *v14; /*0x6785*/
            }
            while ( v4 < *(unsigned __int8 *)(*(_DWORD *)(a2 + 76) + 4) ); /*0x6790*/
          }
          return 0; /*0x6792*/
        }
      }
    }
  }
  return result; /*0x6795*/
}


// Function: XhciGetHubDescriptor @ 0x67a0 (0x8f bytes)
// Index: 64/119

__int16 __fastcall XhciGetHubDescriptor(int a1, void (__cdecl **a2)(_DWORD, _DWORD, _DWORD, _DWORD), int a3)
{
  char v4; // bl
  __int16 result; // ax
  int v7; // [esp+Ch] [ebp-8h] BYREF
  _BYTE v8[2]; // [esp+10h] [ebp-4h] BYREF
  __int16 v9; // [esp+12h] [ebp-2h]

  v4 = 0; /*0x67aa*/
  (*(void (__cdecl **)(int, void *, _DWORD, _DWORD, int *))(*(_DWORD *)a1 + 32))(a1, &unk_8930, 0, 0, &v7); /*0x67bc*/
  a2[4](a1, a2, a3, 4); /*0x67c6*/
  while ( 1 ) /*0x67d5*/
  {
    ((void (__cdecl **)(int, _DWORD, int, _BYTE *))a2)[3](a1, a2, a3, v8); /*0x67d5*/
    if ( (v9 & 0x10) != 0 ) /*0x67e1*/
      break; /*0x67e1*/
    (*(void (__cdecl **)(int, int, int))(v7 + 4))(a1, v7, 1000); /*0x67ed*/
    if ( (unsigned __int8)++v4 >= 0x64u ) /*0x67f8*/
    {
      result = v9; /*0x67fa*/
      if ( (v9 & 0x10) == 0 ) /*0x6800*/
        return result; /*0x6800*/
      break; /*0x6800*/
    }
  }
  a2[5](a1, a2, a3, 20); /*0x6802*/
  ((void (__cdecl **)(int, _DWORD, int, _BYTE *))a2)[3](a1, a2, a3, v8); /*0x6815*/
  return (*(__int16 (__cdecl **)(int, int, int))(v7 + 4))(a1, v7, 10000); /*0x6828*/
}


// Function: XhciGetHubCount @ 0x682f (0x4f bytes)
// Index: 65/119

int __fastcall XhciGetHubCount(
        int a1,
        int (__cdecl **a2)(int, _DWORD, int *, _DWORD, int, int, int, _BYTE *),
        unsigned __int8 a3,
        int a4)
{
  int n65185; // [esp+8h] [ebp-Ch] BYREF
  __int16 v8; // [esp+Ch] [ebp-8h]
  __int16 v9; // [esp+Eh] [ebp-6h]
  _BYTE v10[4]; // [esp+10h] [ebp-4h] BYREF

  (*(void (__cdecl **)(int *, int, _DWORD))(*(_DWORD *)a1 + 84))(&n65185, 8, 0); /*0x6845*/
  v8 = a3; /*0x684e*/
  n65185 = 65185; /*0x6856*/
  v9 = 1; /*0x6865*/
  return (*a2)(a1, a2, &n65185, 0, 3000, a4, 1, v10); /*0x6878*/
}


// Function: XhciInitUsb2Port @ 0x687e (0x155 bytes)
// Index: 66/119

int __fastcall XhciInitUsb2Port(int a1, int a2)
{
  int v2; // esi
  int result; // eax
  int v5; // ebx
  unsigned __int8 *v6; // eax
  char v7; // [esp+12h] [ebp-16h]
  unsigned __int8 v8; // [esp+13h] [ebp-15h] BYREF
  int n2; // [esp+14h] [ebp-14h]
  unsigned __int8 *v10; // [esp+18h] [ebp-10h] BYREF
  int v11; // [esp+1Ch] [ebp-Ch] BYREF
  int v12; // [esp+20h] [ebp-8h] BYREF
  int v13; // [esp+24h] [ebp-4h]

  v8 = 0; /*0x6889*/
  v2 = a2; /*0x688e*/
  v13 = a2; /*0x6895*/
  result = (*(int (__cdecl **)(int, int, unsigned __int8 **))(a2 + 8))(a1, a2, &v10); /*0x6899*/
  if ( result >= 0 ) /*0x68a1*/
  {
    if ( v10[5] == 8 && v10[7] == 80 ) /*0x68b9*/
    {
      XhciGetHubCount(a1, (int (__cdecl **)(int, _DWORD, int *, _DWORD, int, int, int, _BYTE *))v2, v10[2], (int)&v8); /*0x68cd*/
      v7 = 0; /*0x68d4*/
LABEL_5:
      result = (*(int (__cdecl **)(int, int, int *))(*(_DWORD *)a1 + 76))(a1, 76, &v11); /*0x68d9*/
      if ( result >= 0 ) /*0x68ec*/
      {
        v5 = v11; /*0x68f5*/
        (*(void (__cdecl **)(int, int, _DWORD))(*(_DWORD *)a1 + 84))(v11, 76, 0); /*0x68fe*/
        *(_DWORD *)v5 = 1414480469; /*0x6901*/
        *(_DWORD *)(v5 + 44) = v2; /*0x690a*/
        v6 = v10; /*0x690d*/
        *(_DWORD *)(v5 + 68) = 0; /*0x6911*/
        *(_DWORD *)(v5 + 48) = v6; /*0x6915*/
        *(_DWORD *)(v5 + 28) = 3; /*0x691c*/
        *(_DWORD *)(v5 + 40) = 512; /*0x6923*/
        *(_BYTE *)(v5 + 72) = v7; /*0x692a*/
        LOBYTE(n2) = 0; /*0x692d*/
        while ( 1 ) /*0x693d*/
        {
          result = (*(int (__cdecl **)(int, int, int, int *))(v2 + 12))(a1, v2, n2, &v12); /*0x693d*/
          if ( result < 0 ) /*0x6945*/
            break; /*0x6945*/
          if ( *(_BYTE *)(v12 + 3) == 2 ) /*0x6953*/
          {
            if ( *(char *)(v12 + 2) >= 0 ) /*0x6959*/
              *(_DWORD *)(v5 + 56) = v12; /*0x6960*/
            else
              *(_DWORD *)(v5 + 52) = v12; /*0x695b*/
          }
          LOBYTE(n2) = n2 + 1; /*0x6969*/
          if ( (unsigned __int8)n2 >= 2u ) /*0x696f*/
          {
            *(_DWORD *)(v5 + 4) = XhciGetInterrupt; /*0x697f*/
            *(_DWORD *)(v5 + 8) = XhciAckInterrupt; /*0x6980*/
            *(_DWORD *)(v5 + 12) = XhciRecoveryPort; /*0x6981*/
            *(_DWORD *)(v5 + 16) = unk_85D4; /*0x698a*/
            *(_DWORD *)(v5 + 20) = &unk_8940; /*0x698b*/
            *(_DWORD *)(v5 + 24) = 0; /*0x698c*/
            *(_DWORD *)(v5 + 24) = v5 + 4; /*0x698d*/
            result = XhciSetDeviceAddress(a1, (_DWORD *)v5); /*0x6990*/
            if ( result >= 0 ) /*0x6997*/
            {
              result = (*(int (__cdecl **)(int, int))(*(_DWORD *)a1 + 24))(a1, v5 + 16); /*0x69a1*/
              if ( result >= 0 ) /*0x69a8*/
              {
                v2 = v13; /*0x69ae*/
                if ( (unsigned __int8)++v7 <= v8 ) /*0x69bc*/
                  goto LABEL_5; /*0x69bc*/
                return 0; /*0x69c2*/
              }
            }
            return result; /*0x69c4*/
          }
        }
      }
    }
    else
    {
      return -2147483634; /*0x69c6*/
    }
  }
  return result; /*0x69cb*/
}


// Function: XhciGetInterrupt @ 0x69d3 (0xd bytes)
// Index: 67/119

// (too small: 0xd bytes)


// Function: XhciAckInterrupt @ 0x69e0 (0x26 bytes)
// Index: 68/119

int __cdecl XhciAckInterrupt(int a1, _DWORD *a2, int a3, _DWORD *a4)
{
  int result; // eax

  result = XhciResetDevice(a1, (int)(a2 - 1)); /*0x69ec*/
  if ( result >= 0 ) /*0x69f3*/
  {
    *a4 = a2[6]; /*0x69ff*/
    a4[1] = a2[7]; /*0x6a00*/
    a4[2] = a2[8]; /*0x6a01*/
    a4[3] = a2[9]; /*0x6a02*/
    return 0; /*0x69fd*/
  }
  return result; /*0x6a04*/
}


// Function: XhciResetDevice @ 0x6a06 (0x122 bytes)
// Index: 69/119

int __fastcall XhciResetDevice(int a1, int a2)
{
  int v2; // ebp
  int v5; // edi
  int result; // eax
  char n2; // al
  char n40; // cl
  int v9; // eax
  int v10; // ecx
  char v11; // al
  char v12; // [esp+12h] [ebp-Ah]
  unsigned __int8 n3; // [esp+13h] [ebp-9h]
  int v14; // [esp+14h] [ebp-8h] BYREF
  int v15; // [esp+18h] [ebp-4h] BYREF

  v2 = v15; /*0x6a0b*/
  v12 = 0; /*0x6a15*/
  n3 = 0; /*0x6a1a*/
  while ( 1 ) /*0x6a28*/
  {
    v5 = XhciClearEndpointHalt(a1, a2); /*0x6a28*/
    if ( v5 >= 0 ) /*0x6a2c*/
      return v5; /*0x6b16*/
    if ( !n3 ) /*0x6a37*/
    {
      if ( !*(_DWORD *)(a2 + 64) ) /*0x6a39*/
      {
        result = (*(int (__cdecl **)(int, int, int *))(*(_DWORD *)a1 + 76))(a1, 18, &v14); /*0x6a49*/
        if ( result < 0 ) /*0x6a51*/
          return result; /*0x6a51*/
        *(_DWORD *)(a2 + 64) = v14; /*0x6a5b*/
      }
      v2 = *(_DWORD *)(a2 + 64); /*0x6a60*/
      (*(void (__cdecl **)(int, int, _DWORD))(*(_DWORD *)a1 + 84))(v2, 18, 0); /*0x6a68*/
      (*(void (__cdecl **)(int, void *, _DWORD, _DWORD, int *))(*(_DWORD *)a1 + 32))(a1, &unk_8930, 0, 0, &v15); /*0x6a7c*/
    }
    XhciClearDeviceFeature(a1, (_DWORD *)a2, v2); /*0x6a87*/
    n2 = *(_BYTE *)(v2 + 2) & 0xF; /*0x6a8f*/
    n40 = *(_BYTE *)(v2 + 12); /*0x6a92*/
    if ( n2 == 2 ) /*0x6a97*/
      break; /*0x6a97*/
    if ( n2 != 6 || n40 != 40 ) /*0x6ada*/
    {
LABEL_18:
      v11 = v12; /*0x6adc*/
      goto LABEL_19; /*0x6adc*/
    }
LABEL_15:
    v11 = 1; /*0x6acb*/
    v12 = 1; /*0x6acd*/
LABEL_19:
    *(_DWORD *)(a2 + 40) = 0; /*0x6ae0*/
    v10 = -2147483641; /*0x6ae4*/
    *(_BYTE *)(a2 + 32) = 0; /*0x6ae9*/
    v5 = -2147483641; /*0x6aed*/
    if ( !v11 ) /*0x6af1*/
      return v10; /*0x6af1*/
    (*(void (__cdecl **)(int, int, int))(v15 + 4))(a1, v15, 100000); /*0x6afe*/
    if ( ++n3 >= 0x19u ) /*0x6b10*/
      return v5; /*0x6b10*/
  }
  if ( n40 == 4 || n40 == 6 || n40 == 8 ) /*0x6aab*/
    goto LABEL_15; /*0x6aab*/
  if ( n40 != 58 ) /*0x6ab0*/
    goto LABEL_18; /*0x6ab0*/
  if ( n3 < 3u ) /*0x6ab7*/
    goto LABEL_15; /*0x6ab7*/
  v9 = XhciWaitForPortReset(a1, (_DWORD *)a2); /*0x6abd*/
  v10 = -2147483636; /*0x6ac2*/
  if ( v9 != -2147483636 ) /*0x6ac9*/
    goto LABEL_15; /*0x6ac9*/
  *(_BYTE *)(a2 + 32) = 0; /*0x6b20*/
  return v10; /*0x6b18*/
}


// Function: XhciRecoveryPort @ 0x6b28 (0x142 bytes)
// Index: 70/119

int __cdecl XhciRecoveryPort(int a1, int a2, int a3, unsigned int a4, int a5, unsigned int a6, int a7)
{
  int v7; // esi
  int result; // eax
  int v9; // ecx
  unsigned int v10; // eax
  int v11; // ebp
  unsigned __int8 n3; // bl
  bool v13; // zf
  int v14; // [esp+4h] [ebp-8h] BYREF
  unsigned int v15; // [esp+8h] [ebp-4h]

  v7 = a2 - 4; /*0x6b2f*/
  if ( !a7 ) /*0x6b37*/
    return -2147483646; /*0x6b37*/
  result = a6; /*0x6b43*/
  if ( a6 ) /*0x6b49*/
  {
    if ( *(_BYTE *)(a2 + 28) ) /*0x6b4f*/
    {
      if ( a5 ) /*0x6b66*/
        return -2147483646; /*0x6b66*/
      v9 = a4; /*0x6b68*/
      if ( a4 > *(_DWORD *)(a2 + 32) ) /*0x6b6f*/
        return -2147483646; /*0x6b3e*/
      v10 = a6 / *(_DWORD *)(a2 + 36); /*0x6b79*/
      v11 = a7; /*0x6b7e*/
      n3 = 0; /*0x6b82*/
      v15 = v10; /*0x6b89*/
      while ( XhciGetMaxLun(a1, (_DWORD *)v7, a7, v9, a5, v10) < 0 ) /*0x6ba5*/
      {
        if ( !n3 ) /*0x6bad*/
        {
          if ( !*(_DWORD *)(v7 + 64) ) /*0x6baf*/
          {
            result = (*(int (__cdecl **)(int, int, int *))(*(_DWORD *)a1 + 76))(a1, 18, &a2); /*0x6bbf*/
            if ( result < 0 ) /*0x6bc7*/
              return result; /*0x6bc7*/
            *(_DWORD *)(v7 + 64) = a2; /*0x6bd1*/
          }
          v11 = *(_DWORD *)(v7 + 64); /*0x6bd6*/
          (*(void (__cdecl **)(int, int, _DWORD))(*(_DWORD *)a1 + 84))(v11, 18, 0); /*0x6bde*/
          (*(void (__cdecl **)(int, void *, _DWORD, _DWORD, int *))(*(_DWORD *)a1 + 32))(a1, &unk_8930, 0, 0, &v14); /*0x6bf2*/
        }
        if ( XhciClearDeviceFeature(a1, (_DWORD *)v7, v11) < 0 ) /*0x6c05*/
          return -2147483641; /*0x6c05*/
        if ( (*(_BYTE *)(v11 + 2) & 0xF) == 2 && *(_BYTE *)(v11 + 12) == 58 ) /*0x6c14*/
        {
          result = XhciWaitForPortReset(a1, (_DWORD *)v7); /*0x6c1a*/
          if ( result < 0 ) /*0x6c21*/
          {
            if ( result == -2147483636 ) /*0x6c4d*/
              *(_BYTE *)(v7 + 32) = 0; /*0x6c4f*/
            return result; /*0x6c53*/
          }
        }
        (*(void (__cdecl **)(int, int, int))(v14 + 4))(a1, v14, 9000); /*0x6c2e*/
        v13 = ++n3 == 3; /*0x6c36*/
        if ( n3 >= 3u ) /*0x6c39*/
          goto LABEL_24; /*0x6c39*/
        v9 = a4; /*0x6c3b*/
        v10 = v15; /*0x6c3f*/
      }
      v13 = n3 == 3; /*0x6c55*/
LABEL_24:
      if ( v13 ) /*0x6c58*/
        return -2147483641; /*0x6c5f*/
      return 0; /*0x6c61*/
    }
    else
    {
      return -2147483636; /*0x6b55*/
    }
  }
  return result; /*0x6c66*/
}


// Function: XhciWaitForPortReset @ 0x6c6a (0xe8 bytes)
// Index: 71/119

int __fastcall XhciWaitForPortReset(int a1, _DWORD *a2)
{
  int result; // eax
  int v5; // ebp
  int v6; // ecx
  int v7; // edi
  char v8; // [esp+Bh] [ebp-15h]
  int v9; // [esp+Ch] [ebp-14h] BYREF
  int v10; // [esp+10h] [ebp-10h] BYREF
  int n36[3]; // [esp+14h] [ebp-Ch] BYREF

  if ( !a2[16] ) /*0x6c73*/
  {
    result = (*(int (__cdecl **)(int, int, int *))(*(_DWORD *)a1 + 76))(a1, 18, &v9); /*0x6c83*/
    if ( result < 0 ) /*0x6c8b*/
      return result; /*0x6c8b*/
    a2[16] = v9; /*0x6c95*/
  }
  v5 = a2[16]; /*0x6c9b*/
  (*(void (__cdecl **)(int, int, _DWORD))(*(_DWORD *)a1 + 84))(v5, 18, 0); /*0x6ca3*/
  (*(void (__cdecl **)(int, void *, _DWORD, _DWORD, int *))(*(_DWORD *)a1 + 32))(a1, &unk_8930, 0, 0, &v10); /*0x6cb7*/
  v8 = 0; /*0x6cbd*/
  while ( 1 ) /*0x6cc3*/
  {
    (*(void (__cdecl **)(int *, int, _DWORD))(*(_DWORD *)a1 + 84))(n36, 12, 0); /*0x6cce*/
    LOBYTE(n36[0]) = 0; /*0x6cd6*/
    XhciGetEndpointDescriptor(a1, a2, n36, v6, 0, 0, 2u, 0x1388u); /*0x6ced*/
    if ( XhciClearDeviceFeature(a1, a2, v5) < 0 ) /*0x6d01*/
      break; /*0x6d01*/
    v7 = -2147483641; /*0x6d06*/
    if ( (*(_BYTE *)(v5 + 2) & 0xF) == 0 ) /*0x6d10*/
      return 0; /*0x6d43*/
    if ( (*(_BYTE *)(v5 + 2) & 0xF) == 2 && *(_BYTE *)(v5 + 12) == 58 ) /*0x6d19*/
    {
      v7 = -2147483636; /*0x6d1f*/
      (*(void (__cdecl **)(int, int, int))(v10 + 4))(a1, v10, 20000); /*0x6d29*/
    }
    if ( (unsigned __int8)++v8 >= 3u ) /*0x6d3b*/
      return v7; /*0x6d3b*/
  }
  return -2147483641; /*0x6d4c*/
}


// Function: XhciIsPortReset @ 0x6d52 (0x55 bytes)
// Index: 72/119

int __fastcall XhciIsPortReset(int a1, int a2, char a3, unsigned __int8 *a4)
{
  unsigned __int8 n0x10; // bl
  int result; // eax
  int v8; // [esp+Ch] [ebp-8h] BYREF
  int v9; // [esp+10h] [ebp-4h]

  n0x10 = 0; /*0x6d5b*/
  LOBYTE(v9) = 0; /*0x6d61*/
  while ( 1 ) /*0x6d6f*/
  {
    result = XhciGetFrameNumber(a1, a2, v9, &v8); /*0x6d6f*/
    if ( result < 0 ) /*0x6d79*/
      break; /*0x6d79*/
    if ( *(_BYTE *)(v8 + 2) != a3 ) /*0x6d81*/
    {
      LOBYTE(v9) = ++n0x10; /*0x6d85*/
      if ( n0x10 < 0x10u ) /*0x6d8b*/
        continue; /*0x6d8b*/
    }
    if ( n0x10 == 16 ) /*0x6d90*/
      return -2147483646; /*0x6d92*/
    *a4 = n0x10; /*0x6d9c*/
    return 0; /*0x6d97*/
  }
  return result; /*0x6da0*/
}


// Function: XhciCheckStall @ 0x6da7 (0x3e bytes)
// Index: 73/119

int __cdecl XhciCheckStall(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
{
  return (**(int (__cdecl ***)(int, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, int, int, int, int *, int, int))(a2 + 60))( /*0x6de3*/
           a1,
           *(_DWORD *)(a2 + 60),
           *(unsigned __int8 *)(a2 + 48),
           *(unsigned __int8 *)(a2 + 52),
           *(unsigned __int8 *)(a2 + 50),
           *(unsigned __int16 *)(a2 + 140),
           a3,
           a4,
           a6,
           &a7,
           a5,
           a8);
}


// Function: XhciClearStall @ 0x6de5 (0x90 bytes)
// Index: 74/119

int __cdecl XhciClearStall(int a1, int a2, int a3, int a4, int a5, int a6, int a7)
{
  int v7; // esi
  int v8; // ebp
  int result; // eax
  unsigned __int8 v10; // di
  int v11; // edx
  int v12; // eax
  char v13; // bl
  unsigned __int8 v14; // [esp+Bh] [ebp-1h] BYREF

  v7 = a2; /*0x6df0*/
  v8 = *(_DWORD *)(a2 + 60); /*0x6dfb*/
  result = XhciIsPortReset(a1, a2, a3, &v14); /*0x6dfe*/
  if ( result >= 0 ) /*0x6e07*/
  {
    v10 = v14; /*0x6e0b*/
    v11 = *(unsigned __int16 *)(*(_DWORD *)(v7 + 4 * v14 + 76) + 4); /*0x6e1e*/
    v12 = *(unsigned __int16 *)(v7 + 140); /*0x6e32*/
    LOBYTE(a2) = ((unsigned __int8)(1 << v14) & *(_BYTE *)(v7 + 53)) != 0; /*0x6e40*/
    v13 = a2; /*0x6e39*/
    result = (*(int (__cdecl **)(int, int, _DWORD, int, _DWORD, int, int, int, int, int *, int, int))(v8 + 4))( /*0x6e59*/
               a1,
               v8,
               *(unsigned __int8 *)(v7 + 48),
               a3,
               *(unsigned __int8 *)(v7 + 52),
               v11,
               v12,
               a4,
               a5,
               &a2,
               a6,
               a7);
    if ( v13 != (_BYTE)a2 ) /*0x6e63*/
      *(_BYTE *)(v7 + 53) ^= 1 << v10; /*0x6e6c*/
  }
  return result; /*0x6e71*/
}


// Function: XhciGetTransferStatus @ 0x6e75 (0x93 bytes)
// Index: 75/119

int __cdecl XhciGetTransferStatus(int a1, int a2, int a3, int a4, int a5, int a6)
{
  int v6; // esi
  int v7; // ebp
  int result; // eax
  unsigned __int8 v9; // di
  int v10; // edx
  char v11; // bl
  int v12; // eax
  unsigned __int8 v13; // [esp+Bh] [ebp-5h] BYREF
  _BYTE v14[4]; // [esp+Ch] [ebp-4h] BYREF

  v6 = a2; /*0x6e81*/
  v7 = *(_DWORD *)(a2 + 60); /*0x6e8c*/
  result = XhciIsPortReset(a1, a2, a3, &v13); /*0x6e8f*/
  if ( result >= 0 ) /*0x6e98*/
  {
    v9 = v13; /*0x6e9c*/
    v10 = *(unsigned __int16 *)(*(_DWORD *)(v6 + 4 * v13 + 76) + 4); /*0x6ea7*/
    v12 = *(unsigned __int16 *)(v6 + 140); /*0x6ec7*/
    LOBYTE(a2) = ((unsigned __int8)(1 << v13) & *(_BYTE *)(v6 + 53)) != 0; /*0x6ed2*/
    v11 = a2; /*0x6ebf*/
    result = (*(int (__cdecl **)(int, int, _DWORD, int, _DWORD, int, int, int, int, int *, int, _BYTE *))(v7 + 28))( /*0x6eeb*/
               a1,
               v7,
               *(unsigned __int8 *)(v6 + 48),
               a3,
               *(unsigned __int8 *)(v6 + 52),
               v10,
               v12,
               a4,
               a5,
               &a2,
               a6,
               v14);
    if ( v11 != (_BYTE)a2 ) /*0x6ef5*/
      *(_BYTE *)(v6 + 53) ^= 1 << v9; /*0x6efe*/
  }
  return result; /*0x6f03*/
}


// Function: XhciIsTransferDone @ 0x6f08 (0x10 bytes)
// Index: 76/119

int __cdecl XhciIsTransferDone(int a1, int a2, _DWORD *a3)
{
  *a3 = *(_DWORD *)(a2 + 72); /*0x6f13*/
  return 0; /*0x6f17*/
}


// Function: XhciGetFrameNumber @ 0x6f18 (0x26 bytes)
// Index: 77/119

int __cdecl XhciGetFrameNumber(int a1, int a2, unsigned __int8 a3, _DWORD *a4)
{
  if ( a3 >= *(_BYTE *)(*(_DWORD *)(a2 + 72) + 4) ) /*0x6f26*/
    return -2147483646; /*0x6f28*/
  *a4 = *(_DWORD *)(a2 + 4 * a3 + 76); /*0x6f39*/
  return 0; /*0x6f2d*/
}


// Function: XhciGetMicroframeNumber @ 0x6f3e (0x46 bytes)
// Index: 78/119

int __cdecl XhciGetMicroframeNumber(int a1, int a2)
{
  unsigned __int8 v2; // bl
  int result; // eax

  XhciGetHubDescriptor( /*0x6f50*/
    a1,
    *(void (__cdecl ***)(_DWORD, _DWORD, _DWORD, _DWORD))(a2 + 60),
    *(unsigned __int8 *)(a2 + 48));
  v2 = *(_BYTE *)(a2 + 48); /*0x6f55*/
  *(_BYTE *)(a2 + 48) = 0; /*0x6f62*/
  result = XhciRecoveryPacket(a1, (int (__cdecl **)(int, _DWORD, _WORD *, int, int, _DWORD, _DWORD, _BYTE *))a2, v2); /*0x6f66*/
  if ( result >= 0 ) /*0x6f6f*/
  {
    *(_BYTE *)(a2 + 48) = v2; /*0x6f77*/
    return XhciStopEndpoint(a1, (int (__cdecl **)(int, _DWORD, _WORD *, int, int, _DWORD, _DWORD, _BYTE *))a2); /*0x6f7c*/
  }
  return result; /*0x6f7a*/
}


// Function: XhciShortPacketFix @ 0x6f84 (0x50 bytes)
// Index: 79/119

int __fastcall XhciShortPacketFix(
        int a1,
        int (__cdecl **a2)(int, _DWORD, _WORD *, _DWORD, int, _BYTE *, _DWORD, _BYTE *),
        __int16 n256,
        _BYTE *a4,
        __int16 n8,
        _BYTE *a6)
{
  _WORD v7[4]; // [esp+0h] [ebp-Ch] BYREF
  _BYTE v8[4]; // [esp+8h] [ebp-4h] BYREF

  if ( !a2 ) /*0x6f8c*/
    return -2147483646; /*0x6f8e*/
  v7[1] = n256; /*0x6f9a*/
  v7[0] = 1664; /*0x6fa3*/
  v7[2] = 0; /*0x6fa9*/
  v7[3] = n8; /*0x6fb2*/
  return (*a2)(a1, a2, v7, 0, 3000, a6, (unsigned __int16)n8, v8); /*0x6fd0*/
}


// Function: XhciRecoveryPacket @ 0x6fd4 (0x42 bytes)
// Index: 80/119

int __fastcall XhciRecoveryPacket(
        int a1,
        int (__cdecl **a2)(int, _DWORD, _WORD *, int, int, _DWORD, _DWORD, _BYTE *),
        __int16 a3)
{
  _WORD v4[2]; // [esp+0h] [ebp-Ch] BYREF
  int v5; // [esp+4h] [ebp-8h]
  _BYTE v6[4]; // [esp+8h] [ebp-4h] BYREF

  if ( !a2 ) /*0x6fdc*/
    return -2147483646; /*0x6fde*/
  v4[1] = a3; /*0x6fe9*/
  v5 = 0; /*0x6fef*/
  v4[0] = 1280; /*0x7004*/
  return (*a2)(a1, a2, v4, 2, 3000, 0, 0, v6); /*0x7012*/
}


// Function: XhciStopEndpoint @ 0x7016 (0x4c bytes)
// Index: 81/119

int __fastcall XhciStopEndpoint(int a1, int (__cdecl **a2)(int, _DWORD, _WORD *, int, int, _DWORD, _DWORD, _BYTE *))
{
  _WORD v5[2]; // [esp+Ch] [ebp-Ch] BYREF
  int v6; // [esp+10h] [ebp-8h]
  _BYTE v7[4]; // [esp+14h] [ebp-4h] BYREF

  (*(void (__cdecl **)(_WORD *, int, _DWORD))(*(_DWORD *)a1 + 84))(v5, 8, 0); /*0x702e*/
  v5[0] = 2304; /*0x7033*/
  v5[1] = 1; /*0x703a*/
  v6 = 0; /*0x7040*/
  return (*a2)(a1, a2, v5, 2, 3000, 0, 0, v7); /*0x705b*/
}


// Function: XhciSetupPacket @ 0x7062 (0x98 bytes)
// Index: 82/119

int __fastcall XhciSetupPacket(int a1, int a2, unsigned __int8 n2)
{
  unsigned __int8 n0x10; // bl
  int result; // eax
  int v7; // edx
  _BYTE v8[2]; // [esp+Ch] [ebp-14h] BYREF
  __int16 v9; // [esp+Eh] [ebp-12h]
  __int16 n2_1; // [esp+10h] [ebp-10h]
  __int16 v11; // [esp+12h] [ebp-Eh]
  _BYTE v12[4]; // [esp+14h] [ebp-Ch] BYREF
  int v13; // [esp+18h] [ebp-8h] BYREF
  int v14; // [esp+1Ch] [ebp-4h]

  n0x10 = 0; /*0x706a*/
  LOBYTE(v14) = 0; /*0x7071*/
  do /*0x709a*/
  {
    if ( (*(int (__cdecl **)(int, int, int, int *))(a2 + 12))(a1, a2, v14, &v13) < 0 ) /*0x7085*/
      return -2147483646; /*0x7085*/
    if ( *(_BYTE *)(v13 + 2) == n2 ) /*0x7090*/
      break; /*0x7090*/
    LOBYTE(v14) = ++n0x10; /*0x7094*/
  }
  while ( n0x10 < 0x10u ); /*0x709a*/
  if ( n0x10 == 16 ) /*0x709f*/
    return -2147483646; /*0x70ee*/
  v8[0] = 2; /*0x70a3*/
  v9 = 0; /*0x70a7*/
  n2_1 = n2; /*0x70b1*/
  v11 = 0; /*0x70b7*/
  v8[1] = 1; /*0x70cd*/
  result = (*(int (__cdecl **)(int, int, _BYTE *, int, int, _DWORD, _DWORD, _BYTE *))a2)(a1, a2, v8, 2, 3000, 0, 0, v12); /*0x70d3*/
  v7 = *(unsigned __int8 *)(a2 + 53); /*0x70dc*/
  if ( ((1 << v14) & v7) != 0 ) /*0x70e4*/
    *(_BYTE *)(a2 + 53) = v7 ^ (1 << v14); /*0x70e9*/
  return result; /*0x70f3*/
}


// Function: XhciReadPortStatus @ 0x70fa (0x9d bytes)
// Index: 83/119

int __fastcall XhciReadPortStatus(int a1, int a2, unsigned __int8 a3, _DWORD *a4)
{
  int result; // eax
  char n4_1; // cl
  _DWORD *v8; // ecx
  unsigned __int8 n10; // bl
  int v10; // edi
  int n10_1; // esi
  int v12; // [esp+10h] [ebp-10h] BYREF
  _BYTE v13[4]; // [esp+14h] [ebp-Ch] BYREF
  int n163; // [esp+18h] [ebp-8h] BYREF
  __int16 v15; // [esp+1Ch] [ebp-4h]
  __int16 n4; // [esp+1Eh] [ebp-2h]

  v12 = 0; /*0x710a*/
  (*(void (__cdecl **)(int *, int, _DWORD))(*(_DWORD *)a1 + 84))(&n163, 8, 0); /*0x7115*/
  v15 = a3; /*0x7120*/
  n163 = 163; /*0x712f*/
  n4 = 4; /*0x7142*/
  result = (*(int (__cdecl **)(int, int, int *, _DWORD, int, int *, int, _BYTE *))a2)( /*0x714a*/
             a1,
             a2,
             &n163,
             0,
             3000,
             &v12,
             4,
             v13);
  n4_1 = *(_BYTE *)(a2 + 52); /*0x714c*/
  if ( n4_1 == 4 || n4_1 == 5 ) /*0x715c*/
  {
    v8 = &unk_8A10; /*0x7167*/
    n10 = 10; /*0x716c*/
  }
  else
  {
    v8 = &unk_8A60; /*0x715e*/
    n10 = 13; /*0x7163*/
  }
  v10 = v12; /*0x7172*/
  n10_1 = n10; /*0x7176*/
  *a4 = 0; /*0x7179*/
  do /*0x718b*/
  {
    if ( (v10 & *v8) != 0 ) /*0x717e*/
      *a4 |= v8[1]; /*0x7183*/
    v8 += 2; /*0x7185*/
    --n10_1; /*0x7188*/
  }
  while ( n10_1 ); /*0x718b*/
  return result; /*0x718d*/
}


// Function: XhciReadPortUsb20 @ 0x7197 (0x55 bytes)
// Index: 84/119

int __fastcall XhciReadPortUsb20(
        int a1,
        int (__cdecl **a2)(int, _DWORD, _WORD *, int, int, _DWORD, _DWORD, _BYTE *),
        unsigned __int8 a3,
        unsigned __int8 n8)
{
  _WORD v7[4]; // [esp+8h] [ebp-Ch] BYREF
  _BYTE v8[4]; // [esp+10h] [ebp-4h] BYREF

  (*(void (__cdecl **)(_WORD *, int, _DWORD))(*(_DWORD *)a1 + 84))(v7, 8, 0); /*0x71ad*/
  v7[1] = n8; /*0x71b4*/
  v7[2] = a3; /*0x71bc*/
  v7[3] = 0; /*0x71c2*/
  v7[0] = 803; /*0x71d8*/
  return (*a2)(a1, a2, v7, 2, 3000, 0, 0, v8); /*0x71e6*/
}


// Function: XhciWritePortStatus @ 0x71ec (0x55 bytes)
// Index: 85/119

int __fastcall XhciWritePortStatus(
        int a1,
        int (__cdecl **a2)(int, _DWORD, _WORD *, int, int, _DWORD, _DWORD, _BYTE *),
        char a3,
        char n16)
{
  _WORD v7[4]; // [esp+8h] [ebp-Ch] BYREF
  _BYTE v8[4]; // [esp+10h] [ebp-4h] BYREF

  (*(void (__cdecl **)(_WORD *, int, _DWORD))(*(_DWORD *)a1 + 84))(v7, 8, 0); /*0x7202*/
  v7[1] = (unsigned __int8)n16; /*0x7209*/
  v7[2] = (unsigned __int8)a3; /*0x7211*/
  v7[3] = 0; /*0x7217*/
  v7[0] = 291; /*0x722d*/
  return (*a2)(a1, a2, v7, 2, 3000, 0, 0, v8); /*0x723b*/
}


// Function: XhciSetPortFeature @ 0x7241 (0x4d bytes)
// Index: 86/119

int __fastcall XhciSetPortFeature(
        int a1,
        int (__cdecl **a2)(int, _DWORD, int *, _DWORD, int, int, int, _BYTE *),
        int a3)
{
  int n160; // [esp+8h] [ebp-Ch] BYREF
  __int16 v7; // [esp+Ch] [ebp-8h]
  __int16 n4; // [esp+Eh] [ebp-6h]
  _BYTE v9[4]; // [esp+10h] [ebp-4h] BYREF

  (*(void (__cdecl **)(int *, int, _DWORD))(*(_DWORD *)a1 + 84))(&n160, 8, 0); /*0x7257*/
  n160 = 160; /*0x725f*/
  v7 = 0; /*0x7266*/
  n4 = 4; /*0x7275*/
  return (*a2)(a1, a2, &n160, 0, 3000, a3, 4, v9); /*0x7288*/
}


// Function: XhciClearPortFeature @ 0x728e (0x4c bytes)
// Index: 87/119

int __fastcall XhciClearPortFeature(
        int a1,
        int (__cdecl **a2)(int, _DWORD, _WORD *, int, int, _DWORD, _DWORD, _BYTE *),
        unsigned __int8 a3)
{
  _WORD v6[2]; // [esp+8h] [ebp-Ch] BYREF
  int v7; // [esp+Ch] [ebp-8h]
  _BYTE v8[4]; // [esp+10h] [ebp-4h] BYREF

  (*(void (__cdecl **)(_WORD *, int, _DWORD))(*(_DWORD *)a1 + 84))(v6, 8, 0); /*0x72a4*/
  v6[1] = a3; /*0x72ab*/
  v7 = 0; /*0x72b1*/
  v6[0] = 288; /*0x72c6*/
  return (*a2)(a1, a2, v6, 2, 3000, 0, 0, v8); /*0x72d4*/
}


// Function: XhciGetPortState @ 0x72da (0x68 bytes)
// Index: 88/119

int __fastcall XhciGetPortState(int a1, int a2, int a3, int a4)
{
  char n4; // al
  bool v7; // zf
  __int16 n10752; // ax
  _WORD v10[4]; // [esp+8h] [ebp-Ch] BYREF
  _BYTE v11[4]; // [esp+10h] [ebp-4h] BYREF

  (*(void (__cdecl **)(_WORD *, int, _DWORD))(*(_DWORD *)a1 + 84))(v10, 8, 0); /*0x72f0*/
  n4 = *(_BYTE *)(a2 + 52); /*0x72f3*/
  v10[0] = 1696; /*0x72f9*/
  if ( n4 == 4 || (v7 = n4 == 5, n10752 = 10496, v7) ) /*0x730a*/
    n10752 = 10752; /*0x730c*/
  v10[1] = n10752; /*0x7314*/
  v10[2] = 0; /*0x731a*/
  v10[3] = 12; /*0x7329*/
  return (*(int (__cdecl **)(int, int, _WORD *, _DWORD, int, int, int, _BYTE *))a2)(a1, a2, v10, 0, 3000, a4, 12, v11); /*0x733c*/
}


// Function: XhciControlTransferLow @ 0x7342 (0x185 bytes)
// Index: 89/119

int __fastcall XhciControlTransferLow(int a1, int a2)
{
  int v4; // ecx
  __int16 v5; // bp
  char n4; // al
  unsigned int v8; // ecx
  unsigned int v9; // eax
  unsigned int v10; // ecx
  unsigned int v11; // eax
  char v12; // al
  _BYTE v13[2]; // [esp+10h] [ebp-20h] BYREF
  __int16 v14; // [esp+12h] [ebp-1Eh]
  unsigned int v15; // [esp+14h] [ebp-1Ch] BYREF
  int v16; // [esp+18h] [ebp-18h] BYREF
  _DWORD v17[2]; // [esp+1Ch] [ebp-14h] BYREF
  _BYTE v18[12]; // [esp+24h] [ebp-Ch] BYREF

  (*(void (__cdecl **)(int, void *, _DWORD, _DWORD, int *))(*(_DWORD *)a1 + 32))(a1, &unk_8930, 0, 0, &v16); /*0x735e*/
  (*(void (__cdecl **)(_BYTE *, int, _DWORD))(*(_DWORD *)a1 + 84))(v18, 12, 0); /*0x736b*/
  v5 = *(unsigned __int8 *)(a2 + 150); /*0x7378*/
  n4 = *(_BYTE *)(a2 + 56); /*0x737d*/
  if ( n4 == 4 || n4 == 5 ) /*0x7386*/
  {
    (*(void (__cdecl **)(_DWORD *, int, _DWORD))(*(_DWORD *)a1 + 84))(v17, 8, 0); /*0x7393*/
    LOWORD(v17[0]) = 3104; /*0x7398*/
    v17[1] = 0; /*0x739f*/
    HIWORD(v17[0]) = v5; /*0x73b7*/
    if ( (*(int (__cdecl **)(int, int, _DWORD *, int, int, _DWORD, _DWORD, unsigned int *))(a2 + 4))( /*0x73c6*/
           a1,
           a2 + 4,
           v17,
           2,
           3000,
           0,
           0,
           &v15) < 0 )
      return -2147483641; /*0x73c6*/
  }
  if ( XhciGetPortState(a1, a2 + 4, v4, (int)v18) < 0 ) /*0x73e5*/
    return -2147483641; /*0x73e5*/
  *(_BYTE *)(a2 + 59) = v18[2]; /*0x73ed*/
  if ( XhciSetPortFeature(a1, (int (__cdecl **)(int, _DWORD, int *, _DWORD, int, int, int, _BYTE *))(a2 + 4), (int)v13) < 0 ) /*0x73ff*/
    return -2147483641; /*0x73ff*/
  LOBYTE(v8) = 0; /*0x7401*/
  v15 = 0; /*0x7403*/
  if ( *(_BYTE *)(a2 + 59) ) /*0x7407*/
  {
    do /*0x7432*/
    {
      XhciReadPortStatus(a1, a2 + 4, v8 + 1, v17); /*0x741c*/
      v9 = *(unsigned __int8 *)(a2 + 59); /*0x7421*/
      v8 = v15 + 1; /*0x742b*/
      v15 = v8; /*0x742c*/
    }
    while ( v8 < v9 ); /*0x7432*/
  }
  LOBYTE(v10) = 0; /*0x7434*/
  v15 = 0; /*0x7436*/
  if ( *(_BYTE *)(a2 + 59) ) /*0x743a*/
  {
    do /*0x7462*/
    {
      XhciReadPortUsb20( /*0x744c*/
        a1,
        (int (__cdecl **)(int, _DWORD, _WORD *, int, int, _DWORD, _DWORD, _BYTE *))(a2 + 4),
        v10 + 1,
        8u);
      v11 = *(unsigned __int8 *)(a2 + 59); /*0x7451*/
      v10 = v15 + 1; /*0x745b*/
      v15 = v10; /*0x745c*/
    }
    while ( v10 < v11 ); /*0x7462*/
  }
  if ( XhciSetPortFeature(a1, (int (__cdecl **)(int, _DWORD, int *, _DWORD, int, int, int, _BYTE *))(a2 + 4), (int)v13) < 0 ) /*0x7475*/
    return -2147483641; /*0x73c8*/
  v12 = v14; /*0x747b*/
  if ( (v14 & 1) != 0 ) /*0x7482*/
  {
    XhciClearPortFeature(a1, (int (__cdecl **)(int, _DWORD, _WORD *, int, int, _DWORD, _DWORD, _BYTE *))(a2 + 4), 0); /*0x748a*/
    v12 = v14; /*0x748f*/
  }
  if ( (v12 & 2) != 0 ) /*0x7497*/
    XhciClearPortFeature(a1, (int (__cdecl **)(int, _DWORD, _WORD *, int, int, _DWORD, _DWORD, _BYTE *))(a2 + 4), 1u); /*0x749f*/
  (*(void (__cdecl **)(int, int, int))(v16 + 4))(a1, v16, 2000 * v18[5]); /*0x74b7*/
  return 0; /*0x74bf*/
}


// Function: XhciResetPort @ 0x74c7 (0x83 bytes)
// Index: 90/119

int __fastcall XhciResetPort(
        int a1,
        int (__cdecl **a2)(int, _DWORD, _WORD *, int, int, _DWORD, _DWORD, _BYTE *),
        unsigned __int8 a3)
{
  char n20; // bl
  int v7; // [esp+Ch] [ebp-8h] BYREF
  int v8; // [esp+10h] [ebp-4h] BYREF

  (*(void (__cdecl **)(int, void *, _DWORD, _DWORD, int *))(*(_DWORD *)a1 + 32))(a1, &unk_8930, 0, 0, &v8); /*0x74e3*/
  XhciReadPortUsb20(a1, a2, a3, 4u); /*0x74ef*/
  n20 = 20; /*0x74f7*/
  do /*0x7523*/
  {
    XhciReadPortStatus(a1, (int)a2, a3, &v7); /*0x7504*/
    (*(void (__cdecl **)(int, int, int))(v8 + 4))(a1, v8, 1000); /*0x7513*/
    --n20; /*0x7519*/
  }
  while ( (v7 & 0x100000) == 0 && n20 ); /*0x7523*/
  (*(void (__cdecl **)(int, int, int))(v8 + 4))(a1, v8, 10000); /*0x752f*/
  return XhciWritePortStatus(a1, a2, a3, 20); /*0x7543*/
}


// Function: XhciSetDeviceAddress @ 0x754a (0x8d bytes)
// Index: 91/119

int __fastcall XhciSetDeviceAddress(int a1, _DWORD *a2)
{
  int v4; // ecx
  int v6[9]; // [esp+Ch] [ebp-30h] BYREF
  int n36; // [esp+30h] [ebp-Ch] BYREF
  char n36_1; // [esp+34h] [ebp-8h]

  (*(void (__cdecl **)(int *, int, _DWORD))(*(_DWORD *)a1 + 84))(&n36, 12, 0); /*0x7562*/
  (*(void (__cdecl **)(int *, int, _DWORD))(*(_DWORD *)a1 + 84))(v6, 36, 0); /*0x756e*/
  LOBYTE(n36) = 18; /*0x7574*/
  BYTE2(n36) = 0; /*0x757b*/
  n36_1 = 36; /*0x7580*/
  if ( XhciGetEndpointDescriptor(a1, a2, &n36, v4, (int)v6, &n36_, 0, 0x1388u) < 0 ) /*0x759e*/
    return -2147483641; /*0x75a0*/
  if ( (v6[0] & 0x1F) == 5 ) /*0x75ae*/
  {
    a2[15] = 3; /*0x75b0*/
    a2[10] = 2048; /*0x75b7*/
  }
  else
  {
    a2[15] = 1; /*0x75c0*/
    a2[10] = 512; /*0x75c7*/
  }
  return 0; /*0x75d0*/
}


// Function: XhciClearDeviceFeature @ 0x75d7 (0x54 bytes)
// Index: 92/119

int __fastcall XhciClearDeviceFeature(int ecx0, _DWORD *a2, int a3)
{
  int v5; // ecx
  int n36; // [esp+8h] [ebp-Ch] BYREF
  char n18; // [esp+Ch] [ebp-8h]

  (*(void (__cdecl **)(int *, int, _DWORD))(*(_DWORD *)ecx0 + 84))(&n36, 12, 0); /*0x75ed*/
  LOBYTE(n36) = 3; /*0x75f3*/
  n18 = 18; /*0x75fa*/
  if ( XhciGetEndpointDescriptor(ecx0, a2, &n36, v5, a3, &n36__0, 0, 0x1388u) >= 0 ) /*0x761c*/
    return 0; /*0x7625*/
  else
    return -2147483641; /*0x761e*/
}


// Function: XhciClearEndpointHalt @ 0x762b (0xdf bytes)
// Index: 93/119

int __fastcall XhciClearEndpointHalt(int a1, int a2)
{
  int v4; // ecx
  int v6; // ecx
  int v7; // eax
  bool v8; // zf
  _BYTE v9[512]; // [esp+Ch] [ebp-214h] BYREF
  int n36[3]; // [esp+20Ch] [ebp-14h] BYREF
  _BYTE v11[8]; // [esp+218h] [ebp-8h] BYREF

  (*(void (__cdecl **)(_BYTE *, int, _DWORD))(*(_DWORD *)a1 + 84))(v11, 8, 0); /*0x7646*/
  (*(void (__cdecl **)(int *, int, _DWORD))(*(_DWORD *)a1 + 84))(n36, 12, 0); /*0x7652*/
  LOBYTE(n36[0]) = 37; /*0x7658*/
  if ( XhciGetEndpointDescriptor(a1, (_DWORD *)a2, n36, v4, (int)v11, &n36__1, 0, 0x1388u) < 0 ) /*0x767b*/
    return -2147483641; /*0x767d*/
  v6 = v11[1] | (v11[0] << 8); /*0x768f*/
  *(_BYTE *)(a2 + 32) = 1; /*0x7691*/
  v7 = v11[5]; /*0x76a7*/
  *(_DWORD *)(a2 + 36) = v11[3] | ((v11[2] | (v6 << 8)) << 8); /*0x76ab*/
  v8 = *(_DWORD *)(a2 + 60) == 1; /*0x76c9*/
  *(_DWORD *)(a2 + 40) = v11[7] | ((v11[6] | ((v7 | (v11[4] << 8)) << 8)) << 8); /*0x76cd*/
  if ( v8 && XhciGetMaxLun(a1, (_DWORD *)a2, (int)v9, 0, 0, 1u) >= 0 ) /*0x76eb*/
    XhciGetEndpointState((int)v9, *(_DWORD *)(a2 + 36), (_DWORD *)(a2 + 68)); /*0x76fa*/
  return 0; /*0x7703*/
}


// Function: XhciGetEndpointState @ 0x770a (0x77 bytes)
// Index: 94/119

unsigned __int8 __usercall XhciGetEndpointState@<al>(int a1@<edx>, unsigned int a2, _DWORD *a3)
{
  int v3; // edx
  int v4; // ecx
  char v5; // bl
  unsigned __int8 n4; // al
  char v7; // ah
  unsigned __int8 i; // cl
  _DWORD v9[4]; // [esp+Ch] [ebp-10h]

  v3 = a1 + 446; /*0x7710*/
  v4 = 0; /*0x7716*/
  v5 = 0; /*0x771e*/
  for ( n4 = 0; n4 < 4u; ++n4 ) /*0x7720*/
  {
    v7 = *(_BYTE *)v3; /*0x7722*/
    v9[n4] = 0; /*0x7727*/
    if ( (v7 & 0x7F) != 0 || *(_DWORD *)(v3 + 8) > a2 ) /*0x7734*/
      return n4; /*0x7734*/
    ++v5; /*0x7736*/
    v9[n4] = v3; /*0x7738*/
    if ( v7 < 0 ) /*0x773e*/
      v4 = v3; /*0x7740*/
    v3 += 16; /*0x7742*/
  }
  if ( !v5 ) /*0x774d*/
    return n4; /*0x774d*/
  if ( v4 ) /*0x7751*/
  {
LABEL_14:
    *a3 = *(_DWORD *)(v4 + 8); /*0x7772*/
    return (unsigned __int8)a3; /*0x7772*/
  }
  for ( i = 0; i < 4u; ++i ) /*0x7753*/
  {
    n4 = i; /*0x7755*/
    if ( v9[i] ) /*0x7758*/
      break; /*0x775d*/
  }
  if ( i != 4 ) /*0x7769*/
  {
    v4 = v9[i]; /*0x776e*/
    goto LABEL_14; /*0x776e*/
  }
  return n4; /*0x777a*/
}


// Function: XhciGetMaxLun @ 0x7781 (0xe0 bytes)
// Index: 95/119

int __fastcall XhciGetMaxLun(int a1, _DWORD *a2, int a3, int a4, int a5, unsigned int a6)
{
  unsigned int v7; // esi
  unsigned __int16 v10; // ax
  unsigned int v11; // ecx
  bool v12; // cc
  int v13; // ecx
  int v14; // ebp
  int result; // eax
  unsigned int v18; // [esp+18h] [ebp-10h]
  int n36; // [esp+1Ch] [ebp-Ch] BYREF
  char v20; // [esp+20h] [ebp-8h]
  char v21; // [esp+21h] [ebp-7h]
  char v22; // [esp+23h] [ebp-5h]
  char v23; // [esp+24h] [ebp-4h]
  int v24; // [esp+2Ch] [ebp+4h]
  unsigned __int16 v25; // [esp+30h] [ebp+8h]
  int *n36_1; // [esp+38h] [ebp+10h]

  (*(void (__cdecl **)(int *, int, _DWORD))(*(_DWORD *)a1 + 84))(&n36, 12, 0); /*0x779f*/
  v7 = a6; /*0x77ac*/
  v10 = 0x10000u / a2[10]; /*0x77bd*/
  v24 = a2[10]; /*0x77c0*/
  v25 = v10; /*0x77c4*/
  if ( !a6 ) /*0x77ca*/
    return 0; /*0x7857*/
  v11 = v10; /*0x77d0*/
  v18 = v10; /*0x77d3*/
  while ( 1 ) /*0x77d7*/
  {
    v12 = v7 <= v11; /*0x77d7*/
    v13 = (unsigned __int16)v7; /*0x77d9*/
    if ( !v12 ) /*0x77dc*/
      v13 = v10; /*0x77de*/
    v14 = (unsigned __int16)v13; /*0x77e3*/
    v20 = BYTE1(a4); /*0x77f0*/
    HIBYTE(n36) = BYTE2(a4); /*0x77f9*/
    BYTE2(n36) = HIBYTE(a4); /*0x7802*/
    v22 = BYTE1(v13); /*0x780b*/
    v23 = v13; /*0x7815*/
    n36_1 = (int *)(v24 * (unsigned __int16)v13); /*0x7819*/
    LOBYTE(n36) = 40; /*0x781d*/
    v21 = a4; /*0x7822*/
    result = XhciGetEndpointDescriptor(a1, a2, &n36, v13, a3, n36_1, 0, 2000 * v13); /*0x7839*/
    if ( result ) /*0x7843*/
      break; /*0x7843*/
    a3 += (int)n36_1; /*0x7845*/
    a4 += v14; /*0x7849*/
    v10 = v25; /*0x784b*/
    v11 = v18; /*0x784f*/
    v7 -= v14; /*0x7853*/
    if ( !v7 ) /*0x7855*/
      return 0; /*0x7855*/
  }
  return result; /*0x7859*/
}


// Function: XhciGetConfigDescriptor @ 0x7861 (0x7f bytes)
// Index: 96/119

int __fastcall XhciGetConfigDescriptor(int a1, _DWORD *a2)
{
  int (__cdecl **v4)(int, _DWORD, _DWORD *, int, int, _DWORD, _DWORD, _BYTE *); // edi
  int v6; // esi
  _BYTE v7[4]; // [esp+Ch] [ebp-Ch] BYREF
  _DWORD v8[2]; // [esp+10h] [ebp-8h] BYREF

  v4 = (int (__cdecl **)(int, _DWORD, _DWORD *, int, int, _DWORD, _DWORD, _BYTE *))a2[11]; /*0x786b*/
  if ( !v4 ) /*0x7870*/
    return -2147483646; /*0x7872*/
  (*(void (__cdecl **)(_DWORD *, int, _DWORD))(*(_DWORD *)a1 + 84))(v8, 8, 0); /*0x7887*/
  v8[0] = 65313; /*0x788c*/
  v8[1] = 0; /*0x7894*/
  v6 = (*v4)(a1, v4, v8, 2, 3000, 0, 0, v7); /*0x78b4*/
  XhciSetupPacket(a1, (int)v4, *(_BYTE *)(a2[13] + 2)); /*0x78bd*/
  XhciSetupPacket(a1, (int)v4, *(_BYTE *)(a2[14] + 2)); /*0x78ce*/
  return v6; /*0x78d9*/
}


// Function: XhciGetStringDescriptor @ 0x78e0 (0xae bytes)
// Index: 97/119

int __fastcall XhciGetStringDescriptor(int a1, int a2, int *n36, int a4, int n36a, int n2, unsigned __int16 n5000)
{
  int v8; // ebx
  int v9; // eax
  int v10; // esi
  int n31; // [esp+10h] [ebp-2Ch] BYREF
  int v13; // [esp+14h] [ebp-28h]
  char v14[4]; // [esp+18h] [ebp-24h] BYREF
  _DWORD v15[3]; // [esp+1Ch] [ebp-20h] BYREF
  char v16; // [esp+28h] [ebp-14h]
  char v17; // [esp+29h] [ebp-13h]
  char n12; // [esp+2Ah] [ebp-12h]
  int v19; // [esp+2Bh] [ebp-11h]
  int v20; // [esp+2Fh] [ebp-Dh]
  int v21; // [esp+33h] [ebp-9h]

  v13 = a1; /*0x78eb*/
  v8 = *(_DWORD *)(a2 + 44); /*0x78f7*/
  (*(void (__cdecl **)(_DWORD *, int, _DWORD))(*(_DWORD *)a1 + 84))(v15, 31, 0); /*0x78fd*/
  v15[2] = n36a; /*0x7911*/
  v15[0] = 1128420181; /*0x791a*/
  v15[1] = 1; /*0x7924*/
  v16 = n2 != 0 ? 0 : 0x80;
  v17 = *(_BYTE *)(a2 + 72); /*0x7933*/
  n12 = 12; /*0x7942*/
  v19 = *n36; /*0x794c*/
  v9 = *(_DWORD *)(a2 + 56); /*0x7952*/
  n31 = 31; /*0x7955*/
  v20 = n36[1]; /*0x795d*/
  v21 = n36[2]; /*0x795e*/
  v10 = v13; /*0x7963*/
  if ( (*(int (__cdecl **)(int, int, _DWORD, _DWORD *, int *, _DWORD, char *))(v8 + 4))( /*0x7972*/
         v13,
         v8,
         *(unsigned __int8 *)(v9 + 2),
         v15,
         &n31,
         n5000,
         v14) >= 0 )
    return 0; /*0x7984*/
  XhciGetConfigDescriptor(v10, (_DWORD *)a2); /*0x7978*/
  return -2147483641; /*0x7986*/
}


// Function: XhciGetInterfaceDescriptor @ 0x798e (0xcb bytes)
// Index: 98/119

int __fastcall XhciGetInterfaceDescriptor(
        int a1,
        _DWORD *a2,
        unsigned int *p_n36,
        int a4,
        int n2,
        unsigned __int16 n5000)
{
  int v6; // ebp
  unsigned int v7; // ebx
  unsigned int n36; // esi
  int v9; // ecx
  int v10; // edi
  int n5000_1; // ecx
  int v12; // eax
  unsigned int n36_2; // edi
  unsigned int n36_1; // ebx
  int v15; // ebp
  unsigned int v17; // [esp+10h] [ebp-14h]
  unsigned int n36_3; // [esp+14h] [ebp-10h] BYREF
  int v19; // [esp+18h] [ebp-Ch]
  int v20; // [esp+1Ch] [ebp-8h]
  char v21[4]; // [esp+20h] [ebp-4h] BYREF

  v6 = a2[11]; /*0x7993*/
  v7 = 0; /*0x7996*/
  v20 = a1; /*0x799e*/
  v19 = v6; /*0x79a2*/
  n36 = *p_n36; /*0x79a6*/
  v17 = 0; /*0x79a8*/
  if ( n2 ) /*0x79b0*/
    v9 = a2[14]; /*0x79b7*/
  else
    v9 = a2[13]; /*0x79b2*/
  LOBYTE(n2) = *(_BYTE *)(v9 + 2); /*0x79bd*/
  v10 = *(unsigned __int16 *)(v9 + 4); /*0x79c5*/
  if ( n36 ) /*0x79ca*/
  {
    n5000_1 = n5000; /*0x79cc*/
    v12 = a4; /*0x79d1*/
    n36_2 = 16 * v10; /*0x79d5*/
    while ( 1 ) /*0x79d8*/
    {
      n36_1 = n36_2; /*0x79d8*/
      if ( n36 <= n36_2 ) /*0x79dc*/
        n36_1 = n36; /*0x79de*/
      n36_3 = n36_1; /*0x79e4*/
      v15 = (*(int (__cdecl **)(int, int, int, int, unsigned int *, int, char *))(v6 + 4))( /*0x7a00*/
              v20,
              v6,
              n2,
              v12,
              &n36_3,
              n5000_1,
              v21);
      v17 += n36_3; /*0x7a02*/
      if ( v15 < 0 ) /*0x7a0b*/
        break; /*0x7a0b*/
      if ( n36_3 >= n36_1 ) /*0x7a0f*/
      {
        v6 = v19; /*0x7a15*/
        v12 = n36_3 + a4; /*0x7a19*/
        n36 -= n36_3; /*0x7a1b*/
        a4 += n36_3; /*0x7a1d*/
        n5000_1 = n5000; /*0x7a21*/
        if ( n36 ) /*0x7a26*/
          continue; /*0x7a26*/
      }
      v7 = v17; /*0x7a28*/
      goto LABEL_12; /*0x7a28*/
    }
    if ( (v21[0] & 2) != 0 ) /*0x7a41*/
      XhciSetupPacket(v20, v19, n2); /*0x7a4f*/
    return v15; /*0x7a55*/
  }
  else
  {
LABEL_12:
    *p_n36 = v7; /*0x7a2c*/
    return 0; /*0x7a32*/
  }
}


// Function: XhciSelectInterface @ 0x7a59 (0xde bytes)
// Index: 99/119

int __fastcall XhciSelectInterface(int a1, _DWORD *a2, _BYTE *p_n36, unsigned __int16 n5000)
{
  int v6; // edi
  int v7; // edi
  int v9; // [esp+10h] [ebp-2Ch] BYREF
  int n13; // [esp+14h] [ebp-28h] BYREF
  unsigned __int8 n2[4]; // [esp+18h] [ebp-24h]
  _DWORD v12[3]; // [esp+1Ch] [ebp-20h] BYREF
  char v13; // [esp+28h] [ebp-14h]

  v6 = a2[11]; /*0x7a6c*/
  (*(void (__cdecl **)(_DWORD *, int, _DWORD))(*(_DWORD *)a1 + 84))(v12, 31, 0); /*0x7a72*/
  n2[0] = *(_BYTE *)(a2[13] + 2); /*0x7a80*/
  n13 = 13; /*0x7a8e*/
  if ( (*(int (__cdecl **)(int, int, _DWORD, _DWORD *, int *, _DWORD, int *))(v6 + 4))( /*0x7aaa*/
         a1,
         v6,
         *(_DWORD *)n2,
         v12,
         &n13,
         n5000,
         &v9) >= 0 )
    goto LABEL_10; /*0x7aaa*/
  if ( (v9 & 2) != 0 ) /*0x7ab1*/
    XhciSetupPacket(a1, v6, n2[0]); /*0x7abb*/
  v9 = 0; /*0x7ac1*/
  n13 = 13; /*0x7ad0*/
  v7 = (*(int (__cdecl **)(int, int, _DWORD, _DWORD *, int *, _DWORD, int *))(v6 + 4))( /*0x7ae7*/
         a1,
         v6,
         *(_DWORD *)n2,
         v12,
         &n13,
         n5000,
         &v9);
  if ( v7 >= 0 ) /*0x7aee*/
  {
LABEL_10:
    if ( n13 == 13 && v12[0] == 1396855637 && v12[1] == 1 ) /*0x7b1a*/
    {
      *p_n36 = v13; /*0x7b24*/
      return 0; /*0x7b26*/
    }
    else
    {
      return -2147483641; /*0x7b2a*/
    }
  }
  else
  {
    if ( (v9 & 2) != 0 ) /*0x7af5*/
      XhciGetConfigDescriptor(a1, a2); /*0x7afb*/
    return v7; /*0x7b00*/
  }
}


// Function: XhciGetEndpointDescriptor @ 0x7b37 (0x8f bytes)
// Index: 100/119

int __fastcall XhciGetEndpointDescriptor(
        int a1,
        _DWORD *a2,
        int *n36,
        int a4,
        int a5,
        int *n36a,
        unsigned int n2,
        unsigned __int16 n5000)
{
  int *n36a_1; // ebp
  int InterfaceDescriptor; // ebx

  n36a_1 = n36a; /*0x7b39*/
  InterfaceDescriptor = 0; /*0x7b3d*/
  if ( XhciGetStringDescriptor(a1, (int)a2, n36, a1, (int)n36a, n2, n5000) < 0 ) /*0x7b5d*/
    return -2147483641; /*0x7b5d*/
  if ( n2 <= 1 ) /*0x7b6b*/
  {
    n36 = n36a_1; /*0x7b75*/
    InterfaceDescriptor = XhciGetInterfaceDescriptor(a1, a2, (unsigned int *)&n36, a5, n2, n5000); /*0x7b8e*/
  }
  if ( XhciSelectInterface(a1, a2, &n36, n5000) < 0 ) /*0x7ba6*/
    return -2147483641; /*0x7ba6*/
  if ( (_BYTE)n36 ) /*0x7bae*/
  {
    if ( (unsigned __int8)n36 > 1u ) /*0x7bb2*/
      XhciGetConfigDescriptor(a1, a2); /*0x7bb8*/
    return -2147483641; /*0x7b64*/
  }
  return InterfaceDescriptor; /*0x7bc1*/
}


// Function: XhciSetConfig @ 0x7bc6 (0x42 bytes)
// Index: 101/119

__int64 __cdecl XhciSetConfig(__int64 a1)
{
  unsigned int n0x40; // ecx
  int v2; // eax
  __int64 v3; // rax
  char n0x40_1; // [esp+0h] [ebp-4h]

  n0x40_1 = n0x40; /*0x7bca*/
  if ( n0x40 >= 0x40 ) /*0x7bd0*/
  {
    v2 = DebugPrintUsbStatus(); /*0x7bd2*/
    if ( v2 ) /*0x7bd9*/
      (*(void (__cdecl **)(const char *, int, const char *))(v2 + 4))( /*0x7be7*/
        "e:\\hs\\MdePkg\\Library\\BaseLib\\LShiftU64.c",
        39,
        "Count < 64");
  }
  LODWORD(v3) = 0; /*0x7bf0*/
  HIDWORD(v3) = a1; /*0x7bf2*/
  if ( (n0x40_1 & 0x20) == 0 ) /*0x7bf8*/
    v3 = a1; /*0x7bfa*/
  return v3 << (n0x40_1 & 0x1F); /*0x7c04*/
}


// Function: XhciClearConfig @ 0x7c08 (0x42 bytes)
// Index: 102/119

unsigned __int64 __cdecl XhciClearConfig(unsigned __int64 BarAddr)
{
  unsigned int n0x40; // ecx
  int v2; // eax
  unsigned __int64 BarAddr_1; // rax
  char n0x40_1; // [esp+0h] [ebp-4h]

  n0x40_1 = n0x40; /*0x7c0c*/
  if ( n0x40 >= 0x40 ) /*0x7c12*/
  {
    v2 = DebugPrintUsbStatus(); /*0x7c14*/
    if ( v2 ) /*0x7c1b*/
      (*(void (__cdecl **)(const char *, int, const char *))(v2 + 4))( /*0x7c29*/
        "e:\\hs\\MdePkg\\Library\\BaseLib\\RShiftU64.c",
        39,
        "Count < 64");
  }
  BarAddr_1 = HIDWORD(BarAddr); /*0x7c34*/
  if ( (n0x40_1 & 0x20) == 0 ) /*0x7c3a*/
    BarAddr_1 = BarAddr; /*0x7c3e*/
  return BarAddr_1 >> (n0x40_1 & 0x1F); /*0x7c46*/
}


// Function: DebugPrintUsbStatus @ 0x7c4a (0x31 bytes)
// Index: 103/119

int DebugPrintUsbStatus()
{
  int v0; // eax
  _BYTE v2[4]; // [esp+0h] [ebp-8h] BYREF
  int v3; // [esp+4h] [ebp-4h] BYREF

  v0 = CopyMem(); /*0x7c4f*/
  if ( (*(int (__cdecl **)(int, void *, _DWORD, _BYTE *, int *))(*(_DWORD *)v0 + 32))(v0, &unk_8920, 0, v2, &v3) >= 0 ) /*0x7c6e*/
    return v3; /*0x7c74*/
  else
    return 0; /*0x7c70*/
}


// Function: DebugPrint @ 0x7c7b (0x2a bytes)
// Index: 104/119

int DebugPrint(int a1, int a2, ...)
{
  int result; // eax
  int (__cdecl **v3)(int, int, char *); // esi
  va_list va; // [esp+10h] [ebp+Ch] BYREF

  va_start(va, a2);
  result = DebugPrintUsbStatus(); /*0x7c7c*/
  v3 = (int (__cdecl **)(int, int, char *))result; /*0x7c81*/
  if ( result ) /*0x7c85*/
  {
    result = SetMem(); /*0x7c87*/
    if ( (result & a1) != 0 ) /*0x7c92*/
      return (*v3)(a1, a2, (char *)va); /*0x7c9e*/
  }
  return result; /*0x7ca3*/
}


// Function: DebugAssert @ 0x7ca5 (0x1e bytes)
// Index: 105/119

int __fastcall DebugAssert(int a1, int a2, int a3)
{
  int result; // eax

  result = DebugPrintUsbStatus(); /*0x7cab*/
  if ( result ) /*0x7cb2*/
    return (*(int (__cdecl **)(int, int, int))(result + 4))(a1, a2, a3); /*0x7cba*/
  return result; /*0x7cc0*/
}


// Function: DebugEnabled @ 0x7cc3 (0x3 bytes)
// Index: 106/119

// (too small: 0x3 bytes)


// Function: DebugLevelEnabled @ 0x7cc6 (0x3 bytes)
// Index: 107/119

// (too small: 0x3 bytes)


// Function: MmioRead8 @ 0x7cc9 (0x3 bytes)
// Index: 108/119

// (too small: 0x3 bytes)


// Function: MmioWrite8 @ 0x7ccc (0x5 bytes)
// Index: 109/119

// (too small: 0x5 bytes)


// Function: MmioRead16 @ 0x7cd1 (0x2e bytes)
// Index: 110/119

int __fastcall MmioRead16(unsigned __int16 *a1)
{
  int v2; // eax

  if ( ((unsigned __int8)a1 & 1) != 0 ) /*0x7cd7*/
  {
    v2 = DebugPrintUsbStatus(); /*0x7cd9*/
    if ( v2 ) /*0x7ce0*/
      (*(void (__cdecl **)(const char *, int, const char *))(v2 + 4))( /*0x7cf1*/
        "e:\\hs\\MdePkg\\Library\\BaseIoLibIntrinsic\\IoLib.c",
        151,
        "(Address & 1) == 0");
  }
  return *a1; /*0x7cfd*/
}


// Function: MmioWrite16 @ 0x7cff (0x33 bytes)
// Index: 111/119

__int16 __fastcall MmioWrite16(_WORD *a1, __int16 a2)
{
  int v4; // eax

  if ( ((unsigned __int8)a1 & 1) != 0 ) /*0x7d09*/
  {
    v4 = DebugPrintUsbStatus(); /*0x7d0b*/
    if ( v4 ) /*0x7d12*/
      (*(void (__cdecl **)(const char *, int, const char *))(v4 + 4))( /*0x7d23*/
        "e:\\hs\\MdePkg\\Library\\BaseIoLibIntrinsic\\IoLib.c",
        183,
        "(Address & 1) == 0");
  }
  *a1 = a2; /*0x7d29*/
  return a2; /*0x7d2f*/
}


// Function: MmioRead32 @ 0x7d32 (0x3 bytes)
// Index: 112/119

// (too small: 0x3 bytes)


// Function: MmioWrite32 @ 0x7d35 (0x5 bytes)
// Index: 113/119

// (too small: 0x5 bytes)


// Function: MmioRead64 @ 0x7d3a (0x2d bytes)
// Index: 114/119

__int64 __fastcall MmioRead64(int a1)
{
  int v2; // eax

  if ( (a1 & 7) != 0 ) /*0x7d40*/
  {
    v2 = DebugPrintUsbStatus(); /*0x7d42*/
    if ( v2 ) /*0x7d49*/
      (*(void (__cdecl **)(const char *, int, const char *))(v2 + 4))( /*0x7d5a*/
        "e:\\hs\\MdePkg\\Library\\BaseIoLibIntrinsic\\IoLib.c",
        284,
        "(Address & 7) == 0");
  }
  return *(_QWORD *)a1; /*0x7d65*/
}


// Function: MmioWrite64 @ 0x7d67 (0x35 bytes)
// Index: 115/119

int __cdecl MmioWrite64(int a1, int a2)
{
  _DWORD *v2; // ecx
  _DWORD *v3; // ebx
  int v4; // eax

  v3 = v2; /*0x7d68*/
  if ( ((unsigned __int8)v2 & 7) != 0 ) /*0x7d6d*/
  {
    v4 = DebugPrintUsbStatus(); /*0x7d6f*/
    if ( v4 ) /*0x7d76*/
      (*(void (__cdecl **)(const char *, int, const char *))(v4 + 4))( /*0x7d87*/
        "e:\\hs\\MdePkg\\Library\\BaseIoLibIntrinsic\\IoLib.c",
        314,
        "(Address & 7) == 0");
  }
  *v3 = a1; /*0x7d95*/
  v3[1] = a2; /*0x7d97*/
  return a1; /*0x7d9a*/
}


// Function: ZeroMem @ 0x7d9c (0x5b bytes)
// Index: 116/119

void *__fastcall ZeroMem(int buf, unsigned int count)
{
  int v5; // eax
  int v6; // eax

  if ( !count ) /*0x7da4*/
    return (void *)buf; /*0x7da6*/
  if ( !buf ) /*0x7db2*/
  {
    v5 = DebugPrintUsbStatus(); /*0x7db4*/
    if ( v5 ) /*0x7dbb*/
      (*(void (__cdecl **)(const char *, int, const char *))(v5 + 4))( /*0x7dc5*/
        "e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\ZeroMemWrapper.c",
        53,
        "Buffer != ((void *) 0)");
  }
  if ( count > -buf ) /*0x7dd1*/
  {
    v6 = DebugPrintUsbStatus(); /*0x7dd3*/
    if ( v6 ) /*0x7dda*/
      (*(void (__cdecl **)(const char *, int, const char *))(v6 + 4))( /*0x7de4*/
        "e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\ZeroMemWrapper.c",
        54,
        "Length <= (0xFFFFFFFF - (UINTN)Buffer + 1)");
  }
  return XhciGetPciCfg((void *)buf, count); /*0x7df4*/
}


// Function: CopyMem @ 0x7df7 (0x32 bytes)
// Index: 117/119

int CopyMem()
{
  int v0; // esi
  _BYTE v2[2]; // [esp+4h] [ebp-8h] BYREF
  int v3; // [esp+6h] [ebp-6h]

  CompareMem(v2); /*0x7e00*/
  v0 = *(_DWORD *)(v3 - 4); /*0x7e08*/
  if ( !v0 ) /*0x7e0d*/
    DebugAssert( /*0x7e1c*/
      (int)"e:\\hs\\MdePkg\\Library\\PeiServicesTablePointerLibIdt\\PeiServicesTablePointer.c",
      48,
      (int)"PeiServices != ((void *) 0)");
  return v0; /*0x7e24*/
}


// Function: SetMem @ 0x7e29 (0x4f bytes)
// Index: 118/119

int SetMem()
{
  unsigned __int8 v0; // al
  char n3; // al
  char n3_1; // cl

  v0 = __inbyte(0x70u); /*0x7e2f*/
  __outbyte(0x70u, v0 & 0x80 | 0x4A); /*0x7e34*/
  n3 = __inbyte(0x71u); /*0x7e3b*/
  n3_1 = n3; /*0x7e3c*/
  if ( (unsigned __int8)n3 <= 3u ) /*0x7e41*/
  {
LABEL_4:
    if ( !n3_1 ) /*0x7e5c*/
      return 0; /*0x7e5c*/
    goto LABEL_5; /*0x7e5c*/
  }
  n3_1 = n3; /*0x7e43*/
  if ( !n3 ) /*0x7e4b*/
  {
    n3_1 = MEMORY[0xFDAF0490] & 2 | 1; /*0x7e57*/
    goto LABEL_4; /*0x7e57*/
  }
LABEL_5:
  if ( n3_1 != -1 )
    return n3_1 != 1 ? -2147483578 : -2147483644;
  return 0; /*0x7e74*/
}


// Function: CompareMem @ 0x7e78 (0x23 bytes)
// Index: 119/119

void *__thiscall CompareMem(void *this)
{
  void *this_1; // eax

  if ( !this ) /*0x7e7e*/
    DebugAssert((int)"e:\\hs\\MdePkg\\Library\\BaseLib\\X86ReadIdtr.c", 37, (int)"Idtr != ((void *) 0)"); /*0x7e8d*/
  this_1 = this; /*0x7e93*/
  __sidt(this); /*0x7e96*/
  return this_1; /*0x7e9a*/
}