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