summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlistair Strachan <astrachan@google.com>2018-05-10 12:23:31 -0700
committerAlistair Strachan <astrachan@google.com>2018-05-16 10:55:08 -0700
commit4186e8bbdec00546f0af20ee2da557e7fcfe127a (patch)
treef59cd59f0f19660e04979e982e129720d9edcf85
parent7868877020bf21ba99a7428b88f6318631462753 (diff)
Add xf86drm.h wrapper with pending features.
Fork of a libdrm change so we can move forward with a mesa3d merge without needing to update libdrm again. From: Robert Foss <robert.foss@collabora.com> drmHandleMatch is intended to allow for userspace to filter out devices that it does not want to open. Opening specific devices using paths alone is not a reliable due to probing order. This function intends to provide a mechanism for filtering out devices that don't fit what you need using an extensible set of filters. drm_match_key_t is intended to be extended with whatever filter that would come in handy down the line. As a catch-all filter, the DRM_MATCH_FUNCTION was included which allows the caller to filter based on an arbitrary function. An function pointer filter could of course filter based on anything. But for the sake of convenience a few other simple filters have been included. If the function pointer filter ends up being called with a boilerplate fp by mutliple libdrm users, perhaps that funtion could be moved into libdrm at a future date. Signed-off-by: Robert Foss <robert.foss@collabora.com> [astrachan: cherry picked pending upstream change to resolve merge issue] Bug: 79165890 List: https://patchwork.kernel.org/patch/10368203/ Change-Id: I2d3e6e0e85e5ac0d3039051078d7df9abb36e126 Signed-off-by: Alistair Strachan <astrachan@google.com>
-rw-r--r--include/xf86drm.h130
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;
+}
+