]> mj.ucw.cz Git - pciutils.git/blob - lib/i386-io-linux.h
lib: fixup DOE status register bit
[pciutils.git] / lib / i386-io-linux.h
1 /*
2  *      The PCI Library -- Access to i386 I/O ports on Linux
3  *
4  *      Copyright (c) 1997--2006 Martin Mares <mj@ucw.cz>
5  *
6  *      Can be freely distributed and used under the terms of the GNU GPL v2+
7  *
8  *      SPDX-License-Identifier: GPL-2.0-or-later
9  */
10
11 #include <sys/io.h>
12 #include <errno.h>
13
14 static int ioperm_enabled;
15 static int iopl_enabled;
16
17 static int
18 intel_setup_io(struct pci_access *a UNUSED)
19 {
20   if (ioperm_enabled || iopl_enabled)
21     return 1;
22
23   /*
24    * Before Linux 2.6.8, only the first 0x3ff I/O ports permissions can be
25    * modified via ioperm(). Since 2.6.8 all ports are supported.
26    * Since Linux 5.5, EFLAGS-based iopl() implementation was removed and
27    * replaced by new TSS-IOPB-map-all-based emulator. Before Linux 5.5,
28    * EFLAGS-based iopl() allowed userspace to enable/disable interrupts,
29    * which is dangerous. So prefer usage of ioperm() and fallback to iopl().
30    */
31   if (ioperm(0xcf8, 8, 1) < 0) /* conf1 + conf2 ports */
32     {
33       if (errno == EINVAL) /* ioperm() unsupported */
34         {
35           if (iopl(3) < 0)
36             return 0;
37           iopl_enabled = 1;
38           return 1;
39         }
40       return 0;
41     }
42   if (ioperm(0xc000, 0xfff, 1) < 0) /* remaining conf2 ports */
43     {
44       ioperm(0xcf8, 8, 0);
45       return 0;
46     }
47
48   ioperm_enabled = 1;
49   return 1;
50 }
51
52 static inline void
53 intel_cleanup_io(struct pci_access *a UNUSED)
54 {
55   if (ioperm_enabled)
56     {
57       ioperm(0xcf8, 8, 0);
58       ioperm(0xc000, 0xfff, 0);
59       ioperm_enabled = 0;
60     }
61
62   if (iopl_enabled)
63     {
64       iopl(0);
65       iopl_enabled = 0;
66     }
67 }
68
69 static inline void intel_io_lock(void)
70 {
71 }
72
73 static inline void intel_io_unlock(void)
74 {
75 }