xref: /aosp_15_r20/external/pciutils/lib/i386-io-windows.h (revision c2e0c6b56a71da9abe8df5c8348fb3eb5c2c9251)
1*c2e0c6b5SAndroid Build Coastguard Worker /*
2*c2e0c6b5SAndroid Build Coastguard Worker  *	The PCI Library -- Access to i386 I/O ports on Windows
3*c2e0c6b5SAndroid Build Coastguard Worker  *
4*c2e0c6b5SAndroid Build Coastguard Worker  *	Copyright (c) 2004 Alexander Stock <[email protected]>
5*c2e0c6b5SAndroid Build Coastguard Worker  *	Copyright (c) 2006 Martin Mares <[email protected]>
6*c2e0c6b5SAndroid Build Coastguard Worker  *	Copyright (c) 2021 Pali Rohár <[email protected]>
7*c2e0c6b5SAndroid Build Coastguard Worker  *
8*c2e0c6b5SAndroid Build Coastguard Worker  *	Can be freely distributed and used under the terms of the GNU GPL v2+
9*c2e0c6b5SAndroid Build Coastguard Worker  *
10*c2e0c6b5SAndroid Build Coastguard Worker  *	SPDX-License-Identifier: GPL-2.0-or-later
11*c2e0c6b5SAndroid Build Coastguard Worker  */
12*c2e0c6b5SAndroid Build Coastguard Worker 
13*c2e0c6b5SAndroid Build Coastguard Worker #include <windows.h>
14*c2e0c6b5SAndroid Build Coastguard Worker #include "win32-helpers.h"
15*c2e0c6b5SAndroid Build Coastguard Worker 
16*c2e0c6b5SAndroid Build Coastguard Worker #include "i386-io-access.h"
17*c2e0c6b5SAndroid Build Coastguard Worker 
18*c2e0c6b5SAndroid Build Coastguard Worker /*
19*c2e0c6b5SAndroid Build Coastguard Worker  * Define __readeflags() for MSVC and GCC compilers.
20*c2e0c6b5SAndroid Build Coastguard Worker  * MSVC since version 14.00 included in WDK 6001 and since version 15.00
21*c2e0c6b5SAndroid Build Coastguard Worker  * included in VS 2008 provides __readeflags() intrinsic for both 32 and 64-bit
22*c2e0c6b5SAndroid Build Coastguard Worker  * modes. WDK 6001 defines macro __BUILDMACHINE__ to value WinDDK. VS 2008 does
23*c2e0c6b5SAndroid Build Coastguard Worker  * not define this macro at all. MSVC throws error if name of user defined
24*c2e0c6b5SAndroid Build Coastguard Worker  * function conflicts with some MSVC intrinsic.
25*c2e0c6b5SAndroid Build Coastguard Worker  * MSVC supports inline assembly via __asm keyword in 32-bit mode only.
26*c2e0c6b5SAndroid Build Coastguard Worker  * GCC version 4.9.0 and higher provides __builtin_ia32_readeflags_uXX()
27*c2e0c6b5SAndroid Build Coastguard Worker  * builtin for XX-mode. This builtin is also available as __readeflags()
28*c2e0c6b5SAndroid Build Coastguard Worker  * function indirectly via <x86intrin.h> header file.
29*c2e0c6b5SAndroid Build Coastguard Worker  *
30*c2e0c6b5SAndroid Build Coastguard Worker  * CAVEAT: Semicolon in MSVC __asm block means start of the comment, and not
31*c2e0c6b5SAndroid Build Coastguard Worker  * end of the __asm statement, like it is for all other C statements. Also
32*c2e0c6b5SAndroid Build Coastguard Worker  * function which uses MSVC inline assembly cannot be inlined to another function
33*c2e0c6b5SAndroid Build Coastguard Worker  * (compiler reports a warning about it, not a fatal error). So we add explicit
34*c2e0c6b5SAndroid Build Coastguard Worker  * curly brackets for __asm blocks, remove misleading semicolons and do not
35*c2e0c6b5SAndroid Build Coastguard Worker  * declare functions as inline.
36*c2e0c6b5SAndroid Build Coastguard Worker  */
37*c2e0c6b5SAndroid Build Coastguard Worker #if defined(_MSC_VER) && (_MSC_VER >= 1500 || (_MSC_VER >= 1400 && defined(__BUILDMACHINE__)))
38*c2e0c6b5SAndroid Build Coastguard Worker #pragma intrinsic(__readeflags)
39*c2e0c6b5SAndroid Build Coastguard Worker #elif defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 9) || (__GNUC__ > 4))
40*c2e0c6b5SAndroid Build Coastguard Worker #include <x86intrin.h>
41*c2e0c6b5SAndroid Build Coastguard Worker #elif defined(_MSC_VER) && defined(_M_IX86)
42*c2e0c6b5SAndroid Build Coastguard Worker static unsigned int
__readeflags(void)43*c2e0c6b5SAndroid Build Coastguard Worker __readeflags(void)
44*c2e0c6b5SAndroid Build Coastguard Worker {
45*c2e0c6b5SAndroid Build Coastguard Worker   __asm {
46*c2e0c6b5SAndroid Build Coastguard Worker     pushfd
47*c2e0c6b5SAndroid Build Coastguard Worker     pop eax
48*c2e0c6b5SAndroid Build Coastguard Worker   }
49*c2e0c6b5SAndroid Build Coastguard Worker }
50*c2e0c6b5SAndroid Build Coastguard Worker #elif defined(__GNUC__)
51*c2e0c6b5SAndroid Build Coastguard Worker static inline unsigned
52*c2e0c6b5SAndroid Build Coastguard Worker #ifdef __x86_64__
53*c2e0c6b5SAndroid Build Coastguard Worker long long
54*c2e0c6b5SAndroid Build Coastguard Worker #endif
55*c2e0c6b5SAndroid Build Coastguard Worker int
__readeflags(void)56*c2e0c6b5SAndroid Build Coastguard Worker __readeflags(void)
57*c2e0c6b5SAndroid Build Coastguard Worker {
58*c2e0c6b5SAndroid Build Coastguard Worker   unsigned
59*c2e0c6b5SAndroid Build Coastguard Worker #ifdef __x86_64__
60*c2e0c6b5SAndroid Build Coastguard Worker   long long
61*c2e0c6b5SAndroid Build Coastguard Worker #endif
62*c2e0c6b5SAndroid Build Coastguard Worker   int eflags;
63*c2e0c6b5SAndroid Build Coastguard Worker   asm volatile ("pushf\n\tpop %0\n" : "=r" (eflags));
64*c2e0c6b5SAndroid Build Coastguard Worker   return eflags;
65*c2e0c6b5SAndroid Build Coastguard Worker }
66*c2e0c6b5SAndroid Build Coastguard Worker #else
67*c2e0c6b5SAndroid Build Coastguard Worker #error "Unsupported compiler"
68*c2e0c6b5SAndroid Build Coastguard Worker #endif
69*c2e0c6b5SAndroid Build Coastguard Worker 
70*c2e0c6b5SAndroid Build Coastguard Worker /* Read IOPL of the current process, IOPL is stored in eflag bits [13:12]. */
71*c2e0c6b5SAndroid Build Coastguard Worker #define read_iopl() ((__readeflags() >> 12) & 0x3)
72*c2e0c6b5SAndroid Build Coastguard Worker 
73*c2e0c6b5SAndroid Build Coastguard Worker /*
74*c2e0c6b5SAndroid Build Coastguard Worker  * Unfortunately NtSetInformationProcess() function, ProcessUserModeIOPL
75*c2e0c6b5SAndroid Build Coastguard Worker  * constant and all other helpers for its usage are not specified in any
76*c2e0c6b5SAndroid Build Coastguard Worker  * standard WinAPI header file. So define all of required constants and types.
77*c2e0c6b5SAndroid Build Coastguard Worker  * Function NtSetInformationProcess() is available in ntdll.dll library on all
78*c2e0c6b5SAndroid Build Coastguard Worker  * Windows systems but marked as it can be removed in some future version.
79*c2e0c6b5SAndroid Build Coastguard Worker  */
80*c2e0c6b5SAndroid Build Coastguard Worker #ifndef NTSTATUS
81*c2e0c6b5SAndroid Build Coastguard Worker #define NTSTATUS LONG
82*c2e0c6b5SAndroid Build Coastguard Worker #endif
83*c2e0c6b5SAndroid Build Coastguard Worker #ifndef STATUS_NOT_IMPLEMENTED
84*c2e0c6b5SAndroid Build Coastguard Worker #define STATUS_NOT_IMPLEMENTED (NTSTATUS)0xC0000002
85*c2e0c6b5SAndroid Build Coastguard Worker #endif
86*c2e0c6b5SAndroid Build Coastguard Worker #ifndef STATUS_PRIVILEGE_NOT_HELD
87*c2e0c6b5SAndroid Build Coastguard Worker #define STATUS_PRIVILEGE_NOT_HELD (NTSTATUS)0xC0000061
88*c2e0c6b5SAndroid Build Coastguard Worker #endif
89*c2e0c6b5SAndroid Build Coastguard Worker #ifndef PROCESSINFOCLASS
90*c2e0c6b5SAndroid Build Coastguard Worker #define PROCESSINFOCLASS DWORD
91*c2e0c6b5SAndroid Build Coastguard Worker #endif
92*c2e0c6b5SAndroid Build Coastguard Worker #ifndef ProcessUserModeIOPL
93*c2e0c6b5SAndroid Build Coastguard Worker #define ProcessUserModeIOPL 16
94*c2e0c6b5SAndroid Build Coastguard Worker #endif
95*c2e0c6b5SAndroid Build Coastguard Worker typedef NTSTATUS (NTAPI *NtSetInformationProcessProt)(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength);
96*c2e0c6b5SAndroid Build Coastguard Worker typedef ULONG (NTAPI *RtlNtStatusToDosErrorProt)(NTSTATUS Status);
97*c2e0c6b5SAndroid Build Coastguard Worker 
98*c2e0c6b5SAndroid Build Coastguard Worker /*
99*c2e0c6b5SAndroid Build Coastguard Worker  * ProcessUserModeIOPL is syscall for NT kernel to change x86 IOPL
100*c2e0c6b5SAndroid Build Coastguard Worker  * of the current running process to 3.
101*c2e0c6b5SAndroid Build Coastguard Worker  *
102*c2e0c6b5SAndroid Build Coastguard Worker  * Process handle argument for ProcessUserModeIOPL is ignored and
103*c2e0c6b5SAndroid Build Coastguard Worker  * IOPL is always changed for the current running process. So pass
104*c2e0c6b5SAndroid Build Coastguard Worker  * GetCurrentProcess() handle for documentation purpose. Process
105*c2e0c6b5SAndroid Build Coastguard Worker  * information buffer and length are unused for ProcessUserModeIOPL.
106*c2e0c6b5SAndroid Build Coastguard Worker  *
107*c2e0c6b5SAndroid Build Coastguard Worker  * ProcessUserModeIOPL may success (return value >= 0) or may fail
108*c2e0c6b5SAndroid Build Coastguard Worker  * because it is not implemented or because of missing privilege.
109*c2e0c6b5SAndroid Build Coastguard Worker  * Other errors are not defined, so handle them as unknown.
110*c2e0c6b5SAndroid Build Coastguard Worker  */
111*c2e0c6b5SAndroid Build Coastguard Worker static BOOL
SetProcessUserModeIOPLFunc(LPVOID Arg)112*c2e0c6b5SAndroid Build Coastguard Worker SetProcessUserModeIOPLFunc(LPVOID Arg)
113*c2e0c6b5SAndroid Build Coastguard Worker {
114*c2e0c6b5SAndroid Build Coastguard Worker   RtlNtStatusToDosErrorProt RtlNtStatusToDosErrorPtr = (RtlNtStatusToDosErrorProt)(((LPVOID *)Arg)[1]);
115*c2e0c6b5SAndroid Build Coastguard Worker   NtSetInformationProcessProt NtSetInformationProcessPtr = (NtSetInformationProcessProt)(((LPVOID *)Arg)[0]);
116*c2e0c6b5SAndroid Build Coastguard Worker   NTSTATUS nt_status = NtSetInformationProcessPtr(GetCurrentProcess(), ProcessUserModeIOPL, NULL, 0);
117*c2e0c6b5SAndroid Build Coastguard Worker   if (nt_status >= 0)
118*c2e0c6b5SAndroid Build Coastguard Worker     return TRUE;
119*c2e0c6b5SAndroid Build Coastguard Worker 
120*c2e0c6b5SAndroid Build Coastguard Worker   /*
121*c2e0c6b5SAndroid Build Coastguard Worker    * If we have optional RtlNtStatusToDosError() function then use it for
122*c2e0c6b5SAndroid Build Coastguard Worker    * translating NT status to Win32 error. If we do not have it then translate
123*c2e0c6b5SAndroid Build Coastguard Worker    * two important status codes which we use later STATUS_NOT_IMPLEMENTED and
124*c2e0c6b5SAndroid Build Coastguard Worker    * STATUS_PRIVILEGE_NOT_HELD.
125*c2e0c6b5SAndroid Build Coastguard Worker    */
126*c2e0c6b5SAndroid Build Coastguard Worker   if (RtlNtStatusToDosErrorPtr)
127*c2e0c6b5SAndroid Build Coastguard Worker     SetLastError(RtlNtStatusToDosErrorPtr(nt_status));
128*c2e0c6b5SAndroid Build Coastguard Worker   else if (nt_status == STATUS_NOT_IMPLEMENTED)
129*c2e0c6b5SAndroid Build Coastguard Worker     SetLastError(ERROR_INVALID_FUNCTION);
130*c2e0c6b5SAndroid Build Coastguard Worker   else if (nt_status == STATUS_PRIVILEGE_NOT_HELD)
131*c2e0c6b5SAndroid Build Coastguard Worker     SetLastError(ERROR_PRIVILEGE_NOT_HELD);
132*c2e0c6b5SAndroid Build Coastguard Worker   else
133*c2e0c6b5SAndroid Build Coastguard Worker     SetLastError(ERROR_GEN_FAILURE);
134*c2e0c6b5SAndroid Build Coastguard Worker 
135*c2e0c6b5SAndroid Build Coastguard Worker   return FALSE;
136*c2e0c6b5SAndroid Build Coastguard Worker }
137*c2e0c6b5SAndroid Build Coastguard Worker 
138*c2e0c6b5SAndroid Build Coastguard Worker /*
139*c2e0c6b5SAndroid Build Coastguard Worker  * Set x86 I/O Privilege Level to 3 for the whole current NT process. Do it via
140*c2e0c6b5SAndroid Build Coastguard Worker  * NtSetInformationProcess() call with ProcessUserModeIOPL information class,
141*c2e0c6b5SAndroid Build Coastguard Worker  * which is supported by 32-bit Windows NT kernel versions and requires Tcb
142*c2e0c6b5SAndroid Build Coastguard Worker  * privilege.
143*c2e0c6b5SAndroid Build Coastguard Worker  */
144*c2e0c6b5SAndroid Build Coastguard Worker static BOOL
SetProcessUserModeIOPL(VOID)145*c2e0c6b5SAndroid Build Coastguard Worker SetProcessUserModeIOPL(VOID)
146*c2e0c6b5SAndroid Build Coastguard Worker {
147*c2e0c6b5SAndroid Build Coastguard Worker   LPVOID Arg[2];
148*c2e0c6b5SAndroid Build Coastguard Worker   UINT prev_error_mode;
149*c2e0c6b5SAndroid Build Coastguard Worker   HMODULE ntdll;
150*c2e0c6b5SAndroid Build Coastguard Worker   BOOL ret;
151*c2e0c6b5SAndroid Build Coastguard Worker 
152*c2e0c6b5SAndroid Build Coastguard Worker   /*
153*c2e0c6b5SAndroid Build Coastguard Worker    * Load ntdll.dll library with disabled critical-error-handler and
154*c2e0c6b5SAndroid Build Coastguard Worker    * file-not-found message box.
155*c2e0c6b5SAndroid Build Coastguard Worker    * It means that NT kernel does not show unwanted GUI message box to user
156*c2e0c6b5SAndroid Build Coastguard Worker    * when LoadLibrary() function fails.
157*c2e0c6b5SAndroid Build Coastguard Worker    */
158*c2e0c6b5SAndroid Build Coastguard Worker   prev_error_mode = win32_change_error_mode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
159*c2e0c6b5SAndroid Build Coastguard Worker   ntdll = LoadLibrary(TEXT("ntdll.dll"));
160*c2e0c6b5SAndroid Build Coastguard Worker   win32_change_error_mode(prev_error_mode);
161*c2e0c6b5SAndroid Build Coastguard Worker   if (!ntdll)
162*c2e0c6b5SAndroid Build Coastguard Worker     {
163*c2e0c6b5SAndroid Build Coastguard Worker       SetLastError(ERROR_INVALID_FUNCTION);
164*c2e0c6b5SAndroid Build Coastguard Worker       return FALSE;
165*c2e0c6b5SAndroid Build Coastguard Worker     }
166*c2e0c6b5SAndroid Build Coastguard Worker 
167*c2e0c6b5SAndroid Build Coastguard Worker   /* Retrieve pointer to NtSetInformationProcess() function. */
168*c2e0c6b5SAndroid Build Coastguard Worker   Arg[0] = (LPVOID)GetProcAddress(ntdll, "NtSetInformationProcess");
169*c2e0c6b5SAndroid Build Coastguard Worker   if (!Arg[0])
170*c2e0c6b5SAndroid Build Coastguard Worker     {
171*c2e0c6b5SAndroid Build Coastguard Worker       FreeLibrary(ntdll);
172*c2e0c6b5SAndroid Build Coastguard Worker       SetLastError(ERROR_INVALID_FUNCTION);
173*c2e0c6b5SAndroid Build Coastguard Worker       return FALSE;
174*c2e0c6b5SAndroid Build Coastguard Worker     }
175*c2e0c6b5SAndroid Build Coastguard Worker 
176*c2e0c6b5SAndroid Build Coastguard Worker   /* Retrieve pointer to optional RtlNtStatusToDosError() function, it may be NULL. */
177*c2e0c6b5SAndroid Build Coastguard Worker   Arg[1] = (LPVOID)GetProcAddress(ntdll, "RtlNtStatusToDosError");
178*c2e0c6b5SAndroid Build Coastguard Worker 
179*c2e0c6b5SAndroid Build Coastguard Worker   /* Call ProcessUserModeIOPL with Tcb privilege. */
180*c2e0c6b5SAndroid Build Coastguard Worker   ret = win32_call_func_with_tcb_privilege(SetProcessUserModeIOPLFunc, (LPVOID)&Arg);
181*c2e0c6b5SAndroid Build Coastguard Worker 
182*c2e0c6b5SAndroid Build Coastguard Worker   FreeLibrary(ntdll);
183*c2e0c6b5SAndroid Build Coastguard Worker 
184*c2e0c6b5SAndroid Build Coastguard Worker   if (!ret)
185*c2e0c6b5SAndroid Build Coastguard Worker     return FALSE;
186*c2e0c6b5SAndroid Build Coastguard Worker 
187*c2e0c6b5SAndroid Build Coastguard Worker   /*
188*c2e0c6b5SAndroid Build Coastguard Worker    * Some Windows NT kernel versions (e.g. Windows 2003 x64) do not
189*c2e0c6b5SAndroid Build Coastguard Worker    * implement ProcessUserModeIOPL syscall at all but incorrectly
190*c2e0c6b5SAndroid Build Coastguard Worker    * returns success when it is called by user process. So always
191*c2e0c6b5SAndroid Build Coastguard Worker    * after this call verify that IOPL is set to 3.
192*c2e0c6b5SAndroid Build Coastguard Worker    */
193*c2e0c6b5SAndroid Build Coastguard Worker   if (read_iopl() != 3)
194*c2e0c6b5SAndroid Build Coastguard Worker     {
195*c2e0c6b5SAndroid Build Coastguard Worker       SetLastError(ERROR_INVALID_FUNCTION);
196*c2e0c6b5SAndroid Build Coastguard Worker       return FALSE;
197*c2e0c6b5SAndroid Build Coastguard Worker     }
198*c2e0c6b5SAndroid Build Coastguard Worker 
199*c2e0c6b5SAndroid Build Coastguard Worker   return TRUE;
200*c2e0c6b5SAndroid Build Coastguard Worker }
201*c2e0c6b5SAndroid Build Coastguard Worker 
202*c2e0c6b5SAndroid Build Coastguard Worker static int
intel_setup_io(struct pci_access * a)203*c2e0c6b5SAndroid Build Coastguard Worker intel_setup_io(struct pci_access *a)
204*c2e0c6b5SAndroid Build Coastguard Worker {
205*c2e0c6b5SAndroid Build Coastguard Worker #ifndef _WIN64
206*c2e0c6b5SAndroid Build Coastguard Worker   /* 16/32-bit non-NT systems allow applications to access PCI I/O ports without any special setup. */
207*c2e0c6b5SAndroid Build Coastguard Worker   if (win32_is_non_nt_system())
208*c2e0c6b5SAndroid Build Coastguard Worker     {
209*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("Detected 16/32-bit non-NT system, skipping NT setup...");
210*c2e0c6b5SAndroid Build Coastguard Worker       return 1;
211*c2e0c6b5SAndroid Build Coastguard Worker     }
212*c2e0c6b5SAndroid Build Coastguard Worker #endif
213*c2e0c6b5SAndroid Build Coastguard Worker 
214*c2e0c6b5SAndroid Build Coastguard Worker   /* Check if we have I/O permission */
215*c2e0c6b5SAndroid Build Coastguard Worker   if (read_iopl() == 3)
216*c2e0c6b5SAndroid Build Coastguard Worker     {
217*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("IOPL is already set to 3, skipping NT setup...");
218*c2e0c6b5SAndroid Build Coastguard Worker       return 1;
219*c2e0c6b5SAndroid Build Coastguard Worker     }
220*c2e0c6b5SAndroid Build Coastguard Worker 
221*c2e0c6b5SAndroid Build Coastguard Worker   /* On NT-based systems issue ProcessUserModeIOPL syscall which changes IOPL to 3. */
222*c2e0c6b5SAndroid Build Coastguard Worker   if (!SetProcessUserModeIOPL())
223*c2e0c6b5SAndroid Build Coastguard Worker     {
224*c2e0c6b5SAndroid Build Coastguard Worker       DWORD error = GetLastError();
225*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("NT ProcessUserModeIOPL call failed: %s.", error == ERROR_INVALID_FUNCTION ? "Call is not supported" : win32_strerror(error));
226*c2e0c6b5SAndroid Build Coastguard Worker       return 0;
227*c2e0c6b5SAndroid Build Coastguard Worker     }
228*c2e0c6b5SAndroid Build Coastguard Worker 
229*c2e0c6b5SAndroid Build Coastguard Worker   a->debug("NT ProcessUserModeIOPL call succeeded...");
230*c2e0c6b5SAndroid Build Coastguard Worker   return 1;
231*c2e0c6b5SAndroid Build Coastguard Worker }
232*c2e0c6b5SAndroid Build Coastguard Worker 
233*c2e0c6b5SAndroid Build Coastguard Worker static inline void
intel_cleanup_io(struct pci_access * a UNUSED)234*c2e0c6b5SAndroid Build Coastguard Worker intel_cleanup_io(struct pci_access *a UNUSED)
235*c2e0c6b5SAndroid Build Coastguard Worker {
236*c2e0c6b5SAndroid Build Coastguard Worker   /*
237*c2e0c6b5SAndroid Build Coastguard Worker    * 16/32-bit non-NT systems do not use any special setup and on NT-based
238*c2e0c6b5SAndroid Build Coastguard Worker    * systems ProcessUserModeIOPL permanently changes IOPL to 3 for the current
239*c2e0c6b5SAndroid Build Coastguard Worker    * NT process, no revert for current process is possible.
240*c2e0c6b5SAndroid Build Coastguard Worker    */
241*c2e0c6b5SAndroid Build Coastguard Worker }
242*c2e0c6b5SAndroid Build Coastguard Worker 
intel_io_lock(void)243*c2e0c6b5SAndroid Build Coastguard Worker static inline void intel_io_lock(void)
244*c2e0c6b5SAndroid Build Coastguard Worker {
245*c2e0c6b5SAndroid Build Coastguard Worker }
246*c2e0c6b5SAndroid Build Coastguard Worker 
intel_io_unlock(void)247*c2e0c6b5SAndroid Build Coastguard Worker static inline void intel_io_unlock(void)
248*c2e0c6b5SAndroid Build Coastguard Worker {
249*c2e0c6b5SAndroid Build Coastguard Worker }
250