From 881026ad315a673763682499c041d6c93e369bca Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sat, 27 Oct 2012 13:55:54 +0200 Subject: [PATCH] uterm: monitor: report primary GPUs to caller 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 --- src/uterm.h | 1 + src/uterm_monitor.c | 36 ++++++++++++++++++++++++++++++++++++ src/uterm_video.h | 18 ++++++++++++++++++ src/uterm_video_drm.c | 16 ++++++++++++++++ 4 files changed, 71 insertions(+) diff --git a/src/uterm.h b/src/uterm.h index 2f7671d..17ffd0f 100644 --- a/src/uterm.h +++ b/src/uterm.h @@ -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 { diff --git a/src/uterm_monitor.c b/src/uterm_monitor.c index 8d4a750..8480a9f 100644 --- a/src/uterm_monitor.c +++ b/src/uterm_monitor.c @@ -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 @@ -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) { diff --git a/src/uterm_video.h b/src/uterm_video.h index 1fa8c16..9ef3e2c 100644 --- a/src/uterm_video.h +++ b/src/uterm_video.h @@ -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 */ diff --git a/src/uterm_video_drm.c b/src/uterm_video_drm.c index a54b603..6a17cdd 100644 --- a/src/uterm_video_drm.c +++ b/src/uterm_video_drm.c @@ -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,