diff options
-rw-r--r-- | include/xf86drm.h | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/include/xf86drm.h b/include/xf86drm.h new file mode 100644 index 0000000000..dd6e2b92ea --- /dev/null +++ b/include/xf86drm.h @@ -0,0 +1,130 @@ +/* + * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include_next <xf86drm.h> + +#include <string.h> +#include <errno.h> + +/* + * FIXME: Below code comes from https://patchwork.kernel.org/patch/10368203/ + * FIXME: Remove or rework once that has been merged + */ + +typedef enum drm_match_key { + /* Match against DRM_NODE_{PRIMARY,RENDER,...} type */ + DRM_MATCH_NODE_TYPE = 1, + DRM_MATCH_DRIVER_NAME = 2, + DRM_MATCH_BUS_PCI_VENDOR = 3, + DRM_MATCH_FUNCTION = 4, +} drm_match_key_t; + +typedef struct drm_match_func { + void *data; + int (*fp)(int, void*); /* Intended arguments are fp(fd, data) */ +} drm_match_func_t; + +typedef struct drm_match { + drm_match_key_t type; + union { + int s; + uint16_t u16; + char *str; + drm_match_func_t func; + }; +} drm_match_t; + +static inline int drmHandleMatch(int fd, drm_match_t *filters, int nbr_filters) +{ + if (fd < 0) + goto error; + + if (nbr_filters > 0 && filters == NULL) + goto error; + + drmVersionPtr ver = drmGetVersion(fd); + if (!ver) + goto fail; + + drmDevicePtr dev = NULL; + if (drmGetDevice2(fd, 0, &dev) != 0) { + goto fail; + } + + for (int i = 0; i < nbr_filters; i++) { + drm_match_t *f = &filters[i]; + switch (f->type) { + case DRM_MATCH_NODE_TYPE: + if (!(dev->available_nodes & (1 << f->s))) + goto fail; + break; + case DRM_MATCH_DRIVER_NAME: + if (!f->str) + goto error; + + /* This bypass is used by when the driver name is used + by the Android property_get() func, when it hasn't found + the property and the string is empty as a result. */ + if (strlen(f->str) == 0) + continue; + + if (strncmp(ver->name, f->str, strlen(ver->name))) + goto fail; + break; + case DRM_MATCH_BUS_PCI_VENDOR: + if (dev->bustype != DRM_BUS_PCI) + goto fail; + if (dev->deviceinfo.pci->vendor_id != f->u16) + goto fail; + break; + case DRM_MATCH_FUNCTION: + if (!f->func.fp) + goto error; + int (*fp)(int, void*) = f->func.fp; + void *data = f->func.data; + if (!fp(fd, data)) + goto fail; + break; + default: + goto error; + } + } + +success: + drmFreeVersion(ver); + drmFreeDevice(&dev); + return 0; +error: + drmFreeVersion(ver); + drmFreeDevice(&dev); + return -EINVAL; +fail: + drmFreeVersion(ver); + drmFreeDevice(&dev); + return 1; +} + |