[Mesa-dev] [PATCH] loader: Get driver name from udev hwdb when available
Kristian Høgsberg
krh at bitplanet.net
Mon Jan 20 12:42:54 PST 2014
The udev hwdb is a mechanism for applying udev properties to devices at
hotplug time. The hwdb text files are compiled into a binary database
that lets udev efficiently look up and apply properties to devices that
match a given modalias.
This patch exports the mesa PCI ID tables as hwdb files and extends the
loader code to try to look up the driver name from the DRI_DRIVER udev
property. The benefits to this approach are:
- No longer PCI specific, any device udev can match with a modalias can
be assigned a DRI driver.
- Available outside mesa; writing a DRI2 compatible generic DDX with
glamor needs to know the DRI driver name to send to the client.
- Can be overridden by custom udev rules.
Signed-off-by: Kristian Høgsberg <krh at bitplanet.net>
---
configure.ac | 14 ++++++++++++++
src/loader/Makefile.am | 15 +++++++++++++++
src/loader/dump-hwdb.c | 31 +++++++++++++++++++++++++++++++
src/loader/loader.c | 33 +++++++++++++++++++++++++--------
src/loader/loader.h | 2 +-
5 files changed, 86 insertions(+), 9 deletions(-)
create mode 100644 src/loader/dump-hwdb.c
diff --git a/configure.ac b/configure.ac
index d9e1896..8670908 100644
--- a/configure.ac
+++ b/configure.ac
@@ -771,6 +771,20 @@ if test "x$have_libdrm" = xyes; then
DEFINES="$DEFINES -DHAVE_LIBDRM"
fi
+# This /lib prefix does not change with 32/64 bits it's always /lib
+case "$prefix" in
+/usr) default_udevhwdbdir=/lib/udev/hwdb.d ;;
+NONE) default_udevhwdbdir=${ac_default_prefix}/lib/udev/hwdb.d ;;
+*) default_udevhwdbdir=$prefix/lib/udev/hwdb.d ;;
+esac
+
+AC_ARG_WITH([udev-hwdb-dir],
+ [AS_HELP_STRING([--with-udev-hwdb-dir=DIR],
+ [directory for the udev hwdb @<:@/lib/udev/hwdb.d@:>@])],
+ [udevhwdbdir="$withval"],
+ [udevhwdbdir=$default_udevhwdbdir])
+AC_SUBST([udevhwdbdir])
+
PKG_CHECK_MODULES([LIBUDEV], [libudev >= $LIBUDEV_REQUIRED],
have_libudev=yes, have_libudev=no)
diff --git a/src/loader/Makefile.am b/src/loader/Makefile.am
index 371dd57..bf3918b 100644
--- a/src/loader/Makefile.am
+++ b/src/loader/Makefile.am
@@ -44,3 +44,18 @@ libloader_la_LIBADD += \
endif
libloader_la_SOURCES = $(LOADER_C_FILES)
+
+
+noinst_PROGRAMS = dump-hwdb
+dump_hwdb_SOURCES = dump-hwdb.c
+dump_hwdb_CPPFLAGS = -I$(top_srcdir)/include
+
+dist_udevhwdb_DATA = 20-dri-driver.hwdb
+
+# Update hwdb on installation. Do not bother if installing
+# in DESTDIR, since this is likely for packaging purposes.
+install-data-hook:
+ -test -n "$(DESTDIR)" || udevadm hwdb --update
+
+20-dri-driver.hwdb : dump-hwdb
+ $(builddir)/dump-hwdb > $@
diff --git a/src/loader/dump-hwdb.c b/src/loader/dump-hwdb.c
new file mode 100644
index 0000000..d48452d
--- /dev/null
+++ b/src/loader/dump-hwdb.c
@@ -0,0 +1,31 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#define DRIVER_MAP_DRI2_ONLY
+#define __IS_LOADER
+
+#include "loader.h"
+#include "pci_ids/pci_id_driver_map.h"
+
+#define PROP_NAME "DRI_DRIVER"
+
+int main(int argc, char *argv[])
+{
+ int i, j;
+
+ for (i = 0; driver_map[i].driver; i++) {
+ if (driver_map[i].num_chips_ids == -1) {
+ /* Add a match for display base class (bc03) for drivers that don't
+ * export per-device IDs (nouveau) */
+ printf("pci:v%08x*bc03*\n " PROP_NAME "=%s\n\n",
+ driver_map[i].vendor_id, driver_map[i].driver);
+ continue;
+ }
+
+ for (j = 0; j < driver_map[i].num_chips_ids; j++)
+ printf("pci:v%08xd%08x*\n " PROP_NAME "=%s\n\n",
+ driver_map[i].vendor_id,
+ driver_map[i].chip_ids[j],
+ driver_map[i].driver);
+ }
+}
diff --git a/src/loader/loader.c b/src/loader/loader.c
index a5bd769..03d8148 100644
--- a/src/loader/loader.c
+++ b/src/loader/loader.c
@@ -114,13 +114,15 @@ udev_device_new_from_fd(struct udev *udev, int fd)
}
int
-loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
+loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id, char **driver)
{
struct udev *udev = NULL;
struct udev_device *device = NULL, *parent;
const char *pci_id;
+ const char *hwdb_driver;
*chip_id = -1;
+ *driver = NULL;
udev = udev_new();
device = udev_device_new_from_fd(udev, fd);
@@ -133,6 +135,12 @@ loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
goto out;
}
+ hwdb_driver = udev_device_get_property_value(parent, "DRI_DRIVER");
+ if (hwdb_driver != NULL) {
+ *driver = strdup(hwdb_driver);
+ goto out;
+ }
+
pci_id = udev_device_get_property_value(parent, "PCI_ID");
if (pci_id == NULL ||
sscanf(pci_id, "%x:%x", vendor_id, chip_id) != 2) {
@@ -147,7 +155,7 @@ out:
if (udev)
udev_unref(udev);
- return (*chip_id >= 0);
+ return (*driver != NULL) || (*chip_id >= 0);
}
#elif defined(ANDROID) && !defined(__NOT_HAVE_DRM_H)
@@ -158,11 +166,12 @@ out:
#include <radeon_drm.h>
int
-loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
+loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id, char **driver)
{
drmVersionPtr version;
*chip_id = -1;
+ *driver = NULL;
version = drmGetVersion(fd);
if (!version) {
@@ -224,7 +233,7 @@ loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
#else
int
-loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
+loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id, char **driver)
{
return 0;
}
@@ -267,7 +276,7 @@ loader_get_driver_for_fd(int fd, unsigned driver_types)
if (!driver_types)
driver_types = _LOADER_GALLIUM | _LOADER_DRI;
- if (!loader_get_pci_id_for_fd(fd, &vendor_id, &chip_id)) {
+ if (!loader_get_pci_id_for_fd(fd, &vendor_id, &chip_id, &driver)) {
#ifndef __NOT_HAVE_DRM_H
/* fallback to drmGetVersion(): */
@@ -287,6 +296,9 @@ loader_get_driver_for_fd(int fd, unsigned driver_types)
return driver;
}
+ if (driver)
+ goto out;
+
for (i = 0; driver_map[i].driver; i++) {
if (vendor_id != driver_map[i].vendor_id)
continue;
@@ -307,9 +319,14 @@ loader_get_driver_for_fd(int fd, unsigned driver_types)
}
out:
- log_(driver ? _LOADER_INFO : _LOADER_WARNING,
- "pci id for fd %d: %04x:%04x, driver %s",
- fd, vendor_id, chip_id, driver);
+ if (driver && chip_id == -1) {
+ log_(_LOADER_INFO, "using driver %s from udev hwdb", driver);
+ } else {
+ log_(driver ? _LOADER_INFO : _LOADER_WARNING,
+ "pci id for fd %d: %04x:%04x, driver %s",
+ fd, vendor_id, chip_id, driver);
+ }
+
return driver;
}
diff --git a/src/loader/loader.h b/src/loader/loader.h
index dfd77ba..5771280 100644
--- a/src/loader/loader.h
+++ b/src/loader/loader.h
@@ -33,7 +33,7 @@
#define _LOADER_GALLIUM (1 << 1)
int
-loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id);
+loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id, char **driver);
char *
loader_get_driver_for_fd(int fd, unsigned driver_types);
--
1.8.4.2
More information about the mesa-dev
mailing list