38f5b257400ad99193d03671ede6e2288663b78b
[mesa.git] / src / egl / drivers / dri2 / common.c
1 #include <stdio.h>
2 #include <string.h>
3
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <unistd.h>
7
8 #include "egl_dri2.h"
9
10 #ifdef HAVE_LIBUDEV
11
12 #define DRIVER_MAP_DRI2_ONLY
13 #include "pci_ids/pci_id_driver_map.h"
14
15 #include <libudev.h>
16
17 static struct udev_device *
18 dri2_udev_device_new_from_fd(struct udev *udev, int fd)
19 {
20 struct udev_device *device;
21 struct stat buf;
22
23 if (fstat(fd, &buf) < 0) {
24 _eglLog(_EGL_WARNING, "EGL-DRI2: failed to stat fd %d", fd);
25 return NULL;
26 }
27
28 device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev);
29 if (device == NULL) {
30 _eglLog(_EGL_WARNING,
31 "EGL-DRI2: could not create udev device for fd %d", fd);
32 return NULL;
33 }
34
35 return device;
36 }
37
38 char *
39 dri2_get_device_name_for_fd(int fd)
40 {
41 struct udev *udev;
42 struct udev_device *device;
43 const char *const_device_name;
44 char *device_name = NULL;
45
46 udev = udev_new();
47 device = dri2_udev_device_new_from_fd(udev, fd);
48 if (device == NULL)
49 return NULL;
50
51 const_device_name = udev_device_get_devnode(device);
52 if (!const_device_name)
53 goto out;
54 device_name = strdup(const_device_name);
55
56 out:
57 udev_device_unref(device);
58 udev_unref(udev);
59
60 return device_name;
61 }
62
63 char *
64 dri2_get_driver_for_fd(int fd)
65 {
66 struct udev *udev;
67 struct udev_device *device, *parent;
68 const char *pci_id;
69 char *driver = NULL;
70 int vendor_id, chip_id, i, j;
71
72 udev = udev_new();
73 device = dri2_udev_device_new_from_fd(udev, fd);
74 if (device == NULL)
75 return NULL;
76
77 parent = udev_device_get_parent(device);
78 if (parent == NULL) {
79 _eglLog(_EGL_WARNING, "DRI2: could not get parent device");
80 goto out;
81 }
82
83 pci_id = udev_device_get_property_value(parent, "PCI_ID");
84 if (pci_id == NULL ||
85 sscanf(pci_id, "%x:%x", &vendor_id, &chip_id) != 2) {
86 _eglLog(_EGL_WARNING, "EGL-DRI2: malformed or no PCI ID");
87 goto out;
88 }
89
90 for (i = 0; driver_map[i].driver; i++) {
91 if (vendor_id != driver_map[i].vendor_id)
92 continue;
93 if (driver_map[i].num_chips_ids == -1) {
94 driver = strdup(driver_map[i].driver);
95 _eglLog(_EGL_DEBUG, "pci id for %d: %04x:%04x, driver %s",
96 fd, vendor_id, chip_id, driver);
97 goto out;
98 }
99
100 for (j = 0; j < driver_map[i].num_chips_ids; j++)
101 if (driver_map[i].chip_ids[j] == chip_id) {
102 driver = strdup(driver_map[i].driver);
103 _eglLog(_EGL_DEBUG, "pci id for %d: %04x:%04x, driver %s",
104 fd, vendor_id, chip_id, driver);
105 goto out;
106 }
107 }
108
109 out:
110 udev_device_unref(device);
111 udev_unref(udev);
112
113 return driver;
114 }
115
116 #endif /* HAVE_LIBUDEV */