pkgsrc-WIP-changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

libdrm-dfbsd: Update wip/libdrm-dfbsd to 2.4.91



Module Name:	pkgsrc-wip
Committed By:	David Shao <davshao%gmail.com@localhost>
Pushed By:	dshao
Date:		Mon Apr 30 23:39:42 2018 -0700
Changeset:	bb674e20a032596b0f21f3977603daf530c54d30

Modified Files:
	libdrm-dfbsd/Makefile
	libdrm-dfbsd/PLIST
	libdrm-dfbsd/builtin.mk
	libdrm-dfbsd/distinfo
	libdrm-dfbsd/patches/patch-ab
	libdrm-dfbsd/patches/patch-ac
	libdrm-dfbsd/patches/patch-libkms_vmwgfx.c
	libdrm-dfbsd/patches/patch-radeon_radeon__bo__gem.c
	libdrm-dfbsd/patches/patch-radeon_radeon__cs__gem.c
	libdrm-dfbsd/patches/patch-xf86drmMode.c
Added Files:
	libdrm-dfbsd/patches/patch-libsync.h

Log Message:
libdrm-dfbsd: Update wip/libdrm-dfbsd to 2.4.91

To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=bb674e20a032596b0f21f3977603daf530c54d30

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

diffstat:
 libdrm-dfbsd/Makefile                              |   16 +-
 libdrm-dfbsd/PLIST                                 |    5 +-
 libdrm-dfbsd/builtin.mk                            |    2 +-
 libdrm-dfbsd/distinfo                              |   23 +-
 libdrm-dfbsd/patches/patch-ab                      | 1322 ++++++++++++--------
 libdrm-dfbsd/patches/patch-ac                      |   41 +-
 libdrm-dfbsd/patches/patch-libkms_vmwgfx.c         |   37 +-
 libdrm-dfbsd/patches/patch-libsync.h               |   18 +
 .../patches/patch-radeon_radeon__bo__gem.c         |   22 +-
 .../patches/patch-radeon_radeon__cs__gem.c         |   13 +-
 libdrm-dfbsd/patches/patch-xf86drmMode.c           |  118 +-
 11 files changed, 1040 insertions(+), 577 deletions(-)

diffs:
diff --git a/libdrm-dfbsd/Makefile b/libdrm-dfbsd/Makefile
index 82be8525da..6e35fb458d 100644
--- a/libdrm-dfbsd/Makefile
+++ b/libdrm-dfbsd/Makefile
@@ -1,6 +1,6 @@
-# $NetBSD: Makefile,v 1.73 2017/05/26 09:28:14 wiz Exp $
+# $NetBSD: Makefile,v 1.80 2018/03/07 12:12:35 wiz Exp $
 
-DISTNAME=		libdrm-2.4.81
+DISTNAME=		libdrm-2.4.91
 CATEGORIES=		x11 graphics
 MASTER_SITES=		http://dri.freedesktop.org/libdrm/
 EXTRACT_SUFX=		.tar.bz2
@@ -13,7 +13,7 @@ ONLY_FOR_PLATFORM=	NetBSD-*-* DragonFly-*-* FreeBSD-*-* OpenBSD-*-* \
 			Linux-*-* SunOS-*-*
 
 USE_PKGLOCALEDIR=	yes
-USE_TOOLS+=		pkg-config
+USE_TOOLS+=		gmake pkg-config
 USE_LIBTOOL=		yes
 PKGCONFIG_OVERRIDE+=	libdrm.pc.in
 PKGCONFIG_OVERRIDE+=	libkms.pc.in
@@ -31,9 +31,12 @@ ATOMIC_OPS_CHECK=	0
 .if exists(${CROSS_DESTDIR}/usr/include/sys/atomic.h)
 ATOMIC_OPS_CHECK=	1
 .else
+# Intel driver no longer needs libatomic_ops
+.if ${MACHINE_ARCH} != "i386" && ${MACHINE_ARCH} != x86_64
 .  include "../../devel/libatomic_ops/buildlink3.mk"
 CONFIGURE_ENV+=		drm_cv_atomic_primitives=libatomic-ops
 .endif
+.endif
 
 CONFIGURE_ARGS+=	--disable-manpages
 CONFIGURE_ARGS+=	--disable-valgrind
@@ -60,6 +63,9 @@ PKG_SUGGESTED_OPTIONS+=	pthreadstubs
 PKG_SUGGESTED_OPTIONS+=	libkms
 .endif
 
+# avoid circular dependency in case cairo supports OpenGL (cairo->mesa-libs->libdrm->cairo)
+CONFIGURE_ARGS+=	--disable-cairo-tests
+
 .include "../../mk/bsd.options.mk"
 
 .if !empty(PKG_OPTIONS:Mpthreadstubs)
@@ -67,9 +73,9 @@ CONFIGURE_ARGS+=	PTHREADSTUBS_CFLAGS=-I${PREFIX}/include \
 			PTHREADSTUBS_LIBS=-L${PREFIX}/lib
 .endif
 
-PLIST_VARS+=		libkms	
+PLIST_VARS+=	libkms	
 .if !empty(PKG_OPTIONS:Mlibkms)
-PLIST.libkms=		yes
+PLIST.libkms=	yes
 CONFIGURE_ARGS+=	--enable-libkms
 .else
 CONFIGURE_ARGS+=	--disable-libkms
diff --git a/libdrm-dfbsd/PLIST b/libdrm-dfbsd/PLIST
index b83036426e..0182516978 100644
--- a/libdrm-dfbsd/PLIST
+++ b/libdrm-dfbsd/PLIST
@@ -1,4 +1,4 @@
-@comment $NetBSD: PLIST,v 1.19 2016/11/15 10:05:52 wiz Exp $
+@comment $NetBSD: PLIST,v 1.20 2017/08/26 05:47:56 wiz Exp $
 ${PLIST.arm}include/freedreno/freedreno_drmif.h
 ${PLIST.arm}include/freedreno/freedreno_ringbuffer.h
 include/libdrm/amdgpu.h
@@ -37,12 +37,12 @@ include/libdrm/savage_drm.h
 include/libdrm/sis_drm.h
 include/libdrm/tegra_drm.h
 include/libdrm/vc4_drm.h
+${PLIST.libkms}include/libkms/libkms.h
 ${PLIST.arm}include/libdrm/vc4_packet.h
 ${PLIST.arm}include/libdrm/vc4_qpu_defines.h
 include/libdrm/via_drm.h
 include/libdrm/virtgpu_drm.h
 include/libdrm/vmwgfx_drm.h
-${PLIST.libkms}include/libkms/libkms.h
 include/libsync.h
 include/xf86drm.h
 include/xf86drmMode.h
@@ -61,3 +61,4 @@ lib/pkgconfig/libdrm_nouveau.pc
 lib/pkgconfig/libdrm_radeon.pc
 ${PLIST.arm}lib/pkgconfig/libdrm_vc4.pc
 ${PLIST.libkms}lib/pkgconfig/libkms.pc
+share/libdrm/amdgpu.ids
diff --git a/libdrm-dfbsd/builtin.mk b/libdrm-dfbsd/builtin.mk
index 1b52d9b25e..d9fe1b4f32 100644
--- a/libdrm-dfbsd/builtin.mk
+++ b/libdrm-dfbsd/builtin.mk
@@ -1,6 +1,6 @@
 # $NetBSD: builtin.mk,v 1.3 2014/03/10 11:05:53 jperkin Exp $
 
-BUILTIN_PKG:=		libdrm
+BUILTIN_PKG:=	libdrm
 PKGCONFIG_FILE.libdrm=	${X11BASE}/lib/pkgconfig/libdrm.pc
 PKGCONFIG_FILE.libdrm+=	${X11BASE}/lib${LIBABISUFFIX}/pkgconfig/libdrm.pc
 
diff --git a/libdrm-dfbsd/distinfo b/libdrm-dfbsd/distinfo
index 3a3b783b83..4b1b7e266d 100644
--- a/libdrm-dfbsd/distinfo
+++ b/libdrm-dfbsd/distinfo
@@ -1,14 +1,15 @@
-$NetBSD: distinfo,v 1.72 2017/04/17 07:28:30 wiz Exp $
+$NetBSD: distinfo,v 1.80 2018/03/07 12:12:35 wiz Exp $
 
-SHA1 (libdrm-2.4.81.tar.bz2) = 40f0994b5fb9992e6f55d3a14537def21719d896
-RMD160 (libdrm-2.4.81.tar.bz2) = e2ac3f8aacab4e63580c06c808a2b9c46b0e3f9b
-SHA512 (libdrm-2.4.81.tar.bz2) = 5f7a1524acad59890d3f890bed90a660a424e18a88d587ca356223bde4a7446d1c540f97ec11cb10d2e7ed1b4ae86127957634354a1be6d04199295ab24782e5
-Size (libdrm-2.4.81.tar.bz2) = 786276 bytes
-SHA1 (patch-ab) = a61abf809f77b375e29f887d82c07eaa3126bbac
-SHA1 (patch-ac) = 67c998df7dfc0dabc86320ea6d015cede3e464ea
+SHA1 (libdrm-2.4.91.tar.bz2) = 44e42ce3cd41666e343ba393c73f6f1ad9fe1e74
+RMD160 (libdrm-2.4.91.tar.bz2) = d1c35b94703fdfb944c54451fe65977d24d7a568
+SHA512 (libdrm-2.4.91.tar.bz2) = 07578c00c121ba37033db7172590e26d1545f81c242bbce2cfb7fb904bde504822c275d6468e5c5d20360d0046ae73d9b058aa0459ba35eb11927141cc998772
+Size (libdrm-2.4.91.tar.bz2) = 815419 bytes
+SHA1 (patch-ab) = c2d32279cbf91e57ee1fd1d237186e029ebaffaf
+SHA1 (patch-ac) = 87d34e929f6ebeaa7991d343b3025a0a3b276329
 SHA1 (patch-include_drm_drm.h) = 48a912f40bf2b2a1c23edbe4446fa7869212f17b
-SHA1 (patch-libkms_vmwgfx.c) = d2204c0b79098c6c36b7f282b486c58c6354bd1d
-SHA1 (patch-radeon_radeon__bo__gem.c) = 4924fde172b2a2a713d47bf7b60a6b52851d7a8f
-SHA1 (patch-radeon_radeon__cs__gem.c) = 516b5dd6408c10a4f33f2815b3719e34a16d863a
+SHA1 (patch-libkms_vmwgfx.c) = 159228d66cfa12bbbad268a8881ffdf5127799b5
+SHA1 (patch-libsync.h) = 937d1150bf816e5f7809fa96ad7f981895bf99f5
+SHA1 (patch-radeon_radeon__bo__gem.c) = 93a9238277f40813b3d1c1e6984106657d654dc7
+SHA1 (patch-radeon_radeon__cs__gem.c) = 5cc9bd1a5f62fb380f9f92b7ce1c44769b35c751
 SHA1 (patch-xf86atomic.h) = 887db95db00125bdfa1ab298b2ccc555dec70366
-SHA1 (patch-xf86drmMode.c) = 29485f5d03d2538145599fd74a28e2d2acd7d8d6
+SHA1 (patch-xf86drmMode.c) = ad3c2c9188e6582c4f311851bd366ad873455750
diff --git a/libdrm-dfbsd/patches/patch-ab b/libdrm-dfbsd/patches/patch-ab
index 55beeffd11..a399ac786c 100644
--- a/libdrm-dfbsd/patches/patch-ab
+++ b/libdrm-dfbsd/patches/patch-ab
@@ -3,88 +3,48 @@ $NetBSD: patch-ab,v 1.8 2015/08/14 17:12:35 wiz Exp $
 Code for OpenBSD adapted for NetBSD.  Assumes NetBSD kernel has been
 patched to use drm ioctl number 0x0f.
 
-Patches from FreeBSD ports libdrm 2.4.75.
+Patches from FreeBSD ports / DragonFly dports for graphics/libdrm 2.4.84.
 
-Patches from https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=214580
-and code from libdevq 0.0.4.
-
-Tries to account for DragonFly major number not well defined.
-
-Tries to account for FreeBSD device control64D to be ignored.
-
-Many debugging messages added for use with LIBGL_DEBUG=verbose.
-
-Added code to deduce node type from a device name such as dri/card0
-for FreeBSD, DragonFly, and NetBSD, OSes that support devname().
-Moved static drmGetNodeType() for drmGetNodeTypeFromFd().
-
---- xf86drm.c.orig	2017-05-24 15:03:41.000000000 +0000
+--- xf86drm.c.orig	2017-12-18 01:33:10.000000000 +0000
 +++ xf86drm.c
-@@ -31,6 +31,36 @@
-  * DEALINGS IN THE SOFTWARE.
-  */
- 
-+/* Port for FreeBSD and DragonFly uses code from libdevq 0.0.4
-+ *     https://github.com/freebsd/libdevq
-+ * with copyright notice:
-+ *
-+ * Copyright (c) 2014 Jean-Sebastien Pedron <dumbbell%FreeBSD.org@localhost>
-+ * Copyright (c) 2016 Koop Mast <kwm%FreeBSD.org@localhost>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer
-+ *    in this position and unchanged.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
- #ifdef HAVE_CONFIG_H
- # include <config.h>
- #endif
-@@ -72,6 +102,10 @@
- 
- #include "util_math.h"
- 
-+#if defined(__FreeBSD__) || defined(__DragonFly__)
+@@ -49,6 +49,9 @@
+ #include <signal.h>
+ #include <time.h>
+ #include <sys/types.h>
++#ifdef HAVE_SYS_SYSCTL_H
 +#include <sys/sysctl.h>
 +#endif
-+
- #ifdef __OpenBSD__
- #define DRM_PRIMARY_MINOR_NAME  "drm"
- #define DRM_CONTROL_MINOR_NAME  "drmC"
-@@ -82,12 +116,22 @@
- #define DRM_RENDER_MINOR_NAME   "renderD"
+ #include <sys/stat.h>
+ #define stat_t struct stat
+ #include <sys/ioctl.h>
+@@ -62,6 +65,10 @@
  #endif
+ #include <math.h>
  
--#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
--#define DRM_MAJOR 145
-+/*
-+ * The major number of the device corresponding to the file descriptor
-+ * is not well defined on either FreeBSD or DragonFly, so for these
-+ * OSes checking using DRM_MAJOR will be ignored.
-+ */ 
-+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-+#define DRM_MAJOR 0 
++#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
++#include <sys/pciio.h>
 +#endif
 +
-+#if defined(__DragonFly__)
-+#define DRM_MAJOR 64
+ /* Not all systems have MAP_FAILED defined */
+ #ifndef MAP_FAILED
+ #define MAP_FAILED ((void *)-1)
+@@ -72,22 +79,13 @@
+ 
+ #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
++#define DRM_MAJOR 0	/* Major ID unused on systems with devfs */
  #endif
  
  #ifdef __NetBSD__
@@ -94,7 +54,7 @@ Moved static drmGetNodeType() for drmGetNodeTypeFromFd().
  #endif
  
  #ifdef __OpenBSD__
-@@ -102,7 +146,7 @@
+@@ -102,7 +100,7 @@
  #define DRM_MAJOR 226 /* Linux */
  #endif
  
@@ -103,7 +63,7 @@ Moved static drmGetNodeType() for drmGetNodeTypeFromFd().
  struct drm_pciinfo {
  	uint16_t	domain;
  	uint8_t		bus;
-@@ -114,8 +158,12 @@ struct drm_pciinfo {
+@@ -114,8 +112,12 @@ struct drm_pciinfo {
  	uint16_t	subdevice_id;
  	uint8_t		revision_id;
  };
@@ -116,11 +76,20 @@ Moved static drmGetNodeType() for drmGetNodeTypeFromFd().
  #endif
  
  #define DRM_MSG_VERBOSITY 3
-@@ -189,7 +237,15 @@ drmIoctl(int fd, unsigned long request,
+@@ -180,7 +182,7 @@ void drmFree(void *pt)
+ }
+ 
+ /**
+- * Call ioctl, restarting if it is interupted
++ * Call ioctl, restarting if it is interrupted
+  */
+ int
+ drmIoctl(int fd, unsigned long request, void *arg)
+@@ -189,10 +191,111 @@ drmIoctl(int fd, unsigned long request,
  
      do {
          ret = ioctl(fd, request, arg);
-+#if defined(__FreeBSD__)
++#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 +/*
 + * FreeBSD Bug 204174: error code 512 (ERESTARTSYS) leaked from kernel space
 + * for some older kernels.
@@ -129,145 +98,385 @@ Moved static drmGetNodeType() for drmGetNodeTypeFromFd().
 +#else
      } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
 +#endif
++    if (ret) {
++        struct stat sbuf;
++        char name[64];
++
++        fstat(fd, &sbuf);
++        snprintf(name, sizeof(name), "%s", devname(sbuf.st_rdev, S_IFCHR));
++
++        drmMsg("[drm] drmIoctl FAILED  : fd (%d), device (%s): request (0x%08lx): ret (%d), errno (%d), (%s)\n",
++            fd, name, request, ret, errno, strerror(errno));
++    }
      return ret;
  }
  
-@@ -499,17 +555,25 @@ int drmAvailable(void)
-     int           retval = 0;
-     int           fd;
- 
-+    drmMsg("drmAvailable: Testing if DRM kernel driver has been loaded\n");
++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;
++    };
++}
 +
-     if ((fd = drmOpenMinor(0, 1, DRM_NODE_PRIMARY)) < 0) {
- #ifdef __linux__
-         /* Try proc for backward Linux compatibility */
++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;
++    }
++}
++
++#if defined(__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;
++}
++
+ static unsigned long drmGetKeyFromFd(int fd)
+ {
+     stat_t     st;
+@@ -290,7 +393,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 +430,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 +441,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 +552,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;
+@@ -505,11 +594,17 @@ int drmAvailable(void)
          if (!access("/proc/dri/0", R_OK))
              return 1;
  #endif
 +
-+        drmMsg("drmAvailable: FAILED to open drm minor 0 (%d)\n", fd);
++        drmMsg("[drm] drmAvailable: FAILED  to open drm minor 0: fd (%d)\n", fd);
 +
          return 0;
      }
  
-+    drmMsg("drmAvailable: Opened drm minor 0 with fd (%d)\n", fd);
++    drmMsg("[drm] drmAvailable: OPENED drm minor 0 with fd (%d)\n", fd);
 +
      if ((version = drmGetVersion(fd))) {
          retval = 1;
-+        drmMsg("drmAvailable: Success version non-null for fd (%d)\n", fd);
++        drmMsg("[drm] drmAvailable: SUCCESS to open drm minor 0: fd (%d)\n", fd);
          drmFreeVersion(version);
      }
      close(fd);
-@@ -531,6 +595,7 @@ static int drmGetMinorBase(int type)
-     };
+@@ -517,51 +612,6 @@ int drmAvailable(void)
+     return retval;
  }
  
-+#if !defined(__FreeBSD__) && !defined(__DragonFly__)
- static int drmGetMinorType(int minor)
- {
-     int type = minor >> 6;
-@@ -547,7 +612,9 @@ static int drmGetMinorType(int minor)
-         return -1;
-     }
- }
-+#endif
+-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.
+  *
+@@ -2740,50 +2790,80 @@ int drmDropMaster(int fd)
  
-+#if defined(__linux__)
- static const char *drmGetMinorName(int type)
+ char *drmGetDeviceNameFromFd(int fd)
  {
-     switch (type) {
-@@ -561,6 +628,7 @@ static const char *drmGetMinorName(int t
-         return NULL;
-     }
- }
-+#endif
+-    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. */
  
- /**
-  * Open the device by bus ID.
-@@ -2729,14 +2797,46 @@ char *drmGetDeviceNameFromFd(int fd)
-     return strdup(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++) {
++    drmMsg("[drm] drmGetDeviceNameFromFd: fd (%d)\n", fd);
++
++    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;
+-    }
+-    if (i == DRM_MAX_MINOR)
+-        return NULL;
++        if (stat(name, &sbuf) == 0 && sbuf.st_rdev == d) {
+ 
+-    return strdup(name);
++            drmMsg("[drm] drmGetDeviceNameFromFd: device name (%s)\n", name);
++
++            return strdup(name);
++        }
++    }
++    return NULL;
  }
  
-+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;
+ int drmGetNodeTypeFromFd(int fd)
+ {
+-    struct stat sbuf;
++#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
++    char *name = drmGetDeviceNameFromFd2(fd);
 +
-+    if (strncmp(name, DRM_RENDER_MINOR_NAME,
-+        sizeof(DRM_RENDER_MINOR_NAME) - 1) == 0)
-+        return DRM_NODE_RENDER;
++    drmMsg("[drm] drmGetNodeTypeFromFd: fd (%d)\n", fd);
 +
-+    return -EINVAL;
-+}
++    if (!name) {
++        errno = ENODEV;
++        return -1;
++    }
++    
++    drmMsg("[drm] drmGetNodeTypeFromFd: device name (%s)\n", name);
 +
- int drmGetNodeTypeFromFd(int fd)
- {
-     struct stat sbuf;
++    int type = drmGetNodeType(name);
++
++    drmMsg("[drm] drmGetNodeTypeFromFd: device has type (%d)\n", type);
 +
-+#if defined(__FreeBSD__) || defined(__DragonFly__)
-+    int type;
-+    char dev_name[64];
-+    char base_name[64];
++    free(name);
++    if (type < 0)
++        errno = ENODEV;
++    return type;
 +#else
++    stat_t sbuf;
      int maj, min, type;
-+#endif
-+
-+    drmMsg("drmGetNodeTypeFromFd: File descriptor fd (%d)\n", fd);
  
++    drmMsg("[drm] drmGetNodeTypeFromFd: fd (%d)\n", fd);
++
      if (fstat(fd, &sbuf))
          return -1;
  
-+#if defined(__FreeBSD__) || defined(__DragonFly__)
-+    if (!S_ISCHR(sbuf.st_mode)) {
-+        errno = EINVAL;
-+        return -1;
-+    }
-+#else
      maj = major(sbuf.st_rdev);
      min = minor(sbuf.st_rdev);
  
-@@ -2744,8 +2844,31 @@ int drmGetNodeTypeFromFd(int fd)
++    drmMsg("[drm] drmGetNodeTypeFromFd: major (%d), minor (%d)\n", maj, min);
++
+     if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) {
          errno = EINVAL;
          return -1;
      }
-+#endif
  
-+#if defined(__FreeBSD__) || defined(__DragonFly__)
-+    snprintf(dev_name, sizeof(dev_name), "%s",
-+             devname(sbuf.st_rdev, S_IFCHR));
-+
-+    drmMsg("drmGetNodeTypeFromFd: Device name (%s)\n", dev_name);
-+
-+    memset(base_name, 0, sizeof(base_name));
-+    if (sscanf(dev_name, "dri/%s", base_name) != 1) {
-+        type = -1;
-+        goto out;
-+    }
-+
-+    drmMsg("drmGetNodeTypeFromFd: Device has basename (%s)\n", base_name);
-+
-+    type = drmGetNodeType(base_name);
-+    if (type < 0)
-+        type = -1;
-+#else
      type = drmGetMinorType(min);
-+#endif
 +
-+out:
-+    drmMsg("drmGetNodeTypeFromFd: Device has type (%d)\n", type);
++    drmMsg("[drm] drmGetNodeTypeFromFd: device has type (%d)\n", type);
++
      if (type == -1)
          errno = ENODEV;
      return type;
-@@ -2839,6 +2962,15 @@ static char *drmGetMinorNameForFD(int fd
++#endif
+ }
+ 
+ int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd)
+@@ -2823,7 +2903,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];
+@@ -2874,13 +2954,44 @@ static char *drmGetMinorNameForFD(int fd
  
  out_close_dir:
      closedir(sysdir);
-+#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__)
++#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
++    const char *dev_name = drmGetDeviceName(type);
++    if (!dev_name)
++        return NULL;
++
++    char *name = drmGetDeviceNameFromFd2(fd);
++    if (!name)
++        return NULL;
++
++    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;
++#elif defined(__NetBSD__)
 +    struct stat buf;
 +    char name[64];
 +
@@ -277,9 +486,43 @@ Moved static drmGetNodeType() for drmGetNodeTypeFromFd().
 +
 +    return strdup(name);
  #else
-     struct stat sbuf;
-     char buf[PATH_MAX + 1];
-@@ -2966,7 +3098,9 @@ 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;
+ 
+@@ -2890,20 +3001,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;
+@@ -3001,7 +3098,9 @@ static int drmParseSubsystemType(int maj
          return DRM_BUS_HOST1X;
  
      return -EINVAL;
@@ -290,7 +533,17 @@ Moved static drmGetNodeType() for drmGetNodeTypeFromFd().
      return DRM_BUS_PCI;
  #else
  #warning "Missing implementation of drmParseSubsystemType"
-@@ -2999,18 +3133,26 @@ static int drmParsePciBusInfo(int maj, i
+@@ -3009,7 +3108,8 @@ static int drmParseSubsystemType(int maj
+ #endif
+ }
+ 
+-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;
+@@ -3034,23 +3134,30 @@ static int drmParsePciBusInfo(int maj, i
      info->func = func;
  
      return 0;
@@ -299,86 +552,114 @@ Moved static drmGetNodeType() for drmGetNodeTypeFromFd().
      struct drm_pciinfo pinfo;
      int fd, type;
  
-+    drmMsg("drmParsePciBusInfo: min (%d)\n", min);
++    drmMsg("[drm] drmParsePciBusInfo: min (%d)\n", min);
 +
      type = drmGetMinorType(min);
      if (type == -1)
          return -ENODEV;
  
-+    drmMsg("drmParsePciBusInfo: type (%d), DRM_NODE_PRIMARY (%d)\n",
++    drmMsg("[drm] drmParsePciBusInfo: type (%d), DRM_NODE_PRIMARY (%d)\n",
 +        type, DRM_NODE_PRIMARY);
 +
      fd = drmOpenMinor(min, 0, type);
      if (fd < 0)
          return -errno;
  
-+    drmMsg("drmParsePciBusInfo: ioctl (0x%02x) using fd (%d)\n",
-+        DRM_IOCTL_GET_PCIINFO, fd);
-+
      if (drmIoctl(fd, DRM_IOCTL_GET_PCIINFO, &pinfo)) {
          close(fd);
++        drmMsg("[drm] drmParsePciBusInfo: FAILED  ioctl (0x%08lx), fd (%d)\n", DRM_IOCTL_GET_PCIINFO, fd);
          return -errno;
-@@ -3023,6 +3165,59 @@ static int drmParsePciBusInfo(int maj, i
+     }
+     close(fd);
++    drmMsg("[drm] drmParsePciBusInfo: SUCCESS ioctl (0x%08lx), fd (%d)\n", DRM_IOCTL_GET_PCIINFO, fd);
+ 
+     info->domain = pinfo.domain;
+     info->bus = pinfo.bus;
+@@ -3058,6 +3165,83 @@ static int drmParsePciBusInfo(int maj, i
      info->func = pinfo.func;
  
      return 0;
-+#elif defined(__FreeBSD__) || defined(__DragonFly__)
-+/*
-+ * Read the hw.dri.$min.busid sysctl
-+ * Adapted from function devq_device_get_pcibusaddr(),
-+ * project devq version 0.0.4, file src/freebsd/device.c
-+ */
-+    char sysctl_name[32], sysctl_value[128];
-+    const char *busid_format;
-+    size_t sysctl_value_len;
-+    int domain, bus, dev, func;
-+    int ret;
-+
-+    snprintf(sysctl_name, sizeof(sysctl_name), "hw.dri.%d.busid", min);
-+
-+    drmMsg("drmParsePciBusInfo: Reading sysctl (%s)\n", sysctl_name);
-+
-+    busid_format = "pci:%d:%d:%d.%d";
-+    sysctl_value_len = sizeof(sysctl_value);
-+    memset(sysctl_value, 0, sysctl_value_len);
-+    ret = sysctlbyname(sysctl_name, sysctl_value, &sysctl_value_len,
-+        NULL, 0);
-+    if (ret != 0) {
-+        /*
-+         * If hw.dri.$n.busid isn't available, fallback on
-+         * hw.dri.$n.name.
-+         */
-+         busid_format = "%*s %*s pci:%d:%d:%d.%d";
-+         sysctl_value_len = sizeof(sysctl_value);
-+         memset(sysctl_value, 0, sysctl_value_len);
-+         snprintf(sysctl_name, sizeof(sysctl_name), "hw.dri.%d.name", min);
-+
-+         drmMsg("drmParsePciBusInfo: Reading sysctl (%s)\n", sysctl_name);
-+
-+         ret = sysctlbyname(sysctl_name, sysctl_value, &sysctl_value_len,
-+             NULL, 0);
-+    }
++#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
 +
-+    if (ret != 0)
-+        return (-EINVAL);
++    drmMsg("[drm] drmParsePciBusInfo: node (%s), node_type (%d)\n", node, node_type);
++    drmMsg("[drm] drmParsePciBusInfo: maj (0x%x = %d), min (0x%x = %d), rdev (0x%x)\n",
++        maj, maj, min, min, makedev(maj, min));
 +
-+    drmMsg("drmParsePciBusInfo: Sysctl value (%s) scanned by format (%s)\n",
-+        sysctl_value, busid_format);
++    /*
++     * 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];
 +
-+    if (sscanf(sysctl_value, busid_format,
-+               &domain, &bus, &dev, &func) != 4)
-+        return -EINVAL;
-+    
-+    info->domain = domain;
-+    info->bus = bus;
-+    info->dev = dev;
-+    info->func = func;
++        drmMsg("[drm] drmParsePciBusInfo: node_type (%d) != DRM_NODE_PRIMARY (%d)\n",
++            node_type, DRM_NODE_PRIMARY);
 +
-+    return 0;
++        snprintf(name, sizeof(name), DRM_DEV_NAME, DRM_DIR_NAME,
++                 drmGetNodeNumber(node) - drmGetMinorBase(node_type));
++
++        drmMsg("[drm] drmParsePciBusInfo: stat-ing name (%s)\n", name);
++
++        stat_t sbuf;
++        if (stat(name, &sbuf))
++            return -errno;
++
++        maj = major(sbuf.st_rdev);
++        min = minor(sbuf.st_rdev);
++
++        drmMsg("[drm] drmParsePciBusInfo: maj (0x%x = %d), min (0x%x = %d), rdev (0x%x)\n",
++            maj, maj, min, min, makedev(maj, min));
++    }
++    /*
++     * 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.%d"
++    #define name_fmt "%*s 0x%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.%d.name", i);
++        if (sysctlbyname(name, value, &length, NULL, 0))
++            continue;
++
++        value[length] = '\0';
++
++        drmMsg("[drm] drmParsePciBusInfo: sysctl name (%s) has value (%s)\n", name, value);
++
++        unsigned int rdev = 0, domain = 0, bus = 0, slot = 0, func = 0;
++        int vals = sscanf(value, name_fmt, &rdev, &domain, &bus, &slot, &func);
++
++	if (vals >= 1 && rdev == makedev(maj,min)) {
++            if (vals < 5) {
++
++                drmMsg("[drm] drmParsePciBusInfo: busid not in sysctl name, try busid\n");
++
++                /* busid not in the name, try busid */
++                length = sizeof(value);
++                snprintf(name, sizeof(name), "hw.dri.%d.busid", i);
++                if (sysctlbyname(name, value, &length, NULL, 0))
++                    break;
++                value[length] = '\0';
++
++                drmMsg("[drm] drmParsePciBusInfo: sysctl busid (%s) has value (%s)\n", name, value);
++
++                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,23 +3252,6 @@ int drmDevicesEqual(drmDevicePtr a, drmD
+@@ -3092,32 +3276,6 @@ int drmDevicesEqual(drmDevicePtr a, drmD
      return 0;
  }
  
@@ -399,91 +680,27 @@ Moved static drmGetNodeType() for drmGetNodeTypeFromFd().
 -    return -EINVAL;
 -}
 -
- static int drmGetMaxNodeName(void)
- {
-     return sizeof(DRM_DIR_NAME) +
-@@ -3151,9 +3329,80 @@ static int parse_config_sysfs_file(int m
- }
+-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,
+@@ -3187,6 +3345,7 @@ static int parse_config_sysfs_file(int m
  #endif
  
-+#if defined(__FreeBSD__) || defined(__DragonFly__)
-+/* Uses function of name prefixed by devq_
-+ * from libdevq 0.0.4, file src/freebsd/device.c
-+ */
-+static int
-+compare_vgapci_busaddr(int i, int *domain, int *bus, int *slot,
-+    int *function)
-+{
-+    int ret;
-+    char sysctl_name[32], sysctl_value[128];
-+    size_t sysctl_value_len;
-+
-+    snprintf(sysctl_name, sizeof(sysctl_name), "dev.vgapci.%d.%%location", i);
-+
-+    sysctl_value_len = sizeof(sysctl_value);
-+    memset(sysctl_value, 0, sysctl_value_len);
-+    ret = sysctlbyname(sysctl_name, sysctl_value,
-+        &sysctl_value_len, NULL, 0);
-+    if (ret != 0)
-+        return (-1);
-+
-+    drmMsg("compare_vgapci_busaddr: Read sysctl (%s)\n", sysctl_name);
-+    drmMsg("compare_vgapci_busaddr: Sysctl value (%s)\n", sysctl_value);
-+
-+    /*
-+     * dev.vgapci.$m.%location can have two formats:
-+     *     o  "pci0:2:0:0 handle=\_SB_.PCI0.PEG3.MXM3" (FreeBSD 11+)
-+     *     o  "slot=1 function=0" (DragonFly or up-to FreeBSD 10)
-+     */
-+
-+    ret = sscanf(sysctl_value, "pci%d:%d:%d:%d %*s",
-+        domain, bus, slot, function);
-+
-+    if (ret == 4)
-+        return (0);
-+
-+    ret = sscanf(sysctl_value, "slot=%d function=%d %*s",
-+        slot, function);
-+    if (ret != 2)
-+        return (-1);
-+
-+    snprintf(sysctl_name, sizeof(sysctl_name), "dev.vgapci.%d.%%parent", i);
-+
-+    sysctl_value_len = sizeof(sysctl_value);
-+    memset(sysctl_value, 0, sysctl_value_len);
-+    ret = sysctlbyname(sysctl_name, sysctl_value,
-+        &sysctl_value_len, NULL, 0);
-+    if (ret != 0)
-+        return (-1);
-+    
-+    drmMsg("compare_vgapci_busaddr: Read sysctl (%s)\n", sysctl_name);
-+    drmMsg("compare_vgapci_busaddr: Sysctl value (%s)\n", sysctl_value);
-+
-+    ret = sscanf(sysctl_value, "pci%d", bus);
-+    if (ret != 1)
-+        return (-1);
-+
-+    /* FIXME: What domain to assume? */
-+    *domain = 0;
-+
-+    return (0);
-+}
-+#endif
-+
-+#if defined(__FreeBSD__) || defined(__DragonFly__)
-+static int drmParsePciDeviceInfoBSD(int maj, int min,
-+                                 drmPciDeviceInfoPtr device,
-+                                 drmPciBusInfoPtr info,
-+                                 uint32_t flags)
-+#else
  static int drmParsePciDeviceInfo(int maj, int min,
++                                 drmPciBusInfoPtr info,
                                   drmPciDeviceInfoPtr device,
                                   uint32_t flags)
-+#endif
  {
- #ifdef __linux__
-     if (!(flags & DRM_DEVICE_GET_PCI_REVISION))
-@@ -3163,18 +3412,26 @@ static int drmParsePciDeviceInfo(int maj
+@@ -3198,23 +3357,31 @@ static int drmParsePciDeviceInfo(int maj
          return parse_config_sysfs_file(maj, min, device);
  
      return 0;
@@ -492,357 +709,396 @@ Moved static drmGetNodeType() for drmGetNodeTypeFromFd().
      struct drm_pciinfo pinfo;
      int fd, type;
  
-+    drmMsg("drmParsePciDeviceInfo: min (%d)\n", min);
++    drmMsg("[drm] drmParsePciDeviceInfo: min (%d)\n", min);
 +
      type = drmGetMinorType(min);
      if (type == -1)
          return -ENODEV;
  
-+    drmMsg("drmParsePciDeviceInfo: type (%d), DRM_NODE_PRIMARY (%d)\n",
++    drmMsg("[drm] drmParsePciDeviceInfo: type (%d), DRM_NODE_PRIMARY (%d)\n",
 +        type, DRM_NODE_PRIMARY);
 +
      fd = drmOpenMinor(min, 0, type);
      if (fd < 0)
          return -errno;
  
-+    drmMsg("drmParsePciDeviceInfo: ioctl (0x%02x) using fd (%d)\n",
-+        DRM_IOCTL_GET_PCIINFO, fd);
 +
      if (drmIoctl(fd, DRM_IOCTL_GET_PCIINFO, &pinfo)) {
          close(fd);
++        drmMsg("[drm] drmParsePciDeviceInfo: FAILED  ioctl (0x%08lx), fd (%d)\n", DRM_IOCTL_GET_PCIINFO, fd);
          return -errno;
-@@ -3188,6 +3445,88 @@ static int drmParsePciDeviceInfo(int maj
+     }
+     close(fd);
++    drmMsg("[drm] drmParsePciDeviceInfo: SUCCESS ioctl (0x%08lx), fd (%d)\n", DRM_IOCTL_GET_PCIINFO, fd);
+ 
+     device->vendor_id = pinfo.vendor_id;
+     device->device_id = pinfo.device_id;
+@@ -3223,6 +3390,48 @@ static int drmParsePciDeviceInfo(int maj
      device->subdevice_id = pinfo.subdevice_id;
  
      return 0;
-+#elif defined(__FreeBSD__) || defined(__DragonFly__)
-+/*
-+ * Adapted from function devq_device_get_pciid_full_from_fd(),
-+ * from libdevq 0.0.4, file src/freebsd/device.c,
-+ */
-+    unsigned int vendor_id = 0, device_id = 0, subvendor_id = 0, 
-+        subdevice_id = 0, revision_id = 0;
-+    int i, ret;
-+    char sysctl_name[32], sysctl_value[128];
-+    size_t sysctl_value_len;
-+
-+/*
-+ * Now, look at all dev.vgapci.$m trees until we find the
-+ * correct device. We specifically look at:
-+ *     o  dev.vgapci.$m.%location
-+ *     o  dev.vgapci.$m.%parent
-+ */
-+    for (i = 0; i < DRM_MAX_FDS; ++i) {
-+        int tmp_domain, tmp_bus, tmp_slot, tmp_function;
-+
-+        ret = compare_vgapci_busaddr(i, &tmp_domain, &tmp_bus,
-+            &tmp_slot, &tmp_function);
-+
-+        if (ret == 0 &&
-+            tmp_domain == info->domain &&
-+            tmp_bus == info->bus &&
-+            tmp_slot == info->dev &&
-+            tmp_function == info->func)
-+            break;
-+    }
-+
-+    if (i == DRM_MAX_FDS) {
-+        drmMsg("drmParsePciDeviceInfoBSD: FAILED DRM_MAX_FDS (%d) vgapci!\n",
-+            DRM_MAX_FDS);
-+        errno = ENOENT;
-+        return (-1);
-+    }
-+
-+/*
-+ * Ok, we have the right tree. Let's read dev.vgapci.$m.%pnpinfo
-+ * to gather the PCI ID.
-+ */
-+    snprintf(sysctl_name, sizeof(sysctl_name), "dev.vgapci.%d.%%pnpinfo", i);
-+
-+    sysctl_value_len = sizeof(sysctl_value);
-+    memset(sysctl_value, 0, sysctl_value_len);
-+    ret = sysctlbyname(sysctl_name, sysctl_value,
-+        &sysctl_value_len, NULL, 0);
-+    if (ret != 0)
-+        return (-1);
-+    
-+    drmMsg("drmParsePciDeviceInfoBSD: Sysctl (%s) has value (%s)\n",
-+        sysctl_name, sysctl_value);
-+
-+#if defined(__DragonFly__)
-+/* DragonFly has a device class field following the subdevice field */
-+    ret = sscanf(sysctl_value,
-+        "vendor=0x%04x device=0x%04x subvendor=0x%04x subdevice=0x%04x %*s",
-+        &vendor_id, &device_id, &subvendor_id, &subdevice_id);
-+#else /* FreeBSD */
-+    ret = sscanf(sysctl_value,
-+        "vendor=0x%04x device=0x%04x subvendor=0x%04x subdevice=0x%04x",
-+        &vendor_id, &device_id, &subvendor_id, &subdevice_id);
-+    if (ret != 4) {
-+        ret = sscanf(sysctl_value,
-+            "vendor=0x%04x device=0x%04x subvendor=0x%04x subdevice=0x%04x %*s",
-+            &vendor_id, &device_id, &subvendor_id, &subdevice_id);
-+    }
-+#endif
-+    if (ret != 4) {
-+        errno = EINVAL;
-+        return (-1);
++#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
++    struct pci_conf_io pc;
++    struct pci_match_conf patterns[1];
++    struct pci_conf results[1];
++
++    int fd = open("/dev/pci", O_RDONLY, 0);
++
++    drmMsg("[drm] drmParsePciDeviceInfo: opened /dev/pci with fd (%d)\n", fd);
++
++    if (fd < 0)
++        return -errno;
++
++    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);
++        drmMsg("[drm] drmParsePciDeviceInfo: FAILED  ioctl (0x%08lx), fd (%d)\n", PCIOCGETCONF, fd);
++        return -error;
 +    }
++    close(fd);
++    drmMsg("[drm] drmParsePciDeviceInfo: SUCCESS ioctl (0x%08lx), fd (%d)\n", PCIOCGETCONF, fd);
 +
-+    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;
-+    /* XXX: add code to find out revision id */
-+    device->revision_id = (uint8_t) revision_id;
++    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;
-@@ -3305,6 +3644,11 @@ static int drmProcessPciDevice(drmDevice
+@@ -3303,7 +3512,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;
+@@ -3340,6 +3549,11 @@ static int drmProcessPciDevice(drmDevice
      char *addr;
      int ret;
  
-+    drmMsg("drmProcessPciDevice: node (%s), node_type (%d)\n",
++    drmMsg("[drm] drmProcessPciDevice: node (%s), node_type (%d)\n",
 +        node, node_type);
-+    drmMsg("drmProcessPciDevice: maj (%d), min (%d), flags (%d)\n",
-+        maj, min, flags);
++    drmMsg("[drm] drmProcessPciDevice: maj (%d = 0x%x), min (%d = 0x%x), rdev (0x%x), flags (0x%x)\n",
++        maj, maj, min, min, makedev(maj, min), flags);
 +
      dev = drmDeviceAlloc(node_type, node, sizeof(drmPciBusInfo),
                           sizeof(drmPciDeviceInfo), &addr);
      if (!dev)
-@@ -3315,17 +3659,39 @@ static int drmProcessPciDevice(drmDevice
+@@ -3349,18 +3563,36 @@ static int drmProcessPciDevice(drmDevice
+ 
      dev->businfo.pci = (drmPciBusInfoPtr)addr;
  
-     ret = drmParsePciBusInfo(maj, min, dev->businfo.pci);
+-    ret = drmParsePciBusInfo(maj, min, dev->businfo.pci);
++    ret = drmParsePciBusInfo(node, node_type, maj, min, dev->businfo.pci);
 +
      if (ret)
          goto free_device;
  
-+    drmMsg("drmProcessPciDevice: domain (%04x)\n", dev->businfo.pci->domain);
-+    drmMsg("drmProcessPciDevice: bus    (%02x)\n", dev->businfo.pci->bus);
-+    drmMsg("drmProcessPciDevice: dev    (%02x)\n", dev->businfo.pci->dev);
-+    drmMsg("drmProcessPciDevice: func   (%1u)\n",  dev->businfo.pci->func);
++    drmMsg("[drm] drmProcessPciDevice: DOMAIN    (%04x)\n", dev->businfo.pci->domain);
++    drmMsg("[drm] drmProcessPciDevice: BUS       (%02x)\n", dev->businfo.pci->bus);
++    drmMsg("[drm] drmProcessPciDevice: DEV       (%02x)\n", dev->businfo.pci->dev);
++    drmMsg("[drm] drmProcessPciDevice: FUNC      (%1u)\n",  dev->businfo.pci->func);
 +
      // Fetch the device info if the user has requested it
      if (fetch_deviceinfo) {
          addr += sizeof(drmPciBusInfo);
          dev->deviceinfo.pci = (drmPciDeviceInfoPtr)addr;
  
-+#if defined(__FreeBSD__) || defined(__DragonFly__)
-+        ret = drmParsePciDeviceInfoBSD(maj, min, dev->deviceinfo.pci,
-+            dev->businfo.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;
 +
-+        drmMsg("drmProcessPciDevice: vendor    (%04x)\n",
++        drmMsg("[drm] drmProcessPciDevice: VENDOR    (%04x)\n",
 +            dev->deviceinfo.pci->vendor_id);
-+        drmMsg("drmProcessPciDevice: device    (%04x_\n",
++        drmMsg("[drm] drmProcessPciDevice: DEVICE    (%04x)\n",
 +            dev->deviceinfo.pci->device_id);
-+        drmMsg("drmProcessPciDevice: subvendor (%04x)\n",
++        drmMsg("[drm] drmProcessPciDevice: SUBVENDOR (%04x)\n",
 +            dev->deviceinfo.pci->subvendor_id);
-+        drmMsg("drmProcessPciDevice: subdevice (%04x)\n",
++        drmMsg("[drm] drmProcessPciDevice: SUBDEVICE (%04x)\n",
 +            dev->deviceinfo.pci->subdevice_id);
-+        drmMsg("drmProcessPciDevice: revision  (%02x)\n",
++        drmMsg("[drm] drmProcessPciDevice: REVISION  (%02x)\n",
 +            dev->deviceinfo.pci->revision_id);
      }
  
      *device = dev;
-@@ -3687,6 +4053,35 @@ drm_device_validate_flags(uint32_t flags
-         return (flags & ~DRM_DEVICE_GET_PCI_REVISION);
- }
- 
-+#if defined(__FreeBSD__) || defined(__DragonFly__)
-+/*
-+ * XXX temporary workaround, because FreeBSD doesn't provide 
-+ * pcibus device sysctl trees for renderD and controlD nodes (yet)
-+ * Finds the corresponding /dev/dri/cardn device and also
-+ * returns the number n.
-+ */
-+static int 
-+drmBSDDeviceNameHack(const char *path, char *hacked_path, int length,
-+                     int node_type)
-+{
-+    int start, number, base;
-+    const char *errstr;
-+
-+    base = drmGetMinorBase(node_type);
-+    if (node_type == DRM_NODE_RENDER) {
-+        start = sizeof(DRM_RENDER_MINOR_NAME) - 1;
-+    } else if (node_type == DRM_NODE_CONTROL) {
-+        start = sizeof(DRM_CONTROL_MINOR_NAME) - 1;
-+    } else {
-+        start = sizeof(DRM_PRIMARY_MINOR_NAME) - 1;
-+    }
-+    number = strtonum(&(path[start]), 0, 256, &errstr) - base;
-+    snprintf(hacked_path, length, "card%i", number);
-+
-+    return number;
-+}
-+#endif
-+
- /**
+@@ -3708,7 +3940,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]);
+             }
+         }
+@@ -3726,7 +3958,7 @@ drm_device_validate_flags(uint32_t flags
   * Get information about the opened drm device
   *
-@@ -3779,6 +4174,13 @@ int drmGetDevice2(int fd, uint32_t flags
+  * \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
+  *
+@@ -3744,8 +3976,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;
+@@ -3766,26 +3998,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;
+@@ -3806,14 +4028,17 @@ 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;
      int max_count = 16;
      dev_t find_rdev;
  
-+#if defined(__FreeBSD__) || defined(__DragonFly__)
-+    char hacked_path[128];
-+#endif
-+
-+    drmMsg("drmGetDevice2: fd (%d), flags (%d) vs expected (%d)\n",
++    drmMsg("[drm] drmGetDevice2: fd (%d), flags (%d) vs expected (%d)\n",
 +        fd, flags, DRM_DEVICE_GET_PCI_REVISION);
 +
      if (drm_device_validate_flags(flags))
          return -EINVAL;
  
-@@ -3792,7 +4194,11 @@ int drmGetDevice2(int fd, uint32_t flags
+@@ -3827,11 +4052,16 @@ int drmGetDevice2(int fd, uint32_t flags
      maj = major(sbuf.st_rdev);
      min = minor(sbuf.st_rdev);
  
-+#if defined(__FreeBSD__) || defined(__DragonFly__)
-+    if (!S_ISCHR(sbuf.st_mode))
-+#else
-     if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
-+#endif
+-    if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
++    drmMsg("[drm] drmGetDevice2: maj (%d = 0x%x), min (%d = 0x%x), rdev (0x%x)\n",
++        maj, maj, min, min, makedev(maj, min));
++
++    if ((DRM_MAJOR && maj != DRM_MAJOR) || !S_ISCHR(sbuf.st_mode))
          return -EINVAL;
  
      subsystem_type = drmParseSubsystemType(maj, min);
-@@ -3809,18 +4215,34 @@ int drmGetDevice2(int fd, uint32_t flags
  
-     i = 0;
-     while ((dent = readdir(sysdir))) {
-+
-+#if defined(__FreeBSD__) || defined(__DragonFly__)
-+        int number;
-+#endif
++    drmMsg("[drm] drmGetDevice2: subsystem_type (%d)\n", subsystem_type);
 +
-         node_type = drmGetNodeType(dent->d_name);
+     local_devices = calloc(max_count, sizeof(drmDevicePtr));
+     if (local_devices == NULL)
+         return -ENOMEM;
+@@ -3848,14 +4078,14 @@ int drmGetDevice2(int fd, uint32_t flags
          if (node_type < 0)
              continue;
  
-+#if defined(__FreeBSD__) || defined(__DragonFly__)
-+        number = drmBSDDeviceNameHack(dent->d_name, hacked_path,
-+            sizeof(hacked_path), node_type);
-+
-+        snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, hacked_path);
-+#else
-         snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, dent->d_name);
-+#endif
+-        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 defined(__FreeBSD__) || defined(__DragonFly__)
-+        if (!S_ISCHR(sbuf.st_mode))
-+#else
-         if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
-+#endif
+-        if (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)
-@@ -3828,7 +4250,13 @@ int drmGetDevice2(int fd, uint32_t flags
- 
-         switch (subsystem_type) {
-         case DRM_BUS_PCI:
+@@ -3924,6 +4154,9 @@ int drmGetDevice2(int fd, uint32_t flags
+     free(local_devices);
+     if (*device == NULL)
+         return -ENODEV;
 +
-+#if defined (__FreeBSD__) || defined(__DragonFly__)
-+            ret = drmProcessPciDevice(&d, node, node_type, maj, number, true, flags);
-+#else
-             ret = drmProcessPciDevice(&d, node, node_type, maj, min, true, flags);
-+#endif
++    drmMsg("[drm] drmGetDevice2: SUCCESS\n");
 +
-             if (ret)
-                 continue;
+     return 0;
  
-@@ -3944,6 +4372,13 @@ int drmGetDevices2(uint32_t flags, drmDe
+ free_devices:
+@@ -3972,13 +4205,16 @@ 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;
      int max_count = 16;
  
-+#if defined(__FreeBSD__) || defined(__DragonFly__)
-+    char hacked_path[128];
-+#endif
-+
-+    drmMsg("drmGetDevices2: flags (%d) vs expected (%d), max_devices (%d)\n",
++    drmMsg("[drm] drmGetDevices2: flags (%d) vs expected (%d), max_devices (%d)\n",
 +        flags, DRM_DEVICE_GET_PCI_REVISION, max_devices);
 +
      if (drm_device_validate_flags(flags))
          return -EINVAL;
  
-@@ -3959,18 +4394,34 @@ int drmGetDevices2(uint32_t flags, drmDe
- 
-     i = 0;
-     while ((dent = readdir(sysdir))) {
-+
-+#if defined(__FreeBSD__) || defined(__DragonFly__)
-+        int number;
-+#endif
-+
-         node_type = drmGetNodeType(dent->d_name);
+@@ -3998,14 +4234,14 @@ int drmGetDevices2(uint32_t flags, drmDe
          if (node_type < 0)
              continue;
  
-+#if defined(__FreeBSD__) || defined(__DragonFly__)
-+        number = drmBSDDeviceNameHack(dent->d_name, hacked_path,
-+            sizeof(hacked_path), node_type);
-+
-+        snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, hacked_path);
-+#else
-         snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, dent->d_name);
-+#endif
+-        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 defined(__FreeBSD__) || defined(__DragonFly__)
-+        if (!S_ISCHR(sbuf.st_mode))
-+#else
-         if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
-+#endif
+-        if (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);
-@@ -3980,8 +4431,13 @@ int drmGetDevices2(uint32_t flags, drmDe
+@@ -4082,6 +4318,7 @@ int drmGetDevices2(uint32_t flags, drmDe
  
-         switch (subsystem_type) {
-         case DRM_BUS_PCI:
-+#if defined (__FreeBSD__) || defined(__DragonFly__)
-+            ret = drmProcessPciDevice(&device, node, node_type,
-+                                      maj, number, devices != NULL, flags);
-+#else
-             ret = drmProcessPciDevice(&device, node, node_type,
-                                       maj, min, devices != NULL, flags);
-+#endif
-             if (ret)
-                 continue;
+     closedir(sysdir);
+     free(local_devices);
++    drmMsg("[drm] drmGetDevices2: SUCCESS: device_count (%d)\n", device_count);
+     return device_count;
  
-@@ -4101,6 +4557,19 @@ char *drmGetDeviceNameFromFd2(int fd)
+ free_devices:
+@@ -4113,7 +4350,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;
+ 
+@@ -4136,9 +4373,48 @@ char *drmGetDeviceNameFromFd2(int fd)
      free(value);
  
      return strdup(path);
-+#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__)
++#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
++    stat_t sbuf;
++
++    drmMsg("[drm] drmGetDeviceNameFromFd2: fd (%d)\n", fd);
++
++    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) {
++
++                drmMsg("[drm] drmGetDeviceNameFromFd2: has device name (%s)\n", node);
++
++                return strdup(node);
++            }
++        }
++    }
++    return NULL;
++#elif defined(__NetBSD__)
 +    struct stat sbuf;
 +    char path[64];
 +
++    drmMsg("[drm] drmGetDeviceNameFromFd2: fd (%d)\n", fd);
++
 +    if (fstat(fd, &sbuf))
 +        return NULL;
 +
 +    snprintf(path, sizeof(path), "/dev/%s",
 +             devname(sbuf.st_rdev, S_IFCHR));
 +
-+    drmMsg("drmGetDeviceNameFromFd2: fd (%d) has device name (%s)\n", fd, path);
++    drmMsg("[drm] drmGetDeviceNameFromFd2: has device name (%s)\n", path);
 +
 +    return strdup(path);
  #else
-     struct stat      sbuf;
-     char             node[PATH_MAX + 1];
+-    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;
+@@ -4156,26 +4432,16 @@ char *drmGetDeviceNameFromFd2(int fd)
+     if (node_type == -1)
+         return NULL;
+ 
+-    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/libdrm-dfbsd/patches/patch-ac b/libdrm-dfbsd/patches/patch-ac
index 2b11b37832..f0b2f7544d 100644
--- a/libdrm-dfbsd/patches/patch-ac
+++ b/libdrm-dfbsd/patches/patch-ac
@@ -1,6 +1,6 @@
 $NetBSD: patch-ac,v 1.4 2012/02/16 20:30:56 hans Exp $
 
---- xf86drm.h.orig	2010-03-05 23:21:13.000000000 +0000
+--- xf86drm.h.orig	2017-12-18 01:33:10.000000000 +0000
 +++ xf86drm.h
 @@ -35,7 +35,11 @@
  #define _XF86DRM_H_
@@ -14,7 +14,7 @@ $NetBSD: patch-ac,v 1.4 2012/02/16 20:30:56 hans Exp $
  #include <stdint.h>
  #include <drm.h>
  
-@@ -55,6 +59,9 @@
+@@ -59,6 +63,9 @@ extern "C" {
  #else /* One of the *BSDs */
  
  #include <sys/ioccom.h>
@@ -24,7 +24,42 @@ $NetBSD: patch-ac,v 1.4 2012/02/16 20:30:56 hans Exp $
  #define DRM_IOCTL_NR(n)         ((n) & 0xff)
  #define DRM_IOC_VOID            IOC_VOID
  #define DRM_IOC_READ            IOC_OUT
-@@ -333,7 +340,12 @@ typedef struct _drmSetVersion {
+@@ -78,17 +85,28 @@ 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_PRIMARY_MINOR_NAME  "card"
++#define DRM_CONTROL_MINOR_NAME  "controlD"
++#define DRM_RENDER_MINOR_NAME   "renderD"
+ #define DRM_PROC_NAME "/proc/dri/" /* For backward Linux compatibility */
+ #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 + 3) /* length of the node number */
++
+ #define DRM_ERR_NO_DEVICE  (-1001)
+ #define DRM_ERR_NO_ACCESS  (-1002)
+ #define DRM_ERR_NOT_ROOT   (-1003)
+@@ -354,7 +372,12 @@ typedef struct _drmSetVersion {
  #define DRM_LOCK_HELD  0x80000000U /**< Hardware lock is held */
  #define DRM_LOCK_CONT  0x40000000U /**< Hardware lock is contended */
  
diff --git a/libdrm-dfbsd/patches/patch-libkms_vmwgfx.c b/libdrm-dfbsd/patches/patch-libkms_vmwgfx.c
index bedfefa615..90c42eaa97 100644
--- a/libdrm-dfbsd/patches/patch-libkms_vmwgfx.c
+++ b/libdrm-dfbsd/patches/patch-libkms_vmwgfx.c
@@ -2,15 +2,44 @@ $NetBSD: patch-libkms_vmwgfx.c,v 1.3 2015/05/07 06:31:06 wiz Exp $
 
 Provide compatibility errno number for non-Linux.
 
---- libkms/vmwgfx.c.orig	2015-05-06 23:04:31.000000000 +0000
+From FreeBSD ports for graphics/libdrm version 2.4.84
+
+# the defintion of ERESTART is behind a check for _KERNEL, but
+# defining that causes errno to not be defined. fortunately, there's
+# an alternative switch. unfortunately, those differ by platform and
+# _WANT_KERNEL_ERRNO is too recent to be part of any release, so just
+# define ERESTART if we still don't have it after including errno.h 
+
+--- libkms/vmwgfx.c.orig	2017-11-03 16:44:27.000000000 +0000
 +++ libkms/vmwgfx.c
-@@ -39,6 +39,10 @@
- #include "libdrm_macros.h"
- #include "vmwgfx_drm.h"
+@@ -30,15 +30,31 @@
+ #include "config.h"
+ #endif
  
++#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
++#define _WANT_KERNEL_ERRNO
++#elif defined(__DragonFly__)
++#define _KERNEL_STRUCTURES
++#endif
+ #include <errno.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include "internal.h"
+ 
++#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined(__DragonFly__)
++#ifndef ERESTART
++#define ERESTART (-1)
++#endif
++#else
 +#ifndef ERESTART
 +#define ERESTART 85
 +#endif
++#endif
++
+ #include "xf86drm.h"
+ #include "libdrm_macros.h"
+ #include "vmwgfx_drm.h"
+ 
 +
  struct vmwgfx_bo
  {
diff --git a/libdrm-dfbsd/patches/patch-libsync.h b/libdrm-dfbsd/patches/patch-libsync.h
new file mode 100644
index 0000000000..9b3a1c0327
--- /dev/null
+++ b/libdrm-dfbsd/patches/patch-libsync.h
@@ -0,0 +1,18 @@
+$NetBSD$
+
+From FreeBSD ports x11/libdrm 2.4.84
+
+# define ETIME as ETIMEOUT same as done in Mesa
+
+--- libsync.h.orig	2017-11-03 16:44:27.000000000 +0000
++++ libsync.h
+@@ -35,6 +35,9 @@
+ #include <sys/ioctl.h>
+ #include <sys/poll.h>
+ #include <unistd.h>
++#ifndef ETIME
++#define ETIME ETIMEDOUT
++#endif
+ 
+ #if defined(__cplusplus)
+ extern "C" {
diff --git a/libdrm-dfbsd/patches/patch-radeon_radeon__bo__gem.c b/libdrm-dfbsd/patches/patch-radeon_radeon__bo__gem.c
index 977864f3e0..36f5564c8a 100644
--- a/libdrm-dfbsd/patches/patch-radeon_radeon__bo__gem.c
+++ b/libdrm-dfbsd/patches/patch-radeon_radeon__bo__gem.c
@@ -1,27 +1,37 @@
 $NetBSD: patch-radeon_radeon__bo__gem.c,v 1.1 2014/10/26 10:20:10 wiz Exp $
 
---- radeon/radeon_bo_gem.c.orig	2014-09-28 16:19:54.000000000 +0000
+FreeBSD ports / DragonFly dports does not have this patch.
+
+--- radeon/radeon_bo_gem.c.orig	2017-11-03 16:44:27.000000000 +0000
 +++ radeon/radeon_bo_gem.c
-@@ -178,8 +178,8 @@ static int bo_map(struct radeon_bo_int *
+@@ -178,8 +178,13 @@ static int bo_map(struct radeon_bo_int *
                  boi, boi->handle, r);
          return r;
      }
--    ptr = drm_mmap(0, args.size, PROT_READ|PROT_WRITE, MAP_SHARED, boi->bom->fd, args.addr_ptr);
--    if (ptr == MAP_FAILED)
++#if defined(__FreeBSD__) || defined(__DragonFly__)
+     ptr = drm_mmap(0, args.size, PROT_READ|PROT_WRITE, MAP_SHARED, boi->bom->fd, args.addr_ptr);
+     if (ptr == MAP_FAILED)
++#else
 +    r = drmMap(boi->bom->fd, args.addr_ptr, args.size, &ptr);
 +    if (r)
++#endif
          return -errno;
      bo_gem->priv_ptr = ptr;
  wait:
-@@ -252,9 +252,10 @@ static int bo_set_tiling(struct radeon_b
+@@ -252,9 +257,16 @@ static int bo_set_tiling(struct radeon_b
  static int bo_get_tiling(struct radeon_bo_int *boi, uint32_t *tiling_flags,
                           uint32_t *pitch)
  {
--    struct drm_radeon_gem_set_tiling args = {};
++#if defined(__FreeBSD__) || defined(__DragonFly__)
+     struct drm_radeon_gem_set_tiling args = {};
++#else
 +    struct drm_radeon_gem_set_tiling args;
++#endif
      int r;
  
++#if !defined(__FreeBSD__) && !defined(__DragonFly__)
 +    memset(&args, 0, sizeof args);
++#endif
      args.handle = boi->handle;
  
      r = drmCommandWriteRead(boi->bom->fd,
diff --git a/libdrm-dfbsd/patches/patch-radeon_radeon__cs__gem.c b/libdrm-dfbsd/patches/patch-radeon_radeon__cs__gem.c
index ebe3d7f3e0..9ba1699d68 100644
--- a/libdrm-dfbsd/patches/patch-radeon_radeon__cs__gem.c
+++ b/libdrm-dfbsd/patches/patch-radeon_radeon__cs__gem.c
@@ -1,16 +1,23 @@
 $NetBSD: patch-radeon_radeon__cs__gem.c,v 1.1 2014/10/26 10:20:10 wiz Exp $
 
---- radeon/radeon_cs_gem.c.orig	2014-09-28 16:19:54.000000000 +0000
+FreeBSD ports / DragonFly dports does not have this patch.
+
+--- radeon/radeon_cs_gem.c.orig	2017-11-03 16:44:27.000000000 +0000
 +++ radeon/radeon_cs_gem.c
-@@ -525,9 +525,10 @@ static struct radeon_cs_funcs radeon_cs_
+@@ -528,9 +528,16 @@ static const struct radeon_cs_funcs rade
  
  static int radeon_get_device_id(int fd, uint32_t *device_id)
  {
--    struct drm_radeon_info info = {};
++#if !defined(__FreeBSD__) && !defined(__DragonFly__)
 +    struct drm_radeon_info info;
++#else
+     struct drm_radeon_info info = {};
++#endif
      int r;
  
++#if !defined(__FreeBSD__) && !defined(__DragonFly__)
 +    memset(&info, 0, sizeof info);
++#endif
      *device_id = 0;
      info.request = RADEON_INFO_DEVICE_ID;
      info.value = (uintptr_t)device_id;
diff --git a/libdrm-dfbsd/patches/patch-xf86drmMode.c b/libdrm-dfbsd/patches/patch-xf86drmMode.c
index e780f109cd..582487f40e 100644
--- a/libdrm-dfbsd/patches/patch-xf86drmMode.c
+++ b/libdrm-dfbsd/patches/patch-xf86drmMode.c
@@ -1,20 +1,119 @@
 $NetBSD: patch-xf86drmMode.c,v 1.2 2015/04/11 10:02:11 sevan Exp $
 
-Get rid of patch disabling checking for hw.dri.%d.modesetting on FreeBSD.
+Replace patch disabling checking for hw.dri.%d.modesetting on FreeBSD.
 This sysctl is only available if a KMS module is loaded.
 xf86-video-intel if checking for modesetting fails the first time
-tries to load the kernel module and then check again for modesetting. 
+tries to load the kernel module and then check again for modesetting.
+
+Use patch from FreeBSD ports / DragonFly dports graphics/libdrm 2.4.84.
 
 Get rid of drmModeSetPlane patch (from NetBSD?)
 Android deliberately uses signed crtc_x and crtc_y
 "to allow a destination location that is partially off screen."
 
---- xf86drmMode.c.orig	2017-01-28 01:15:16.000000000 +0000
+--- xf86drmMode.c.orig	2017-11-03 16:44:27.000000000 +0000
 +++ xf86drmMode.c
-@@ -829,6 +829,19 @@ int drmCheckModesettingSupported(const c
- 			return -EINVAL;
- 		return (modesetting ? 0 : -ENOSYS);
+@@ -47,6 +47,9 @@
+ #include <stdlib.h>
+ #include <sys/ioctl.h>
+ #ifdef HAVE_SYS_SYSCTL_H
++#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined(__DragonFly__)
++#include <sys/types.h>
++#endif
+ #include <sys/sysctl.h>
+ #endif
+ #include <stdio.h>
+@@ -796,43 +799,75 @@ 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;
+-
+-	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);
++#elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined(__DragonFly__)
++	#define bus_fmt "pci:%04x:%02x:%02x.%d"
++	#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.%d.name", 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';
++		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.%d.busid", i);
++			if (sysctlbyname(name, value, &length, NULL, 0))
+ 				continue;
+-			return -EINVAL;
++
++			value[length] = '\0';
++			if (sscanf(value, bus_fmt, &d2, &b2, &s2, &f2) != 4)
++ 				continue;
++			/* 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__)
++#elif 0 && defined(__DragonFly__)
+ 	return 0;
+-#endif
+-#ifdef __OpenBSD__
 +#elif defined(__NetBSD__)
 +	int fd;
 +	static const struct drm_mode_card_res zero_res;
@@ -28,6 +127,7 @@ Android deliberately uses signed crtc_x and crtc_y
 +	drmClose(fd);
 +	if (ret == 0)
 +		return 0;
- #elif defined(__DragonFly__)
- 	return 0;
- #endif
++#elif defined(__OpenBSD__)
+ 	int	fd;
+ 	struct drm_mode_card_res res;
+ 	drmModeResPtr r = 0;


Home | Main Index | Thread Index | Old Index