[Mesa-dev] [PATCH v3 8/8] loader: Switch loader to match modalias strings instead of PCI IDs
Kristian Høgsberg
krh at bitplanet.net
Wed Feb 5 02:18:18 CET 2014
This lets us match any device on any bus, including platform devices.
Signed-off-by: Kristian Høgsberg <krh at bitplanet.net>
---
include/pci_ids/pci_id_driver_map.h | 81 -------------------------------------
src/loader/Makefile.am | 10 +++--
src/loader/Makefile.sources | 3 +-
src/loader/dump-hwdb.sh | 50 ++++++++++++++++-------
src/loader/loader.c | 56 +++++++++++--------------
5 files changed, 68 insertions(+), 132 deletions(-)
delete mode 100644 include/pci_ids/pci_id_driver_map.h
diff --git a/include/pci_ids/pci_id_driver_map.h b/include/pci_ids/pci_id_driver_map.h
deleted file mode 100644
index db9e07f..0000000
--- a/include/pci_ids/pci_id_driver_map.h
+++ /dev/null
@@ -1,81 +0,0 @@
-#ifndef _PCI_ID_DRIVER_MAP_H_
-#define _PCI_ID_DRIVER_MAP_H_
-
-#include <stddef.h>
-
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-#endif
-
-#ifndef __IS_LOADER
-# error "Only include from loader.c"
-#endif
-
-static const int i915_chip_ids[] = {
-#define CHIPSET(chip, desc, name) chip,
-#include "pci_ids/i915_pci_ids.h"
-#undef CHIPSET
-};
-
-static const int i965_chip_ids[] = {
-#define CHIPSET(chip, family, name) chip,
-#include "pci_ids/i965_pci_ids.h"
-#undef CHIPSET
-};
-
-static const int r100_chip_ids[] = {
-#define CHIPSET(chip, name, family) chip,
-#include "pci_ids/radeon_pci_ids.h"
-#undef CHIPSET
-};
-
-static const int r200_chip_ids[] = {
-#define CHIPSET(chip, name, family) chip,
-#include "pci_ids/r200_pci_ids.h"
-#undef CHIPSET
-};
-
-static const int r300_chip_ids[] = {
-#define CHIPSET(chip, name, family) chip,
-#include "pci_ids/r300_pci_ids.h"
-#undef CHIPSET
-};
-
-static const int r600_chip_ids[] = {
-#define CHIPSET(chip, name, family) chip,
-#include "pci_ids/r600_pci_ids.h"
-#undef CHIPSET
-};
-
-static const int radeonsi_chip_ids[] = {
-#define CHIPSET(chip, name, family) chip,
-#include "pci_ids/radeonsi_pci_ids.h"
-#undef CHIPSET
-};
-
-static const int vmwgfx_chip_ids[] = {
-#define CHIPSET(chip, name, family) chip,
-#include "pci_ids/vmwgfx_pci_ids.h"
-#undef CHIPSET
-};
-
-static const struct {
- int vendor_id;
- const char *driver;
- const int *chip_ids;
- int num_chips_ids;
- unsigned driver_types;
-} driver_map[] = {
- { 0x8086, "i915", i915_chip_ids, ARRAY_SIZE(i915_chip_ids), _LOADER_DRI | _LOADER_GALLIUM },
- { 0x8086, "i965", i965_chip_ids, ARRAY_SIZE(i965_chip_ids), _LOADER_DRI | _LOADER_GALLIUM },
- { 0x1002, "radeon", r100_chip_ids, ARRAY_SIZE(r100_chip_ids), _LOADER_DRI },
- { 0x1002, "r200", r200_chip_ids, ARRAY_SIZE(r200_chip_ids), _LOADER_DRI },
- { 0x1002, "r300", r300_chip_ids, ARRAY_SIZE(r300_chip_ids), _LOADER_GALLIUM },
- { 0x1002, "r600", r600_chip_ids, ARRAY_SIZE(r600_chip_ids), _LOADER_GALLIUM },
- { 0x1002, "radeonsi", radeonsi_chip_ids, ARRAY_SIZE(radeonsi_chip_ids), _LOADER_GALLIUM},
- { 0x10de, "nouveau", NULL, -1, _LOADER_GALLIUM },
- { 0x15ad, "vmwgfx", vmwgfx_chip_ids, ARRAY_SIZE(vmwgfx_chip_ids), _LOADER_GALLIUM },
- { 0x0000, NULL, NULL, 0 },
-};
-
-#endif /* _PCI_ID_DRIVER_MAP_H_ */
diff --git a/src/loader/Makefile.am b/src/loader/Makefile.am
index 1e0a140..f09185f 100644
--- a/src/loader/Makefile.am
+++ b/src/loader/Makefile.am
@@ -42,6 +42,10 @@ endif
libloader_la_SOURCES = $(LOADER_C_FILES)
+loader.c : modalias-map.h
+
+modalias-map.h :
+ $(srcdir)/dump-hwdb.sh modalias-map > $@-tmp && mv $@-tmp $@
dist_udevhwdb_DATA = 20-dri-driver.hwdb
@@ -53,8 +57,8 @@ install-data-hook :
export DEFINES
20-dri-driver.hwdb :
- $(srcdir)/dump-hwdb.sh > $@-tmp && mv $@-tmp $@
+ $(srcdir)/dump-hwdb.sh hwdb > $@-tmp && mv $@-tmp $@
-20-dri-driver.hwdb : dump-hwdb.sh ../../include/pci_ids/*.h
+modalias-map.h 20-dri-driver.hwdb : dump-hwdb.sh ../../include/pci_ids/*.h
-CLEANFILES = 20-dri-driver.hwdb
+CLEANFILES = 20-dri-driver.hwdb modalias-map.h
diff --git a/src/loader/Makefile.sources b/src/loader/Makefile.sources
index 51a64ea..1201ef1 100644
--- a/src/loader/Makefile.sources
+++ b/src/loader/Makefile.sources
@@ -1,2 +1,3 @@
LOADER_C_FILES := \
- loader.c
\ No newline at end of file
+ loader.c \
+ driver-map.h
\ No newline at end of file
diff --git a/src/loader/dump-hwdb.sh b/src/loader/dump-hwdb.sh
index b4224a9..7d1d97c 100755
--- a/src/loader/dump-hwdb.sh
+++ b/src/loader/dump-hwdb.sh
@@ -2,21 +2,20 @@
set -e
-PROP_NAME=DRI_DRIVER
+function modalias_list() {
+ while read vendor driver; do
+ pci_id_file=../../include/pci_ids/${driver}_pci_ids.h
+ if ! test -r $pci_id_file; then
+ printf "$driver pci:v%08x*bc03*\n" $vendor
+ continue
+ fi
-while read vendor driver; do
- pci_id_file=../../include/pci_ids/${driver}_pci_ids.h
- if ! test -r $pci_id_file; then
- printf "pci:v%08x*bc03*\n $PROP_NAME=$driver\n\n" $vendor
- continue
- fi
-
- gcc -E $DEFINES $pci_id_file |
- while IFS=' (,' read c id rest; do
- test -z "$id" && continue
- printf "pci:v%08xd%08x*\n $PROP_NAME=$driver\n\n" $vendor $id
- done
-done <<EOF
+ gcc -E $DEFINES $pci_id_file |
+ while IFS=' (,' read c id rest; do
+ test -z "$id" && continue
+ printf "$driver pci:v%08xd%08x*\n" $vendor $id
+ done
+ done <<EOF
0x8086 i915
0x8086 i965
0x1002 radeon
@@ -27,3 +26,26 @@ done <<EOF
0x10de nouveau
0x15ad vmwgfx
EOF
+}
+
+case $1 in
+ hwdb)
+ modalias_list | while read driver modalias; do
+ printf "$modalias\n PCI_DRIVER=$driver\n\n"
+ done
+ ;;
+
+ modalias-map)
+ printf "#define NUL \"\\\\0\"\n"
+ printf "static const char modalias_map[] =\n"
+ modalias_list | while read driver modalias; do
+ printf "\t\"$modalias\" NUL \"$driver\" NUL\n"
+ done
+ printf "\tNUL;\n"
+ printf "#undef NUL\n"
+ ;;
+
+ *)
+ echo "usage: $0 hwdb | driver-map"
+ ;;
+esac
diff --git a/src/loader/loader.c b/src/loader/loader.c
index 9bd3561..d8f6f06 100644
--- a/src/loader/loader.c
+++ b/src/loader/loader.c
@@ -67,6 +67,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
+#include <fnmatch.h>
#ifdef HAVE_LIBUDEV
#include <assert.h>
#include <dlfcn.h>
@@ -77,8 +78,7 @@
#include <xf86drm.h>
#endif
-#define __IS_LOADER
-#include "pci_ids/pci_id_driver_map.h"
+#include "modalias-map.h"
static void default_logger(int level, const char *fmt, ...)
{
@@ -93,35 +93,24 @@ static void default_logger(int level, const char *fmt, ...)
static void (*log_)(int level, const char *fmt, ...) = default_logger;
static char *
-lookup_driver_for_pci_id(int vendor_id, int chip_id, unsigned int driver_types)
+lookup_driver_for_modalias(const char *modalias)
{
- int i, j;
-
- for (i = 0; driver_map[i].driver; i++) {
- if (vendor_id != driver_map[i].vendor_id)
- continue;
-
- if (!(driver_types & driver_map[i].driver_types))
- continue;
-
- if (driver_map[i].num_chips_ids == -1)
- goto out;
+ const char *m, *d;
+ char *driver = NULL;
- for (j = 0; j < driver_map[i].num_chips_ids; j++)
- if (driver_map[i].chip_ids[j] == chip_id)
- goto out;
+ for (m = modalias_map; *m; m = d + strlen(d) + 1) {
+ d = m + strlen(m) + 1;
+ if (fnmatch(m, modalias, FNM_NOESCAPE) == 0) {
+ driver = strdup(d);
+ break;
+ }
}
- out:
- if (driver_map[i].driver) {
+ if (driver)
log_(_LOADER_DEBUG,
- "pci id: %04x:%04x, driver %s from internal db",
- vendor_id, chip_id, driver_map[i].driver);
+ "using driver %s for %s from internal db", driver, modalias);
- return strdup(driver_map[i].driver);
- }
-
- return NULL;
+ return driver;
}
static char *
@@ -217,7 +206,6 @@ loader_get_driver_for_fd(int fd, unsigned int driver_types)
{
struct udev *udev = NULL;
struct udev_device *device = NULL, *parent;
- const char *pci_id;
UDEV_SYMBOL(struct udev *, udev_new, (void));
UDEV_SYMBOL(struct udev_device *, udev_device_get_parent,
(struct udev_device *));
@@ -226,8 +214,7 @@ loader_get_driver_for_fd(int fd, unsigned int driver_types)
UDEV_SYMBOL(struct udev_device *, udev_device_unref,
(struct udev_device *));
UDEV_SYMBOL(struct udev *, udev_unref, (struct udev *));
- const char *hwdb_driver;
- int vendor_id, chip_id;
+ const char *hwdb_driver, *modalias;
char *driver = NULL;
udev = udev_new();
@@ -243,14 +230,14 @@ loader_get_driver_for_fd(int fd, unsigned int driver_types)
hwdb_driver = udev_device_get_property_value(parent, "DRI_DRIVER");
if (hwdb_driver != NULL) {
- log_(_LOADER_INFO, "using driver %s from udev hwdb", driver);
+ log_(_LOADER_INFO, "using driver %s from udev hwdb", hwdb_driver);
driver = strdup(hwdb_driver);
goto out;
}
- pci_id = udev_device_get_property_value(parent, "PCI_ID");
- if (pci_id && sscanf(pci_id, "%x:%x", &vendor_id, &chip_id) == 2) {
- driver = lookup_driver_for_pci_id(vendor_id, chip_id, driver_types);
+ modalias = udev_device_get_sysattr_value(parent, "modalias");
+ if (modalias != NULL) {
+ driver = lookup_driver_for_modalias(modalias);
goto out;
}
@@ -341,6 +328,7 @@ char *
loader_get_driver_for_fd(int fd, unsigned int driver_types)
{
int vendor_id, chip_id;
+ char modalias[32];
if (!driver_types)
driver_types = _LOADER_GALLIUM | _LOADER_DRI;
@@ -348,7 +336,9 @@ loader_get_driver_for_fd(int fd, unsigned int driver_types)
if (!loader_get_pci_id_for_fd(fd, &vendor_id, &chip_id))
return fallback_to_kernel_name(fd);
- return lookup_driver_for_pci_id(vendor_id, chip_id, driver_types);
+ snprintf(modalias, sizeof modalias, "pci:v%08xd%08x*", vendor_id, chip_id);
+
+ return lookup_driver_for_modalias(modalias);
}
#else
--
1.8.4.2
More information about the mesa-dev
mailing list