[Spice-devel] [PATCH] qxl: add uevent handler support
Alon Levy
alevy at redhat.com
Sun Jul 7 00:48:58 PDT 2013
On Mon, 2013-07-01 at 14:22 +1000, Dave Airlie wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> This allows the driver to process uevents from the kernel when the mode
> changes.
Power9Blow!Sharp
Looks good to me, one question below, ACK regardless.
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
> configure.ac | 14 +++++++++++++
> src/Makefile.am | 6 +++++-
> src/qxl_drmmode.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> src/qxl_drmmode.h | 10 +++++++++
> src/qxl_kms.c | 3 +++
> 5 files changed, 94 insertions(+), 1 deletion(-)
>
> diff --git a/configure.ac b/configure.ac
> index d481cc1..8b2d450 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -135,6 +135,20 @@ fi
> AM_CONDITIONAL(BUILD_XSPICE, test "x$enable_xspice" = "xyes")
> AM_CONDITIONAL(BUILD_QXL, test "x$enable_qxl" = "xyes")
>
> +AC_ARG_ENABLE([udev],
> + AS_HELP_STRING([--disable-udev], [Disable libudev support [default=auto]]),
> + [enable_udev="$enableval"],
> + [enable_udev=auto])
> +if test "x$enable_udev" != "xno"; then
> + PKG_CHECK_MODULES(LIBUDEV, [libudev], [LIBUDEV=yes], [LIBUDEV=no])
> + if test "x$LIBUDEV" = xyes; then
> + AC_DEFINE(HAVE_LIBUDEV, 1,[libudev support])
> + elif test "x$enable_udev" != "xauto"; then
> + AC_MSG_ERROR([Building with udev requested but libudev not found])
> + fi
> +fi
> +AM_CONDITIONAL(LIBUDEV, test x$LIBUDEV = xyes)
> +
> PKG_CHECK_MODULES([SPICE_PROTOCOL], [spice-protocol >= 0.12.0])
>
> # AC_CHECK_FILE is not supported when cross compiling
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 4349b4e..d6a5445 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -27,7 +27,7 @@
>
> SUBDIRS=uxa
>
> -AM_CFLAGS = $(SPICE_PROTOCOL_CFLAGS) $(XORG_CFLAGS) $(PCIACCESS_CFLAGS) $(CWARNFLAGS) $(DRM_CFLAGS)
> +AM_CFLAGS = $(SPICE_PROTOCOL_CFLAGS) $(XORG_CFLAGS) $(PCIACCESS_CFLAGS) $(CWARNFLAGS) $(DRM_CFLAGS) @LIBUDEV_CFLAGS@
Any reason to use an autoconf variable instead of a make variable?
>
> if BUILD_QXL
> qxl_drv_la_LTLIBRARIES = qxl_drv.la
> @@ -35,6 +35,10 @@ qxl_drv_la_LDFLAGS = -module -avoid-version
> qxl_drv_ladir = @moduledir@/drivers
>
> qxl_drv_la_LIBADD = uxa/libuxa.la
> +if LIBUDEV
> +qxl_drv_la_LIBADD += $(LIBUDEV_LIBS)
> +endif
> +
>
> qxl_drv_la_SOURCES = \
> qxl.h \
> diff --git a/src/qxl_drmmode.c b/src/qxl_drmmode.c
> index c1f5c15..03b4124 100644
> --- a/src/qxl_drmmode.c
> +++ b/src/qxl_drmmode.c
> @@ -875,4 +875,66 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
> return TRUE;
> }
>
> +#ifdef HAVE_LIBUDEV
> +static void
> +drmmode_handle_uevents(int fd, void *closure)
> +{
> + drmmode_ptr drmmode = closure;
> + ScrnInfoPtr scrn = drmmode->scrn;
> + struct udev_device *dev;
> + dev = udev_monitor_receive_device(drmmode->uevent_monitor);
> + if (!dev)
> + return;
> +
> + RRGetInfo(xf86ScrnToScreen(scrn), TRUE);
> + udev_device_unref(dev);
> +}
> +#endif
> +
> +void qxl_drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
> +{
> +#ifdef HAVE_LIBUDEV
> + struct udev *u;
> + struct udev_monitor *mon;
> +
> + u = udev_new();
> + if (!u)
> + return;
> + mon = udev_monitor_new_from_netlink(u, "udev");
> + if (!mon) {
> + udev_unref(u);
> + return;
> + }
> +
> + if (udev_monitor_filter_add_match_subsystem_devtype(mon,
> + "drm",
> + "drm_minor") < 0 ||
> + udev_monitor_enable_receiving(mon) < 0) {
> + udev_monitor_unref(mon);
> + udev_unref(u);
> + return;
> + }
> +
> + drmmode->uevent_handler =
> + xf86AddGeneralHandler(udev_monitor_get_fd(mon),
> + drmmode_handle_uevents,
> + drmmode);
> +
> + drmmode->uevent_monitor = mon;
> +#endif
> +}
> +
> +void qxl_drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode)
> +{
> +#ifdef HAVE_LIBUDEV
> + if (drmmode->uevent_handler) {
> + struct udev *u = udev_monitor_get_udev(drmmode->uevent_monitor);
> + xf86RemoveGeneralHandler(drmmode->uevent_handler);
> +
> + udev_monitor_unref(drmmode->uevent_monitor);
> + udev_unref(u);
> + }
> +#endif
> +}
> +
> #endif
> diff --git a/src/qxl_drmmode.h b/src/qxl_drmmode.h
> index df076c7..04752ec 100644
> --- a/src/qxl_drmmode.h
> +++ b/src/qxl_drmmode.h
> @@ -34,6 +34,9 @@
> #include "xf86str.h"
> #include "randrstr.h"
> #include "xf86Crtc.h"
> +#ifdef HAVE_LIBUDEV
> +#include "libudev.h"
> +#endif
>
> typedef struct {
> int fd;
> @@ -42,6 +45,10 @@ typedef struct {
> drmModeFBPtr mode_fb;
> int cpp;
> ScrnInfoPtr scrn;
> +#ifdef HAVE_LIBUDEV
> + struct udev_monitor *uevent_monitor;
> + InputHandlerProc uevent_handler;
> +#endif
> } drmmode_rec, *drmmode_ptr;
>
> typedef struct {
> @@ -78,6 +85,9 @@ typedef struct {
> } drmmode_output_private_rec, *drmmode_output_private_ptr;
>
> extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp);
> +
> +extern void qxl_drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode);
> +extern void qxl_drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode);
> #endif
>
> #endif
> diff --git a/src/qxl_kms.c b/src/qxl_kms.c
> index b673294..b091a12 100644
> --- a/src/qxl_kms.c
> +++ b/src/qxl_kms.c
> @@ -95,6 +95,7 @@ qxl_close_screen_kms (CLOSE_SCREEN_ARGS_DECL)
> qxl_screen_t *qxl = pScrn->driverPrivate;
> Bool result;
>
> + qxl_drmmode_uevent_fini(pScrn, &qxl->drmmode);
> pScreen->CloseScreen = qxl->close_screen;
>
> result = pScreen->CloseScreen (CLOSE_SCREEN_ARGS);
> @@ -198,6 +199,8 @@ qxl_create_screen_resources_kms(ScreenPtr pScreen)
>
> set_surface (pPixmap, qxl->primary);
>
> + qxl_drmmode_uevent_init(pScrn, &qxl->drmmode);
> +
> if (!uxa_resources_init (pScreen))
> return FALSE;
>
More information about the Spice-devel
mailing list