aboutsummaryrefslogtreecommitdiff
path: root/www/chromium/files/patch-third__party_angle_src_gpu__info__util_SystemInfo__libpci.cpp
blob: 18c36e1708af2cf88026d7f504c9c8b0d9913626 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
--- third_party/angle/src/gpu_info_util/SystemInfo_libpci.cpp.orig	2020-11-13 06:42:14 UTC
+++ third_party/angle/src/gpu_info_util/SystemInfo_libpci.cpp
@@ -12,6 +12,11 @@
 #include <pci/pci.h>
 #include <unistd.h>
 
+#if defined(__FreeBSD__)
+#include <fcntl.h>
+#include <sys/pciio.h>
+#endif
+
 #include "common/angleutils.h"
 #include "common/debug.h"
 
@@ -82,6 +87,75 @@ struct LibPCI : private angle::NonCopyable
 };
 
 }  // anonymous namespace
+
+#if defined(__FreeBSD__)
+// Adds an entry per PCI GPU found and fills the device and vendor ID.
+bool GetPCIDevicesFreeBSD(std::vector<GPUDeviceInfo> *devices)
+{
+    int fd;
+    struct pci_conf_io conf;
+    struct pci_conf *matches;
+    uint32_t offset = 0;
+
+    fd = open("/dev/pci", O_RDONLY);
+    if (fd < 0)
+        return false;
+
+    matches = new struct pci_conf[32];
+    conf.generation = 0;
+    do {
+        conf.pat_buf_len = 0;
+        conf.num_patterns = 0;
+        conf.patterns = NULL;
+        conf.match_buf_len = 32 * sizeof(struct pci_conf);
+        conf.num_matches = 32;
+        conf.matches = matches;
+        conf.offset = offset;
+        conf.status = PCI_GETCONF_ERROR;
+        if (ioctl(fd, PCIOCGETCONF, &conf) < 0) {
+            if (errno == ENODEV)
+                break;
+        }
+        /* PCI_GETCONF_LIST_CHANGED would require us to start over. */
+        if (conf.status == PCI_GETCONF_ERROR || conf.status == PCI_GETCONF_LIST_CHANGED) {
+            break;
+        }
+
+        for (unsigned int i = 0; i < conf.num_matches; i++) {
+            uint16_t device_class = (matches[i].pc_class << 8) |  matches[i].pc_subclass;
+
+            // Skip non-GPU devices
+            switch (device_class)
+            {
+                case PCI_CLASS_DISPLAY_VGA:
+                case PCI_CLASS_DISPLAY_XGA:
+                case PCI_CLASS_DISPLAY_3D:
+                    break;
+                default:
+                    continue;
+            }
+
+            // Skip unknown devices
+            if (matches[i].pc_vendor == 0 || matches[i].pc_device == 0) {
+                continue;
+            }
+
+            GPUDeviceInfo info;
+            info.vendorId = matches[i].pc_vendor;
+            info.deviceId = matches[i].pc_device;
+
+            devices->push_back(info);
+        }
+        offset += conf.num_matches;
+    } while (conf.status == PCI_GETCONF_MORE_DEVS);
+
+    delete[] matches;
+
+    close(fd);
+
+    return true;
+}
+#endif
 
 // Adds an entry per PCI GPU found and fills the device and vendor ID.
 bool GetPCIDevicesWithLibPCI(std::vector<GPUDeviceInfo> *devices)