uterm: monitor: report primary GPUs to caller
authorDavid Herrmann <dh.herrmann@googlemail.com>
Sat, 27 Oct 2012 11:55:54 +0000 (13:55 +0200)
committerDavid Herrmann <dh.herrmann@googlemail.com>
Sat, 27 Oct 2012 11:55:54 +0000 (13:55 +0200)
We check every DRM GPU now whether it matches the primary PCI GPU. If it
does, we set a new UTERM_MONITOR_PRIMARY flag for the device.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
src/uterm.h
src/uterm_monitor.c
src/uterm_video.h
src/uterm_video_drm.c

index 2f7671d..17ffd0f 100644 (file)
@@ -402,6 +402,7 @@ enum uterm_monitor_dev_type {
 
 enum uterm_monitor_dev_flag {
        UTERM_MONITOR_DRM_BACKED        = 0x01,
+       UTERM_MONITOR_PRIMARY           = 0x02,
 };
 
 struct uterm_monitor_event {
index 8d4a750..8480a9f 100644 (file)
@@ -44,6 +44,7 @@
 #include "shl_dlist.h"
 #include "uterm.h"
 #include "uterm_pci.h"
+#include "uterm_video.h"
 
 #ifdef BUILD_ENABLE_MULTI_SEAT
        #include <systemd/sd-login.h>
@@ -450,6 +451,39 @@ err_close:
        return res;
 }
 
+static bool is_drm_primary(struct uterm_monitor *mon, const char *node)
+{
+       int fd;
+       char *id;
+       bool res;
+
+       if (!mon->pci_primary_id)
+               return false;
+
+       fd = open(node, O_RDWR | O_CLOEXEC);
+       if (fd < 0) {
+               log_warning("cannot open DRM device %s for primary-detection (%d): %m",
+                           node, errno);
+               return false;
+       }
+
+       id = video_drm_get_id(fd);
+       if (!id) {
+               log_warning("cannot get bus-id for DRM device %s (%d): %m",
+                           node, errno);
+               close(fd);
+               return false;
+       }
+
+       close(fd);
+       res = !strcmp(id, mon->pci_primary_id);
+       video_drm_free_id(id);
+
+       if (res)
+               log_debug("DRM device %s is primary PCI GPU", node);
+       return res;
+}
+
 static void monitor_udev_add(struct uterm_monitor *mon,
                                struct udev_device *dev)
 {
@@ -496,6 +530,8 @@ static void monitor_udev_add(struct uterm_monitor *mon,
                sname = udev_device_get_property_value(dev, "ID_SEAT");
                type = UTERM_MONITOR_DRM;
                flags = 0;
+               if (is_drm_primary(mon, node))
+                       flags |= UTERM_MONITOR_PRIMARY;
        } else if (!strcmp(subs, "graphics")) {
 #ifdef BUILD_ENABLE_MULTI_SEAT
                if (udev_device_has_tag(dev, "seat") != 1) {
index 1fa8c16..9ef3e2c 100644 (file)
@@ -418,4 +418,22 @@ static inline int video_do_use(struct uterm_video *video)
        return VIDEO_CALL(video->ops->use, -EOPNOTSUPP, video);
 }
 
+#ifdef BUILD_ENABLE_VIDEO_DRM
+
+char *video_drm_get_id(int fd);
+void video_drm_free_id(char *id);
+
+#else
+
+static inline char *video_drm_get_id(int fd)
+{
+       return NULL;
+}
+
+static inline void video_drm_free_id(char *id)
+{
+}
+
+#endif
+
 #endif /* UTERM_VIDEO_H */
index a54b603..6a17cdd 100644 (file)
@@ -1251,6 +1251,22 @@ static int video_wake_up(struct uterm_video *video)
        return 0;
 }
 
+char *video_drm_get_id(int fd)
+{
+       if (fd < 0)
+               return NULL;
+
+       return drmGetBusid(fd);
+}
+
+void video_drm_free_id(char *id)
+{
+       if (!id)
+               return;
+
+       drmFreeBusid(id);
+}
+
 const struct mode_ops drm_mode_ops = {
        .init = NULL,
        .destroy = NULL,