From 7b7d881386ffb84e7aa8f4ade09cab570c0e7479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 10 Jan 2019 18:07:12 +0100 Subject: [PATCH] udev: Add helpers to list DRM devices Will be used to move out some udev related logic when adding GPUs. https://gitlab.gnome.org/GNOME/mutter/issues/548 https://gitlab.gnome.org/GNOME/mutter/merge_requests/525 --- .../native/meta-backend-native-types.h | 26 ++++ src/backends/native/meta-backend-native.c | 2 +- src/backends/native/meta-udev.c | 116 +++++++++++++++++- src/backends/native/meta-udev.h | 11 +- src/meson.build | 1 + 5 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 src/backends/native/meta-backend-native-types.h diff --git a/src/backends/native/meta-backend-native-types.h b/src/backends/native/meta-backend-native-types.h new file mode 100644 index 000000000..3112e915d --- /dev/null +++ b/src/backends/native/meta-backend-native-types.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_BACKEND_NATIVE_TYPES_H +#define META_BACKEND_NATIVE_TYPES_H + +typedef struct _MetaBackendNative MetaBackendNative; + +#endif /* META_BACKEND_NATIVE_TYPES_H */ diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c index 30a5d9906..7bf8d6243 100644 --- a/src/backends/native/meta-backend-native.c +++ b/src/backends/native/meta-backend-native.c @@ -531,7 +531,7 @@ meta_backend_native_initable_init (GInitable *initable, if (!native->launcher) return FALSE; - native->udev = meta_udev_new (); + native->udev = meta_udev_new (native); native->barrier_manager = meta_barrier_manager_native_new (); return initable_parent_iface->init (initable, cancellable, error); diff --git a/src/backends/native/meta-udev.c b/src/backends/native/meta-udev.c index e308e99d9..b36001eac 100644 --- a/src/backends/native/meta-udev.c +++ b/src/backends/native/meta-udev.c @@ -22,6 +22,11 @@ #include "backends/native/meta-udev.h" +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-launcher.h" + +#define DRM_CARD_UDEV_DEVICE_TYPE "drm_minor" + enum { DEVICE_ADDED, @@ -35,6 +40,8 @@ struct _MetaUdev { GObject parent; + MetaBackendNative *backend_native; + GUdevClient *gudev_client; guint uevent_handler_id; @@ -42,6 +49,106 @@ struct _MetaUdev G_DEFINE_TYPE (MetaUdev, meta_udev, G_TYPE_OBJECT) +gboolean +meta_is_udev_device_platform_device (GUdevDevice *device) +{ + g_autoptr (GUdevDevice) platform_device = NULL; + + platform_device = g_udev_device_get_parent_with_subsystem (device, + "platform", + NULL); + return !!platform_device; +} + +gboolean +meta_is_udev_device_boot_vga (GUdevDevice *device) +{ + g_autoptr (GUdevDevice) pci_device = NULL; + + pci_device = g_udev_device_get_parent_with_subsystem (device, "pci", NULL); + if (!pci_device) + return FALSE; + + return g_udev_device_get_sysfs_attr_as_int (pci_device, "boot_vga") == 1; +} + +static gboolean +meta_udev_is_drm_device (MetaUdev *udev, + GUdevDevice *device) +{ + MetaLauncher *launcher = + meta_backend_native_get_launcher (udev->backend_native); + const char *seat_id; + const char *device_type; + const char *device_seat; + + /* Filter out devices that are not character device, like card0-VGA-1. */ + if (g_udev_device_get_device_type (device) != G_UDEV_DEVICE_TYPE_CHAR) + return FALSE; + + device_type = g_udev_device_get_property (device, "DEVTYPE"); + if (g_strcmp0 (device_type, DRM_CARD_UDEV_DEVICE_TYPE) != 0) + return FALSE; + + device_seat = g_udev_device_get_property (device, "ID_SEAT"); + if (!device_seat) + { + /* When ID_SEAT is not set, it means seat0. */ + device_seat = "seat0"; + } + + /* Skip devices that do not belong to our seat. */ + seat_id = meta_launcher_get_seat_id (launcher); + if (g_strcmp0 (seat_id, device_seat)) + return FALSE; + + return TRUE; +} + +GList * +meta_udev_list_drm_devices (MetaUdev *udev, + GError **error) +{ + g_autoptr (GUdevEnumerator) enumerator = NULL; + GList *devices; + GList *l; + + enumerator = g_udev_enumerator_new (udev->gudev_client); + + g_udev_enumerator_add_match_name (enumerator, "card*"); + g_udev_enumerator_add_match_tag (enumerator, "seat"); + + /* + * We need to explicitly match the subsystem for now. + * https://bugzilla.gnome.org/show_bug.cgi?id=773224 + */ + g_udev_enumerator_add_match_subsystem (enumerator, "drm"); + + devices = g_udev_enumerator_execute (enumerator); + if (!devices) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + "No drm devices found"); + return FALSE; + } + + for (l = devices; l;) + { + GUdevDevice *device = l->data; + GList *l_next = l->next; + + if (!meta_udev_is_drm_device (udev, device)) + { + g_object_unref (device); + devices = g_list_delete_link (devices, l); + } + + l = l_next; + } + + return devices; +} + static void on_uevent (GUdevClient *client, const char *action, @@ -64,9 +171,14 @@ meta_udev_get_gudev_client (MetaUdev *udev) } MetaUdev * -meta_udev_new (void) +meta_udev_new (MetaBackendNative *backend_native) { - return g_object_new (META_TYPE_UDEV, NULL); + MetaUdev *udev; + + udev = g_object_new (META_TYPE_UDEV, NULL); + udev->backend_native = backend_native; + + return udev; } static void diff --git a/src/backends/native/meta-udev.h b/src/backends/native/meta-udev.h index c407997ed..4618114f4 100644 --- a/src/backends/native/meta-udev.h +++ b/src/backends/native/meta-udev.h @@ -23,11 +23,20 @@ #include +#include "backends/native/meta-backend-native-types.h" + #define META_TYPE_UDEV (meta_udev_get_type ()) G_DECLARE_FINAL_TYPE (MetaUdev, meta_udev, META, UDEV, GObject) GUdevClient * meta_udev_get_gudev_client (MetaUdev *udev); -MetaUdev * meta_udev_new (void); +gboolean meta_is_udev_device_platform_device (GUdevDevice *device); + +gboolean meta_is_udev_device_boot_vga (GUdevDevice *device); + +GList * meta_udev_list_drm_devices (MetaUdev *udev, + GError **error); + +MetaUdev * meta_udev_new (MetaBackendNative *backend_native); #endif /* META_UDEV_H */ diff --git a/src/meson.build b/src/meson.build index 4341d347f..22516d868 100644 --- a/src/meson.build +++ b/src/meson.build @@ -569,6 +569,7 @@ if have_native_backend 'backends/native/meta-backend-native.c', 'backends/native/meta-backend-native.h', 'backends/native/meta-backend-native-private.h', + 'backends/native/meta-backend-native-types.h', 'backends/native/meta-barrier-native.c', 'backends/native/meta-barrier-native.h', 'backends/native/meta-clutter-backend-native.c',