> Date: Wed, 23 Nov 2016 11:50:49 +1100 > From: Jonathan Gray <j...@jsg.id.au> > > On Tue, Nov 22, 2016 at 09:29:03PM +0100, Mark Kettenis wrote: > > > Date: Sat, 19 Nov 2016 19:31:18 +1100 > > > From: Jonathan Gray <j...@jsg.id.au> > > > > > > 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? > > This was carried over from the old Mesa loader code, updated diff to > use PATH_MAX and inline ioctl definition:
ok kettenis@ > diff --git xf86drm.c xf86drm.c > index 3c2c5d4..38f6440 100644 > --- xf86drm.c > +++ xf86drm.c > @@ -103,7 +103,23 @@ > #endif > > #ifdef __OpenBSD__ > + > #define X_PRIVSEP > + > +struct drm_pciinfo { > + uint16_t domain; > + uint8_t bus; > + uint8_t dev; > + uint8_t func; > + uint16_t vendor_id; > + uint16_t device_id; > + uint16_t subvendor_id; > + uint16_t subdevice_id; > + uint8_t revision_id; > +}; > + > +#define DRM_IOCTL_GET_PCIINFO DRM_IOR(0x15, struct drm_pciinfo) > + > #endif > > #define DRM_MSG_VERBOSITY 3 > @@ -2851,7 +2867,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[PATH_MAX + 1]; > + 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 +2921,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 +2965,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 +3060,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[PATH_MAX + 1]; > + 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 +3204,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 +3351,7 @@ free_devices: > free_locals: > free(local_devices); > return ret; > +#endif > } > > /** >