1 # Buildsheet autogenerated by ravenadm tool -- Do not edit.
7 SDESC[standard]= Direct Rendering Module services kernel interface
8 HOMEPAGE= http://dri.freedesktop.org
12 SITES[main]= http://dri.freedesktop.org/libdrm/
13 DISTFILE[1]= libdrm-2.4.80.tar.bz2:main
15 SPKGS[standard]= single
17 OPTIONS_AVAILABLE= ARM X86
18 OPTIONS_STANDARD= ARM X86
23 BUILD_DEPENDS= libpthread-stubs:single:standard
24 docbook-xsl:primary:standard
25 libxslt:single:standard
26 libxml2:single:standard
28 USES= libtool pkgconfig
29 XORG_COMPONENTS= pciaccess
31 FPC_EQUIVALENT= graphics/libdrm
34 CONFIGURE_ARGS= --disable-cairo-tests
35 --enable-install-test-programs
37 INSTALL_TARGET= install-strip
38 INSTALL_REQ_TOOLCHAIN= yes
40 [X86].DESCRIPTION= DRM Drivers for amd64 and i386 architectures
42 [ARM].DESCRIPTION= DRM Drivers for AARCH64 architecture
44 [FILE:70:descriptions/desc.single]
45 Userspace interface to kernel DRM (Direct Rendering Module) services.
49 a82a519601e9cdfad795e760807eb07ac8913b225e25fc8fe9bc03e3be6549f1 771243 libdrm-2.4.80.tar.bz2
52 [FILE:1959:manifests/plist.single]
61 %%ARM-ON%%include/freedreno/
63 freedreno_ringbuffer.h
64 %%X86-ON%%include/libdrm/
73 %%X86-ON%%include/libdrm/
80 %%X86-ON%%include/libdrm/nouveau/nouveau.h
81 %%X86-ON%%include/libdrm/nouveau/nvif/
93 %%X86-ON%%include/libdrm/
103 %%X86-ON%%include/libdrm/
110 %%ARM-ON%%include/libdrm/
117 include/libkms/libkms.h
129 libdrm_amdgpu.so.1.0.0
132 libdrm_freedreno.so.1
133 libdrm_freedreno.so.1.0.0
137 libdrm_intel.so.1.0.0
140 libdrm_nouveau.so.2.0.0
143 libdrm_radeon.so.1.0.1
150 %%X86-ON%%lib/pkgconfig/
152 %%ARM-ON%%lib/pkgconfig/
154 %%X86-ON%%lib/pkgconfig/
158 %%ARM-ON%%lib/pkgconfig/
165 drmModeGetResources.3.gz
175 [FILE:801:patches/patch-libkms_vmwgfx.c]
176 # the defintion of ERESTART is behind a check for _KERNEL, but
177 # defining that causes errno to not be defined. fortunately, there's
178 # an alternative switch. unfortunately, those differ by platform and
179 # _WANT_KERNEL_ERRNO is too recent to be part of any release, so just
180 # define ERESTART if we still don't have it after including errno.h
182 --- libkms/vmwgfx.c.orig 2017-04-14 23:29:46 UTC
188 +#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
189 +#define _WANT_KERNEL_ERRNO
190 +#elif defined(__DragonFly__)
191 +#define _KERNEL_STRUCTURES
196 #include "internal.h"
198 +#define ERESTART (-1)
202 #include "libdrm_macros.h"
205 [FILE:283:patches/patch-libsync.h]
206 # define ETIME as ETIMEOUT same as done in Mesa
208 --- libsync.h.orig 2017-04-14 23:29:46 UTC
211 #include <sys/ioctl.h>
212 #include <sys/poll.h>
215 +#define ETIME ETIMEDOUT
218 #if defined(__cplusplus)
222 [FILE:24055:patches/patch-xf86drm.c]
223 --- xf86drm.c.orig 2017-04-07 08:49:13 UTC
228 #include <sys/types.h>
229 +#ifdef HAVE_SYS_SYSCTL_H
230 +#include <sys/sysctl.h>
232 #include <sys/stat.h>
233 #define stat_t struct stat
234 #include <sys/ioctl.h>
239 +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
240 +#include <sys/pciio.h>
243 /* Not all systems have MAP_FAILED defined */
245 #define MAP_FAILED ((void *)-1)
248 #include "util_math.h"
251 -#define DRM_PRIMARY_MINOR_NAME "drm"
252 -#define DRM_CONTROL_MINOR_NAME "drmC"
253 -#define DRM_RENDER_MINOR_NAME "drmR"
255 -#define DRM_PRIMARY_MINOR_NAME "card"
256 -#define DRM_CONTROL_MINOR_NAME "controlD"
257 -#define DRM_RENDER_MINOR_NAME "renderD"
260 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
261 -#define DRM_MAJOR 145
262 +#define DRM_MAJOR 0 /* Major ID unused on systems with devfs */
266 @@ -180,7 +177,7 @@ void drmFree(void *pt)
270 - * Call ioctl, restarting if it is interupted
271 + * Call ioctl, restarting if it is interrupted
274 drmIoctl(int fd, unsigned long request, void *arg)
275 @@ -223,6 +220,89 @@ drmHashEntry *drmGetEntry(int fd)
279 +static int drmGetMinorBase(int type)
282 + case DRM_NODE_PRIMARY:
283 + case DRM_NODE_CONTROL:
284 + case DRM_NODE_RENDER:
291 +static int drmGetMinorType(int minor)
296 + int type = minor >> 6;
298 + case DRM_NODE_PRIMARY:
299 + case DRM_NODE_CONTROL:
300 + case DRM_NODE_RENDER:
308 +static const char *drmGetMinorName(int type)
311 + case DRM_NODE_PRIMARY:
312 + return DRM_PRIMARY_MINOR_NAME;
313 + case DRM_NODE_CONTROL:
314 + return DRM_CONTROL_MINOR_NAME;
315 + case DRM_NODE_RENDER:
316 + return DRM_RENDER_MINOR_NAME;
323 +static const char *drmGetDeviceName(int type)
326 + case DRM_NODE_PRIMARY:
327 + return DRM_DEV_NAME;
328 + case DRM_NODE_CONTROL:
329 + return DRM_CONTROL_DEV_NAME;
330 + case DRM_NODE_RENDER:
331 + return DRM_RENDER_DEV_NAME;
337 +static int drmGetNodeNumber(const char *name)
339 + size_t name_len = strnlen(name, DRM_NODE_NAME_MAX);
340 + while (name_len && isdigit(name[name_len - 1]))
342 + return strtol(name + name_len, NULL, 10);
345 +static int drmGetNodeType(const char *name)
347 + if (strncmp(name, DRM_PRIMARY_MINOR_NAME,
348 + sizeof(DRM_PRIMARY_MINOR_NAME) - 1) == 0)
349 + return DRM_NODE_PRIMARY;
351 + if (strncmp(name, DRM_CONTROL_MINOR_NAME,
352 + sizeof(DRM_CONTROL_MINOR_NAME ) - 1) == 0)
353 + return DRM_NODE_CONTROL;
355 + if (strncmp(name, DRM_RENDER_MINOR_NAME,
356 + sizeof(DRM_RENDER_MINOR_NAME) - 1) == 0)
357 + return DRM_NODE_RENDER;
363 * Compare two busid strings
365 @@ -290,7 +370,7 @@ static int drmMatchBusID(const char *id1
368 * Checks for failure. If failure was caused by signal call chown again.
369 - * If any other failure happened then it will output error mesage using
370 + * If any other failure happened then it will output error message using
374 @@ -327,8 +407,8 @@ static int chown_check_return(const char
375 static int drmOpenDevice(dev_t dev, int minor, int type)
378 - const char *dev_name;
380 + const char *dev_name = drmGetDeviceName(type);
381 + char buf[DRM_NODE_NAME_MAX];
383 mode_t devmode = DRM_DEV_MODE, serv_mode;
385 @@ -338,21 +418,14 @@ static int drmOpenDevice(dev_t dev, int
386 gid_t group = DRM_DEV_GID;
390 - case DRM_NODE_PRIMARY:
391 - dev_name = DRM_DEV_NAME;
393 - case DRM_NODE_CONTROL:
394 - dev_name = DRM_CONTROL_DEV_NAME;
396 - case DRM_NODE_RENDER:
397 - dev_name = DRM_RENDER_DEV_NAME;
404 +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
405 + sprintf(buf, dev_name, DRM_DIR_NAME, minor + drmGetMinorBase(type));
407 sprintf(buf, dev_name, DRM_DIR_NAME, minor);
409 drmMsg("drmOpenDevice: node name is %s\n", buf);
411 if (drm_server_info && drm_server_info->get_perms) {
412 @@ -456,27 +529,20 @@ wait_for_udev:
413 static int drmOpenMinor(int minor, int create, int type)
417 - const char *dev_name;
418 + char buf[DRM_NODE_NAME_MAX];
419 + const char *dev_name = drmGetDeviceName(type);
422 return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type);
425 - case DRM_NODE_PRIMARY:
426 - dev_name = DRM_DEV_NAME;
428 - case DRM_NODE_CONTROL:
429 - dev_name = DRM_CONTROL_DEV_NAME;
431 - case DRM_NODE_RENDER:
432 - dev_name = DRM_RENDER_DEV_NAME;
439 +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
440 + sprintf(buf, dev_name, DRM_DIR_NAME, minor + drmGetMinorBase(type));
442 sprintf(buf, dev_name, DRM_DIR_NAME, minor);
444 if ((fd = open(buf, O_RDWR, 0)) >= 0)
447 @@ -517,51 +583,6 @@ int drmAvailable(void)
451 -static int drmGetMinorBase(int type)
454 - case DRM_NODE_PRIMARY:
456 - case DRM_NODE_CONTROL:
458 - case DRM_NODE_RENDER:
465 -static int drmGetMinorType(int minor)
467 - int type = minor >> 6;
473 - case DRM_NODE_PRIMARY:
474 - case DRM_NODE_CONTROL:
475 - case DRM_NODE_RENDER:
482 -static const char *drmGetMinorName(int type)
485 - case DRM_NODE_PRIMARY:
486 - return DRM_PRIMARY_MINOR_NAME;
487 - case DRM_NODE_CONTROL:
488 - return DRM_CONTROL_MINOR_NAME;
489 - case DRM_NODE_RENDER:
490 - return DRM_RENDER_MINOR_NAME;
497 * Open the device by bus ID.
499 @@ -2705,33 +2726,40 @@ int drmDropMaster(int fd)
501 char *drmGetDeviceNameFromFd(int fd)
508 /* The whole drmOpen thing is a fiasco and we need to find a way
509 * back to just using open(2). For now, however, lets just make
510 * things worse with even more ad hoc directory walking code to
511 * discover the device file name. */
516 + dev_t d = sbuf.st_rdev;
518 - for (i = 0; i < DRM_MAX_MINOR; i++) {
519 + for (int i = 0; i < DRM_MAX_MINOR; i++) {
520 + char name[DRM_NODE_NAME_MAX];
521 snprintf(name, sizeof name, DRM_DEV_NAME, DRM_DIR_NAME, i);
522 if (stat(name, &sbuf) == 0 && sbuf.st_rdev == d)
524 + return strdup(name);
526 - if (i == DRM_MAX_MINOR)
529 - return strdup(name);
533 int drmGetNodeTypeFromFd(int fd)
536 +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
537 + char *name = drmGetDeviceNameFromFd2(fd);
543 + int type = drmGetNodeType(name);
552 if (fstat(fd, &sbuf))
553 @@ -2749,6 +2777,7 @@ int drmGetNodeTypeFromFd(int fd)
560 int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd)
561 @@ -2788,7 +2817,7 @@ static char *drmGetMinorNameForFD(int fd
564 struct dirent *pent, *ent;
567 const char *name = drmGetMinorName(type);
569 char dev_name[64], buf[64];
570 @@ -2839,13 +2868,35 @@ static char *drmGetMinorNameForFD(int fd
574 +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
575 + const char *dev_name = drmGetDeviceName(type);
579 + char *name = drmGetDeviceNameFromFd2(fd);
583 + int oldnum = drmGetNodeNumber(name);
584 + int oldtype = drmGetMinorType(oldnum);
590 + int newnum = oldnum - drmGetMinorBase(oldtype) + drmGetMinorBase(type);
591 + snprintf(name, DRM_NODE_NAME_MAX, dev_name, DRM_DIR_NAME, newnum);
595 - char buf[PATH_MAX + 1];
596 - const char *dev_name;
598 + char buf[DRM_NODE_NAME_MAX];
599 + const char *dev_name = drmGetDeviceName(type);
600 unsigned int maj, min;
606 if (fstat(fd, &sbuf))
609 @@ -2855,20 +2906,6 @@ out_close_dir:
610 if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
614 - case DRM_NODE_PRIMARY:
615 - dev_name = DRM_DEV_NAME;
617 - case DRM_NODE_CONTROL:
618 - dev_name = DRM_CONTROL_DEV_NAME;
620 - case DRM_NODE_RENDER:
621 - dev_name = DRM_RENDER_DEV_NAME;
627 base = drmGetMinorBase(type);
630 @@ -2966,7 +3003,7 @@ static int drmParseSubsystemType(int maj
631 return DRM_BUS_HOST1X;
634 -#elif defined(__OpenBSD__)
635 +#elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
638 #warning "Missing implementation of drmParseSubsystemType"
639 @@ -2974,7 +3011,8 @@ static int drmParseSubsystemType(int maj
643 -static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info)
644 +static int drmParsePciBusInfo(const char *node, int node_type,
645 + int maj, int min, drmPciBusInfoPtr info)
648 unsigned int domain, bus, dev, func;
649 @@ -3023,6 +3061,60 @@ static int drmParsePciBusInfo(int maj, i
650 info->func = pinfo.func;
653 +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
655 + * Only the primary nodes can be mapped to hw.dri.%i via major/minor
656 + * Determine the primary node by offset and use its major/minor pair
658 + if (node_type != DRM_NODE_PRIMARY) {
659 + char name[DRM_NODE_NAME_MAX];
660 + snprintf(name, sizeof(name), DRM_DEV_NAME, DRM_DIR_NAME,
661 + drmGetNodeNumber(node) - drmGetMinorBase(node_type));
664 + if (stat(name, &sbuf))
667 + maj = major(sbuf.st_rdev);
668 + min = minor(sbuf.st_rdev);
671 + * Major/minor appear after the driver name in the hw.dri.%i.name node
672 + * Find the node with matching major/minor pair and parse the bus ID,
673 + * which may be after the name or may be alone in hw.dri.%i.busid
675 + #define bus_fmt "pci:%04x:%02x:%02x.%u"
676 + #define name_fmt "%*s %x " bus_fmt
677 + for (int i = 0; i < DRM_MAX_MINOR; ++i) {
678 + char name[16], value[256];
679 + size_t length = sizeof(value);
680 + snprintf(name, sizeof(name), "hw.dri.%i.name", i);
681 + if (sysctlbyname(name, value, &length, NULL, 0))
684 + value[length] = '\0';
685 + unsigned int rdev = 0, domain = 0, bus = 0, slot = 0, func = 0;
686 + int vals = sscanf(value, name_fmt, &rdev, &domain, &bus, &slot, &func);
688 + if (vals >= 1 && rdev == makedev(maj,min)) {
690 + /* busid not in the name, try busid */
691 + length = sizeof(value);
692 + snprintf(name, sizeof(name), "hw.dri.%i.busid", i);
693 + if (sysctlbyname(name, value, &length, NULL, 0))
695 + value[length] = '\0';
696 + if (sscanf(value, bus_fmt, &domain, &bus, &slot, &func) != 4)
699 + info->domain = domain;
708 #warning "Missing implementation of drmParsePciBusInfo"
710 @@ -3057,32 +3149,6 @@ static int drmCompareBusInfo(drmDevicePt
714 -static int drmGetNodeType(const char *name)
716 - if (strncmp(name, DRM_PRIMARY_MINOR_NAME,
717 - sizeof(DRM_PRIMARY_MINOR_NAME) - 1) == 0)
718 - return DRM_NODE_PRIMARY;
720 - if (strncmp(name, DRM_CONTROL_MINOR_NAME,
721 - sizeof(DRM_CONTROL_MINOR_NAME ) - 1) == 0)
722 - return DRM_NODE_CONTROL;
724 - if (strncmp(name, DRM_RENDER_MINOR_NAME,
725 - sizeof(DRM_RENDER_MINOR_NAME) - 1) == 0)
726 - return DRM_NODE_RENDER;
731 -static int drmGetMaxNodeName(void)
733 - return sizeof(DRM_DIR_NAME) +
734 - MAX3(sizeof(DRM_PRIMARY_MINOR_NAME),
735 - sizeof(DRM_CONTROL_MINOR_NAME),
736 - sizeof(DRM_RENDER_MINOR_NAME)) +
737 - 3 /* length of the node number */;
741 static int parse_separate_sysfs_files(int maj, int min,
742 drmPciDeviceInfoPtr device,
743 @@ -3152,6 +3218,7 @@ static int parse_config_sysfs_file(int m
746 static int drmParsePciDeviceInfo(int maj, int min,
747 + drmPciBusInfoPtr info,
748 drmPciDeviceInfoPtr device,
751 @@ -3188,6 +3255,43 @@ static int drmParsePciDeviceInfo(int maj
752 device->subdevice_id = pinfo.subdevice_id;
755 +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
756 + struct pci_conf_io pc;
757 + struct pci_match_conf patterns[1];
758 + struct pci_conf results[1];
760 + int fd = open("/dev/pci", O_RDONLY, 0);
764 + bzero(&patterns, sizeof(patterns));
765 + patterns[0].pc_sel.pc_domain = info->domain;
766 + patterns[0].pc_sel.pc_bus = info->bus;
767 + patterns[0].pc_sel.pc_dev = info->dev;
768 + patterns[0].pc_sel.pc_func = info->func;
769 + patterns[0].flags = PCI_GETCONF_MATCH_DOMAIN | PCI_GETCONF_MATCH_BUS
770 + | PCI_GETCONF_MATCH_DEV | PCI_GETCONF_MATCH_FUNC;
771 + bzero(&pc, sizeof(struct pci_conf_io));
772 + pc.num_patterns = 1;
773 + pc.pat_buf_len = sizeof(patterns);
774 + pc.patterns = patterns;
775 + pc.match_buf_len = sizeof(results);
776 + pc.matches = results;
778 + if (ioctl(fd, PCIOCGETCONF, &pc) || pc.status == PCI_GETCONF_ERROR) {
785 + device->vendor_id = results[0].pc_vendor;
786 + device->device_id = results[0].pc_device;
787 + device->subvendor_id = results[0].pc_subvendor;
788 + device->subdevice_id = results[0].pc_subdevice;
789 + device->revision_id = results[0].pc_revid;
793 #warning "Missing implementation of drmParsePciDeviceInfo"
795 @@ -3268,7 +3372,7 @@ static drmDevicePtr drmDeviceAlloc(unsig
799 - max_node_length = ALIGN(drmGetMaxNodeName(), sizeof(void *));
800 + max_node_length = ALIGN(DRM_NODE_NAME_MAX, sizeof(void *));
801 extra = DRM_NODE_MAX * (sizeof(void *) + max_node_length);
803 size = sizeof(*device) + extra + bus_size + device_size;
804 @@ -3314,7 +3418,7 @@ static int drmProcessPciDevice(drmDevice
806 dev->businfo.pci = (drmPciBusInfoPtr)addr;
808 - ret = drmParsePciBusInfo(maj, min, dev->businfo.pci);
809 + ret = drmParsePciBusInfo(node, node_type, maj, min, dev->businfo.pci);
813 @@ -3323,7 +3427,7 @@ static int drmProcessPciDevice(drmDevice
814 addr += sizeof(drmPciBusInfo);
815 dev->deviceinfo.pci = (drmPciDeviceInfoPtr)addr;
817 - ret = drmParsePciDeviceInfo(maj, min, dev->deviceinfo.pci, flags);
818 + ret = drmParsePciDeviceInfo(maj, min, dev->businfo.pci, dev->deviceinfo.pci, flags);
822 @@ -3673,7 +3777,7 @@ static void drmFoldDuplicatedDevices(drm
823 local_devices[i]->available_nodes |= local_devices[j]->available_nodes;
824 node_type = log2(local_devices[j]->available_nodes);
825 memcpy(local_devices[i]->nodes[node_type],
826 - local_devices[j]->nodes[node_type], drmGetMaxNodeName());
827 + local_devices[j]->nodes[node_type], DRM_NODE_NAME_MAX);
828 drmFreeDevice(&local_devices[j]);
831 @@ -3691,7 +3795,7 @@ drm_device_validate_flags(uint32_t flags
832 * Get information about the opened drm device
834 * \param fd file descriptor of the drm device
835 - * \param flags feature/behaviour bitmask
836 + * \param flags feature/behavior bitmask
837 * \param device the address of a drmDevicePtr where the information
838 * will be allocated in stored
840 @@ -3709,8 +3813,8 @@ int drmGetDevice2(int fd, uint32_t flags
841 * Avoid stat'ing all of /dev needlessly by implementing this custom path.
845 - char node[PATH_MAX + 1];
847 + char node[DRM_NODE_NAME_MAX];
848 const char *dev_name;
849 int node_type, subsystem_type;
850 int maj, min, n, ret, base;
851 @@ -3731,26 +3835,16 @@ int drmGetDevice2(int fd, uint32_t flags
855 - switch (node_type) {
856 - case DRM_NODE_PRIMARY:
857 - dev_name = DRM_DEV_NAME;
859 - case DRM_NODE_CONTROL:
860 - dev_name = DRM_CONTROL_DEV_NAME;
862 - case DRM_NODE_RENDER:
863 - dev_name = DRM_RENDER_DEV_NAME;
866 + dev_name = drmGetDeviceName(node_type);
871 base = drmGetMinorBase(node_type);
875 - n = snprintf(node, PATH_MAX, dev_name, DRM_DIR_NAME, min - base);
876 - if (n == -1 || n >= PATH_MAX)
877 + n = snprintf(node, sizeof(node), dev_name, DRM_DIR_NAME, min - base);
878 + if (n == -1 || n >= sizeof(node))
880 if (stat(node, &sbuf))
882 @@ -3771,8 +3865,8 @@ int drmGetDevice2(int fd, uint32_t flags
887 - char node[PATH_MAX + 1];
889 + char node[DRM_NODE_NAME_MAX];
890 int node_type, subsystem_type;
892 int ret, i, node_count;
893 @@ -3792,7 +3886,7 @@ int drmGetDevice2(int fd, uint32_t flags
894 maj = major(sbuf.st_rdev);
895 min = minor(sbuf.st_rdev);
897 - if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
898 + if ((DRM_MAJOR && maj != DRM_MAJOR) || !S_ISCHR(sbuf.st_mode))
901 subsystem_type = drmParseSubsystemType(maj, min);
902 @@ -3813,14 +3907,14 @@ int drmGetDevice2(int fd, uint32_t flags
906 - snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, dent->d_name);
907 + snprintf(node, sizeof(node), "%s/%s", DRM_DIR_NAME, dent->d_name);
908 if (stat(node, &sbuf))
911 maj = major(sbuf.st_rdev);
912 min = minor(sbuf.st_rdev);
914 - if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
915 + if ((DRM_MAJOR && maj != DRM_MAJOR) || !S_ISCHR(sbuf.st_mode))
918 if (drmParseSubsystemType(maj, min) != subsystem_type)
919 @@ -3918,7 +4012,7 @@ int drmGetDevice(int fd, drmDevicePtr *d
921 * Get drm devices on the system
923 - * \param flags feature/behaviour bitmask
924 + * \param flags feature/behavior bitmask
925 * \param devices the array of devices with drmDevicePtr elements
926 * can be NULL to get the device number first
927 * \param max_devices the maximum number of devices for the array
928 @@ -3937,8 +4031,8 @@ int drmGetDevices2(uint32_t flags, drmDe
933 - char node[PATH_MAX + 1];
935 + char node[DRM_NODE_NAME_MAX];
936 int node_type, subsystem_type;
938 int ret, i, node_count, device_count;
939 @@ -3963,14 +4057,14 @@ int drmGetDevices2(uint32_t flags, drmDe
943 - snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, dent->d_name);
944 + snprintf(node, sizeof(node), "%s/%s", DRM_DIR_NAME, dent->d_name);
945 if (stat(node, &sbuf))
948 maj = major(sbuf.st_rdev);
949 min = minor(sbuf.st_rdev);
951 - if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
952 + if ((DRM_MAJOR && maj != DRM_MAJOR) || !S_ISCHR(sbuf.st_mode))
955 subsystem_type = drmParseSubsystemType(maj, min);
956 @@ -4078,7 +4172,7 @@ int drmGetDevices(drmDevicePtr devices[]
957 char *drmGetDeviceNameFromFd2(int fd)
962 char path[PATH_MAX + 1], *value;
963 unsigned int maj, min;
965 @@ -4101,9 +4195,26 @@ char *drmGetDeviceNameFromFd2(int fd)
969 +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
971 + if (fstat(fd, &sbuf))
974 + dev_t rdev = sbuf.st_rdev;
975 + /* minor numbers don't depend on node name suffix, search for a match */
976 + for (int i = 0; i < DRM_MAX_MINOR; ++i) {
977 + char node[DRM_NODE_NAME_MAX];
978 + for (int j = 0; j < DRM_NODE_MAX; ++j) {
979 + snprintf(node, sizeof(node), drmGetDeviceName(j),
980 + DRM_DIR_NAME, drmGetMinorBase(j) + i);
981 + if (stat(node, &sbuf) == 0 && sbuf.st_rdev == rdev)
982 + return strdup(node);
988 - char node[PATH_MAX + 1];
990 + char node[DRM_NODE_NAME_MAX];
991 const char *dev_name;
993 int maj, min, n, base;
994 @@ -4121,26 +4232,16 @@ char *drmGetDeviceNameFromFd2(int fd)
998 - switch (node_type) {
999 - case DRM_NODE_PRIMARY:
1000 - dev_name = DRM_DEV_NAME;
1002 - case DRM_NODE_CONTROL:
1003 - dev_name = DRM_CONTROL_DEV_NAME;
1005 - case DRM_NODE_RENDER:
1006 - dev_name = DRM_RENDER_DEV_NAME;
1009 + dev_name = drmGetDeviceName(node_type);
1014 base = drmGetMinorBase(node_type);
1018 - n = snprintf(node, PATH_MAX, dev_name, DRM_DIR_NAME, min - base);
1019 - if (n == -1 || n >= PATH_MAX)
1020 + n = snprintf(node, sizeof(node), dev_name, DRM_DIR_NAME, min - base);
1021 + if (n == -1 || n >= sizeof(node))
1024 return strdup(node);
1027 [FILE:1334:patches/patch-xf86drm.h]
1028 --- xf86drm.h.orig 2017-04-07 08:49:13 UTC
1030 @@ -78,17 +78,27 @@ extern "C" {
1033 #define DRM_DIR_NAME "/dev"
1034 -#define DRM_DEV_NAME "%s/drm%d"
1035 -#define DRM_CONTROL_DEV_NAME "%s/drmC%d"
1036 -#define DRM_RENDER_DEV_NAME "%s/drmR%d"
1037 +#define DRM_PRIMARY_MINOR_NAME "drm"
1038 +#define DRM_CONTROL_MINOR_NAME "drmC"
1039 +#define DRM_RENDER_MINOR_NAME "drmR"
1041 #define DRM_DIR_NAME "/dev/dri"
1042 -#define DRM_DEV_NAME "%s/card%d"
1043 -#define DRM_CONTROL_DEV_NAME "%s/controlD%d"
1044 -#define DRM_RENDER_DEV_NAME "%s/renderD%d"
1045 -#define DRM_PROC_NAME "/proc/dri/" /* For backward Linux compatibility */
1046 +#define DRM_PRIMARY_MINOR_NAME "card"
1047 +#define DRM_CONTROL_MINOR_NAME "controlD"
1048 +#define DRM_RENDER_MINOR_NAME "renderD"
1051 +#define DRM_DEV_NAME "%s/" DRM_PRIMARY_MINOR_NAME "%d"
1052 +#define DRM_CONTROL_DEV_NAME "%s/" DRM_CONTROL_MINOR_NAME "%d"
1053 +#define DRM_RENDER_DEV_NAME "%s/" DRM_RENDER_MINOR_NAME "%d"
1055 +#define DRM_NODE_NAME_MAX \
1056 + (sizeof(DRM_DIR_NAME) + \
1057 + MAX3(sizeof(DRM_PRIMARY_MINOR_NAME), \
1058 + sizeof(DRM_CONTROL_MINOR_NAME), \
1059 + sizeof(DRM_RENDER_MINOR_NAME)) \
1060 + + 3) /* length of the node number */
1062 #define DRM_ERR_NO_DEVICE (-1001)
1063 #define DRM_ERR_NO_ACCESS (-1002)
1064 #define DRM_ERR_NOT_ROOT (-1003)
1067 [FILE:3299:patches/patch-xf86drmMode.c]
1068 --- xf86drmMode.c.orig 2017-04-07 08:49:13 UTC
1072 #include <sys/ioctl.h>
1073 #ifdef HAVE_SYS_SYSCTL_H
1074 +#include <sys/types.h>
1075 #include <sys/sysctl.h>
1078 @@ -796,43 +797,60 @@ int drmCheckModesettingSupported(const c
1082 -#elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
1083 - char kbusid[1024], sbusid[1024];
1085 - int domain, bus, dev, func;
1086 - int i, modesetting, ret;
1088 +#elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__DragonFly__)
1089 + #define bus_fmt "pci:%04x:%02x:%02x.%u"
1090 + #define name_fmt "%*s %*s " bus_fmt
1091 + unsigned int d1 = 0, b1 = 0, s1 = 0, f1 = 0;
1092 + if (sscanf(busid, bus_fmt, &d1, &b1, &s1, &f1) != 4)
1095 + * hw.dri.%i.bus is not always present and hw.dri.%i.name does not
1096 + * always contain the busid, so try both for best chance of success
1098 + for (int i = 0; i < DRM_MAX_MINOR; ++i) {
1099 + char name[22], value[256];
1100 + size_t length = sizeof(value);
1101 + snprintf(name, sizeof(name), "hw.dri.%i.name", i);
1102 + if (sysctlbyname(name, value, &length, NULL, 0))
1105 - ret = sscanf(busid, "pci:%04x:%02x:%02x.%d", &domain, &bus, &dev,
1109 - snprintf(kbusid, sizeof(kbusid), "pci:%04x:%02x:%02x.%d", domain, bus,
1111 + value[length] = '\0';
1112 + unsigned int d2 = 0, b2 = 0, s2 = 0, f2 = 0;
1113 + switch (sscanf(value, name_fmt, &d2, &b2, &s2, &f2)) {
1114 + case 0: /* busid not in the name, try busid */
1115 + length = sizeof(value);
1116 + snprintf(name, sizeof(name), "hw.dri.%i.busid", i);
1117 + if (sysctlbyname(name, value, &length, NULL, 0))
1120 - /* How many GPUs do we expect in the machine ? */
1121 - for (i = 0; i < 16; i++) {
1122 - snprintf(oid, sizeof(oid), "hw.dri.%d.busid", i);
1123 - len = sizeof(sbusid);
1124 - ret = sysctlbyname(oid, sbusid, &len, NULL, 0);
1126 - if (errno == ENOENT)
1127 + value[length] = '\0';
1128 + if (sscanf(value, bus_fmt, &d2, &b2, &s2, &f2) != 4)
1131 + /* fall through after parsing busid */
1133 + case 4: /* if we jumped here then busid was in the name */
1134 + if (d1 == d2 && b1 == b2 && s1 == s2 && f1 == f2) {
1136 + * Confirm the drm driver for this device supports KMS,
1137 + * except on DragonFly where all the drm drivers do so
1138 + * but only hw.dri.0.modesetting is present
1140 + #ifndef __DragonFly__
1141 + int modesetting = 0;
1142 + length = sizeof(modesetting);
1143 + snprintf(name, sizeof(name), "hw.dri.%i.modesetting", i);
1144 + if (sysctlbyname(name, &modesetting, &length, NULL, 0)
1145 + || length != sizeof(modesetting) || !modesetting)
1154 - if (strcmp(sbusid, kbusid) != 0)
1156 - snprintf(oid, sizeof(oid), "hw.dri.%d.modesetting", i);
1157 - len = sizeof(modesetting);
1158 - ret = sysctlbyname(oid, &modesetting, &len, NULL, 0);
1159 - if (ret == -1 || len != sizeof(modesetting))
1161 - return (modesetting ? 0 : -ENOSYS);
1163 -#elif defined(__DragonFly__)
1167 +#elif defined(__OpenBSD__)
1169 struct drm_mode_card_res res;
1170 drmModeResPtr r = 0;
1173 [FILE:728:freebsd/patch-xf86drm.c]
1174 Error code 512 is being leaked from kernel space. While it should be
1175 converted to either EINTR or EAGAIN in the kernel. Teach libdrm to do this
1176 for now. Newer kernel modules will have this fixed included.
1178 dragonfly fixed this issue in,
1179 http://gitweb.dragonflybsd.org/dragonfly.git/commit/b922632f623ee2cc2c1346bb3a6894a7756676aa
1180 which has been included since the 4.4 release.
1182 --- xf86drm.c.orig 2017-01-30 13:59:15.919081000 +0100
1184 @@ -197,7 +197,7 @@ drmIoctl(int fd, unsigned long request,
1187 ret = ioctl(fd, request, arg);
1188 - } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
1189 + } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == 512));