uterm: monitor: mark DRM-fbdev devices as such
Most DRM drivers also provide a legacy fbdev device so fbcon can pick it up (and more importantly, we get kernel panics on it). However, as an application developer, I don't want to use two devices which drive the same physical hardware. This marks all such DRM fbdev devices as FBDEV_DRM so kmscon doesn't pick them up automatically. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
parent
ed969b99a8
commit
02ddaaeb9f
@ -373,6 +373,7 @@ enum uterm_monitor_event_type {
|
|||||||
enum uterm_monitor_dev_type {
|
enum uterm_monitor_dev_type {
|
||||||
UTERM_MONITOR_DRM,
|
UTERM_MONITOR_DRM,
|
||||||
UTERM_MONITOR_FBDEV,
|
UTERM_MONITOR_FBDEV,
|
||||||
|
UTERM_MONITOR_FBDEV_DRM,
|
||||||
UTERM_MONITOR_INPUT,
|
UTERM_MONITOR_INPUT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,9 +34,12 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <libudev.h>
|
#include <libudev.h>
|
||||||
|
#include <linux/fb.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "shl_dlist.h"
|
#include "shl_dlist.h"
|
||||||
#include "uterm.h"
|
#include "uterm.h"
|
||||||
@ -389,6 +392,56 @@ static int get_fb_id(struct udev_device *dev)
|
|||||||
return devnum;
|
return devnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Nearly all DRM drivers do also create fbdev nodes which refer to the same
|
||||||
|
* hardware as the DRM devices. So we shouldn't advertise these fbdev nodes as
|
||||||
|
* real devices. Otherwise, the user might use these and the DRM devices
|
||||||
|
* simultaneously, thinking that they deal with two different hardware devices.
|
||||||
|
*
|
||||||
|
* We also report that it is a drm-device if we actually cannot verify that it
|
||||||
|
* is not some DRM device.
|
||||||
|
*/
|
||||||
|
static bool is_drm_fbdev(const char *node)
|
||||||
|
{
|
||||||
|
int fd, ret, len;
|
||||||
|
struct fb_fix_screeninfo finfo;
|
||||||
|
bool res = true;
|
||||||
|
|
||||||
|
fd = open(node, O_RDWR | O_CLOEXEC);
|
||||||
|
if (fd < 0) {
|
||||||
|
log_warning("cannot open fbdev node %s for drm-device verification (%d): %m",
|
||||||
|
node, errno);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ioctl(fd, FBIOGET_FSCREENINFO, &finfo);
|
||||||
|
if (ret) {
|
||||||
|
log_warning("cannot retrieve finfo from fbdev node %s for drm-device verification (%d): %m",
|
||||||
|
node, errno);
|
||||||
|
goto err_close;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: we really need some reliable flag here that tells us that we
|
||||||
|
* are dealing with a DRM device indirectly. Checking for "drmfb" suffix
|
||||||
|
* seems fine, but that may be just luck.
|
||||||
|
* If this turns out to not work reliably, we can also fall back to
|
||||||
|
* checking whether the parent udev device node does also provide a DRM
|
||||||
|
* device. */
|
||||||
|
len = strlen(finfo.id);
|
||||||
|
if (len > 5 && !strcmp(&finfo.id[len - 5], "drmfb"))
|
||||||
|
goto err_close;
|
||||||
|
if (!strcmp(finfo.id, "nouveaufb"))
|
||||||
|
goto err_close;
|
||||||
|
if (!strcmp(finfo.id, "psbfb"))
|
||||||
|
goto err_close;
|
||||||
|
|
||||||
|
res = false;
|
||||||
|
|
||||||
|
err_close:
|
||||||
|
close(fd);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static void monitor_udev_add(struct uterm_monitor *mon,
|
static void monitor_udev_add(struct uterm_monitor *mon,
|
||||||
struct udev_device *dev)
|
struct udev_device *dev)
|
||||||
{
|
{
|
||||||
@ -447,6 +500,9 @@ static void monitor_udev_add(struct uterm_monitor *mon,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sname = udev_device_get_property_value(dev, "ID_SEAT");
|
sname = udev_device_get_property_value(dev, "ID_SEAT");
|
||||||
|
if (is_drm_fbdev(node))
|
||||||
|
type = UTERM_MONITOR_FBDEV_DRM;
|
||||||
|
else
|
||||||
type = UTERM_MONITOR_FBDEV;
|
type = UTERM_MONITOR_FBDEV;
|
||||||
} else if (!strcmp(subs, "input")) {
|
} else if (!strcmp(subs, "input")) {
|
||||||
sysname = udev_device_get_sysname(dev);
|
sysname = udev_device_get_sysname(dev);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user