aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/config/udev.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/config/udev.c')
-rw-r--r--xorg-server/config/udev.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/xorg-server/config/udev.c b/xorg-server/config/udev.c
index 1995184f3..5297b9009 100644
--- a/xorg-server/config/udev.c
+++ b/xorg-server/config/udev.c
@@ -52,6 +52,12 @@
static struct udev_monitor *udev_monitor;
+#ifdef CONFIG_UDEV_KMS
+static Bool
+config_udev_odev_setup_attribs(const char *path, const char *syspath,
+ config_odev_probe_proc_ptr probe_callback);
+#endif
+
static void
device_added(struct udev_device *udev_device)
{
@@ -85,6 +91,20 @@ device_added(struct udev_device *udev_device)
if (!SeatId && strcmp(dev_seat, "seat0"))
return;
+#ifdef CONFIG_UDEV_KMS
+ if (!strcmp(udev_device_get_subsystem(udev_device), "drm")) {
+ const char *sysname = udev_device_get_sysname(udev_device);
+
+ if (strncmp(sysname, "card", 4) != 0)
+ return;
+
+ LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n", path);
+
+ config_udev_odev_setup_attribs(path, syspath, NewGPUDeviceRequest);
+ return;
+ }
+#endif
+
if (!udev_device_get_property_value(udev_device, "ID_INPUT")) {
LogMessageVerb(X_INFO, 10,
"config/udev: ignoring device %s without "
@@ -240,6 +260,22 @@ device_removed(struct udev_device *device)
char *value;
const char *syspath = udev_device_get_syspath(device);
+#ifdef CONFIG_UDEV_KMS
+ if (!strcmp(udev_device_get_subsystem(device), "drm")) {
+ const char *sysname = udev_device_get_sysname(device);
+ const char *path = udev_device_get_devnode(device);
+
+ if (strncmp(sysname,"card", 4) != 0)
+ return;
+ ErrorF("removing GPU device %s %d\n", syspath, path);
+ if (!path)
+ return;
+
+ config_udev_odev_setup_attribs(path, syspath, DeleteGPUDeviceRequest);
+ return;
+ }
+#endif
+
if (asprintf(&value, "udev:%s", syspath) == -1)
return;
@@ -296,6 +332,9 @@ config_udev_pre_init(void)
udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "input",
NULL);
udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "tty", NULL); /* For Wacom serial devices */
+#ifdef CONFIG_UDEV_KMS
+ udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "drm", NULL); /* For output GPU devices */
+#endif
#ifdef HAVE_UDEV_MONITOR_FILTER_ADD_MATCH_TAG
if (SeatId && strcmp(SeatId, "seat0"))
@@ -322,6 +361,9 @@ config_udev_init(void)
udev_enumerate_add_match_subsystem(enumerate, "input");
udev_enumerate_add_match_subsystem(enumerate, "tty");
+#ifdef CONFIG_UDEV_KMS
+ udev_enumerate_add_match_subsystem(enumerate, "drm");
+#endif
#ifdef HAVE_UDEV_ENUMERATE_ADD_MATCH_TAG
if (SeatId && strcmp(SeatId, "seat0"))
@@ -366,3 +408,72 @@ config_udev_fini(void)
udev_monitor = NULL;
udev_unref(udev);
}
+
+#ifdef CONFIG_UDEV_KMS
+
+static Bool
+config_udev_odev_setup_attribs(const char *path, const char *syspath,
+ config_odev_probe_proc_ptr probe_callback)
+{
+ struct OdevAttributes *attribs = config_odev_allocate_attribute_list();
+ int ret;
+
+ if (!attribs)
+ return FALSE;
+
+ ret = config_odev_add_attribute(attribs, ODEV_ATTRIB_PATH, path);
+ if (ret == FALSE)
+ goto fail;
+
+ ret = config_odev_add_attribute(attribs, ODEV_ATTRIB_SYSPATH, syspath);
+ if (ret == FALSE)
+ goto fail;
+
+ /* ownership of attribs is passed to probe layer */
+ probe_callback(attribs);
+ return TRUE;
+fail:
+ config_odev_free_attributes(attribs);
+ free(attribs);
+ return FALSE;
+}
+
+void
+config_udev_odev_probe(config_odev_probe_proc_ptr probe_callback)
+{
+ struct udev *udev;
+ struct udev_enumerate *enumerate;
+ struct udev_list_entry *devices, *device;
+
+ udev = udev_monitor_get_udev(udev_monitor);
+ enumerate = udev_enumerate_new(udev);
+ if (!enumerate)
+ return;
+
+ udev_enumerate_add_match_subsystem(enumerate, "drm");
+ udev_enumerate_add_match_sysname(enumerate, "card[0-9]*");
+ udev_enumerate_scan_devices(enumerate);
+ devices = udev_enumerate_get_list_entry(enumerate);
+ udev_list_entry_foreach(device, devices) {
+ const char *syspath = udev_list_entry_get_name(device);
+ struct udev_device *udev_device = udev_device_new_from_syspath(udev, syspath);
+ const char *path = udev_device_get_devnode(udev_device);
+ const char *sysname = udev_device_get_sysname(udev_device);
+
+ if (!path || !syspath)
+ goto no_probe;
+ else if (strcmp(udev_device_get_subsystem(udev_device), "drm") != 0)
+ goto no_probe;
+ else if (strncmp(sysname, "card", 4) != 0)
+ goto no_probe;
+
+ config_udev_odev_setup_attribs(path, syspath, probe_callback);
+
+ no_probe:
+ udev_device_unref(udev_device);
+ }
+ udev_enumerate_unref(enumerate);
+ return;
+}
+#endif
+