xf86-video-intel: src/sna/sna_driver.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Tue Oct 7 02:28:10 PDT 2014


 src/sna/sna.h        |    2 +
 src/sna/sna_driver.c |   56 +++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 52 insertions(+), 6 deletions(-)

New commits:
commit 9ed1ac8b506509be410c12870397417c7638886e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Oct 6 21:37:14 2014 +0100

    sna: Wrap rrGetInfo so that we can probe when udev is not active
    
    If the ddx is configured without udev support, we do not receive
    notifications when the MST topology is changed. This leads us to query
    the kernel for bad connectors, and so we end up reporting an unknown
    connection status for them, which the user and client often find
    confusing. However, we can not simply act upon the detection failure as
    we are too deep inside the callback chain and cannot change the arrays of
    known connectors whilst iterating over them. A neat compromise is to
    hook into the rrGetInfo call chain and poll for MST changes before we
    report back the current configuration.
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=84718
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index e035634..4cd85d1 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -312,6 +312,8 @@ struct sna {
 		struct udev_monitor *backlight_monitor;
 		pointer backlight_handler;
 #endif
+
+		Bool (*rrGetInfo)(ScreenPtr, Rotation *);
 	} mode;
 
 	struct {
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index f28ca87..a09aa98 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -59,6 +59,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include <sys/ioctl.h>
 #include <sys/fcntl.h>
+#include <sys/poll.h>
 #include "i915_drm.h"
 
 #ifdef HAVE_VALGRIND
@@ -866,6 +867,22 @@ err_dev:
 	goto out;
 }
 
+static bool sna_uevent_poll(struct sna *sna)
+{
+	struct pollfd pfd;
+
+	if (sna->uevent_monitor == NULL)
+		return false;
+
+	pfd.fd = udev_monitor_get_fd(sna->uevent_monitor);
+	pfd.events = POLLIN;
+
+	if (poll(&pfd, 1, 0) > 0)
+		sna_handle_uevents(pfd.fd, sna);
+
+	return true;
+}
+
 static void
 sna_uevent_fini(struct sna *sna)
 {
@@ -887,9 +904,21 @@ sna_uevent_fini(struct sna *sna)
 }
 #else
 static void sna_uevent_init(struct sna *sna) { }
+static bool sna_uevent_poll(struct sna *sna) { return false; }
 static void sna_uevent_fini(struct sna *sna) { }
 #endif /* HAVE_UDEV */
 
+static Bool
+sna_randr_getinfo(ScreenPtr screen, Rotation *rotations)
+{
+	struct sna *sna = to_sna_from_screen(screen);
+
+	if (!sna_uevent_poll(sna))
+		sna_mode_discover(sna);
+
+	return sna->mode.rrGetInfo(screen, rotations);
+}
+
 static void sna_leave_vt(VT_FUNC_ARGS_DECL)
 {
 	SCRN_INFO_PTR(arg);
@@ -1035,6 +1064,25 @@ agp_aperture_size(struct pci_device *dev, int gen)
 }
 
 static Bool
+sna_mode_init(struct sna *sna, ScreenPtr screen)
+{
+	rrScrPrivPtr rp;
+
+	if (!xf86CrtcScreenInit(screen))
+		return FALSE;
+
+	xf86RandR12SetRotations(screen, RR_Rotate_All | RR_Reflect_All);
+	xf86RandR12SetTransformSupport(screen, TRUE);
+
+	/* Wrap RR queries to catch pending MST topology changes */
+	rp = rrGetScrPriv(screen);
+	sna->mode.rrGetInfo = rp->rrGetInfo;
+	rp->rrGetInfo = sna_randr_getinfo;
+
+	return TRUE;
+}
+
+static Bool
 sna_screen_init(SCREEN_INIT_ARGS_DECL)
 {
 	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
@@ -1134,12 +1182,9 @@ sna_screen_init(SCREEN_INIT_ARGS_DECL)
 	sna->CloseScreen = screen->CloseScreen;
 	screen->CloseScreen = sna_early_close_screen;
 
-	if (!xf86CrtcScreenInit(screen))
+	if (!sna_mode_init(sna, screen))
 		return FALSE;
 
-	xf86RandR12SetRotations(screen, RR_Rotate_All | RR_Reflect_All);
-	xf86RandR12SetTransformSupport(screen, TRUE);
-
 	if (!miCreateDefColormap(screen))
 		return FALSE;
 
@@ -1151,6 +1196,7 @@ sna_screen_init(SCREEN_INIT_ARGS_DECL)
 
 	xf86DPMSInit(screen, sna_dpms_set, 0);
 
+	sna_uevent_init(sna);
 	sna_video_init(sna, screen);
 	sna_dri_init(sna, screen);
 
@@ -1165,8 +1211,6 @@ sna_screen_init(SCREEN_INIT_ARGS_DECL)
 
 	sna->suspended = FALSE;
 
-	sna_uevent_init(sna);
-
 	return TRUE;
 }
 


More information about the xorg-commit mailing list