This lets us match any device on any bus, including platform devices. Signed-off-by: Kristian Høgsberg <k...@bitplanet.net>
v2: (Emil) - correctly handle chip_id = 0 devices under android - fnmatch.h is only available under linux - cleanup a few typos s/driver-map/modalias-map/ XXX: - scons build is broken Signed-off-by: Emil Velikov <emil.l.veli...@gmail.com> --- include/pci_ids/pci_id_driver_map.h | 81 ---------------------------- src/loader/.gitignore | 1 + src/loader/Makefile.am | 6 ++- src/loader/Makefile.sources | 3 +- src/loader/dump-hwdb.sh | 50 +++++++++++++----- src/loader/loader.c | 102 +++++++++++++++++++++++++----------- 6 files changed, 114 insertions(+), 129 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/.gitignore b/src/loader/.gitignore index b2ba87a..3289ee9 100644 --- a/src/loader/.gitignore +++ b/src/loader/.gitignore @@ -1 +1,2 @@ 20-dri-driver.hwdb* +modalias-map.h* diff --git a/src/loader/Makefile.am b/src/loader/Makefile.am index 96132d0..f850caa 100644 --- a/src/loader/Makefile.am +++ b/src/loader/Makefile.am @@ -42,6 +42,9 @@ endif libloader_la_SOURCES = $(LOADER_C_FILES) +modalias-map.h : + $(srcdir)/dump-hwdb.sh $(top_srcdir)/include/pci_ids modalias-map > $@-tmp && mv $@-tmp $@ + dist_udevhwdb_DATA = 20-dri-driver.hwdb # Update hwdb on installation. Do not bother if installing @@ -53,4 +56,5 @@ install-data-hook : $(srcdir)/dump-hwdb.sh $(top_srcdir)/include/pci_ids > $@-tmp && mv $@-tmp $@ CLEANFILES = \ - 20-dri-driver.hwdb* + 20-dri-driver.hwdb* \ + modalias-map.h* diff --git a/src/loader/Makefile.sources b/src/loader/Makefile.sources index 51a64ea..78ed204 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 \ + modalias-map.h \ No newline at end of file diff --git a/src/loader/dump-hwdb.sh b/src/loader/dump-hwdb.sh index 59ecc06..f933764 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=$1/${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=$1/${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 $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 $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 $2 in + hwdb) + modalias_list $1 | 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 $1 | while read driver modalias; do + printf "\t\"$modalias\" NUL \"$driver\" NUL\n" + done + printf "\tNUL;\n" + printf "#undef NUL\n" + ;; + + *) + echo "usage: $0 headers-location hwdb | modalias-map" + ;; +esac diff --git a/src/loader/loader.c b/src/loader/loader.c index db14a74..cbb501d 100644 --- a/src/loader/loader.c +++ b/src/loader/loader.c @@ -67,6 +67,9 @@ #include <stdarg.h> #include <stdio.h> #include <string.h> +#if defined(__linux__) +#include <fnmatch.h> +#endif #ifdef HAVE_LIBUDEV #include <assert.h> #include <dlfcn.h> @@ -77,8 +80,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 +95,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 * @@ -299,22 +290,63 @@ out: return (*chip_id >= 0); } +int +loader_get_modalias_for_fd(int fd) +{ + struct udev *udev; + struct udev_device *device, *parent; + const char *modalias; + UDEV_SYMBOL(struct udev *, udev_new, (void)); + UDEV_SYMBOL(struct udev_device *, udev_device_get_parent, + (struct udev_device *)); + UDEV_SYMBOL(const char *, udev_device_get_property_value, + (struct udev_device *, const char *)); + UDEV_SYMBOL(struct udev_device *, udev_device_unref, + (struct udev_device *)); + UDEV_SYMBOL(struct udev *, udev_unref, (struct udev *)); + + udev = udev_new(); + device = udev_device_new_from_fd(udev, fd); + if (device == NULL) + goto out_unref; + + parent = udev_device_get_parent(device); + if (parent == NULL) { + log_(_LOADER_WARNING, "MESA-LOADER: could not get parent device\n"); + goto out_device_unref; + } + + modalias = udev_device_get_sysattr_value(parent, "modalias"); + if (modalias == NULL) + log_(_LOADER_WARNING, "MESA-LOADER: cannot retrieve device modalias\n"); + } + +out_device_unref: + udev_device_unref(device); + +out_unref: + udev_unref(udev); + + return modalias; +} + char * loader_get_driver_for_fd(int fd, unsigned int driver_types) { int vendor_id, chip_id = -1; - char *driver = NULL; + char *driver, *modalias; if (!driver_types) driver_types = _LOADER_GALLIUM | _LOADER_DRI; driver = loader_get_hwdb_driver_for_fd(fd); - if (driver == NULL) { - if (!loader_get_pci_id_for_fd(fd, &vendor_id, &chip_id)) - return fallback_to_kernel_name(fd); - - driver = lookup_driver_for_pci_id(vendor_id, chip_id, driver_types); + if (driver == NULL) + modalias = loader_get_modalias_for_fd(fd); + if (modalias != NULL) + driver = lookup_driver_for_modalias(modalias); } + if (driver == NULL) + driver = fallback_to_kernel_name(fd); if (driver == NULL) log_(_LOADER_WARNING, "no driver %s for %d\n", fd); @@ -403,6 +435,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; @@ -410,7 +443,12 @@ 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); + if (chip_id != 0) + snprintf(modalias, sizeof(modalias), "pci:v%08Xd%08X", vendor_id, chip_id); + else + snprintf(modalias, sizeof(modalias), "pci:v%08X", vendor_id); + + return lookup_driver_for_modalias(modalias); } #else -- 1.8.5.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev