Commit 0816e8fc authored by Adam Jackson's avatar Adam Jackson

linux: Make platform device probe less fragile

At the point where xf86BusProbe runs we haven't yet taken our own VT,
which means we can't perform drm "master" operations on the device. This
is tragic, because we need master to fish the bus id string out of the
kernel, which we can only do after drmSetInterfaceVersion, which for
some reason stores that string on the device not the file handle and
thus needs master access.

Fortunately we know the format of the busid string, and it happens to
almost be the same as the ID_PATH variable from udev. Use that instead
and stop calling drmSetInterfaceVersion.
Reviewed-by: Peter Hutterer's avatarPeter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Adam Jackson's avatarAdam Jackson <ajax@redhat.com>
parent 71703e4e
Pipeline #5982 passed with stage
in 3 minutes and 9 seconds
......@@ -56,7 +56,7 @@ static struct udev_monitor *udev_monitor;
#ifdef CONFIG_UDEV_KMS
static void
config_udev_odev_setup_attribs(const char *path, const char *syspath,
config_udev_odev_setup_attribs(struct udev_device *udev_device, const char *path, const char *syspath,
int major, int minor,
config_odev_probe_proc_ptr probe_callback);
#endif
......@@ -128,7 +128,7 @@ device_added(struct udev_device *udev_device)
LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n", path);
config_udev_odev_setup_attribs(path, syspath, major(devnum),
config_udev_odev_setup_attribs(udev_device, path, syspath, major(devnum),
minor(devnum), NewGPUDeviceRequest);
return;
}
......@@ -322,7 +322,7 @@ device_removed(struct udev_device *device)
LogMessage(X_INFO, "config/udev: removing GPU device %s %s\n",
syspath, path);
config_udev_odev_setup_attribs(path, syspath, major(devnum),
config_udev_odev_setup_attribs(device, path, syspath, major(devnum),
minor(devnum), DeleteGPUDeviceRequest);
/* Retry vtenter after a drm node removal */
systemd_logind_vtenter();
......@@ -465,17 +465,24 @@ config_udev_fini(void)
#ifdef CONFIG_UDEV_KMS
static void
config_udev_odev_setup_attribs(const char *path, const char *syspath,
config_udev_odev_setup_attribs(struct udev_device *udev_device, const char *path, const char *syspath,
int major, int minor,
config_odev_probe_proc_ptr probe_callback)
{
struct OdevAttributes *attribs = config_odev_allocate_attributes();
const char *value;
attribs->path = XNFstrdup(path);
attribs->syspath = XNFstrdup(syspath);
attribs->major = major;
attribs->minor = minor;
value = udev_device_get_property_value(udev_device, "ID_PATH");
if (value && !strncmp(value, "pci-", 4)) {
attribs->busid = XNFstrdup(value);
attribs->busid[3] = ':';
}
/* ownership of attribs is passed to probe layer */
probe_callback(attribs);
}
......@@ -516,7 +523,7 @@ config_udev_odev_probe(config_odev_probe_proc_ptr probe_callback)
else if (!check_seat(udev_device))
goto no_probe;
config_udev_odev_setup_attribs(path, syspath, major(devnum),
config_udev_odev_setup_attribs(udev_device, path, syspath, major(devnum),
minor(devnum), probe_callback);
no_probe:
udev_device_unref(udev_device);
......
......@@ -23,13 +23,13 @@
static Bool
get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
{
drmSetVersion sv;
drmVersionPtr v;
char *buf;
int fd;
int err = 0;
Bool paused, server_fd = FALSE;
LogMessage(X_INFO, "Platform probe for %s\n", attribs->syspath);
fd = systemd_logind_take_fd(attribs->major, attribs->minor, path, &paused);
if (fd != -1) {
if (paused) {
......@@ -48,18 +48,6 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
if (fd == -1)
return FALSE;
sv.drm_di_major = 1;
sv.drm_di_minor = 4;
sv.drm_dd_major = -1; /* Don't care */
sv.drm_dd_minor = -1; /* Don't care */
err = drmSetInterfaceVersion(fd, &sv);
if (err) {
xf86Msg(X_ERROR, "%s: failed to set DRM interface version 1.4: %s\n",
path, strerror(-err));
goto out;
}
/* for a delayed probe we've already added the device */
if (delayed_index == -1) {
xf86_add_platform_device(attribs, FALSE);
......@@ -69,10 +57,6 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
if (server_fd)
xf86_platform_devices[delayed_index].flags |= XF86_PDEV_SERVER_FD;
buf = drmGetBusid(fd);
xf86_platform_odev_attributes(delayed_index)->busid = XNFstrdup(buf);
drmFreeBusid(buf);
v = drmGetVersion(fd);
if (!v) {
xf86Msg(X_ERROR, "%s: failed to query DRM version\n", path);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment