Blame SOURCES/ignore-early-fb-devices.patch

ff86aa
From 10e686c2128bde0e70e7c137191dbe004d2f46fd Mon Sep 17 00:00:00 2001
ff86aa
From: Ray Strode <rstrode@redhat.com>
ff86aa
Date: Mon, 3 Mar 2014 13:27:30 -0500
ff86aa
Subject: [PATCH 1/2] device-manager: handle drm hotplug separately from
ff86aa
 /dev/fb
ff86aa
ff86aa
Right now, we piggyback off fb subsystem events to know whether or
ff86aa
not a drm device is hotplugged (since all drm devices have fb devices
ff86aa
for backward compat).
ff86aa
ff86aa
This commit makes drm and fb processing more independent, so we don't
ff86aa
rely on the compat device being available for drm hotplug to work..
ff86aa
---
ff86aa
 src/libply-splash-core/ply-device-manager.c | 182 ++++++++++++++--------------
ff86aa
 1 file changed, 89 insertions(+), 93 deletions(-)
ff86aa
ff86aa
diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c
ff86aa
index 36e814d..25f7d54 100644
ff86aa
--- a/src/libply-splash-core/ply-device-manager.c
ff86aa
+++ b/src/libply-splash-core/ply-device-manager.c
ff86aa
@@ -11,60 +11,63 @@
ff86aa
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
ff86aa
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
ff86aa
  * GNU General Public License for more details.
ff86aa
  *
ff86aa
  * You should have received a copy of the GNU General Public License
ff86aa
  * along with this program; if not, write to the Free Software
ff86aa
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
ff86aa
  * 02111-1307, USA.
ff86aa
  */
ff86aa
 #include "config.h"
ff86aa
 #include "ply-device-manager.h"
ff86aa
 
ff86aa
 #include <assert.h>
ff86aa
 #include <fcntl.h>
ff86aa
 #include <stdbool.h>
ff86aa
 #include <stdlib.h>
ff86aa
 #include <stdio.h>
ff86aa
 #include <string.h>
ff86aa
 #include <sys/inotify.h>
ff86aa
 #include <sys/stat.h>
ff86aa
 #include <sys/types.h>
ff86aa
 
ff86aa
 #include <libudev.h>
ff86aa
 
ff86aa
 #include "ply-logger.h"
ff86aa
 #include "ply-event-loop.h"
ff86aa
 #include "ply-hashtable.h"
ff86aa
 #include "ply-list.h"
ff86aa
 #include "ply-utils.h"
ff86aa
 
ff86aa
+#define SUBSYSTEM_DRM "drm"
ff86aa
+#define SUBSYSTEM_FRAME_BUFFER "graphics"
ff86aa
+
ff86aa
 static void create_seat_for_terminal_and_renderer_type (ply_device_manager_t *manager,
ff86aa
                                                         const char           *device_path,
ff86aa
                                                         ply_terminal_t       *terminal,
ff86aa
                                                         ply_renderer_type_t   renderer_type);
ff86aa
 struct _ply_device_manager
ff86aa
 {
ff86aa
   ply_device_manager_flags_t  flags;
ff86aa
   ply_event_loop_t           *loop;
ff86aa
   ply_hashtable_t            *terminals;
ff86aa
   ply_terminal_t             *local_console_terminal;
ff86aa
   ply_seat_t                 *local_console_seat;
ff86aa
   ply_list_t                 *seats;
ff86aa
   struct udev                *udev_context;
ff86aa
   struct udev_queue          *udev_queue;
ff86aa
   int                         udev_queue_fd;
ff86aa
   ply_fd_watch_t             *udev_queue_fd_watch;
ff86aa
   struct udev_monitor        *udev_monitor;
ff86aa
 
ff86aa
   ply_seat_added_handler_t    seat_added_handler;
ff86aa
   ply_seat_removed_handler_t  seat_removed_handler;
ff86aa
   void                       *seat_event_handler_data;
ff86aa
 };
ff86aa
 
ff86aa
 static void
ff86aa
 detach_from_event_loop (ply_device_manager_t *manager)
ff86aa
 {
ff86aa
   assert (manager != NULL);
ff86aa
 
ff86aa
   manager->loop = NULL;
ff86aa
 }
ff86aa
@@ -84,342 +87,334 @@ attach_to_event_loop (ply_device_manager_t *manager,
ff86aa
                                  manager);
ff86aa
 }
ff86aa
 
ff86aa
 static bool
ff86aa
 device_is_for_local_console (ply_device_manager_t *manager,
ff86aa
                              struct udev_device   *device)
ff86aa
 {
ff86aa
   const char *device_path;
ff86aa
   struct udev_device *bus_device;
ff86aa
   char *bus_device_path;
ff86aa
   const char *boot_vga;
ff86aa
   bool for_local_console;
ff86aa
 
ff86aa
   /* Look at the associated bus device to see if this card is the
ff86aa
    * card the kernel is using for its console. */
ff86aa
   device_path = udev_device_get_syspath (device);
ff86aa
   asprintf (&bus_device_path, "%s/device", device_path);
ff86aa
   bus_device = udev_device_new_from_syspath (manager->udev_context, bus_device_path);
ff86aa
 
ff86aa
   boot_vga = udev_device_get_sysattr_value (bus_device, "boot_vga");
ff86aa
   free (bus_device_path);
ff86aa
 
ff86aa
   if (boot_vga != NULL && strcmp (boot_vga, "1") == 0)
ff86aa
     for_local_console = true;
ff86aa
   else
ff86aa
     for_local_console = false;
ff86aa
 
ff86aa
   return for_local_console;
ff86aa
 }
ff86aa
 
ff86aa
-static char *
ff86aa
-get_drm_device_node_path_from_fb_device (ply_device_manager_t *manager,
ff86aa
-                                         struct udev_device   *fb_device)
ff86aa
+static bool
ff86aa
+fb_device_has_drm_device (ply_device_manager_t *manager,
ff86aa
+                          struct udev_device   *fb_device)
ff86aa
 {
ff86aa
   struct udev_enumerate *card_matches;
ff86aa
   struct udev_list_entry *card_entry;
ff86aa
   const char *id_path;
ff86aa
-  char *device_node_path = NULL;
ff86aa
+  bool has_drm_device = false;
ff86aa
 
ff86aa
   /* We want to see if the framebuffer is associated with a DRM-capable
ff86aa
    * graphics card, if it is, we'll use the DRM device */
ff86aa
   card_matches = udev_enumerate_new (manager->udev_context);
ff86aa
   udev_enumerate_add_match_is_initialized(card_matches);
ff86aa
   udev_enumerate_add_match_parent (card_matches, udev_device_get_parent (fb_device));
ff86aa
   udev_enumerate_add_match_subsystem (card_matches, "drm");
ff86aa
   id_path = udev_device_get_property_value (fb_device, "ID_PATH");
ff86aa
   udev_enumerate_add_match_property (card_matches, "ID_PATH", id_path);
ff86aa
 
ff86aa
   ply_trace ("trying to find associated drm node for fb device (path: %s)", id_path);
ff86aa
 
ff86aa
   udev_enumerate_scan_devices (card_matches);
ff86aa
 
ff86aa
   /* there should only ever be at most one match so we don't iterate through
ff86aa
    * the list, but just look at the first entry */
ff86aa
   card_entry = udev_enumerate_get_list_entry (card_matches);
ff86aa
 
ff86aa
   if (card_entry != NULL)
ff86aa
     {
ff86aa
       struct udev_device *card_device = NULL;
ff86aa
       const char *card_node;
ff86aa
       const char *card_path;
ff86aa
 
ff86aa
       card_path = udev_list_entry_get_name (card_entry);
ff86aa
       card_device = udev_device_new_from_syspath (manager->udev_context, card_path);
ff86aa
       card_node = udev_device_get_devnode (card_device);
ff86aa
       if (card_node != NULL)
ff86aa
-        device_node_path = strdup (card_node);
ff86aa
+        has_drm_device = true;
ff86aa
       else
ff86aa
         ply_trace ("no card node!");
ff86aa
 
ff86aa
       udev_device_unref (card_device);
ff86aa
     }
ff86aa
   else
ff86aa
     {
ff86aa
       ply_trace ("no card entry!");
ff86aa
     }
ff86aa
 
ff86aa
   udev_enumerate_unref (card_matches);
ff86aa
-  return device_node_path;
ff86aa
+  return has_drm_device;
ff86aa
 }
ff86aa
 
ff86aa
 static void
ff86aa
 create_seat_for_udev_device (ply_device_manager_t *manager,
ff86aa
                              struct udev_device   *device)
ff86aa
 {
ff86aa
   bool for_local_console;
ff86aa
-  char *card_path;
ff86aa
+  const char *device_path;
ff86aa
   ply_terminal_t *terminal = NULL;
ff86aa
 
ff86aa
   for_local_console = device_is_for_local_console (manager, device);
ff86aa
 
ff86aa
   ply_trace ("device is for local console: %s", for_local_console? "yes" : "no");
ff86aa
 
ff86aa
   if (for_local_console)
ff86aa
     terminal = manager->local_console_terminal;
ff86aa
 
ff86aa
-  card_path = get_drm_device_node_path_from_fb_device (manager, device);
ff86aa
+  device_path = udev_device_get_devnode (device);
ff86aa
 
ff86aa
-  if (card_path != NULL)
ff86aa
-    {
ff86aa
-      create_seat_for_terminal_and_renderer_type (manager,
ff86aa
-                                                  card_path,
ff86aa
-                                                  terminal,
ff86aa
-                                                  PLY_RENDERER_TYPE_DRM);
ff86aa
-      free (card_path);
ff86aa
-    }
ff86aa
-  else
ff86aa
+  if (device_path != NULL)
ff86aa
     {
ff86aa
-      const char *fb_device_node_path;
ff86aa
+      const char *subsystem;
ff86aa
+      ply_renderer_type_t renderer_type = PLY_RENDERER_TYPE_NONE;
ff86aa
+
ff86aa
+      subsystem = udev_device_get_subsystem (device);
ff86aa
+
ff86aa
+      if (strcmp (subsystem, SUBSYSTEM_DRM) == 0)
ff86aa
+        {
ff86aa
+          ply_trace ("found DRM device %s", device_path);
ff86aa
+          renderer_type = PLY_RENDERER_TYPE_DRM;
ff86aa
+        }
ff86aa
+      else if (strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0)
ff86aa
+        {
ff86aa
+          ply_trace ("found frame buffer device %s", device_path);
ff86aa
+          if (!fb_device_has_drm_device (manager, device))
ff86aa
+            {
ff86aa
+              renderer_type = PLY_RENDERER_TYPE_FRAME_BUFFER;
ff86aa
+            }
ff86aa
+          else
ff86aa
+            {
ff86aa
+              ply_trace ("ignoring, since there's a DRM device associated with it");
ff86aa
+            }
ff86aa
+        }
ff86aa
 
ff86aa
-      fb_device_node_path = udev_device_get_devnode (device);
ff86aa
-      if (fb_device_node_path != NULL)
ff86aa
+      if (renderer_type != PLY_RENDERER_TYPE_NONE)
ff86aa
         create_seat_for_terminal_and_renderer_type (manager,
ff86aa
-                                                    fb_device_node_path,
ff86aa
+                                                    device_path,
ff86aa
                                                     terminal,
ff86aa
-                                                    PLY_RENDERER_TYPE_FRAME_BUFFER);
ff86aa
+                                                    renderer_type);
ff86aa
     }
ff86aa
 }
ff86aa
 
ff86aa
 static void
ff86aa
 free_seat_from_device_path (ply_device_manager_t *manager,
ff86aa
                             const char           *device_path)
ff86aa
 {
ff86aa
   ply_list_node_t *node;
ff86aa
 
ff86aa
   node = ply_list_get_first_node (manager->seats);
ff86aa
   while (node != NULL)
ff86aa
     {
ff86aa
       ply_seat_t *seat;
ff86aa
       ply_renderer_t *renderer;
ff86aa
       ply_list_node_t *next_node;
ff86aa
       const char *renderer_device_path;
ff86aa
 
ff86aa
       seat = ply_list_node_get_data (node);
ff86aa
       next_node = ply_list_get_next_node (manager->seats, node);
ff86aa
       renderer = ply_seat_get_renderer (seat);
ff86aa
 
ff86aa
       if (renderer != NULL)
ff86aa
         {
ff86aa
           renderer_device_path = ply_renderer_get_device_name (renderer);
ff86aa
 
ff86aa
           if (renderer_device_path != NULL)
ff86aa
             {
ff86aa
               if (strcmp (device_path, renderer_device_path) == 0)
ff86aa
                 {
ff86aa
                   ply_trace ("removing seat associated with %s", device_path);
ff86aa
 
ff86aa
                   if (manager->seat_removed_handler != NULL)
ff86aa
                     manager->seat_removed_handler (manager->seat_event_handler_data, seat);
ff86aa
 
ff86aa
                   ply_seat_free (seat);
ff86aa
                   ply_list_remove_node (manager->seats, node);
ff86aa
                   break;
ff86aa
                 }
ff86aa
             }
ff86aa
         }
ff86aa
 
ff86aa
       node = next_node;
ff86aa
     }
ff86aa
 }
ff86aa
 
ff86aa
 static void
ff86aa
 free_seat_for_udev_device (ply_device_manager_t *manager,
ff86aa
                            struct udev_device   *device)
ff86aa
 {
ff86aa
-  char *card_path;
ff86aa
-
ff86aa
- card_path = get_drm_device_node_path_from_fb_device (manager, device);
ff86aa
-
ff86aa
-  if (card_path != NULL)
ff86aa
-    {
ff86aa
-      free_seat_from_device_path (manager, card_path);
ff86aa
-      free (card_path);
ff86aa
-    }
ff86aa
-  else
ff86aa
-    {
ff86aa
-      const char *fb_device_node_path;
ff86aa
+  const char *device_path;
ff86aa
 
ff86aa
-      fb_device_node_path = udev_device_get_devnode (device);
ff86aa
+  device_path = udev_device_get_devnode (device);
ff86aa
 
ff86aa
-      if (fb_device_node_path != NULL)
ff86aa
-        free_seat_from_device_path (manager, fb_device_node_path);
ff86aa
-    }
ff86aa
+  if (device_path != NULL)
ff86aa
+    free_seat_from_device_path (manager, device_path);
ff86aa
 }
ff86aa
 
ff86aa
 static bool
ff86aa
-scan_graphics_devices (ply_device_manager_t *manager)
ff86aa
+create_seats_for_subsystem (ply_device_manager_t *manager,
ff86aa
+                            const char           *subsystem)
ff86aa
 {
ff86aa
-  struct udev_enumerate *fb_matches;
ff86aa
-  struct udev_list_entry *fb_entry;
ff86aa
+  struct udev_enumerate *matches;
ff86aa
+  struct udev_list_entry *entry;
ff86aa
   bool found_device = false;
ff86aa
 
ff86aa
-  ply_trace ("scanning for graphics devices");
ff86aa
-  /* graphics subsystem is for /dev/fb devices.  kms drivers provide /dev/fb for backward
ff86aa
-   * compatibility, and do so at the end of their initialization, so we can be confident
ff86aa
-   * that when this subsystem is available the drm device is fully initialized */
ff86aa
-  fb_matches = udev_enumerate_new (manager->udev_context);
ff86aa
-  udev_enumerate_add_match_subsystem (fb_matches, "graphics");
ff86aa
-  udev_enumerate_scan_devices (fb_matches);
ff86aa
+  ply_trace ("creating seats for %s devices",
ff86aa
+             strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0?
ff86aa
+             "frame buffer":
ff86aa
+             subsystem);
ff86aa
 
ff86aa
-  udev_list_entry_foreach (fb_entry, udev_enumerate_get_list_entry (fb_matches))
ff86aa
+  matches = udev_enumerate_new (manager->udev_context);
ff86aa
+  udev_enumerate_add_match_subsystem (matches, subsystem);
ff86aa
+  udev_enumerate_scan_devices (matches);
ff86aa
+
ff86aa
+  udev_list_entry_foreach (entry, udev_enumerate_get_list_entry (matches))
ff86aa
     {
ff86aa
-      struct udev_device *fb_device = NULL;
ff86aa
-      const char *fb_path;
ff86aa
+      struct udev_device *device = NULL;
ff86aa
+      const char *path;
ff86aa
 
ff86aa
-      fb_path = udev_list_entry_get_name (fb_entry);
ff86aa
+      path = udev_list_entry_get_name (entry);
ff86aa
 
ff86aa
-      if (fb_path == NULL)
ff86aa
+      if (path == NULL)
ff86aa
         {
ff86aa
-          ply_trace ("fb path was null!");
ff86aa
+          ply_trace ("path was null!");
ff86aa
           continue;
ff86aa
         }
ff86aa
 
ff86aa
-      ply_trace ("found device %s", fb_path);
ff86aa
+      ply_trace ("found device %s", path);
ff86aa
 
ff86aa
-      /* skip virtual fbcon device
ff86aa
-       */
ff86aa
-      if (strcmp (fb_path, "/sys/devices/virtual/graphics/fbcon") == 0)
ff86aa
-        {
ff86aa
-          ply_trace ("ignoring since it's fbcon");
ff86aa
-          continue;
ff86aa
-        }
ff86aa
-
ff86aa
-      fb_device = udev_device_new_from_syspath (manager->udev_context, fb_path);
ff86aa
+      device = udev_device_new_from_syspath (manager->udev_context, path);
ff86aa
 
ff86aa
       /* if device isn't fully initialized, we'll get an add event later
ff86aa
        */
ff86aa
-      if (udev_device_get_is_initialized (fb_device))
ff86aa
+      if (udev_device_get_is_initialized (device))
ff86aa
         {
ff86aa
           ply_trace ("device is initialized");
ff86aa
+
ff86aa
           /* We only care about devices assigned to a (any) seat. Floating
ff86aa
-           * devices should be ignored.  As a side-effect, this conveniently
ff86aa
-           * filters out the fbcon device which we don't care about.
ff86aa
+           * devices should be ignored.
ff86aa
            */
ff86aa
-          if (udev_device_has_tag (fb_device, "seat"))
ff86aa
+          if (udev_device_has_tag (device, "seat"))
ff86aa
             {
ff86aa
-              const char *fb_node;
ff86aa
-              fb_node = udev_device_get_devnode (fb_device);
ff86aa
-              if (fb_node != NULL)
ff86aa
+              const char *node;
ff86aa
+              node = udev_device_get_devnode (device);
ff86aa
+              if (node != NULL)
ff86aa
                 {
ff86aa
-                  ply_trace ("found node %s", fb_node);
ff86aa
+                  ply_trace ("found node %s", node);
ff86aa
                   found_device = true;
ff86aa
-                  create_seat_for_udev_device (manager, fb_device);
ff86aa
+                  create_seat_for_udev_device (manager, device);
ff86aa
                 }
ff86aa
             }
ff86aa
           else
ff86aa
             {
ff86aa
               ply_trace ("device doesn't have a seat tag");
ff86aa
             }
ff86aa
         }
ff86aa
       else
ff86aa
         {
ff86aa
           ply_trace ("it's not initialized");
ff86aa
         }
ff86aa
 
ff86aa
-      udev_device_unref (fb_device);
ff86aa
+      udev_device_unref (device);
ff86aa
     }
ff86aa
 
ff86aa
-  udev_enumerate_unref (fb_matches);
ff86aa
+  udev_enumerate_unref (matches);
ff86aa
 
ff86aa
   return found_device;
ff86aa
 }
ff86aa
 
ff86aa
 static void
ff86aa
-on_udev_graphics_event (ply_device_manager_t *manager)
ff86aa
+on_udev_event (ply_device_manager_t *manager)
ff86aa
 {
ff86aa
   struct udev_device *device;
ff86aa
   const char *action;
ff86aa
 
ff86aa
   device = udev_monitor_receive_device (manager->udev_monitor);
ff86aa
   if (device == NULL)
ff86aa
     return;
ff86aa
 
ff86aa
   action = udev_device_get_action (device);
ff86aa
 
ff86aa
   ply_trace ("got %s event for device %s", action, udev_device_get_sysname (device));
ff86aa
 
ff86aa
   if (action == NULL)
ff86aa
     return;
ff86aa
 
ff86aa
   if (strcmp (action, "add") == 0)
ff86aa
     create_seat_for_udev_device (manager, device);
ff86aa
   else if (strcmp (action, "remove") == 0)
ff86aa
     free_seat_for_udev_device (manager, device);
ff86aa
 
ff86aa
   udev_device_unref (device);
ff86aa
 }
ff86aa
 
ff86aa
 static void
ff86aa
 watch_for_udev_events (ply_device_manager_t *manager)
ff86aa
 {
ff86aa
   int fd;
ff86aa
   assert (manager != NULL);
ff86aa
   assert (manager->udev_monitor == NULL);
ff86aa
 
ff86aa
   ply_trace ("watching for udev graphics device add and remove events");
ff86aa
 
ff86aa
   manager->udev_monitor = udev_monitor_new_from_netlink (manager->udev_context, "udev");
ff86aa
 
ff86aa
-  /* The filter matching here mimics the matching done in scan_graphics_devices.
ff86aa
-   * See the comments in that function, for an explanation of what we're doing.
ff86aa
-   */
ff86aa
-  udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, "graphics", NULL);
ff86aa
+  udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_DRM, NULL);
ff86aa
+  udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_FRAME_BUFFER, NULL);
ff86aa
   udev_monitor_filter_add_match_tag (manager->udev_monitor, "seat");
ff86aa
   udev_monitor_enable_receiving (manager->udev_monitor);
ff86aa
 
ff86aa
   fd = udev_monitor_get_fd (manager->udev_monitor);
ff86aa
   ply_event_loop_watch_fd (manager->loop,
ff86aa
                            fd,
ff86aa
                            PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
ff86aa
                            (ply_event_handler_t)
ff86aa
-                           on_udev_graphics_event,
ff86aa
+                           on_udev_event,
ff86aa
                            NULL,
ff86aa
                            manager);
ff86aa
 }
ff86aa
 
ff86aa
 static void
ff86aa
 free_seats (ply_device_manager_t *manager)
ff86aa
 {
ff86aa
   ply_list_node_t *node;
ff86aa
 
ff86aa
   ply_trace ("removing seats");
ff86aa
   node = ply_list_get_first_node (manager->seats);
ff86aa
   while (node != NULL)
ff86aa
     {
ff86aa
       ply_seat_t *seat;
ff86aa
       ply_list_node_t *next_node;
ff86aa
 
ff86aa
       seat = ply_list_node_get_data (node);
ff86aa
       next_node = ply_list_get_next_node (manager->seats, node);
ff86aa
 
ff86aa
       if (manager->seat_removed_handler != NULL)
ff86aa
         manager->seat_removed_handler (manager->seat_event_handler_data, seat);
ff86aa
 
ff86aa
       ply_seat_free (seat);
ff86aa
       ply_list_remove_node (manager->seats, node);
ff86aa
 
ff86aa
       node = next_node;
ff86aa
     }
ff86aa
 }
ff86aa
 
ff86aa
 static void
ff86aa
@@ -657,77 +652,78 @@ create_seats_from_terminals (ply_device_manager_t *manager)
ff86aa
   int num_consoles;
ff86aa
 
ff86aa
   ply_trace ("checking for consoles");
ff86aa
 
ff86aa
   if (manager->flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES)
ff86aa
     {
ff86aa
       num_consoles = 0;
ff86aa
       ply_trace ("ignoring all consoles but default console because explicitly told to.");
ff86aa
     }
ff86aa
   else
ff86aa
     {
ff86aa
       num_consoles = add_consoles_from_file (manager, "/sys/class/tty/console/active");
ff86aa
 
ff86aa
       if (num_consoles == 0)
ff86aa
         ply_trace ("ignoring all consoles but default console because /sys/class/tty/console/active could not be read");
ff86aa
     }
ff86aa
 
ff86aa
   if (num_consoles > 1)
ff86aa
     {
ff86aa
       ply_trace ("serial consoles detected, managing them with details forced");
ff86aa
       ply_hashtable_foreach (manager->terminals,
ff86aa
                              (ply_hashtable_foreach_func_t *)
ff86aa
                              create_seat_for_terminal,
ff86aa
                              manager);
ff86aa
       return true;
ff86aa
     }
ff86aa
 
ff86aa
   return false;
ff86aa
 }
ff86aa
 
ff86aa
-static bool
ff86aa
+static void
ff86aa
 create_seats_from_udev (ply_device_manager_t *manager)
ff86aa
 {
ff86aa
-  bool found_device;
ff86aa
+  bool found_drm_device, found_fb_device;
ff86aa
 
ff86aa
   ply_trace ("Looking for devices from udev");
ff86aa
-  found_device = scan_graphics_devices (manager);
ff86aa
-  if (!found_device)
ff86aa
-    {
ff86aa
-      ply_trace ("Creating non-graphical seat, since there's no suitable graphics hardware");
ff86aa
-      create_seat_for_terminal_and_renderer_type (manager,
ff86aa
-                                                  ply_terminal_get_name (manager->local_console_terminal),
ff86aa
-                                                  manager->local_console_terminal,
ff86aa
-                                                  PLY_RENDERER_TYPE_NONE);
ff86aa
-    }
ff86aa
 
ff86aa
-  return true;
ff86aa
+  found_drm_device = create_seats_for_subsystem (manager, SUBSYSTEM_DRM);
ff86aa
+  found_fb_device = create_seats_for_subsystem (manager, SUBSYSTEM_FRAME_BUFFER);
ff86aa
+
ff86aa
+  if (found_drm_device || found_fb_device)
ff86aa
+    return;
ff86aa
+
ff86aa
+  ply_trace ("Creating non-graphical seat, since there's no suitable graphics hardware");
ff86aa
+  create_seat_for_terminal_and_renderer_type (manager,
ff86aa
+                                              ply_terminal_get_name (manager->local_console_terminal),
ff86aa
+                                              manager->local_console_terminal,
ff86aa
+                                              PLY_RENDERER_TYPE_NONE);
ff86aa
 }
ff86aa
 
ff86aa
 static void
ff86aa
 create_fallback_seat (ply_device_manager_t *manager)
ff86aa
 {
ff86aa
   create_seat_for_terminal_and_renderer_type (manager,
ff86aa
                                               ply_terminal_get_name (manager->local_console_terminal),
ff86aa
                                               manager->local_console_terminal,
ff86aa
                                               PLY_RENDERER_TYPE_AUTO);
ff86aa
 }
ff86aa
 
ff86aa
 static void
ff86aa
 on_udev_queue_changed (ply_device_manager_t *manager)
ff86aa
 {
ff86aa
 
ff86aa
   if (!udev_queue_get_queue_is_empty (manager->udev_queue))
ff86aa
     return;
ff86aa
 
ff86aa
   ply_trace ("udev coldplug complete");
ff86aa
   ply_event_loop_stop_watching_fd (manager->loop, manager->udev_queue_fd_watch);
ff86aa
   manager->udev_queue_fd_watch = NULL;
ff86aa
   udev_queue_unref (manager->udev_queue);
ff86aa
 
ff86aa
   close (manager->udev_queue_fd);
ff86aa
   manager->udev_queue_fd = -1;
ff86aa
 
ff86aa
   manager->udev_queue = NULL;
ff86aa
 
ff86aa
   create_seats_from_udev (manager);
ff86aa
 }
ff86aa
-- 
ff86aa
1.8.3.1
ff86aa
ff86aa
ff86aa
From 20603c552e7e31f65f6265ed7230ba4bcaf12bf5 Mon Sep 17 00:00:00 2001
ff86aa
From: Ray Strode <rstrode@redhat.com>
ff86aa
Date: Mon, 3 Mar 2014 17:25:44 -0500
ff86aa
Subject: [PATCH 2/2] device-manager: defer /dev/fb compat processing until
ff86aa
 after coldplug
ff86aa
ff86aa
We never want to use a /dev/fb device if a DRM device will work instead
ff86aa
(since it supports multi-monitor, isn't a legacy interface, etc)
ff86aa
ff86aa
Unfortunately, right now plymouthd notices efifb at early start up,
ff86aa
see's there is no DRM device associated with it and chooses it for
ff86aa
the main display, which causes all sort of problems.
ff86aa
ff86aa
This commit defers using /dev/fb devices until after udev settles.
ff86aa
---
ff86aa
 src/libply-splash-core/ply-device-manager.c | 24 +++++++++++++++++++++---
ff86aa
 1 file changed, 21 insertions(+), 3 deletions(-)
ff86aa
ff86aa
diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c
ff86aa
index 25f7d54..d06e1b5 100644
ff86aa
--- a/src/libply-splash-core/ply-device-manager.c
ff86aa
+++ b/src/libply-splash-core/ply-device-manager.c
ff86aa
@@ -161,62 +161,63 @@ fb_device_has_drm_device (ply_device_manager_t *manager,
ff86aa
       ply_trace ("no card entry!");
ff86aa
     }
ff86aa
 
ff86aa
   udev_enumerate_unref (card_matches);
ff86aa
   return has_drm_device;
ff86aa
 }
ff86aa
 
ff86aa
 static void
ff86aa
 create_seat_for_udev_device (ply_device_manager_t *manager,
ff86aa
                              struct udev_device   *device)
ff86aa
 {
ff86aa
   bool for_local_console;
ff86aa
   const char *device_path;
ff86aa
   ply_terminal_t *terminal = NULL;
ff86aa
 
ff86aa
   for_local_console = device_is_for_local_console (manager, device);
ff86aa
 
ff86aa
   ply_trace ("device is for local console: %s", for_local_console? "yes" : "no");
ff86aa
 
ff86aa
   if (for_local_console)
ff86aa
     terminal = manager->local_console_terminal;
ff86aa
 
ff86aa
   device_path = udev_device_get_devnode (device);
ff86aa
 
ff86aa
   if (device_path != NULL)
ff86aa
     {
ff86aa
       const char *subsystem;
ff86aa
       ply_renderer_type_t renderer_type = PLY_RENDERER_TYPE_NONE;
ff86aa
 
ff86aa
       subsystem = udev_device_get_subsystem (device);
ff86aa
+      ply_trace ("device subsystem is %s", subsystem);
ff86aa
 
ff86aa
-      if (strcmp (subsystem, SUBSYSTEM_DRM) == 0)
ff86aa
+      if (subsystem != NULL && strcmp (subsystem, SUBSYSTEM_DRM) == 0)
ff86aa
         {
ff86aa
           ply_trace ("found DRM device %s", device_path);
ff86aa
           renderer_type = PLY_RENDERER_TYPE_DRM;
ff86aa
         }
ff86aa
       else if (strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0)
ff86aa
         {
ff86aa
           ply_trace ("found frame buffer device %s", device_path);
ff86aa
           if (!fb_device_has_drm_device (manager, device))
ff86aa
             {
ff86aa
               renderer_type = PLY_RENDERER_TYPE_FRAME_BUFFER;
ff86aa
             }
ff86aa
           else
ff86aa
             {
ff86aa
               ply_trace ("ignoring, since there's a DRM device associated with it");
ff86aa
             }
ff86aa
         }
ff86aa
 
ff86aa
       if (renderer_type != PLY_RENDERER_TYPE_NONE)
ff86aa
         create_seat_for_terminal_and_renderer_type (manager,
ff86aa
                                                     device_path,
ff86aa
                                                     terminal,
ff86aa
                                                     renderer_type);
ff86aa
     }
ff86aa
 }
ff86aa
 
ff86aa
 static void
ff86aa
 free_seat_from_device_path (ply_device_manager_t *manager,
ff86aa
                             const char           *device_path)
ff86aa
 {
ff86aa
   ply_list_node_t *node;
ff86aa
@@ -332,63 +333,80 @@ create_seats_for_subsystem (ply_device_manager_t *manager,
ff86aa
         {
ff86aa
           ply_trace ("it's not initialized");
ff86aa
         }
ff86aa
 
ff86aa
       udev_device_unref (device);
ff86aa
     }
ff86aa
 
ff86aa
   udev_enumerate_unref (matches);
ff86aa
 
ff86aa
   return found_device;
ff86aa
 }
ff86aa
 
ff86aa
 static void
ff86aa
 on_udev_event (ply_device_manager_t *manager)
ff86aa
 {
ff86aa
   struct udev_device *device;
ff86aa
   const char *action;
ff86aa
 
ff86aa
   device = udev_monitor_receive_device (manager->udev_monitor);
ff86aa
   if (device == NULL)
ff86aa
     return;
ff86aa
 
ff86aa
   action = udev_device_get_action (device);
ff86aa
 
ff86aa
   ply_trace ("got %s event for device %s", action, udev_device_get_sysname (device));
ff86aa
 
ff86aa
   if (action == NULL)
ff86aa
     return;
ff86aa
 
ff86aa
   if (strcmp (action, "add") == 0)
ff86aa
-    create_seat_for_udev_device (manager, device);
ff86aa
+    {
ff86aa
+      const char *subsystem;
ff86aa
+      bool coldplug_complete = manager->udev_queue_fd_watch == NULL;
ff86aa
+
ff86aa
+      subsystem = udev_device_get_subsystem (device);
ff86aa
+
ff86aa
+      if (strcmp (subsystem, SUBSYSTEM_DRM) == 0 ||
ff86aa
+          coldplug_complete)
ff86aa
+        {
ff86aa
+          create_seat_for_udev_device (manager, device);
ff86aa
+        }
ff86aa
+      else
ff86aa
+        {
ff86aa
+          ply_trace ("ignoring since we only handle subsystem %s devices after coldplug completes", subsystem);
ff86aa
+        }
ff86aa
+    }
ff86aa
   else if (strcmp (action, "remove") == 0)
ff86aa
-    free_seat_for_udev_device (manager, device);
ff86aa
+    {
ff86aa
+      free_seat_for_udev_device (manager, device);
ff86aa
+    }
ff86aa
 
ff86aa
   udev_device_unref (device);
ff86aa
 }
ff86aa
 
ff86aa
 static void
ff86aa
 watch_for_udev_events (ply_device_manager_t *manager)
ff86aa
 {
ff86aa
   int fd;
ff86aa
   assert (manager != NULL);
ff86aa
   assert (manager->udev_monitor == NULL);
ff86aa
 
ff86aa
   ply_trace ("watching for udev graphics device add and remove events");
ff86aa
 
ff86aa
   manager->udev_monitor = udev_monitor_new_from_netlink (manager->udev_context, "udev");
ff86aa
 
ff86aa
   udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_DRM, NULL);
ff86aa
   udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_FRAME_BUFFER, NULL);
ff86aa
   udev_monitor_filter_add_match_tag (manager->udev_monitor, "seat");
ff86aa
   udev_monitor_enable_receiving (manager->udev_monitor);
ff86aa
 
ff86aa
   fd = udev_monitor_get_fd (manager->udev_monitor);
ff86aa
   ply_event_loop_watch_fd (manager->loop,
ff86aa
                            fd,
ff86aa
                            PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
ff86aa
                            (ply_event_handler_t)
ff86aa
                            on_udev_event,
ff86aa
                            NULL,
ff86aa
                            manager);
ff86aa
 }
ff86aa
 
ff86aa
-- 
ff86aa
1.8.3.1
ff86aa