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
parent
fd190564da
commit
0825792723
62
xf86drm.c
62
xf86drm.c
|
@ -3251,6 +3251,67 @@ drm_device_validate_flags(uint32_t flags)
|
||||||
*/
|
*/
|
||||||
int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
|
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 *local_devices;
|
||||||
drmDevicePtr d;
|
drmDevicePtr d;
|
||||||
DIR *sysdir;
|
DIR *sysdir;
|
||||||
|
@ -3360,6 +3421,7 @@ free_devices:
|
||||||
free_locals:
|
free_locals:
|
||||||
free(local_devices);
|
free(local_devices);
|
||||||
return ret;
|
return ret;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue