> Date: Sat, 19 Nov 2016 19:31:18 +1100
> From: Jonathan Gray <[email protected]>
>
> Support libdrm functions required for Mesa versions >= 13.
>
> On linux this information is pulled out of a psuedo filesystem, here the
> new DRM_IOCTL_GET_PCIINFO ioctl is used for the same.
>
> Only primary drm nodes are handled, render and control nodes which we
> don't have aren't. This also only handles devices with PCI ids.
>
> drmGetMinorNameForFD() based on code the Mesa loader used to have.
See my reply to the kernel diff. One nit...
> diff --git xf86drm.c xf86drm.c
> index 3c2c5d4..03fe257 100644
> --- xf86drm.c
> +++ xf86drm.c
> @@ -62,6 +62,10 @@
> #endif
> #include <math.h>
>
> +#ifdef __OpenBSD__
> +#include <sys/pciio.h>
> +#endif
> +
> /* Not all systems have MAP_FAILED defined */
> #ifndef MAP_FAILED
> #define MAP_FAILED ((void *)-1)
> @@ -2851,7 +2855,25 @@ static char *drmGetMinorNameForFD(int fd, int type)
> out_close_dir:
> closedir(sysdir);
> #else
> -#warning "Missing implementation of drmGetMinorNameForFD"
> + struct stat sbuf;
> + unsigned int maj, min;
> + char buf[0x40];
Any reason not to use PATH_MAX + 1 here?
> + int n;
> +
> + if (fstat(fd, &sbuf))
> + return NULL;
> +
> + maj = major(sbuf.st_rdev);
> + min = minor(sbuf.st_rdev);
> +
> + if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
> + return NULL;
> +
> + n = snprintf(buf, sizeof(buf), DRM_DEV_NAME, DRM_DIR_NAME, min);
> + if (n == -1 || n >= sizeof(buf))
> + return NULL;
> +
> + return strdup(buf);
> #endif
> return NULL;
> }
> @@ -2887,6 +2909,8 @@ static int drmParseSubsystemType(int maj, int min)
> return DRM_BUS_PCI;
>
> return -EINVAL;
> +#elif defined(__OpenBSD__)
> + return DRM_BUS_PCI;
> #else
> #warning "Missing implementation of drmParseSubsystemType"
> return -EINVAL;
> @@ -2929,6 +2953,26 @@ static int drmParsePciBusInfo(int maj, int min,
> drmPciBusInfoPtr info)
> info->func = func;
>
> return 0;
> +#elif defined(__OpenBSD__)
> + struct drm_pciinfo pinfo;
> + int fd;
> +
> + fd = drmOpenMinor(min, 0, DRM_NODE_PRIMARY);
> + if (fd < 0)
> + return -errno;
> +
> + if (drmIoctl(fd, DRM_IOCTL_GET_PCIINFO, &pinfo)) {
> + close(fd);
> + return -errno;
> + }
> + close(fd);
> +
> + info->domain = pinfo.domain;
> + info->bus = pinfo.bus;
> + info->dev = pinfo.dev;
> + info->func = pinfo.func;
> +
> + return 0;
> #else
> #warning "Missing implementation of drmParsePciBusInfo"
> return -EINVAL;
> @@ -3004,6 +3048,37 @@ static int drmParsePciDeviceInfo(const char *d_name,
> device->subdevice_id = config[46] | (config[47] << 8);
>
> return 0;
> +#elif defined(__OpenBSD__)
> + struct drm_pciinfo pinfo;
> + char buf[0x40];
And here?
> + int fd, n;
> +
> + n = snprintf(buf, sizeof(buf), "%s/%s", DRM_DIR_NAME, d_name);
> + if (n == -1 || n >= sizeof(buf))
> + return -errno;
> +
> +#ifndef X_PRIVSEP
> + fd = open(buf, O_RDWR, 0);
> +#else
> + fd = priv_open_device(buf);
> +#endif
> +
> + if (fd < 0)
> + return -errno;
> +
> + if (drmIoctl(fd, DRM_IOCTL_GET_PCIINFO, &pinfo)) {
> + close(fd);
> + return -errno;
> + }
> + close(fd);
> +
> + device->vendor_id = pinfo.vendor_id;
> + device->device_id = pinfo.device_id;
> + device->revision_id = pinfo.revision_id;
> + device->subvendor_id = pinfo.subvendor_id;
> + device->subdevice_id = pinfo.subdevice_id;
> +
> + return 0;
> #else
> #warning "Missing implementation of drmParsePciDeviceInfo"
> return -EINVAL;
> @@ -3117,6 +3192,46 @@ static void drmFoldDuplicatedDevices(drmDevicePtr
> local_devices[], int count)
> */
> int drmGetDevice(int fd, drmDevicePtr *device)
> {
> +#ifdef __OpenBSD__
> + drmDevicePtr d;
> + struct stat sbuf;
> + char node[PATH_MAX + 1];
> + char d_name[PATH_MAX + 1];
> + int maj, min, n;
> + int ret;
> + int max_count = 1;
> +
> + if (fd == -1 || device == NULL)
> + return -EINVAL;
> +
> + if (fstat(fd, &sbuf))
> + return -errno;
> +
> + maj = major(sbuf.st_rdev);
> + min = minor(sbuf.st_rdev);
> +
> + if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
> + return -EINVAL;
> +
> + n = snprintf(d_name, PATH_MAX, "drm%d", min);
> + if (n == -1 || n >= PATH_MAX)
> + return -errno;
> +
> + n = snprintf(node, PATH_MAX, DRM_DEV_NAME, DRM_DIR_NAME, min);
> + if (n == -1 || n >= PATH_MAX)
> + return -errno;
> + if (stat(node, &sbuf))
> + return -EINVAL;
> +
> + ret = drmProcessPciDevice(&d, d_name, node, DRM_NODE_PRIMARY,
> + maj, min, true);
> + if (ret)
> + return ret;
> +
> + *device = d;
> +
> + return 0;
> +#else
> drmDevicePtr *local_devices;
> drmDevicePtr d;
> DIR *sysdir;
> @@ -3224,6 +3339,7 @@ free_devices:
> free_locals:
> free(local_devices);
> return ret;
> +#endif
> }
>
> /**
>
>