diff --git a/graphics/libdrm/Makefile b/graphics/libdrm/Makefile index cd49b7f397f2..94efd46258ca 100644 --- a/graphics/libdrm/Makefile +++ b/graphics/libdrm/Makefile @@ -2,9 +2,8 @@ # $FreeBSD$ PORTNAME= libdrm -PORTVERSION= 2.4.75 +PORTVERSION= 2.4.78 PORTEPOCH= 1 -PORTREVISION= 3 CATEGORIES= graphics x11 MASTER_SITES= http://dri.freedesktop.org/libdrm/ @@ -14,8 +13,7 @@ COMMENT= Userspace interface to kernel Direct Rendering Module services LICENSE= MIT BUILD_DEPENDS= ${LOCALBASE}/libdata/pkgconfig/pthread-stubs.pc:devel/libpthread-stubs -LIB_DEPENDS= libpciaccess.so:devel/libpciaccess \ - libdevq.so:devel/libdevq +LIB_DEPENDS= libpciaccess.so:devel/libpciaccess USES= libtool pkgconfig tar:bzip2 GNU_CONFIGURE= yes @@ -74,7 +72,7 @@ PLIST_SUB+= RADEON_DRIVERS="@comment " # This variable is not for users. So use a non-default name, intended for # people working on DRM kernel module development. -.if !defined(LIBDRM_SKIP_RETURN_PATCH) +.if ${OPSYS} == FreeBSD && !defined(LIBDRM_SKIP_RETURN_PATCH) EXTRA_PATCHES+= ${FILESDIR}/extra-xf86drm.c .endif diff --git a/graphics/libdrm/distinfo b/graphics/libdrm/distinfo index b71613397c70..e2be5f04b589 100644 --- a/graphics/libdrm/distinfo +++ b/graphics/libdrm/distinfo @@ -1,3 +1,3 @@ -TIMESTAMP = 1485779860 -SHA256 (libdrm-2.4.75.tar.bz2) = 2d5a500eef412cc287d12268eed79d571e262d4957a2ec9258073f305985054f -SIZE (libdrm-2.4.75.tar.bz2) = 774589 +TIMESTAMP = 1491604820 +SHA256 (libdrm-2.4.78.tar.bz2) = 3dbe2ed3e2ee6ebe8a848195286ef362f66675a7102958e42906d734aa6925d8 +SIZE (libdrm-2.4.78.tar.bz2) = 772306 diff --git a/graphics/libdrm/files/Makefile.am b/graphics/libdrm/files/Makefile.am deleted file mode 100644 index 9d4bc2498779..000000000000 --- a/graphics/libdrm/files/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ ---- Makefile.am.orig 2016-12-13 03:45:20.000000000 +0100 -+++ Makefile.am 2017-01-30 14:02:04.821902000 +0100 -@@ -115,9 +115,9 @@ - libdrm_la_LTLIBRARIES = libdrm.la - libdrm_ladir = $(libdir) - libdrm_la_LDFLAGS = -version-number 2:4:0 -no-undefined --libdrm_la_LIBADD = @CLOCK_LIB@ -lm -+libdrm_la_LIBADD = @CLOCK_LIB@ -lm @LIBDEVQ_LIBS@ - --libdrm_la_CPPFLAGS = -I$(top_srcdir)/include/drm -+libdrm_la_CPPFLAGS = -I$(top_srcdir)/include/drm @LIBDEVQ_CFLAGS@ - AM_CFLAGS = \ - $(WARN_CFLAGS) \ - $(VALGRIND_CFLAGS) diff --git a/graphics/libdrm/files/configure.ac b/graphics/libdrm/files/configure.ac deleted file mode 100644 index 3cdaeecf9359..000000000000 --- a/graphics/libdrm/files/configure.ac +++ /dev/null @@ -1,39 +0,0 @@ ---- configure.ac.orig 2017-01-28 02:15:16.000000000 +0100 -+++ configure.ac 2017-01-30 14:00:14.452530000 +0100 -@@ -72,6 +72,11 @@ - [Enable support for using udev instead of mknod (default: disabled)])], - [UDEV=$enableval], [UDEV=no]) - -+AC_ARG_ENABLE([devq], -+ [AS_HELP_STRING([--enable-devq], -+ [Enable support for using devq for device detection (default: disabled)])], -+ [DEVQ=$enableval], [DEVQ=no]) -+ - AC_ARG_ENABLE(libkms, - AS_HELP_STRING([--disable-libkms], - [Disable KMS mm abstraction library (default: auto, enabled on supported platforms)]), -@@ -322,6 +327,10 @@ - AC_DEFINE(UDEV, 1, [Have UDEV support]) - fi - -+if test "x$DEVQ" = xyes; then -+ AC_DEFINE(DEVQ, 1, [Have DEVQ support]) -+fi -+ - AC_CANONICAL_HOST - if test "x$LIBKMS" = xauto ; then - case $host_os in -@@ -451,6 +460,13 @@ - AC_MSG_RESULT([$CAIRO]) - AM_CONDITIONAL(HAVE_CAIRO, [test "x$CAIRO" = xyes]) - -+# For FreeBSD support -+PKG_CHECK_MODULES([LIBDEVQ], [libdevq-1.0 >= 0.0.4], [HAVE_LIBDEVQ=yes], [HAVE_LIBDEVQ=no]) -+if test "x$HAVE_LIBDEVQ" = xyes; then -+ AC_DEFINE(HAVE_LIBDEVQ, 1, [Have libdevq support]) -+fi -+AM_CONDITIONAL(HAVE_LIBDEVQ, [test "x$HAVE_LIBDEVQ" = xyes]) -+ - # xsltproc for docbook manpages - AC_ARG_ENABLE([manpages], - AS_HELP_STRING([--enable-manpages], [enable manpages @<:@default=auto@:>@]), diff --git a/graphics/libdrm/files/extra-xf86drm.c b/graphics/libdrm/files/extra-xf86drm.c index 7f19e90c2a32..112b0e159b88 100644 --- a/graphics/libdrm/files/extra-xf86drm.c +++ b/graphics/libdrm/files/extra-xf86drm.c @@ -4,7 +4,7 @@ for now. Newer kernel modules will have this fixed included. dragonfly fixed this issue in, http://gitweb.dragonflybsd.org/dragonfly.git/commit/b922632f623ee2cc2c1346bb3a6894a7756676aa -which will be included in the 4.4 release when it is released. +which has been included since the 4.4 release. --- xf86drm.c.orig 2017-01-30 13:59:15.919081000 +0100 +++ xf86drm.c diff --git a/graphics/libdrm/files/patch-Makefile.in b/graphics/libdrm/files/patch-Makefile.in deleted file mode 100644 index 031fa2edd2db..000000000000 --- a/graphics/libdrm/files/patch-Makefile.in +++ /dev/null @@ -1,13 +0,0 @@ ---- Makefile.in.orig 2017-01-28 02:00:33 UTC -+++ Makefile.in -@@ -562,8 +562,8 @@ SUBDIRS = \ - libdrm_la_LTLIBRARIES = libdrm.la - libdrm_ladir = $(libdir) - libdrm_la_LDFLAGS = -version-number 2:4:0 -no-undefined --libdrm_la_LIBADD = @CLOCK_LIB@ -lm --libdrm_la_CPPFLAGS = -I$(top_srcdir)/include/drm -+libdrm_la_LIBADD = @CLOCK_LIB@ -lm @LIBDEVQ_LIBS@ -+libdrm_la_CPPFLAGS = -I$(top_srcdir)/include/drm @LIBDEVQ_CFLAGS@ - AM_CFLAGS = \ - $(WARN_CFLAGS) \ - $(VALGRIND_CFLAGS) diff --git a/graphics/libdrm/files/patch-config.h.in b/graphics/libdrm/files/patch-config.h.in deleted file mode 100644 index 56f9a826d423..000000000000 --- a/graphics/libdrm/files/patch-config.h.in +++ /dev/null @@ -1,22 +0,0 @@ ---- config.h.in.orig 2017-01-28 02:00:33 UTC -+++ config.h.in -@@ -8,6 +8,9 @@ - /* Define to 1 if using `alloca.c'. */ - #undef C_ALLOCA - -+/* Have DEVQ support */ -+#undef DEVQ -+ - /* Define to 1 if you have `alloca', as a function or macro. */ - #undef HAVE_ALLOCA - -@@ -51,6 +54,9 @@ - /* Define to 1 if you have the header file. */ - #undef HAVE_INTTYPES_H - -+/* Have libdevq support */ -+#undef HAVE_LIBDEVQ -+ - /* Enable if your compiler supports the Intel __sync_* atomic primitives */ - #undef HAVE_LIBDRM_ATOMIC_PRIMITIVES - diff --git a/graphics/libdrm/files/patch-configure b/graphics/libdrm/files/patch-configure deleted file mode 100644 index 8daf66b2282b..000000000000 --- a/graphics/libdrm/files/patch-configure +++ /dev/null @@ -1,182 +0,0 @@ ---- configure.orig 2017-01-30 19:04:05 UTC -+++ configure -@@ -646,6 +646,10 @@ HAVE_MANPAGES_STYLESHEET_TRUE - MANPAGES_STYLESHEET - BUILD_MANPAGES_FALSE - BUILD_MANPAGES_TRUE -+HAVE_LIBDEVQ_FALSE -+HAVE_LIBDEVQ_TRUE -+LIBDEVQ_LIBS -+LIBDEVQ_CFLAGS - HAVE_CAIRO_FALSE - HAVE_CAIRO_TRUE - CAIRO_LIBS -@@ -838,6 +842,7 @@ with_gnu_ld - with_sysroot - enable_libtool_lock - enable_udev -+enable_devq - enable_libkms - enable_intel - enable_radeon -@@ -877,6 +882,8 @@ CUNIT_CFLAGS - CUNIT_LIBS - CAIRO_CFLAGS - CAIRO_LIBS -+LIBDEVQ_CFLAGS -+LIBDEVQ_LIBS - VALGRIND_CFLAGS - VALGRIND_LIBS' - -@@ -1511,6 +1518,8 @@ Optional Features: - --disable-libtool-lock avoid locking (might break parallel builds) - --enable-udev Enable support for using udev instead of mknod - (default: disabled) -+ --enable-devq Enable support for using devq for device detection -+ (default: disabled) - --disable-libkms Disable KMS mm abstraction library (default: auto, - enabled on supported platforms) - --disable-intel Enable support for intel's KMS API (default: auto, -@@ -1586,6 +1595,10 @@ Some influential environment variables: - CAIRO_CFLAGS - C compiler flags for CAIRO, overriding pkg-config - CAIRO_LIBS linker flags for CAIRO, overriding pkg-config -+ LIBDEVQ_CFLAGS -+ C compiler flags for LIBDEVQ, overriding pkg-config -+ LIBDEVQ_LIBS -+ linker flags for LIBDEVQ, overriding pkg-config - VALGRIND_CFLAGS - C compiler flags for VALGRIND, overriding pkg-config - VALGRIND_LIBS -@@ -13217,6 +13230,14 @@ else - fi - - -+# Check whether --enable-devq was given. -+if test "${enable_devq+set}" = set; then : -+ enableval=$enable_devq; DEVQ=$enableval -+else -+ DEVQ=no -+fi -+ -+ - # Check whether --enable-libkms was given. - if test "${enable_libkms+set}" = set; then : - enableval=$enable_libkms; LIBKMS=$enableval -@@ -13873,6 +13894,12 @@ $as_echo "#define UDEV 1" >>confdefs.h - - fi - -+if test "x$DEVQ" = xyes; then -+ -+$as_echo "#define DEVQ 1" >>confdefs.h -+ -+fi -+ - - if test "x$LIBKMS" = xauto ; then - case $host_os in -@@ -14331,6 +14358,92 @@ else - fi - - -+# For FreeBSD support -+ -+pkg_failed=no -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBDEVQ" >&5 -+$as_echo_n "checking for LIBDEVQ... " >&6; } -+ -+if test -n "$LIBDEVQ_CFLAGS"; then -+ pkg_cv_LIBDEVQ_CFLAGS="$LIBDEVQ_CFLAGS" -+ elif test -n "$PKG_CONFIG"; then -+ if test -n "$PKG_CONFIG" && \ -+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdevq-1.0 >= 0.0.4\""; } >&5 -+ ($PKG_CONFIG --exists --print-errors "libdevq-1.0 >= 0.0.4") 2>&5 -+ ac_status=$? -+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; }; then -+ pkg_cv_LIBDEVQ_CFLAGS=`$PKG_CONFIG --cflags "libdevq-1.0 >= 0.0.4" 2>/dev/null` -+ test "x$?" != "x0" && pkg_failed=yes -+else -+ pkg_failed=yes -+fi -+ else -+ pkg_failed=untried -+fi -+if test -n "$LIBDEVQ_LIBS"; then -+ pkg_cv_LIBDEVQ_LIBS="$LIBDEVQ_LIBS" -+ elif test -n "$PKG_CONFIG"; then -+ if test -n "$PKG_CONFIG" && \ -+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdevq-1.0 >= 0.0.4\""; } >&5 -+ ($PKG_CONFIG --exists --print-errors "libdevq-1.0 >= 0.0.4") 2>&5 -+ ac_status=$? -+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; }; then -+ pkg_cv_LIBDEVQ_LIBS=`$PKG_CONFIG --libs "libdevq-1.0 >= 0.0.4" 2>/dev/null` -+ test "x$?" != "x0" && pkg_failed=yes -+else -+ pkg_failed=yes -+fi -+ else -+ pkg_failed=untried -+fi -+ -+ -+ -+if test $pkg_failed = yes; then -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+ -+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then -+ _pkg_short_errors_supported=yes -+else -+ _pkg_short_errors_supported=no -+fi -+ if test $_pkg_short_errors_supported = yes; then -+ LIBDEVQ_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libdevq-1.0 >= 0.0.4" 2>&1` -+ else -+ LIBDEVQ_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libdevq-1.0 >= 0.0.4" 2>&1` -+ fi -+ # Put the nasty error message in config.log where it belongs -+ echo "$LIBDEVQ_PKG_ERRORS" >&5 -+ -+ HAVE_LIBDEVQ=no -+elif test $pkg_failed = untried; then -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+ HAVE_LIBDEVQ=no -+else -+ LIBDEVQ_CFLAGS=$pkg_cv_LIBDEVQ_CFLAGS -+ LIBDEVQ_LIBS=$pkg_cv_LIBDEVQ_LIBS -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -+$as_echo "yes" >&6; } -+ HAVE_LIBDEVQ=yes -+fi -+if test "x$HAVE_LIBDEVQ" = xyes; then -+ -+$as_echo "#define HAVE_LIBDEVQ 1" >>confdefs.h -+ -+fi -+ if test "x$HAVE_LIBDEVQ" = xyes; then -+ HAVE_LIBDEVQ_TRUE= -+ HAVE_LIBDEVQ_FALSE='#' -+else -+ HAVE_LIBDEVQ_TRUE='#' -+ HAVE_LIBDEVQ_FALSE= -+fi -+ -+ - # xsltproc for docbook manpages - # Check whether --enable-manpages was given. - if test "${enable_manpages+set}" = set; then : -@@ -14737,6 +14850,10 @@ if test -z "${HAVE_CAIRO_TRUE}" && test - as_fn_error $? "conditional \"HAVE_CAIRO\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${HAVE_LIBDEVQ_TRUE}" && test -z "${HAVE_LIBDEVQ_FALSE}"; then -+ as_fn_error $? "conditional \"HAVE_LIBDEVQ\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - if test -z "${BUILD_MANPAGES_TRUE}" && test -z "${BUILD_MANPAGES_FALSE}"; then - as_fn_error $? "conditional \"BUILD_MANPAGES\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/graphics/libdrm/files/patch-xf86drm.c b/graphics/libdrm/files/patch-xf86drm.c index 8d8991eac12d..a00e4d0d069b 100644 --- a/graphics/libdrm/files/patch-xf86drm.c +++ b/graphics/libdrm/files/patch-xf86drm.c @@ -1,73 +1,411 @@ ---- xf86drm.c.orig 2017-01-30 19:04:05 UTC +--- xf86drm.c.orig 2017-04-07 08:49:13 UTC +++ xf86drm.c -@@ -62,6 +62,10 @@ +@@ -49,6 +49,9 @@ + #include + #include + #include ++#ifdef HAVE_SYS_SYSCTL_H ++#include ++#endif + #include + #define stat_t struct stat + #include +@@ -62,6 +65,10 @@ #endif #include -+#ifdef HAVE_LIBDEVQ -+#include "libdevq.h" ++#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) ++#include +#endif + /* Not all systems have MAP_FAILED defined */ #ifndef MAP_FAILED #define MAP_FAILED ((void *)-1) -@@ -82,8 +86,12 @@ - #define DRM_RENDER_MINOR_NAME "renderD" - #endif +@@ -72,18 +79,8 @@ --#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) + #include "util_math.h" + +-#ifdef __OpenBSD__ +-#define DRM_PRIMARY_MINOR_NAME "drm" +-#define DRM_CONTROL_MINOR_NAME "drmC" +-#define DRM_RENDER_MINOR_NAME "drmR" +-#else +-#define DRM_PRIMARY_MINOR_NAME "card" +-#define DRM_CONTROL_MINOR_NAME "controlD" +-#define DRM_RENDER_MINOR_NAME "renderD" +-#endif +- + #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) -#define DRM_MAJOR 145 -+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -+#define DRM_MAJOR 0 -+#endif -+ -+#if defined(__DragonFly__) -+#define DRM_MAJOR 65 /* was 145 XXX needs checking */ ++#define DRM_MAJOR 0 /* Major ID unused on systems with devfs */ #endif #ifdef __NetBSD__ -@@ -548,6 +556,7 @@ static int drmGetMinorType(int minor) - } +@@ -180,7 +177,7 @@ void drmFree(void *pt) } -+#if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) && !defined(__DragonFly__) - static const char *drmGetMinorName(int type) - { - switch (type) { -@@ -561,6 +570,7 @@ static const char *drmGetMinorName(int t - return NULL; - } - } -+#endif - /** - * Open the device by bus ID. -@@ -2734,7 +2744,7 @@ int drmGetNodeTypeFromFd(int fd) - maj = major(sbuf.st_rdev); - min = minor(sbuf.st_rdev); +- * Call ioctl, restarting if it is interupted ++ * Call ioctl, restarting if it is interrupted + */ + int + drmIoctl(int fd, unsigned long request, void *arg) +@@ -223,6 +220,89 @@ drmHashEntry *drmGetEntry(int fd) + return entry; + } -- if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) { -+ if (DRM_MAJOR && maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) { - errno = EINVAL; - return -1; ++static int drmGetMinorBase(int type) ++{ ++ switch (type) { ++ case DRM_NODE_PRIMARY: ++ case DRM_NODE_CONTROL: ++ case DRM_NODE_RENDER: ++ return type << 6; ++ default: ++ return -1; ++ }; ++} ++ ++static int drmGetMinorType(int minor) ++{ ++ if (minor < 0) ++ return -1; ++ ++ int type = minor >> 6; ++ switch (type) { ++ case DRM_NODE_PRIMARY: ++ case DRM_NODE_CONTROL: ++ case DRM_NODE_RENDER: ++ return type; ++ default: ++ return -1; ++ } ++} ++ ++#ifdef __linux__ ++static const char *drmGetMinorName(int type) ++{ ++ switch (type) { ++ case DRM_NODE_PRIMARY: ++ return DRM_PRIMARY_MINOR_NAME; ++ case DRM_NODE_CONTROL: ++ return DRM_CONTROL_MINOR_NAME; ++ case DRM_NODE_RENDER: ++ return DRM_RENDER_MINOR_NAME; ++ default: ++ return NULL; ++ } ++} ++#endif ++ ++static const char *drmGetDeviceName(int type) ++{ ++ switch (type) { ++ case DRM_NODE_PRIMARY: ++ return DRM_DEV_NAME; ++ case DRM_NODE_CONTROL: ++ return DRM_CONTROL_DEV_NAME; ++ case DRM_NODE_RENDER: ++ return DRM_RENDER_DEV_NAME; ++ default: ++ return NULL; ++ } ++} ++ ++static int drmGetNodeNumber(const char *name) ++{ ++ size_t name_len = strnlen(name, DRM_NODE_NAME_MAX); ++ while (name_len && isdigit(name[name_len - 1])) ++ --name_len; ++ return strtol(name + name_len, NULL, 10); ++} ++ ++static int drmGetNodeType(const char *name) ++{ ++ if (strncmp(name, DRM_PRIMARY_MINOR_NAME, ++ sizeof(DRM_PRIMARY_MINOR_NAME) - 1) == 0) ++ return DRM_NODE_PRIMARY; ++ ++ if (strncmp(name, DRM_CONTROL_MINOR_NAME, ++ sizeof(DRM_CONTROL_MINOR_NAME ) - 1) == 0) ++ return DRM_NODE_CONTROL; ++ ++ if (strncmp(name, DRM_RENDER_MINOR_NAME, ++ sizeof(DRM_RENDER_MINOR_NAME) - 1) == 0) ++ return DRM_NODE_RENDER; ++ ++ return -1; ++} ++ + /** + * Compare two busid strings + * +@@ -290,7 +370,7 @@ static int drmMatchBusID(const char *id1 + * + * \internal + * Checks for failure. If failure was caused by signal call chown again. +- * If any other failure happened then it will output error mesage using ++ * If any other failure happened then it will output error message using + * drmMsg() call. + */ + #if !defined(UDEV) +@@ -327,8 +407,8 @@ static int chown_check_return(const char + static int drmOpenDevice(dev_t dev, int minor, int type) + { + stat_t st; +- const char *dev_name; +- char buf[64]; ++ const char *dev_name = drmGetDeviceName(type); ++ char buf[DRM_NODE_NAME_MAX]; + int fd; + mode_t devmode = DRM_DEV_MODE, serv_mode; + gid_t serv_group; +@@ -338,21 +418,14 @@ static int drmOpenDevice(dev_t dev, int + gid_t group = DRM_DEV_GID; + #endif + +- switch (type) { +- case DRM_NODE_PRIMARY: +- dev_name = DRM_DEV_NAME; +- break; +- case DRM_NODE_CONTROL: +- dev_name = DRM_CONTROL_DEV_NAME; +- break; +- case DRM_NODE_RENDER: +- dev_name = DRM_RENDER_DEV_NAME; +- break; +- default: ++ if (!dev_name) + return -EINVAL; +- }; + ++#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) ++ sprintf(buf, dev_name, DRM_DIR_NAME, minor + drmGetMinorBase(type)); ++#else + sprintf(buf, dev_name, DRM_DIR_NAME, minor); ++#endif + drmMsg("drmOpenDevice: node name is %s\n", buf); + + if (drm_server_info && drm_server_info->get_perms) { +@@ -456,27 +529,20 @@ wait_for_udev: + static int drmOpenMinor(int minor, int create, int type) + { + int fd; +- char buf[64]; +- const char *dev_name; ++ char buf[DRM_NODE_NAME_MAX]; ++ const char *dev_name = drmGetDeviceName(type); + + if (create) + return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type); + +- switch (type) { +- case DRM_NODE_PRIMARY: +- dev_name = DRM_DEV_NAME; +- break; +- case DRM_NODE_CONTROL: +- dev_name = DRM_CONTROL_DEV_NAME; +- break; +- case DRM_NODE_RENDER: +- dev_name = DRM_RENDER_DEV_NAME; +- break; +- default: ++ if (!dev_name) + return -EINVAL; +- }; + ++#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) ++ sprintf(buf, dev_name, DRM_DIR_NAME, minor + drmGetMinorBase(type)); ++#else + sprintf(buf, dev_name, DRM_DIR_NAME, minor); ++#endif + if ((fd = open(buf, O_RDWR, 0)) >= 0) + return fd; + return -errno; +@@ -517,51 +583,6 @@ int drmAvailable(void) + return retval; + } + +-static int drmGetMinorBase(int type) +-{ +- switch (type) { +- case DRM_NODE_PRIMARY: +- return 0; +- case DRM_NODE_CONTROL: +- return 64; +- case DRM_NODE_RENDER: +- return 128; +- default: +- return -1; +- }; +-} +- +-static int drmGetMinorType(int minor) +-{ +- int type = minor >> 6; +- +- if (minor < 0) +- return -1; +- +- switch (type) { +- case DRM_NODE_PRIMARY: +- case DRM_NODE_CONTROL: +- case DRM_NODE_RENDER: +- return type; +- default: +- return -1; +- } +-} +- +-static const char *drmGetMinorName(int type) +-{ +- switch (type) { +- case DRM_NODE_PRIMARY: +- return DRM_PRIMARY_MINOR_NAME; +- case DRM_NODE_CONTROL: +- return DRM_CONTROL_MINOR_NAME; +- case DRM_NODE_RENDER: +- return DRM_RENDER_MINOR_NAME; +- default: +- return NULL; +- } +-} +- + /** + * Open the device by bus ID. + * +@@ -2705,33 +2726,40 @@ int drmDropMaster(int fd) + + char *drmGetDeviceNameFromFd(int fd) + { +- char name[128]; +- struct stat sbuf; +- dev_t d; +- int i; +- + /* The whole drmOpen thing is a fiasco and we need to find a way + * back to just using open(2). For now, however, lets just make + * things worse with even more ad hoc directory walking code to + * discover the device file name. */ + ++ stat_t sbuf; + fstat(fd, &sbuf); +- d = sbuf.st_rdev; ++ dev_t d = sbuf.st_rdev; + +- for (i = 0; i < DRM_MAX_MINOR; i++) { ++ for (int i = 0; i < DRM_MAX_MINOR; i++) { ++ char name[DRM_NODE_NAME_MAX]; + snprintf(name, sizeof name, DRM_DEV_NAME, DRM_DIR_NAME, i); + if (stat(name, &sbuf) == 0 && sbuf.st_rdev == d) +- break; ++ return strdup(name); } -@@ -2833,6 +2843,15 @@ static char *drmGetMinorNameForFD(int fd +- if (i == DRM_MAX_MINOR) +- return NULL; +- +- return strdup(name); ++ return NULL; + } + + int drmGetNodeTypeFromFd(int fd) + { +- struct stat sbuf; ++#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) ++ char *name = drmGetDeviceNameFromFd2(fd); ++ if (!name) { ++ errno = ENODEV; ++ return -1; ++ } ++ ++ int type = drmGetNodeType(name); ++ free(name); ++ if (type < 0) ++ errno = ENODEV; ++ return type; ++#else ++ stat_t sbuf; + int maj, min, type; + + if (fstat(fd, &sbuf)) +@@ -2749,6 +2777,7 @@ int drmGetNodeTypeFromFd(int fd) + if (type == -1) + errno = ENODEV; + return type; ++#endif + } + + int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd) +@@ -2788,7 +2817,7 @@ static char *drmGetMinorNameForFD(int fd + #ifdef __linux__ + DIR *sysdir; + struct dirent *pent, *ent; +- struct stat sbuf; ++ stat_t sbuf; + const char *name = drmGetMinorName(type); + int len; + char dev_name[64], buf[64]; +@@ -2839,13 +2868,35 @@ static char *drmGetMinorNameForFD(int fd out_close_dir: closedir(sysdir); +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) -+ struct stat buf; -+ char name[64]; ++ const char *dev_name = drmGetDeviceName(type); ++ if (!dev_name) ++ return NULL; + -+ fstat(fd, &buf); -+ snprintf(name, sizeof(name), "/dev/%s", -+ devname(buf.st_rdev, S_IFCHR)); ++ char *name = drmGetDeviceNameFromFd2(fd); ++ if (!name) ++ return NULL; + -+ return strdup(name); ++ int oldnum = drmGetNodeNumber(name); ++ int oldtype = drmGetMinorType(oldnum); ++ if (oldtype < 0) { ++ free(name); ++ return NULL; ++ } ++ ++ int newnum = oldnum - drmGetMinorBase(oldtype) + drmGetMinorBase(type); ++ snprintf(name, DRM_NODE_NAME_MAX, dev_name, DRM_DIR_NAME, newnum); ++ return name; #else - struct stat sbuf; - char buf[PATH_MAX + 1]; -@@ -2960,7 +2979,7 @@ static int drmParseSubsystemType(int maj +- struct stat sbuf; +- char buf[PATH_MAX + 1]; +- const char *dev_name; ++ stat_t sbuf; ++ char buf[DRM_NODE_NAME_MAX]; ++ const char *dev_name = drmGetDeviceName(type); + unsigned int maj, min; + int n, base; + ++ if (!dev_name) ++ return NULL; ++ + if (fstat(fd, &sbuf)) + return NULL; + +@@ -2855,20 +2906,6 @@ out_close_dir: + if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) + return NULL; + +- switch (type) { +- case DRM_NODE_PRIMARY: +- dev_name = DRM_DEV_NAME; +- break; +- case DRM_NODE_CONTROL: +- dev_name = DRM_CONTROL_DEV_NAME; +- break; +- case DRM_NODE_RENDER: +- dev_name = DRM_RENDER_DEV_NAME; +- break; +- default: +- return NULL; +- }; +- + base = drmGetMinorBase(type); + if (base < 0) + return NULL; +@@ -2966,7 +3003,7 @@ static int drmParseSubsystemType(int maj return DRM_BUS_HOST1X; return -EINVAL; @@ -76,163 +414,389 @@ return DRM_BUS_PCI; #else #warning "Missing implementation of drmParseSubsystemType" -@@ -3023,6 +3042,61 @@ static int drmParsePciBusInfo(int maj, i +@@ -2974,7 +3011,8 @@ static int drmParseSubsystemType(int maj #endif } -+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) -+/* -+ * XXX temporary workaround, because FreeBSD doesn't provide -+ * pcibus device sysctl trees for renderD and controlD nodes (yet) -+ */ -+static void -+drmBSDDeviceNameHack(const char *path, char *hacked_path, int length) -+{ -+ int start, number; -+ const char *errstr; +-static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info) ++static int drmParsePciBusInfo(const char *node, int node_type, ++ int maj, int min, drmPciBusInfoPtr info) + { + #ifdef __linux__ + unsigned int domain, bus, dev, func; +@@ -3023,6 +3061,60 @@ static int drmParsePciBusInfo(int maj, i + info->func = pinfo.func; + + return 0; ++#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) ++ /* ++ * Only the primary nodes can be mapped to hw.dri.%i via major/minor ++ * Determine the primary node by offset and use its major/minor pair ++ */ ++ if (node_type != DRM_NODE_PRIMARY) { ++ char name[DRM_NODE_NAME_MAX]; ++ snprintf(name, sizeof(name), DRM_DEV_NAME, DRM_DIR_NAME, ++ drmGetNodeNumber(node) - drmGetMinorBase(node_type)); + -+ if (strcmp(path, DRM_DIR_NAME "/controlD") > 0) { -+ start = 17; -+ number = strtonum(&path[start], 0, 256, &errstr) - 64; -+ snprintf(hacked_path, length, "%s/card%i", DRM_DIR_NAME, number); -+ } else if (strcmp(path, DRM_DIR_NAME "/renderD") > 0) { -+ start = 16; -+ number = strtonum(&path[start], 0, 256, &errstr) - 128; -+ snprintf(hacked_path, length, "%s/card%i", DRM_DIR_NAME, number); -+ } else -+ snprintf(hacked_path, length, "%s", path); ++ stat_t sbuf; ++ if (stat(name, &sbuf)) ++ return -errno; + -+ return; -+} -+ -+static int -+drmParsePciBusInfoBSD(const char *path, drmPciBusInfoPtr info) -+{ -+ int fd, ret; -+ int domain = 0, bus = 0, slot = 0, function = 0; -+ char hacked_path[PATH_MAX + 1]; -+ -+ drmBSDDeviceNameHack(path, hacked_path, PATH_MAX); -+ fd = open(hacked_path, O_RDONLY); -+ -+ if (fd < 0) -+ return -errno; -+ -+ ret = devq_device_get_pcibusaddr(fd, &domain, &bus, &slot, &function); -+ -+ if (ret < 0) { -+ close(fd); -+ return -1; ++ maj = major(sbuf.st_rdev); ++ min = minor(sbuf.st_rdev); + } ++ /* ++ * Major/minor appear after the driver name in the hw.dri.%i.name node ++ * Find the node with matching major/minor pair and parse the bus ID, ++ * which may be after the name or may be alone in hw.dri.%i.busid ++ */ ++ #define bus_fmt "pci:%04x:%02x:%02x.%u" ++ #define name_fmt "%*s %x " bus_fmt ++ for (int i = 0; i < DRM_MAX_MINOR; ++i) { ++ char name[16], value[256]; ++ size_t length = sizeof(value); ++ snprintf(name, sizeof(name), "hw.dri.%i.name", i); ++ if (sysctlbyname(name, value, &length, NULL, 0)) ++ continue; + -+ info->domain = (uint16_t) domain; -+ info->bus = (uint8_t) bus; -+ info->dev = (uint8_t) slot; -+ info->func = (uint8_t) function; ++ value[length] = '\0'; ++ unsigned int rdev = 0, domain = 0, bus = 0, slot = 0, func = 0; ++ int vals = sscanf(value, name_fmt, &rdev, &domain, &bus, &slot, &func); + -+ close(fd); -+ return 0; -+} -+#endif -+ - static int drmCompareBusInfo(drmDevicePtr a, drmDevicePtr b) - { - if (a == NULL || b == NULL) -@@ -3188,6 +3262,36 @@ static int drmParsePciDeviceInfo(int maj - #endif ++ if (vals >= 1 && rdev == makedev(maj,min)) { ++ if (vals < 5) { ++ /* busid not in the name, try busid */ ++ length = sizeof(value); ++ snprintf(name, sizeof(name), "hw.dri.%i.busid", i); ++ if (sysctlbyname(name, value, &length, NULL, 0)) ++ break; ++ value[length] = '\0'; ++ if (sscanf(value, bus_fmt, &domain, &bus, &slot, &func) != 4) ++ break; ++ } ++ info->domain = domain; ++ info->bus = bus; ++ info->dev = slot; ++ info->func = func; ++ return 0; ++ } ++ } ++ return -ENODEV; + #else + #warning "Missing implementation of drmParsePciBusInfo" + return -EINVAL; +@@ -3057,32 +3149,6 @@ static int drmCompareBusInfo(drmDevicePt + return -1; } -+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) -+static int drmParsePciDeviceInfoBSD(const char *path, -+ drmPciDeviceInfoPtr device, -+ uint32_t flags) -+{ -+ int fd, vendor_id = 0, device_id = 0, subvendor_id = 0, -+ subdevice_id = 0, revision_id = 0; -+ char hacked_path[PATH_MAX + 1]; +-static int drmGetNodeType(const char *name) +-{ +- if (strncmp(name, DRM_PRIMARY_MINOR_NAME, +- sizeof(DRM_PRIMARY_MINOR_NAME) - 1) == 0) +- return DRM_NODE_PRIMARY; +- +- if (strncmp(name, DRM_CONTROL_MINOR_NAME, +- sizeof(DRM_CONTROL_MINOR_NAME ) - 1) == 0) +- return DRM_NODE_CONTROL; +- +- if (strncmp(name, DRM_RENDER_MINOR_NAME, +- sizeof(DRM_RENDER_MINOR_NAME) - 1) == 0) +- return DRM_NODE_RENDER; +- +- return -EINVAL; +-} +- +-static int drmGetMaxNodeName(void) +-{ +- return sizeof(DRM_DIR_NAME) + +- MAX3(sizeof(DRM_PRIMARY_MINOR_NAME), +- sizeof(DRM_CONTROL_MINOR_NAME), +- sizeof(DRM_RENDER_MINOR_NAME)) + +- 3 /* length of the node number */; +-} +- + #ifdef __linux__ + static int parse_separate_sysfs_files(int maj, int min, + drmPciDeviceInfoPtr device, +@@ -3152,6 +3218,7 @@ static int parse_config_sysfs_file(int m + #endif + + static int drmParsePciDeviceInfo(int maj, int min, ++ drmPciBusInfoPtr info, + drmPciDeviceInfoPtr device, + uint32_t flags) + { +@@ -3188,6 +3255,43 @@ static int drmParsePciDeviceInfo(int maj + device->subdevice_id = pinfo.subdevice_id; + + return 0; ++#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) ++ struct pci_conf_io pc; ++ struct pci_match_conf patterns[1]; ++ struct pci_conf results[1]; + -+ drmBSDDeviceNameHack(path, hacked_path, PATH_MAX); -+ -+ fd = open(hacked_path, O_RDONLY); -+ ++ int fd = open("/dev/pci", O_RDONLY, 0); + if (fd < 0) + return -errno; -+ -+ devq_device_get_pciid_full_from_fd(fd, &vendor_id, &device_id, -+ &subvendor_id, &subdevice_id, &revision_id); + -+ device->vendor_id = (uint16_t) vendor_id; -+ device->device_id = (uint16_t) device_id; -+ device->subvendor_id = (uint16_t) subvendor_id; -+ device->subdevice_id = (uint16_t) subdevice_id; -+ device->revision_id = (uint8_t) revision_id; -+ ++ bzero(&patterns, sizeof(patterns)); ++ patterns[0].pc_sel.pc_domain = info->domain; ++ patterns[0].pc_sel.pc_bus = info->bus; ++ patterns[0].pc_sel.pc_dev = info->dev; ++ patterns[0].pc_sel.pc_func = info->func; ++ patterns[0].flags = PCI_GETCONF_MATCH_DOMAIN | PCI_GETCONF_MATCH_BUS ++ | PCI_GETCONF_MATCH_DEV | PCI_GETCONF_MATCH_FUNC; ++ bzero(&pc, sizeof(struct pci_conf_io)); ++ pc.num_patterns = 1; ++ pc.pat_buf_len = sizeof(patterns); ++ pc.patterns = patterns; ++ pc.match_buf_len = sizeof(results); ++ pc.matches = results; ++ ++ if (ioctl(fd, PCIOCGETCONF, &pc) || pc.status == PCI_GETCONF_ERROR) { ++ int error = errno; ++ close(fd); ++ return -error; ++ } + close(fd); -+ return 0; -+} -+#endif + - static void drmFreePlatformDevice(drmDevicePtr device) - { - if (device->deviceinfo.platform) { -@@ -3308,7 +3412,11 @@ static int drmProcessPciDevice(drmDevice ++ device->vendor_id = results[0].pc_vendor; ++ device->device_id = results[0].pc_device; ++ device->subvendor_id = results[0].pc_subvendor; ++ device->subdevice_id = results[0].pc_subdevice; ++ device->revision_id = results[0].pc_revid; ++ ++ return 0; + #else + #warning "Missing implementation of drmParsePciDeviceInfo" + return -EINVAL; +@@ -3268,7 +3372,7 @@ static drmDevicePtr drmDeviceAlloc(unsig + unsigned int i; + char *ptr; + +- max_node_length = ALIGN(drmGetMaxNodeName(), sizeof(void *)); ++ max_node_length = ALIGN(DRM_NODE_NAME_MAX, sizeof(void *)); + extra = DRM_NODE_MAX * (sizeof(void *) + max_node_length); + + size = sizeof(*device) + extra + bus_size + device_size; +@@ -3314,7 +3418,7 @@ static int drmProcessPciDevice(drmDevice dev->businfo.pci = (drmPciBusInfoPtr)addr; -+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) -+ ret = drmParsePciBusInfoBSD(node, dev->businfo.pci); -+#else - ret = drmParsePciBusInfo(maj, min, dev->businfo.pci); -+#endif +- ret = drmParsePciBusInfo(maj, min, dev->businfo.pci); ++ ret = drmParsePciBusInfo(node, node_type, maj, min, dev->businfo.pci); if (ret) goto free_device; -@@ -3316,8 +3424,11 @@ static int drmProcessPciDevice(drmDevice - if (fetch_deviceinfo) { +@@ -3323,7 +3427,7 @@ static int drmProcessPciDevice(drmDevice addr += sizeof(drmPciBusInfo); dev->deviceinfo.pci = (drmPciDeviceInfoPtr)addr; -- -+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) -+ ret = drmParsePciDeviceInfoBSD(node, dev->deviceinfo.pci, flags); -+#else - ret = drmParsePciDeviceInfo(maj, min, dev->deviceinfo.pci, flags); -+#endif + +- ret = drmParsePciDeviceInfo(maj, min, dev->deviceinfo.pci, flags); ++ ret = drmParsePciDeviceInfo(maj, min, dev->businfo.pci, dev->deviceinfo.pci, flags); if (ret) goto free_device; } -@@ -3786,7 +3897,7 @@ int drmGetDevice2(int fd, uint32_t flags +@@ -3673,7 +3777,7 @@ static void drmFoldDuplicatedDevices(drm + local_devices[i]->available_nodes |= local_devices[j]->available_nodes; + node_type = log2(local_devices[j]->available_nodes); + memcpy(local_devices[i]->nodes[node_type], +- local_devices[j]->nodes[node_type], drmGetMaxNodeName()); ++ local_devices[j]->nodes[node_type], DRM_NODE_NAME_MAX); + drmFreeDevice(&local_devices[j]); + } + } +@@ -3691,7 +3795,7 @@ drm_device_validate_flags(uint32_t flags + * Get information about the opened drm device + * + * \param fd file descriptor of the drm device +- * \param flags feature/behaviour bitmask ++ * \param flags feature/behavior bitmask + * \param device the address of a drmDevicePtr where the information + * will be allocated in stored + * +@@ -3709,8 +3813,8 @@ int drmGetDevice2(int fd, uint32_t flags + * Avoid stat'ing all of /dev needlessly by implementing this custom path. + */ + drmDevicePtr d; +- struct stat sbuf; +- char node[PATH_MAX + 1]; ++ stat_t sbuf; ++ char node[DRM_NODE_NAME_MAX]; + const char *dev_name; + int node_type, subsystem_type; + int maj, min, n, ret, base; +@@ -3731,26 +3835,16 @@ int drmGetDevice2(int fd, uint32_t flags + if (node_type == -1) + return -ENODEV; + +- switch (node_type) { +- case DRM_NODE_PRIMARY: +- dev_name = DRM_DEV_NAME; +- break; +- case DRM_NODE_CONTROL: +- dev_name = DRM_CONTROL_DEV_NAME; +- break; +- case DRM_NODE_RENDER: +- dev_name = DRM_RENDER_DEV_NAME; +- break; +- default: ++ dev_name = drmGetDeviceName(node_type); ++ if (!dev_name) + return -EINVAL; +- }; + + base = drmGetMinorBase(node_type); + if (base < 0) + return -EINVAL; + +- n = snprintf(node, PATH_MAX, dev_name, DRM_DIR_NAME, min - base); +- if (n == -1 || n >= PATH_MAX) ++ n = snprintf(node, sizeof(node), dev_name, DRM_DIR_NAME, min - base); ++ if (n == -1 || n >= sizeof(node)) + return -errno; + if (stat(node, &sbuf)) + return -EINVAL; +@@ -3771,8 +3865,8 @@ int drmGetDevice2(int fd, uint32_t flags + drmDevicePtr d; + DIR *sysdir; + struct dirent *dent; +- struct stat sbuf; +- char node[PATH_MAX + 1]; ++ stat_t sbuf; ++ char node[DRM_NODE_NAME_MAX]; + int node_type, subsystem_type; + int maj, min; + int ret, i, node_count; +@@ -3792,7 +3886,7 @@ int drmGetDevice2(int fd, uint32_t flags maj = major(sbuf.st_rdev); min = minor(sbuf.st_rdev); - if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) -+ if (DRM_MAJOR && maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) ++ if ((DRM_MAJOR && maj != DRM_MAJOR) || !S_ISCHR(sbuf.st_mode)) return -EINVAL; subsystem_type = drmParseSubsystemType(maj, min); -@@ -3814,7 +3925,7 @@ int drmGetDevice2(int fd, uint32_t flags +@@ -3813,14 +3907,14 @@ int drmGetDevice2(int fd, uint32_t flags + if (node_type < 0) + continue; + +- snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, dent->d_name); ++ snprintf(node, sizeof(node), "%s/%s", DRM_DIR_NAME, dent->d_name); + if (stat(node, &sbuf)) + continue; + maj = major(sbuf.st_rdev); min = minor(sbuf.st_rdev); - if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) -+ if (DRM_MAJOR && maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) ++ if ((DRM_MAJOR && maj != DRM_MAJOR) || !S_ISCHR(sbuf.st_mode)) continue; if (drmParseSubsystemType(maj, min) != subsystem_type) -@@ -3964,7 +4075,7 @@ int drmGetDevices2(uint32_t flags, drmDe +@@ -3918,7 +4012,7 @@ int drmGetDevice(int fd, drmDevicePtr *d + /** + * Get drm devices on the system + * +- * \param flags feature/behaviour bitmask ++ * \param flags feature/behavior bitmask + * \param devices the array of devices with drmDevicePtr elements + * can be NULL to get the device number first + * \param max_devices the maximum number of devices for the array +@@ -3937,8 +4031,8 @@ int drmGetDevices2(uint32_t flags, drmDe + drmDevicePtr device; + DIR *sysdir; + struct dirent *dent; +- struct stat sbuf; +- char node[PATH_MAX + 1]; ++ stat_t sbuf; ++ char node[DRM_NODE_NAME_MAX]; + int node_type, subsystem_type; + int maj, min; + int ret, i, node_count, device_count; +@@ -3963,14 +4057,14 @@ int drmGetDevices2(uint32_t flags, drmDe + if (node_type < 0) + continue; + +- snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, dent->d_name); ++ snprintf(node, sizeof(node), "%s/%s", DRM_DIR_NAME, dent->d_name); + if (stat(node, &sbuf)) + continue; + maj = major(sbuf.st_rdev); min = minor(sbuf.st_rdev); - if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) -+ if (DRM_MAJOR && maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) ++ if ((DRM_MAJOR && maj != DRM_MAJOR) || !S_ISCHR(sbuf.st_mode)) continue; subsystem_type = drmParseSubsystemType(maj, min); -@@ -4108,7 +4219,7 @@ char *drmGetDeviceNameFromFd2(int fd) - maj = major(sbuf.st_rdev); - min = minor(sbuf.st_rdev); +@@ -4078,7 +4172,7 @@ int drmGetDevices(drmDevicePtr devices[] + char *drmGetDeviceNameFromFd2(int fd) + { + #ifdef __linux__ +- struct stat sbuf; ++ stat_t sbuf; + char path[PATH_MAX + 1], *value; + unsigned int maj, min; -- if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) -+ if (DRM_MAJOR && maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) +@@ -4101,9 +4195,26 @@ char *drmGetDeviceNameFromFd2(int fd) + free(value); + + return strdup(path); ++#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) ++ stat_t sbuf; ++ if (fstat(fd, &sbuf)) ++ return NULL; ++ ++ dev_t rdev = sbuf.st_rdev; ++ /* minor numbers don't depend on node name suffix, search for a match */ ++ for (int i = 0; i < DRM_MAX_MINOR; ++i) { ++ char node[DRM_NODE_NAME_MAX]; ++ for (int j = 0; j < DRM_NODE_MAX; ++j) { ++ snprintf(node, sizeof(node), drmGetDeviceName(j), ++ DRM_DIR_NAME, drmGetMinorBase(j) + i); ++ if (stat(node, &sbuf) == 0 && sbuf.st_rdev == rdev) ++ return strdup(node); ++ } ++ } ++ return NULL; + #else +- struct stat sbuf; +- char node[PATH_MAX + 1]; ++ stat_t sbuf; ++ char node[DRM_NODE_NAME_MAX]; + const char *dev_name; + int node_type; + int maj, min, n, base; +@@ -4121,26 +4232,16 @@ char *drmGetDeviceNameFromFd2(int fd) + if (node_type == -1) return NULL; - node_type = drmGetMinorType(min); +- switch (node_type) { +- case DRM_NODE_PRIMARY: +- dev_name = DRM_DEV_NAME; +- break; +- case DRM_NODE_CONTROL: +- dev_name = DRM_CONTROL_DEV_NAME; +- break; +- case DRM_NODE_RENDER: +- dev_name = DRM_RENDER_DEV_NAME; +- break; +- default: ++ dev_name = drmGetDeviceName(node_type); ++ if (!dev_name) + return NULL; +- }; + + base = drmGetMinorBase(node_type); + if (base < 0) + return NULL; + +- n = snprintf(node, PATH_MAX, dev_name, DRM_DIR_NAME, min - base); +- if (n == -1 || n >= PATH_MAX) ++ n = snprintf(node, sizeof(node), dev_name, DRM_DIR_NAME, min - base); ++ if (n == -1 || n >= sizeof(node)) + return NULL; + + return strdup(node); diff --git a/graphics/libdrm/files/patch-xf86drm.h b/graphics/libdrm/files/patch-xf86drm.h new file mode 100644 index 000000000000..f054be787e6e --- /dev/null +++ b/graphics/libdrm/files/patch-xf86drm.h @@ -0,0 +1,37 @@ +--- xf86drm.h.orig 2017-04-07 08:49:13 UTC ++++ xf86drm.h +@@ -78,17 +78,27 @@ extern "C" { + + #ifdef __OpenBSD__ + #define DRM_DIR_NAME "/dev" +-#define DRM_DEV_NAME "%s/drm%d" +-#define DRM_CONTROL_DEV_NAME "%s/drmC%d" +-#define DRM_RENDER_DEV_NAME "%s/drmR%d" ++#define DRM_PRIMARY_MINOR_NAME "drm" ++#define DRM_CONTROL_MINOR_NAME "drmC" ++#define DRM_RENDER_MINOR_NAME "drmR" + #else + #define DRM_DIR_NAME "/dev/dri" +-#define DRM_DEV_NAME "%s/card%d" +-#define DRM_CONTROL_DEV_NAME "%s/controlD%d" +-#define DRM_RENDER_DEV_NAME "%s/renderD%d" +-#define DRM_PROC_NAME "/proc/dri/" /* For backward Linux compatibility */ ++#define DRM_PRIMARY_MINOR_NAME "card" ++#define DRM_CONTROL_MINOR_NAME "controlD" ++#define DRM_RENDER_MINOR_NAME "renderD" + #endif + ++#define DRM_DEV_NAME "%s/" DRM_PRIMARY_MINOR_NAME "%d" ++#define DRM_CONTROL_DEV_NAME "%s/" DRM_CONTROL_MINOR_NAME "%d" ++#define DRM_RENDER_DEV_NAME "%s/" DRM_RENDER_MINOR_NAME "%d" ++ ++#define DRM_NODE_NAME_MAX \ ++ (sizeof(DRM_DIR_NAME) + \ ++ MAX3(sizeof(DRM_PRIMARY_MINOR_NAME), \ ++ sizeof(DRM_CONTROL_MINOR_NAME), \ ++ sizeof(DRM_RENDER_MINOR_NAME)) \ ++ + 3) /* length of the node number */ ++ + #define DRM_ERR_NO_DEVICE (-1001) + #define DRM_ERR_NO_ACCESS (-1002) + #define DRM_ERR_NOT_ROOT (-1003) diff --git a/graphics/libdrm/files/patch-xf86drmMode.c b/graphics/libdrm/files/patch-xf86drmMode.c index 3d7ef3780232..35c7458d84c8 100644 --- a/graphics/libdrm/files/patch-xf86drmMode.c +++ b/graphics/libdrm/files/patch-xf86drmMode.c @@ -1,4 +1,4 @@ ---- xf86drmMode.c.orig 2017-01-28 01:15:16 UTC +--- xf86drmMode.c.orig 2017-04-07 08:49:13 UTC +++ xf86drmMode.c @@ -47,6 +47,7 @@ #include @@ -8,3 +8,96 @@ #include #endif #include +@@ -796,43 +797,60 @@ int drmCheckModesettingSupported(const c + closedir(sysdir); + if (found) + return 0; +-#elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__) +- char kbusid[1024], sbusid[1024]; +- char oid[128]; +- int domain, bus, dev, func; +- int i, modesetting, ret; +- size_t len; ++#elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__DragonFly__) ++ #define bus_fmt "pci:%04x:%02x:%02x.%u" ++ #define name_fmt "%*s %*s " bus_fmt ++ unsigned int d1 = 0, b1 = 0, s1 = 0, f1 = 0; ++ if (sscanf(busid, bus_fmt, &d1, &b1, &s1, &f1) != 4) ++ return -EINVAL; ++ /* ++ * hw.dri.%i.bus is not always present and hw.dri.%i.name does not ++ * always contain the busid, so try both for best chance of success ++ */ ++ for (int i = 0; i < DRM_MAX_MINOR; ++i) { ++ char name[22], value[256]; ++ size_t length = sizeof(value); ++ snprintf(name, sizeof(name), "hw.dri.%i.name", i); ++ if (sysctlbyname(name, value, &length, NULL, 0)) ++ continue; + +- ret = sscanf(busid, "pci:%04x:%02x:%02x.%d", &domain, &bus, &dev, +- &func); +- if (ret != 4) +- return -EINVAL; +- snprintf(kbusid, sizeof(kbusid), "pci:%04x:%02x:%02x.%d", domain, bus, +- dev, func); ++ value[length] = '\0'; ++ unsigned int d2 = 0, b2 = 0, s2 = 0, f2 = 0; ++ switch (sscanf(value, name_fmt, &d2, &b2, &s2, &f2)) { ++ case 0: /* busid not in the name, try busid */ ++ length = sizeof(value); ++ snprintf(name, sizeof(name), "hw.dri.%i.busid", i); ++ if (sysctlbyname(name, value, &length, NULL, 0)) ++ continue; + +- /* How many GPUs do we expect in the machine ? */ +- for (i = 0; i < 16; i++) { +- snprintf(oid, sizeof(oid), "hw.dri.%d.busid", i); +- len = sizeof(sbusid); +- ret = sysctlbyname(oid, sbusid, &len, NULL, 0); +- if (ret == -1) { +- if (errno == ENOENT) ++ value[length] = '\0'; ++ if (sscanf(value, bus_fmt, &d2, &b2, &s2, &f2) != 4) + continue; +- return -EINVAL; ++ /* fall through after parsing busid */ ++ ++ case 4: /* if we jumped here then busid was in the name */ ++ if (d1 == d2 && b1 == b2 && s1 == s2 && f1 == f2) { ++ /* ++ * Confirm the drm driver for this device supports KMS, ++ * except on DragonFly where all the drm drivers do so ++ * but only hw.dri.0.modesetting is present ++ */ ++ #ifndef __DragonFly__ ++ int modesetting = 0; ++ length = sizeof(modesetting); ++ snprintf(name, sizeof(name), "hw.dri.%i.modesetting", i); ++ if (sysctlbyname(name, &modesetting, &length, NULL, 0) ++ || length != sizeof(modesetting) || !modesetting) ++ return -ENOSYS; ++ else ++ #endif ++ return 0; ++ } ++ default: ++ break; + } +- if (strcmp(sbusid, kbusid) != 0) +- continue; +- snprintf(oid, sizeof(oid), "hw.dri.%d.modesetting", i); +- len = sizeof(modesetting); +- ret = sysctlbyname(oid, &modesetting, &len, NULL, 0); +- if (ret == -1 || len != sizeof(modesetting)) +- return -EINVAL; +- return (modesetting ? 0 : -ENOSYS); + } +-#elif defined(__DragonFly__) +- return 0; +-#endif +-#ifdef __OpenBSD__ ++#elif defined(__OpenBSD__) + int fd; + struct drm_mode_card_res res; + drmModeResPtr r = 0;