[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