]> mj.ucw.cz Git - pciutils.git/blob - lib/i386-io-linux.h
CXL3.0: Add DVSEC CXLCtrl3 and missing CXLCtl2
[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.
7  */
8
9 #include <sys/io.h>
10 #include <errno.h>
11
12 static int ioperm_enabled;
13 static int iopl_enabled;
14
15 static int
16 intel_setup_io(struct pci_access *a UNUSED)
17 {
18   if (ioperm_enabled || iopl_enabled)
19     return 1;
20
21   /*
22    * Before Linux 2.6.8, only the first 0x3ff I/O ports permissions can be
23    * modified via ioperm(). Since 2.6.8 all ports are supported.
24    * Since Linux 5.5, EFLAGS-based iopl() implementation was removed and
25    * replaced by new TSS-IOPB-map-all-based emulator. Before Linux 5.5,
26    * EFLAGS-based iopl() allowed userspace to enable/disable interrupts,
27    * which is dangerous. So prefer usage of ioperm() and fallback to iopl().
28    */
29   if (ioperm(0xcf8, 8, 1) < 0) /* conf1 + conf2 ports */
30     {
31       if (errno == EINVAL) /* ioperm() unsupported */
32         {
33           if (iopl(3) < 0)
34             return 0;
35           iopl_enabled = 1;
36           return 1;
37         }
38       return 0;
39     }
40   if (ioperm(0xc000, 0xfff, 1) < 0) /* remaining conf2 ports */
41     {
42       ioperm(0xcf8, 8, 0);
43       return 0;
44     }
45
46   ioperm_enabled = 1;
47   return 1;
48 }
49
50 static inline void
51 intel_cleanup_io(struct pci_access *a UNUSED)
52 {
53   if (ioperm_enabled)
54     {
55       ioperm(0xcf8, 8, 0);
56       ioperm(0xc000, 0xfff, 0);
57       ioperm_enabled = 0;
58     }
59
60   if (iopl_enabled)
61     {
62       iopl(0);
63       iopl_enabled = 0;
64     }
65 }
66
67 static inline void intel_io_lock(void)
68 {
69 }
70
71 static inline void intel_io_unlock(void)
72 {
73 }