[mutter] udev: Add helpers to list DRM devices



commit 7b7d881386ffb84e7aa8f4ade09cab570c0e7479
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Thu Jan 10 18:07:12 2019 +0100

    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

 src/backends/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(-)
---
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 <gudev/gudev.h>
 
+#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',


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]