unsigned __int64 __fastcall sub_2EA4(__int64 a1, char a2, __int64 a3, _WORD *a4)
{
__int64 p_n145_2; // r13
__int64 v7; // rdx
__int64 v8; // rcx
__int64 v9; // rsi
__int64 v10; // r8
__int64 v11; // r9
int v12; // r14d
unsigned __int64 v13; // rbp
unsigned int v14; // r14d
__int64 v15; // rdx
__int64 v16; // rcx
__int64 v17; // rsi
__int64 v18; // r8
__int64 v19; // r9
unsigned __int64 n0x40; // rax
int v21; // r9d
unsigned __int16 v22; // r15
__int64 v23; // rdx
__int64 v24; // rcx
__int64 v25; // rdi
__int64 v26; // r8
__int64 v27; // r9
unsigned __int16 n4_3; // di
__int16 n3; // ax
unsigned __int16 n4_1; // si
__int16 v31; // bp
int n2; // ebp
unsigned __int16 v33; // r12
int n145_1; // r15d
__int64 v35; // rcx
__int64 v36; // rcx
__int64 n4_2; // rdi
__int64 p_n145; // rax
__int64 v39; // rdx
__int64 v40; // rcx
__int64 v41; // r8
__int64 v42; // r9
__int64 p_n145_1; // rax
int n2_1; // r8d
unsigned __int64 v45; // [rsp+60h] [rbp-F8h]
__int64 v46; // [rsp+68h] [rbp-F0h] BYREF
_BYTE v47[16]; // [rsp+70h] [rbp-E8h] BYREF
unsigned __int8 n145; // [rsp+80h] [rbp-D8h] BYREF
unsigned __int16 n4; // [rsp+81h] [rbp-D7h]
__int16 v50; // [rsp+160h] [rbp+8h]
v45 = 0x8000000000000003uLL; /*0x2ed9*/
p_n145_2 = 0; /*0x2ede*/
if ( (*(_BYTE *)(a1 + 38) & 0x7F) != 0 || (*(_BYTE *)(a1 + 30) & 0x10) == 0 ) /*0x2eef*/
return 0x8000000000000003uLL; /*0x2ee6*/
v9 = (*(__int64 (__fastcall **)(_QWORD, void *, __int64 *, _QWORD, _QWORD, int))(qword_96A8 + 280))( /*0x2f21*/
*(_QWORD *)(a1 + 16),
&unk_9400,
&v46,
0,
0,
2);
if ( v9 < 0 )
{
if ( (unsigned __int8)sub_7F8(v8, v7, v10, v11) )
{
if ( (unsigned __int8)sub_804(64) )
sub_740(64, "CheckDeviceVpd: OpenProtocol failed. %r\n", v9);
}
return 0x8000000000000003uLL; /*0x2f52*/
}
v12 = *(unsigned __int8 *)(a1 + 76); /*0x2f54*/
v13 = 0; /*0x2f59*/
while ( 1 )
{
v14 = v12 & 0xFFFFFFFC; /*0x2f66*/
v17 = (*(__int64 (__fastcall **)(__int64, __int64, _QWORD, __int64, _BYTE *))(v46 + 48))(v46, 2, v14, 2, v47); /*0x2f83*/
if ( v17 < 0 )
{
if ( (unsigned __int8)sub_7F8(v16, v15, v18, v19) && (unsigned __int8)sub_804(64) )
sub_740(64, "CheckDeviceVpd: Error reading capabilities - CapabilitiesPtr = %x, code=%r\n", v14, v17);
return v17; /*0x3470*/
}
if ( v47[0] == 3 ) /*0x2f94*/
break; /*0x2f94*/
v12 = v47[1]; /*0x2f96*/
n0x40 = v13++; /*0x2f9c*/
if ( n0x40 > 0x40 )
{
if ( (unsigned __int8)sub_7F8(v16, v15, v18, v19) && (unsigned __int8)sub_804(64) )
sub_740(64, "CheckDeviceVpd: Impossible number of capabilities. CapabilitiesPtr = %x%d\n", v12, v21);
v12 = 0; /*0x2fce*/
}
if ( !v12 ) /*0x2fd4*/
return v45; /*0x2fd4*/
}
if ( !v14 ) /*0x2fdf*/
return v45; /*0x2fdf*/
if ( (unsigned __int8)sub_7F8(v16, v15, v18, v19) && (unsigned __int8)sub_804(64) )
sub_740(
64,
"CheckDeviceVpd: Found capabilities %4.4x %4.4x bus=%d,dev=%d,fun=%d,cl=%d.%d.%d, VpdReg=%x\n",
*(unsigned __int16 *)(a1 + 24),
*(unsigned __int16 *)(a1 + 26),
*(_QWORD *)(a1 + 96),
*(_QWORD *)(a1 + 104),
*(_QWORD *)(a1 + 112),
*(unsigned __int8 *)(a1 + 35),
*(unsigned __int8 *)(a1 + 34),
*(unsigned __int8 *)(a1 + 33),
v14);
v50 = 0; /*0x3055*/
v45 = 0x8000000000000003uLL; /*0x305e*/
v22 = 0; /*0x3063*/
while ( 1 )
{
v25 = sub_5A7C((unsigned int)&n145, v22, 4, v46, v14); /*0x308a*/
if ( v25 < 0 )
{
if ( (unsigned __int8)sub_7F8(v24, v23, v26, v27) && (unsigned __int8)sub_804(64) )
sub_740(64, "CheckDeviceVpd: Error reading PciVpd - code = %r\n", v25);
return v45; /*0x343a*/
}
LOBYTE(v24) = n145; /*0x3096*/
switch ( n145 )
{
case 0x78u:
if ( (unsigned __int8)sub_7F8(v24, v23, v26, v27) && (unsigned __int8)sub_804(64) )
sub_740(64, "CheckDeviceVpd: Normal end tag found\n");
return v45; /*0x3416*/
case 0xFF:
if ( (unsigned __int8)sub_7F8(v24, v23, v26, v27) && (unsigned __int8)sub_804(64) )
sub_740(64, "CheckDeviceVpd: Bad ID 0xff found. Done.\n");
return v45; /*0x33f0*/
case 0u:
if ( (unsigned __int8)sub_7F8(v24, v23, v26, v27) && (unsigned __int8)sub_804(64) )
sub_740(64, "CheckDeviceVpd: Bad ID 0x00 found. Done.\n");
return v45; /*0x33d2*/
}
n4_3 = n4; /*0x30b7*/
if ( (n145 & 0x80u) == 0 ) /*0x30bf*/
break; /*0x30bf*/
if ( n4 < 4u )
{
if ( (unsigned __int8)sub_7F8(v24, v23, v26, v27) && (unsigned __int8)sub_804(64) )
{
n2_1 = n4_3; /*0x3378*/
LABEL_72:
sub_740(64, "CheckDeviceVpd: Invalid length of %hd found. Done.\n", n2_1);
return v45; /*0x338b*/
}
return v45; /*0x3372*/
}
n3 = 3; /*0x30ca*/
n4_1 = n4; /*0x30cf*/
v31 = n4 + 3; /*0x30d2*/
LABEL_32:
v33 = v22 + n3; /*0x30f7*/
n145_1 = n145; /*0x30fe*/
v35 = (unsigned int)n145 - 130; /*0x3105*/
if ( n145 != 130 )
{
v36 = (unsigned int)n145 - 144; /*0x3111*/
if ( n145 == 144 )
{
if ( (unsigned __int8)sub_7F8(v36, v23, v26, v27) && (unsigned __int8)sub_804(64) )
sub_740(64, "CheckDeviceVpd: Processing R/O region\n");
}
else if ( n145 != 145 )
{
if ( (unsigned __int8)sub_7F8(v36, v23, v26, v27) && (unsigned __int8)sub_804(64) )
sub_740(64, "CheckDeviceVpd: type 0x%x resource found\n", n145_1);
goto LABEL_61; /*0x314a*/
}
if ( (unsigned __int8)sub_7F8(v36, v23, v26, v27) && (unsigned __int8)sub_804(64) )
sub_740(64, "CheckDeviceVpd: Large Resource Tag type %2.2x found, length = %d\n", n145_1, n4_3);
v35 = 1; /*0x31a5*/
if ( (unsigned __int8)(a2 + 112) <= 1u && n4_1 > 0x10u )
{
n4_2 = n4_1; /*0x31be*/
p_n145 = sub_1D24(n4_1); /*0x31c3*/
p_n145_2 = p_n145; /*0x31c8*/
if ( !p_n145 )
{
if ( (unsigned __int8)sub_7F8(v40, v39, v41, v42) && (unsigned __int8)sub_804(64) )
sub_740(64, "CheckDeviceVpd: Unable to allocate memory for resource Done.\n");
goto LABEL_63; /*0x31fc*/
}
if ( sub_5A7C(p_n145, v33, n4_1, v46, v14) >= 0 )
{
if ( (unsigned __int8)sub_7F8(v35, v23, v26, v27) && (unsigned __int8)sub_804(2) )
sub_740(2, "CheckDeviceVpd: type 0x90/91 - %a\n", p_n145_2);
goto LABEL_60; /*0x324c*/
}
}
LABEL_61:
if ( p_n145_2 ) /*0x32f4*/
sub_1D54(p_n145_2); /*0x32f9*/
goto LABEL_63; /*0x32f9*/
}
if ( a2 != -126 ) /*0x3256*/
goto LABEL_61; /*0x3256*/
n4_2 = n4_1; /*0x325c*/
p_n145_1 = sub_1D2C(n4_1 + 1LL); /*0x3263*/
p_n145_2 = p_n145_1; /*0x3268*/
if ( p_n145_1 )
{
if ( sub_5A7C(p_n145_1, v33, n4_1, v46, v14) >= 0 )
{
if ( (unsigned __int8)sub_7F8(v35, v23, v26, v27) && (unsigned __int8)sub_804(2) )
sub_740(2, "CheckDeviceVpd: type 0x82 - %a\n", p_n145_2);
LABEL_60:
(*(void (__fastcall **)(__int64, __int64, __int64))(qword_96D8 + 352))(a3, p_n145_2, n4_2 + 1); /*0x32c2*/
v45 = 0; /*0x32e9*/
*a4 = n4_1 + 1; /*0x32ee*/
}
goto LABEL_61; /*0x32ee*/
}
LABEL_63:
if ( (unsigned __int8)sub_7F8(v35, v23, v26, v27) && (unsigned __int8)sub_804(64) )
sub_740(64, "CheckDeviceVpd: Done Processing VPD Section\n");
v22 = v31 + v50; /*0x332b*/
v50 += v31; /*0x332f*/
if ( !v31 || v45 != 0x8000000000000003uLL ) /*0x3350*/
return v45; /*0x3350*/
}
n2 = n145 & 7; /*0x30db*/
if ( (unsigned __int16)n2 >= 2u ) /*0x30e6*/
{
n3 = 1; /*0x30ec*/
n4_1 = n145 & 7; /*0x30f1*/
v31 = n2 + 1; /*0x30f4*/
goto LABEL_32; /*0x30f4*/
}
if ( (unsigned __int8)sub_7F8(v24, v23, v26, v27) && (unsigned __int8)sub_804(64) ) /*0x33a0*/
{
n2_1 = n2; /*0x33ad*/
goto LABEL_72; /*0x33b0*/
}
return v45; /*0x3473*/
}