Index: head/graphics/libdrm/Makefile =================================================================== --- head/graphics/libdrm/Makefile (revision 486064) +++ head/graphics/libdrm/Makefile (revision 486065) @@ -1,76 +1,76 @@ # Created by: lesi@FreeBSD.org # $FreeBSD$ PORTNAME= libdrm -PORTVERSION= 2.4.93 +PORTVERSION= 2.4.96 PORTEPOCH= 1 CATEGORIES= graphics x11 MASTER_SITES= http://dri.freedesktop.org/libdrm/ MAINTAINER= x11@FreeBSD.org 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 USES= libtool pkgconfig tar:bzip2 GNU_CONFIGURE= yes USE_LDCONFIG= yes INSTALL_TARGET= install-strip OPTIONS_DEFINE= MANPAGES TESTS OPTIONS_SUB= yes TESTS_DESC= Install test programs (which are always built) .if defined(PACKAGE_BUILDING) OPTIONS_DEFAULT+= MANPAGES .endif MANPAGES_CONFIGURE_ENABLE= manpages MANPAGES_BUILD_DEPENDS= ${LOCALBASE}/share/xsl/docbook/manpages/docbook.xsl:textproc/docbook-xsl MANPAGES_USE= GNOME=libxslt:build TESTS_CONFIGURE_ENABLE= install-test-programs # avoid circular dependency in case cairo supports OpenGL (cairo->mesa-libs->libdrm->cairo) CONFIGURE_ARGS+= --disable-cairo-tests .include .if ${ARCH} == amd64 || ${ARCH} == i386 PLIST_SUB+= ARM_DRIVERS="@comment " PLIST_SUB+= INTEL_DRIVER="" PLIST_SUB+= NOUVEAU_DRIVER="" PLIST_SUB+= RADEON_DRIVERS="" .elif ${ARCH} == powerpc || ${ARCH} == powerpc64 PLIST_SUB+= ARM_DRIVERS="@comment " PLIST_SUB+= INTEL_DRIVER="@comment " PLIST_SUB+= NOUVEAU_DRIVER="" PLIST_SUB+= RADEON_DRIVERS="" .elif ${ARCH} == aarch64 || ${ARCH} == armv6 || ${ARCH} == armv7 PLIST_SUB+= ARM_DRIVERS="" PLIST_SUB+= INTEL_DRIVER="@comment " PLIST_SUB+= NOUVEAU_DRIVER="@comment " PLIST_SUB+= RADEON_DRIVERS="@comment " .else PLIST_SUB+= ARM_DRIVERS="@comment " PLIST_SUB+= INTEL_DRIVER="@comment " PLIST_SUB+= NOUVEAU_DRIVER="@comment " PLIST_SUB+= RADEON_DRIVERS="@comment " .endif # This variable is not for users. So use a non-default name, intended for # people working on DRM kernel module development. .if ${OPSYS} == FreeBSD && !defined(LIBDRM_SKIP_RETURN_PATCH) EXTRA_PATCHES+= ${FILESDIR}/extra-xf86drm.c .endif pre-patch: @${REINPLACE_CMD} 's|{libdir}/pkgconfig|{prefix}/libdata/pkgconfig|g; \ s,i?86|x86_64),i?86|amd64|x86_64),g' \ ${WRKSRC}/configure .include Index: head/graphics/libdrm/distinfo =================================================================== --- head/graphics/libdrm/distinfo (revision 486064) +++ head/graphics/libdrm/distinfo (revision 486065) @@ -1,3 +1,3 @@ -TIMESTAMP = 1533240104 -SHA256 (libdrm-2.4.93.tar.bz2) = 6e84d1dc9548a76f20b59a85cf80a0b230cd8196084f5243469d9e65354fcd3c -SIZE (libdrm-2.4.93.tar.bz2) = 826579 +TIMESTAMP = 1539797646 +SHA256 (libdrm-2.4.96.tar.bz2) = 0d561acf7bb4cc59dc82415100e6c1a44860e8c380e00f9592923e3cd08db393 +SIZE (libdrm-2.4.96.tar.bz2) = 829518 Index: head/graphics/libdrm/files/patch-xf86drm.c =================================================================== --- head/graphics/libdrm/files/patch-xf86drm.c (revision 486064) +++ head/graphics/libdrm/files/patch-xf86drm.c (revision 486065) @@ -1,774 +1,767 @@ ---- xf86drm.c.orig 2018-08-02 20:12:58 UTC +--- xf86drm.c.orig 2018-11-26 18:52:00 UTC +++ xf86drm.c @@ -46,6 +46,9 @@ #include #include #include +#ifdef HAVE_SYS_SYSCTL_H +#include +#endif #include #define stat_t struct stat #include @@ -59,6 +62,10 @@ #endif #include +#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) @@ -69,18 +76,8 @@ #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__ -@@ -177,7 +174,7 @@ void drmFree(void *pt) +@@ -177,7 +174,7 @@ drm_public void drmFree(void *pt) } /** - * Call ioctl, restarting if it is interupted + * Call ioctl, restarting if it is interrupted */ - int + drm_public int drmIoctl(int fd, unsigned long request, void *arg) -@@ -220,6 +217,89 @@ drmHashEntry *drmGetEntry(int fd) +@@ -220,6 +217,89 @@ drm_public drmHashEntry *drmGetEntry(int fd) return entry; } +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 * @@ -287,7 +367,7 @@ static int drmMatchBusID(const char *id1, const char * * * \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 !UDEV @@ -324,8 +404,8 @@ static int chown_check_return(const char *path, uid_t 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; @@ -335,21 +415,14 @@ static int drmOpenDevice(dev_t dev, int minor, int typ 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) { @@ -453,27 +526,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 | O_CLOEXEC, 0)) >= 0) return fd; return -errno; -@@ -514,51 +580,6 @@ int drmAvailable(void) +@@ -514,51 +580,6 @@ drm_public 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. * -@@ -2737,33 +2758,40 @@ int drmDropMaster(int fd) +@@ -2743,28 +2764,22 @@ drm_public int drmDropMaster(int fd) - char *drmGetDeviceNameFromFd(int fd) + drm_public 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); } - if (i == DRM_MAX_MINOR) - return NULL; - - return strdup(name); + return NULL; } - int drmGetNodeTypeFromFd(int fd) + static bool drmNodeIsDRM(int maj, int min) +@@ -2777,13 +2792,26 @@ static bool drmNodeIsDRM(int maj, int min) + maj, min); + return stat(path, &sbuf) == 0; + #else +- return maj == DRM_MAJOR; ++ return !DRM_MAJOR || maj == DRM_MAJOR; + #endif + } + + drm_public 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)) -@@ -2781,6 +2809,7 @@ int drmGetNodeTypeFromFd(int fd) +@@ -2801,6 +2829,7 @@ drm_public 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) -@@ -2820,7 +2849,7 @@ static char *drmGetMinorNameForFD(int fd, int type) + drm_public int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, +@@ -2841,7 +2870,7 @@ static char *drmGetMinorNameForFD(int fd, int type) #ifdef __linux__ DIR *sysdir; struct dirent *ent; - struct stat sbuf; + stat_t sbuf; const char *name = drmGetMinorName(type); int len; char dev_name[64], buf[64]; -@@ -2858,13 +2887,35 @@ static char *drmGetMinorNameForFD(int fd, int type) +@@ -2879,13 +2908,35 @@ static char *drmGetMinorNameForFD(int fd, int type) closedir(sysdir); return NULL; +#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; #else - 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; -@@ -2874,20 +2925,6 @@ static char *drmGetMinorNameForFD(int fd, int type) - if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) +@@ -2895,20 +2946,6 @@ static char *drmGetMinorNameForFD(int fd, int type) + if (!drmNodeIsDRM(maj, min) || !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; -@@ -2990,7 +3027,7 @@ static int drmParseSubsystemType(int maj, int min) +@@ -3011,7 +3048,7 @@ static int drmParseSubsystemType(int maj, int min) return DRM_BUS_VIRTIO; return -EINVAL; -#elif defined(__OpenBSD__) +#elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) return DRM_BUS_PCI; #else #warning "Missing implementation of drmParseSubsystemType" -@@ -3014,7 +3051,8 @@ get_real_pci_path(int maj, int min, char *real_path) - return real_path; +@@ -3035,7 +3072,8 @@ get_pci_path(int maj, int min, char *pci_path) + *term = 0; } -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; -@@ -3064,6 +3102,60 @@ static int drmParsePciBusInfo(int maj, int min, drmPci +@@ -3084,6 +3122,60 @@ static int drmParsePciBusInfo(int maj, int min, drmPci 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)); + + stat_t sbuf; + if (stat(name, &sbuf)) + return -errno; + + 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; + + 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); + + 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; -@@ -3098,32 +3190,6 @@ int drmDevicesEqual(drmDevicePtr a, drmDevicePtr b) +@@ -3118,32 +3210,6 @@ drm_public int drmDevicesEqual(drmDevicePtr a, drmDevi return 0; } -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, -@@ -3198,6 +3264,7 @@ static int parse_config_sysfs_file(int maj, int min, +@@ -3216,6 +3282,7 @@ static int parse_config_sysfs_file(int maj, int min, #endif static int drmParsePciDeviceInfo(int maj, int min, + drmPciBusInfoPtr info, drmPciDeviceInfoPtr device, uint32_t flags) { -@@ -3234,6 +3301,43 @@ static int drmParsePciDeviceInfo(int maj, int min, +@@ -3252,6 +3319,43 @@ static int drmParsePciDeviceInfo(int maj, int min, 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]; + + int fd = open("/dev/pci", O_RDONLY, 0); + 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); + return -error; + } + close(fd); + + 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; -@@ -3314,7 +3418,7 @@ static drmDevicePtr drmDeviceAlloc(unsigned int type, +@@ -3332,7 +3436,7 @@ static drmDevicePtr drmDeviceAlloc(unsigned int type, 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; -@@ -3360,7 +3464,7 @@ static int drmProcessPciDevice(drmDevicePtr *device, +@@ -3378,7 +3482,7 @@ static int drmProcessPciDevice(drmDevicePtr *device, dev->businfo.pci = (drmPciBusInfoPtr)addr; - ret = drmParsePciBusInfo(maj, min, dev->businfo.pci); + ret = drmParsePciBusInfo(node, node_type, maj, min, dev->businfo.pci); if (ret) goto free_device; -@@ -3369,7 +3473,7 @@ static int drmProcessPciDevice(drmDevicePtr *device, +@@ -3387,7 +3491,7 @@ static int drmProcessPciDevice(drmDevicePtr *device, addr += sizeof(drmPciBusInfo); dev->deviceinfo.pci = (drmPciDeviceInfoPtr)addr; - ret = drmParsePciDeviceInfo(maj, min, dev->deviceinfo.pci, flags); + ret = drmParsePciDeviceInfo(maj, min, dev->businfo.pci, dev->deviceinfo.pci, flags); if (ret) goto free_device; } -@@ -3709,8 +3813,8 @@ process_device(drmDevicePtr *device, const char *d_nam +@@ -3727,8 +3831,8 @@ process_device(drmDevicePtr *device, const char *d_nam int req_subsystem_type, bool fetch_deviceinfo, uint32_t flags) { - struct stat sbuf; - char node[PATH_MAX + 1]; + stat_t sbuf; + char node[DRM_NODE_NAME_MAX]; int node_type, subsystem_type; unsigned int maj, min; -@@ -3718,14 +3822,14 @@ process_device(drmDevicePtr *device, const char *d_nam +@@ -3736,7 +3840,7 @@ process_device(drmDevicePtr *device, const char *d_nam if (node_type < 0) return -1; - snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, d_name); + snprintf(node, sizeof(node), "%s/%s", DRM_DIR_NAME, d_name); if (stat(node, &sbuf)) return -1; - 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)) - return -1; - - subsystem_type = drmParseSubsystemType(maj, min); -@@ -3766,7 +3870,7 @@ static void drmFoldDuplicatedDevices(drmDevicePtr loca +@@ -3784,7 +3888,7 @@ static void drmFoldDuplicatedDevices(drmDevicePtr loca 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]); } } -@@ -3806,7 +3910,7 @@ drm_device_has_rdev(drmDevicePtr device, dev_t find_rd +@@ -3824,7 +3928,7 @@ drm_device_has_rdev(drmDevicePtr device, dev_t find_rd * 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 * -@@ -3824,8 +3928,8 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr +@@ -3842,8 +3946,8 @@ drm_public int drmGetDevice2(int fd, uint32_t flags, d * 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; -@@ -3846,26 +3950,16 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr +@@ -3864,26 +3968,16 @@ drm_public int drmGetDevice2(int fd, uint32_t flags, d 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; -@@ -3905,7 +3999,7 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr - 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)) - return -EINVAL; - - subsystem_type = drmParseSubsystemType(maj, min); -@@ -3971,7 +4065,7 @@ int drmGetDevice(int fd, drmDevicePtr *device) +@@ -3989,7 +4083,7 @@ drm_public int drmGetDevice(int fd, drmDevicePtr *devi /** * 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 -@@ -4055,7 +4149,7 @@ int drmGetDevices(drmDevicePtr devices[], int max_devi - char *drmGetDeviceNameFromFd2(int fd) +@@ -4074,7 +4168,7 @@ drm_public int drmGetDevices(drmDevicePtr devices[], i + drm_public char *drmGetDeviceNameFromFd2(int fd) { #ifdef __linux__ - struct stat sbuf; + stat_t sbuf; char path[PATH_MAX + 1], *value; unsigned int maj, min; -@@ -4078,9 +4172,26 @@ char *drmGetDeviceNameFromFd2(int fd) +@@ -4097,9 +4191,26 @@ drm_public 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; -@@ -4098,26 +4209,16 @@ char *drmGetDeviceNameFromFd2(int fd) +@@ -4117,26 +4228,16 @@ drm_public 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); Index: head/graphics/libdrm/files/patch-xf86drmMode.c =================================================================== --- head/graphics/libdrm/files/patch-xf86drmMode.c (revision 486064) +++ head/graphics/libdrm/files/patch-xf86drmMode.c (revision 486065) @@ -1,100 +1,100 @@ ---- xf86drmMode.c.orig 2018-05-13 10:01:15 UTC +--- xf86drmMode.c.orig 2018-10-04 14:50:03 UTC +++ xf86drmMode.c @@ -43,6 +43,7 @@ #include #include #ifdef HAVE_SYS_SYSCTL_H +#include #include #endif #include -@@ -792,41 +793,59 @@ int drmCheckModesettingSupported(const char *busid) +@@ -799,41 +800,59 @@ drm_public int drmCheckModesettingSupported(const char 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; #elif defined(__OpenBSD__) int fd; struct drm_mode_card_res res; Index: head/graphics/libdrm/pkg-plist =================================================================== --- head/graphics/libdrm/pkg-plist (revision 486064) +++ head/graphics/libdrm/pkg-plist (revision 486065) @@ -1,93 +1,94 @@ %%TESTS%%bin/kms-steal-crtc %%TESTS%%bin/kms-universal-planes %%TESTS%%bin/kmstest %%TESTS%%bin/modeprint %%TESTS%%bin/modetest %%TESTS%%bin/proptest %%TESTS%%bin/vbltest %%ARM_DRIVERS%%include/freedreno/freedreno_drmif.h %%ARM_DRIVERS%%include/freedreno/freedreno_ringbuffer.h %%RADEON_DRIVERS%%include/libdrm/amdgpu.h %%RADEON_DRIVERS%%include/libdrm/amdgpu_drm.h include/libdrm/drm.h include/libdrm/drm_fourcc.h include/libdrm/drm_mode.h include/libdrm/drm_sarea.h include/libdrm/i915_drm.h %%INTEL_DRIVER%%include/libdrm/intel_aub.h %%INTEL_DRIVER%%include/libdrm/intel_bufmgr.h %%INTEL_DRIVER%%include/libdrm/intel_debug.h include/libdrm/mach64_drm.h include/libdrm/mga_drm.h +include/libdrm/msm_drm.h %%NOUVEAU_DRIVER%%include/libdrm/nouveau/nouveau.h %%NOUVEAU_DRIVER%%include/libdrm/nouveau/nvif/cl0080.h %%NOUVEAU_DRIVER%%include/libdrm/nouveau/nvif/cl9097.h %%NOUVEAU_DRIVER%%include/libdrm/nouveau/nvif/class.h %%NOUVEAU_DRIVER%%include/libdrm/nouveau/nvif/if0002.h %%NOUVEAU_DRIVER%%include/libdrm/nouveau/nvif/if0003.h %%NOUVEAU_DRIVER%%include/libdrm/nouveau/nvif/ioctl.h %%NOUVEAU_DRIVER%%include/libdrm/nouveau/nvif/unpack.h include/libdrm/nouveau_drm.h include/libdrm/qxl_drm.h include/libdrm/r128_drm.h %%RADEON_DRIVERS%%include/libdrm/r600_pci_ids.h %%RADEON_DRIVERS%%include/libdrm/radeon_bo.h %%RADEON_DRIVERS%%include/libdrm/radeon_bo_gem.h %%RADEON_DRIVERS%%include/libdrm/radeon_bo_int.h %%RADEON_DRIVERS%%include/libdrm/radeon_cs.h %%RADEON_DRIVERS%%include/libdrm/radeon_cs_gem.h %%RADEON_DRIVERS%%include/libdrm/radeon_cs_int.h include/libdrm/radeon_drm.h %%RADEON_DRIVERS%%include/libdrm/radeon_surface.h include/libdrm/savage_drm.h include/libdrm/sis_drm.h include/libdrm/tegra_drm.h include/libdrm/vc4_drm.h %%ARM_DRIVERS%%include/libdrm/vc4_packet.h %%ARM_DRIVERS%%include/libdrm/vc4_qpu_defines.h include/libdrm/via_drm.h include/libdrm/virtgpu_drm.h include/libdrm/vmwgfx_drm.h include/libkms/libkms.h include/libsync.h include/xf86drm.h include/xf86drmMode.h lib/libdrm.so lib/libdrm.so.2 lib/libdrm.so.2.4.0 %%RADEON_DRIVERS%%lib/libdrm_amdgpu.so %%RADEON_DRIVERS%%lib/libdrm_amdgpu.so.1 %%RADEON_DRIVERS%%lib/libdrm_amdgpu.so.1.0.0 %%ARM_DRIVERS%%lib/libdrm_freedreno.so %%ARM_DRIVERS%%lib/libdrm_freedreno.so.1 %%ARM_DRIVERS%%lib/libdrm_freedreno.so.1.0.0 %%INTEL_DRIVER%%lib/libdrm_intel.so %%INTEL_DRIVER%%lib/libdrm_intel.so.1 %%INTEL_DRIVER%%lib/libdrm_intel.so.1.0.0 %%NOUVEAU_DRIVER%%lib/libdrm_nouveau.so %%NOUVEAU_DRIVER%%lib/libdrm_nouveau.so.2 %%NOUVEAU_DRIVER%%lib/libdrm_nouveau.so.2.0.0 %%RADEON_DRIVERS%%lib/libdrm_radeon.so %%RADEON_DRIVERS%%lib/libdrm_radeon.so.1 %%RADEON_DRIVERS%%lib/libdrm_radeon.so.1.0.1 lib/libkms.so lib/libkms.so.1 lib/libkms.so.1.0.0 libdata/pkgconfig/libdrm.pc %%RADEON_DRIVERS%%libdata/pkgconfig/libdrm_amdgpu.pc %%ARM_DRIVERS%%libdata/pkgconfig/libdrm_freedreno.pc %%INTEL_DRIVER%%libdata/pkgconfig/libdrm_intel.pc %%NOUVEAU_DRIVER%%libdata/pkgconfig/libdrm_nouveau.pc %%RADEON_DRIVERS%%libdata/pkgconfig/libdrm_radeon.pc %%ARM_DRIVERS%%libdata/pkgconfig/libdrm_vc4.pc libdata/pkgconfig/libkms.pc %%MANPAGES%%man/man3/drmAvailable.3.gz %%MANPAGES%%man/man3/drmHandleEvent.3.gz %%MANPAGES%%man/man3/drmModeGetResources.3.gz %%MANPAGES%%man/man7/drm-gem.7.gz %%MANPAGES%%man/man7/drm-kms.7.gz %%MANPAGES%%man/man7/drm-memory.7.gz %%MANPAGES%%man/man7/drm-mm.7.gz %%MANPAGES%%man/man7/drm-ttm.7.gz %%MANPAGES%%man/man7/drm.7.gz %%RADEON_DRIVERS%%%%DATADIR%%/amdgpu.ids