|
From: GitLab M. <git...@ke...> - 2025-08-05 16:47:10
|
tests/drmdevice.c | 6 ++++
xf86drm.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
xf86drm.h | 6 ++++
3 files changed, 89 insertions(+)
New commits:
commit d870a12c3abfe0d2347996c37784a34b37457b7a
Author: José Expósito <jos...@gm...>
Date: Fri Aug 1 11:05:17 2025 +0200
xf86drm: Add faux bus
Linux 6.14 included a new type of bus, the "faux" bus [1].
The next version of Linux (v6.16) will move the VKMS driver to the faux
bus. See kernel commit 5686601908d8 ("drm/vkms: convert to use
faux_device") for more details.
Add support for the faux bus so drmGetDeviceFromDevId(), drmGetDevices()
and drmGetDevices2() return the devices on it.
[1] https://lore.kernel.org/all/2025021023-sandstorm-precise-9f5d@gregkh/
Reviewed-by: Dmitry Baryshkov <dmi...@os...>
Signed-off-by: José Expósito <jos...@gm...>
diff --git a/tests/drmdevice.c b/tests/drmdevice.c
index b4b62d9c..9ddfc8dd 100644
--- a/tests/drmdevice.c
+++ b/tests/drmdevice.c
@@ -98,6 +98,12 @@ print_device_info(drmDevicePtr device, int i, bool print_revision)
printf(" %s\n", *compatible);
compatible++;
}
+ } else if (device->bustype == DRM_BUS_FAUX) {
+ printf("| +-> faux\n");
+
+ printf("+-> deviceinfo\n");
+ printf(" +-> faux\n");
+ printf(" +-> name %s\n", device->deviceinfo.faux->name);
} else {
printf("Unknown/unhandled bustype\n");
}
diff --git a/xf86drm.c b/xf86drm.c
index 06fdb85f..e587d714 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -42,6 +42,7 @@
#include <stddef.h>
#include <fcntl.h>
#include <errno.h>
+#include <libgen.h>
#include <limits.h>
#include <signal.h>
#include <time.h>
@@ -3592,6 +3593,7 @@ static int get_subsystem_type(const char *device_path)
{ "/spi", DRM_BUS_PLATFORM },
{ "/host1x", DRM_BUS_HOST1X },
{ "/virtio", DRM_BUS_VIRTIO },
+ { "/faux", DRM_BUS_FAUX },
};
strncpy(path, device_path, PATH_MAX);
@@ -3795,6 +3797,9 @@ drm_public int drmDevicesEqual(drmDevicePtr a, drmDevicePtr b)
case DRM_BUS_HOST1X:
return memcmp(a->businfo.host1x, b->businfo.host1x, sizeof(drmHost1xBusInfo)) == 0;
+ case DRM_BUS_FAUX:
+ return memcmp(a->deviceinfo.faux, b->deviceinfo.faux, sizeof(drmFauxDeviceInfo)) == 0;
+
default:
break;
}
@@ -4015,6 +4020,12 @@ static void drmFreeHost1xDevice(drmDevicePtr device)
}
}
+static void drmFreeFauxDevice(drmDevicePtr device)
+{
+ if (device->deviceinfo.faux)
+ free(device->deviceinfo.faux->name);
+}
+
drm_public void drmFreeDevice(drmDevicePtr *device)
{
if (device == NULL)
@@ -4029,6 +4040,10 @@ drm_public void drmFreeDevice(drmDevicePtr *device)
case DRM_BUS_HOST1X:
drmFreeHost1xDevice(*device);
break;
+
+ case DRM_BUS_FAUX:
+ drmFreeFauxDevice(*device);
+ break;
}
}
@@ -4457,6 +4472,65 @@ free_device:
return ret;
}
+static int drmParseFauxDeviceInfo(int maj, int min, drmFauxDeviceInfoPtr info)
+{
+#ifdef __linux__
+ char path[PATH_MAX + 1] = "";
+ char real_path[PATH_MAX + 1] = "";
+ char *name;
+
+ snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
+
+ if (!realpath(path, real_path))
+ return -errno;
+
+ name = basename(real_path);
+ if (!name)
+ return -ENOENT;
+
+ info->name = strdup(name);
+ if (!info->name)
+ return -errno;
+
+ return 0;
+#else
+#warning "Missing implementation of drmParseFauxDeviceInfo"
+ return -EINVAL;
+#endif
+}
+
+static int drmProcessFauxDevice(drmDevicePtr *device,
+ const char *node, int node_type,
+ int maj, int min, bool fetch_deviceinfo,
+ uint32_t flags)
+{
+ drmDevicePtr dev;
+ char *ptr;
+ int ret;
+
+ dev = drmDeviceAlloc(node_type, node, 0, sizeof(drmFauxDeviceInfo), &ptr);
+ if (!dev)
+ return -ENOMEM;
+
+ dev->bustype = DRM_BUS_FAUX;
+
+ if (fetch_deviceinfo) {
+ dev->deviceinfo.faux = (drmFauxDeviceInfoPtr)ptr;
+
+ ret = drmParseFauxDeviceInfo(maj, min, dev->deviceinfo.faux);
+ if (ret < 0)
+ goto free_device;
+ }
+
+ *device = dev;
+
+ return 0;
+
+free_device:
+ free(dev);
+ return ret;
+}
+
static int
process_device(drmDevicePtr *device, const char *d_name,
int req_subsystem_type,
@@ -4509,6 +4583,9 @@ process_device(drmDevicePtr *device, const char *d_name,
case DRM_BUS_HOST1X:
return drmProcessHost1xDevice(device, node, node_type, maj, min,
fetch_deviceinfo, flags);
+ case DRM_BUS_FAUX:
+ return drmProcessFauxDevice(device, node, node_type, maj, min,
+ fetch_deviceinfo, flags);
default:
return -1;
}
diff --git a/xf86drm.h b/xf86drm.h
index 6d91dfbd..6bfe2782 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -843,6 +843,7 @@ extern char *drmGetRenderDeviceNameFromFd(int fd);
#define DRM_BUS_USB 1
#define DRM_BUS_PLATFORM 2
#define DRM_BUS_HOST1X 3
+#define DRM_BUS_FAUX 4
typedef struct _drmPciBusInfo {
uint16_t domain;
@@ -889,6 +890,10 @@ typedef struct _drmHost1xDeviceInfo {
char **compatible; /* NULL terminated list of compatible strings */
} drmHost1xDeviceInfo, *drmHost1xDeviceInfoPtr;
+typedef struct _drmFauxDeviceInfo {
+ char *name;
+} drmFauxDeviceInfo, *drmFauxDeviceInfoPtr;
+
typedef struct _drmDevice {
char **nodes; /* DRM_NODE_MAX sized array */
int available_nodes; /* DRM_NODE_* bitmask */
@@ -904,6 +909,7 @@ typedef struct _drmDevice {
drmUsbDeviceInfoPtr usb;
drmPlatformDeviceInfoPtr platform;
drmHost1xDeviceInfoPtr host1x;
+ drmFauxDeviceInfoPtr faux;
} deviceinfo;
} drmDevice, *drmDevicePtr;
|