xf86drm: implement an OpenBSD specific drmGetDevice2

DRI devices on OpenBSD are not in their own directory.  They reside in
/dev with a large number of statically generated /dev nodes.

Avoid stat'ing all of /dev on OpenBSD by implementing this custom path.

v2:
   - use drmGetMinorType to get node type
   - adapt to drmProcessPciDevice changes
   - verify drmParseSubsystemType type is PCI
   - add a comment describing why this was added

Signed-off-by: Jonathan Gray <jsg@jsg.id.au>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
main
Jonathan Gray 2016-12-01 15:18:43 +11:00 committed by Emil Velikov
parent fd190564da
commit 0825792723
1 changed files with 62 additions and 0 deletions

View File

@ -3251,6 +3251,67 @@ drm_device_validate_flags(uint32_t flags)
*/
int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
{
#ifdef __OpenBSD__
/*
* DRI device nodes on OpenBSD are not in their own directory, they reside
* in /dev along with a large number of statically generated /dev nodes.
* Avoid stat'ing all of /dev needlessly by implementing this custom path.
*/
drmDevicePtr d;
struct stat sbuf;
char node[PATH_MAX + 1];
const char *dev_name;
int node_type, subsystem_type;
int maj, min, n, ret;
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;
node_type = drmGetMinorType(min);
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:
return -EINVAL;
};
n = snprintf(node, PATH_MAX, dev_name, DRM_DIR_NAME, min);
if (n == -1 || n >= PATH_MAX)
return -errno;
if (stat(node, &sbuf))
return -EINVAL;
subsystem_type = drmParseSubsystemType(maj, min);
if (subsystem_type != DRM_BUS_PCI)
return -ENODEV;
ret = drmProcessPciDevice(&d, node, node_type, maj, min, true, flags);
if (ret)
return ret;
*device = d;
return 0;
#else
drmDevicePtr *local_devices;
drmDevicePtr d;
DIR *sysdir;
@ -3360,6 +3421,7 @@ free_devices:
free_locals:
free(local_devices);
return ret;
#endif
}
/**