aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Gray2016-11-30 22:18:43 -0600
committerEmil Velikov2016-12-05 11:53:11 -0600
commit08257927231e4f51c38e1d2bdbb8db0c2d4aec40 (patch)
tree536b6251b077815068de2a861758c3e4878de2a9 /xf86drm.c
parentfd190564daa4cd530833a94606646730a5c0ee6c (diff)
downloadexternal-libdrm-08257927231e4f51c38e1d2bdbb8db0c2d4aec40.tar.gz
external-libdrm-08257927231e4f51c38e1d2bdbb8db0c2d4aec40.tar.xz
external-libdrm-08257927231e4f51c38e1d2bdbb8db0c2d4aec40.zip
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>
Diffstat (limited to 'xf86drm.c')
-rw-r--r--xf86drm.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/xf86drm.c b/xf86drm.c
index 56353812..2e8c9569 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -3251,6 +3251,67 @@ drm_device_validate_flags(uint32_t flags)
3251 */ 3251 */
3252int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device) 3252int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
3253{ 3253{
3254#ifdef __OpenBSD__
3255 /*
3256 * DRI device nodes on OpenBSD are not in their own directory, they reside
3257 * in /dev along with a large number of statically generated /dev nodes.
3258 * Avoid stat'ing all of /dev needlessly by implementing this custom path.
3259 */
3260 drmDevicePtr d;
3261 struct stat sbuf;
3262 char node[PATH_MAX + 1];
3263 const char *dev_name;
3264 int node_type, subsystem_type;
3265 int maj, min, n, ret;
3266
3267 if (fd == -1 || device == NULL)
3268 return -EINVAL;
3269
3270 if (fstat(fd, &sbuf))
3271 return -errno;
3272
3273 maj = major(sbuf.st_rdev);
3274 min = minor(sbuf.st_rdev);
3275
3276 if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
3277 return -EINVAL;
3278
3279 node_type = drmGetMinorType(min);
3280 if (node_type == -1)
3281 return -ENODEV;
3282
3283 switch (node_type) {
3284 case DRM_NODE_PRIMARY:
3285 dev_name = DRM_DEV_NAME;
3286 break;
3287 case DRM_NODE_CONTROL:
3288 dev_name = DRM_CONTROL_DEV_NAME;
3289 break;
3290 case DRM_NODE_RENDER:
3291 dev_name = DRM_RENDER_DEV_NAME;
3292 break;
3293 default:
3294 return -EINVAL;
3295 };
3296
3297 n = snprintf(node, PATH_MAX, dev_name, DRM_DIR_NAME, min);
3298 if (n == -1 || n >= PATH_MAX)
3299 return -errno;
3300 if (stat(node, &sbuf))
3301 return -EINVAL;
3302
3303 subsystem_type = drmParseSubsystemType(maj, min);
3304 if (subsystem_type != DRM_BUS_PCI)
3305 return -ENODEV;
3306
3307 ret = drmProcessPciDevice(&d, node, node_type, maj, min, true, flags);
3308 if (ret)
3309 return ret;
3310
3311 *device = d;
3312
3313 return 0;
3314#else
3254 drmDevicePtr *local_devices; 3315 drmDevicePtr *local_devices;
3255 drmDevicePtr d; 3316 drmDevicePtr d;
3256 DIR *sysdir; 3317 DIR *sysdir;
@@ -3360,6 +3421,7 @@ free_devices:
3360free_locals: 3421free_locals:
3361 free(local_devices); 3422 free(local_devices);
3362 return ret; 3423 return ret;
3424#endif
3363} 3425}
3364 3426
3365/** 3427/**