summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'media-libs/mesa/files/mesa-10.2-sysfs-instead-of-libudev.patch')
-rw-r--r--media-libs/mesa/files/mesa-10.2-sysfs-instead-of-libudev.patch378
1 files changed, 378 insertions, 0 deletions
diff --git a/media-libs/mesa/files/mesa-10.2-sysfs-instead-of-libudev.patch b/media-libs/mesa/files/mesa-10.2-sysfs-instead-of-libudev.patch
new file mode 100644
index 000000000000..6eed6acbe792
--- /dev/null
+++ b/media-libs/mesa/files/mesa-10.2-sysfs-instead-of-libudev.patch
@@ -0,0 +1,378 @@
+From 85b6f36ca5238dd3fec7c5fcacb8b7074ce53c8e Mon Sep 17 00:00:00 2001
+From: Gary Wong <gtw@gnu.org>
+Date: Wed, 21 May 2014 21:07:42 -0600
+Subject: loader: add optional /sys filesystem method for PCI identification.
+
+Introduce a simple PCI identification method of looking up the answer
+the /sys filesystem (available on Linux). Attempted after libudev, but
+before DRM.
+
+Disabled by default (available only when the --enable-sysfs configure
+option is specified).
+
+Signed-off-by: Gary Wong <gtw@gnu.org>
+Acked-by: Emil Velikov <emil.l.velikov@gmail.com>
+
+Backported to mesa-10.2.8 by Ian Stakenvicius <axs@gentoo.org>
+
+--- a/configure.ac
++++ b/configure.ac
+@@ -870,14 +870,21 @@ fi
+
+ case "$host_os" in
+ linux*)
+- need_libudev=yes ;;
++ need_pci_id=yes ;;
+ *)
+- need_libudev=no ;;
++ need_pci_id=no ;;
+ esac
+
+ PKG_CHECK_MODULES([LIBUDEV], [libudev >= $LIBUDEV_REQUIRED],
+ have_libudev=yes, have_libudev=no)
+
++AC_ARG_ENABLE([sysfs],
++ [AS_HELP_STRING([--enable-sysfs],
++ [enable /sys PCI identification @<:@default=disabled@:>@])],
++ [have_sysfs="$enableval"],
++ [have_sysfs=no]
++)
++
+ if test "x$enable_dri" = xyes; then
+ if test "$enable_static" = yes; then
+ AC_MSG_ERROR([Cannot use static libraries for DRI drivers])
+@@ -973,8 +980,15 @@ xyesno)
+ ;;
+ esac
+
++have_pci_id=no
+ if test "$have_libudev" = yes; then
+ DEFINES="$DEFINES -DHAVE_LIBUDEV"
++ have_pci_id=yes
++fi
++
++if test "$have_sysfs" = yes; then
++ DEFINES="$DEFINES -DHAVE_SYSFS"
++ have_pci_id=yes
+ fi
+
+ # This is outside the case (above) so that it is invoked even for non-GLX
+@@ -1076,8 +1090,8 @@ if test "x$enable_dri" = xyes; then
+ DEFINES="$DEFINES -DHAVE_DRI3"
+ fi
+
+- if test "x$have_libudev" != xyes; then
+- AC_MSG_ERROR([libudev-dev required for building DRI])
++ if test "x$have_pci_id" != xyes; then
++ AC_MSG_ERROR([libudev-dev or sysfs required for building DRI])
+ fi
+
+ case "$host_cpu" in
+@@ -1252,8 +1266,8 @@ if test "x$enable_gbm" = xauto; then
+ esac
+ fi
+ if test "x$enable_gbm" = xyes; then
+- if test "x$need_libudev$have_libudev" = xyesno; then
+- AC_MSG_ERROR([gbm requires udev >= $LIBUDEV_REQUIRED])
++ if test "x$need_pci_id$have_pci_id" = xyesno; then
++ AC_MSG_ERROR([gbm requires udev >= $LIBUDEV_REQUIRED or sysfs])
+ fi
+
+ if test "x$enable_dri" = xyes; then
+@@ -1271,7 +1285,7 @@ if test "x$enable_gbm" = xyes; then
+ fi
+ fi
+ AM_CONDITIONAL(HAVE_GBM, test "x$enable_gbm" = xyes)
+-if test "x$need_libudev" = xyes; then
++if test "x$need_pci_id$have_libudev" = xyesyes; then
+ GBM_PC_REQ_PRIV="libudev >= $LIBUDEV_REQUIRED"
+ else
+ GBM_PC_REQ_PRIV=""
+@@ -1560,9 +1574,9 @@ for plat in $egl_platforms; do
+ ;;
+ esac
+
+- case "$plat$need_libudev$have_libudev" in
++ case "$plat$need_pci_id$have_pci_id" in
+ waylandyesno|drmyesno)
+- AC_MSG_ERROR([cannot build $plat platform without udev >= $LIBUDEV_REQUIRED]) ;;
++ AC_MSG_ERROR([cannot build $plat platform without udev >= $LIBUDEV_REQUIRED or sysfs]) ;;
+ esac
+ done
+
+@@ -1843,8 +1857,8 @@ gallium_require_llvm() {
+
+ gallium_require_drm_loader() {
+ if test "x$enable_gallium_loader" = xyes; then
+- if test "x$need_libudev$have_libudev" = xyesno; then
+- AC_MSG_ERROR([Gallium drm loader requires libudev >= $LIBUDEV_REQUIRED])
++ if test "x$need_pci_id$have_pci_id" = xyesno; then
++ AC_MSG_ERROR([Gallium drm loader requires libudev >= $LIBUDEV_REQUIRED or sysfs])
+ fi
+ if test "x$have_libdrm" != xyes; then
+ AC_MSG_ERROR([Gallium drm loader requires libdrm >= $LIBDRM_REQUIRED])
+--- a/src/loader/loader.c 2014-09-19 13:03:22.000000000 -0400
++++ b/src/loader/loader.c 2014-11-25 12:46:51.412249717 -0500
+@@ -71,6 +71,10 @@
+ #include <assert.h>
+ #include <dlfcn.h>
+ #endif
++#ifdef HAVE_SYSFS
++#include <sys/stat.h>
++#include <sys/types.h>
++#endif
+ #include "loader.h"
+
+ #ifndef __NOT_HAVE_DRM_H
+@@ -113,8 +117,8 @@
+ udev_handle = dlopen("libudev.so.0", RTLD_LOCAL | RTLD_LAZY);
+
+ if (!udev_handle) {
+- log_(_LOADER_FATAL, "Couldn't dlopen libudev.so.1 or libudev.so.0, "
+- "driver detection may be broken.\n");
++ log_(_LOADER_WARNING, "Couldn't dlopen libudev.so.1 or "
++ "libudev.so.0, driver detection may be broken.\n");
+ }
+ }
+ }
+@@ -122,16 +126,19 @@
+ return udev_handle;
+ }
+
++static int dlsym_failed = 0;
++
+ static void *
+-asserted_dlsym(void *dlopen_handle, const char *name)
++checked_dlsym(void *dlopen_handle, const char *name)
+ {
+ void *result = dlsym(dlopen_handle, name);
+- assert(result);
++ if (!result)
++ dlsym_failed = 1;
+ return result;
+ }
+
+ #define UDEV_SYMBOL(ret, name, args) \
+- ret (*name) args = asserted_dlsym(udev_dlopen_handle(), #name);
++ ret (*name) args = checked_dlsym(udev_dlopen_handle(), #name);
+
+
+ static inline struct udev_device *
+@@ -142,6 +149,9 @@
+ UDEV_SYMBOL(struct udev_device *, udev_device_new_from_devnum,
+ (struct udev *udev, char type, dev_t devnum));
+
++ if (dlsym_failed)
++ return NULL;
++
+ if (fstat(fd, &buf) < 0) {
+ log_(_LOADER_WARNING, "MESA-LOADER: failed to stat fd %d\n", fd);
+ return NULL;
+@@ -157,8 +167,8 @@
+ return device;
+ }
+
+-int
+-loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
++static int
++libudev_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
+ {
+ struct udev *udev = NULL;
+ struct udev_device *device = NULL, *parent;
+@@ -174,6 +184,9 @@
+
+ *chip_id = -1;
+
++ if (dlsym_failed)
++ return 0;
++
+ udev = udev_new();
+ device = udev_device_new_from_fd(udev, fd);
+ if (!device)
+@@ -201,16 +214,76 @@
+
+ return (*chip_id >= 0);
+ }
++#endif
++
++#if defined(HAVE_SYSFS)
++static int
++dev_node_from_fd(int fd, unsigned int *maj, unsigned int *min)
++{
++ struct stat buf;
++
++ if (fstat(fd, &buf) < 0) {
++ log_(_LOADER_WARNING, "MESA-LOADER: failed to stat fd %d\n", fd);
++ return -1;
++ }
++
++ if (!S_ISCHR(buf.st_mode)) {
++ log_(_LOADER_WARNING, "MESA-LOADER: fd %d not a character device\n", fd);
++ return -1;
++ }
++
++ *maj = major(buf.st_rdev);
++ *min = minor(buf.st_rdev);
++
++ return 0;
++}
++
++static int
++sysfs_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
++{
++ unsigned int maj, min;
++ FILE *f;
++ char buf[0x40];
+
+-#elif !defined(__NOT_HAVE_DRM_H)
++ if (dev_node_from_fd(fd, &maj, &min) < 0) {
++ *chip_id = -1;
++ return 0;
++ }
+
++ snprintf(buf, sizeof(buf), "/sys/dev/char/%d:%d/device/vendor", maj, min);
++ if (!(f = fopen(buf, "r"))) {
++ *chip_id = -1;
++ return 0;
++ }
++ if (fscanf(f, "%x", vendor_id) != 1) {
++ *chip_id = -1;
++ fclose(f);
++ return 0;
++ }
++ fclose(f);
++ snprintf(buf, sizeof(buf), "/sys/dev/char/%d:%d/device/device", maj, min);
++ if (!(f = fopen(buf, "r"))) {
++ *chip_id = -1;
++ return 0;
++ }
++ if (fscanf(f, "%x", chip_id) != 1) {
++ *chip_id = -1;
++ fclose(f);
++ return 0;
++ }
++ fclose(f);
++ return 1;
++}
++#endif
++
++#if !defined(__NOT_HAVE_DRM_H)
+ /* for i915 */
+ #include <i915_drm.h>
+ /* for radeon */
+ #include <radeon_drm.h>
+
+-int
+-loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
++static int
++drm_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
+ {
+ drmVersionPtr version;
+
+@@ -272,23 +345,33 @@
+
+ return (*chip_id >= 0);
+ }
++#endif
+
+-#else
+
+ int
+ loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
+ {
++#if HAVE_LIBUDEV
++ if (libudev_get_pci_id_for_fd(fd, vendor_id, chip_id))
++ return 1;
++#endif
++#if HAVE_SYSFS
++ if (sysfs_get_pci_id_for_fd(fd, vendor_id, chip_id))
++ return 1;
++#endif
++#if !defined(__NOT_HAVE_DRM_H)
++ if (drm_get_pci_id_for_fd(fd, vendor_id, chip_id))
++ return 1;
++#endif
+ return 0;
+ }
+
+-#endif
+-
+
+-char *
+-loader_get_device_name_for_fd(int fd)
++#ifdef HAVE_LIBUDEV
++static char *
++libudev_get_device_name_for_fd(int fd)
+ {
+ char *device_name = NULL;
+-#ifdef HAVE_LIBUDEV
+ struct udev *udev;
+ struct udev_device *device;
+ const char *const_device_name;
+@@ -312,9 +395,66 @@
+ out:
+ udev_device_unref(device);
+ udev_unref(udev);
++ return device_name;
++}
+ #endif
++
++
++#if HAVE_SYSFS
++static char *
++sysfs_get_device_name_for_fd(int fd)
++{
++ char *device_name = NULL;
++ unsigned int maj, min;
++ FILE *f;
++ char buf[0x40];
++ static const char match[9] = "\0DEVNAME=";
++ int expected = 1;
++
++ if (dev_node_from_fd(fd, &maj, &min) < 0)
++ return NULL;
++
++ snprintf(buf, sizeof(buf), "/sys/dev/char/%d:%d/uevent", maj, min);
++ if (!(f = fopen(buf, "r")))
++ return NULL;
++
++ while (expected < sizeof(match)) {
++ int c = getc(f);
++
++ if (c == EOF) {
++ fclose(f);
++ return NULL;
++ } else if (c == match[expected] )
++ expected++;
++ else
++ expected = 0;
++ }
++
++ strcpy(buf, "/dev/");
++ if (fgets(buf + 5, sizeof(buf) - 5, f))
++ device_name = strdup(buf);
++
++ fclose(f);
+ return device_name;
+ }
++#endif
++
++
++char *
++loader_get_device_name_for_fd(int fd)
++{
++ char *result = NULL;
++
++#if HAVE_LIBUDEV
++ if ((result = libudev_get_device_name_for_fd(fd)))
++ return result;
++#endif
++#if HAVE_SYSFS
++ if ((result = sysfs_get_device_name_for_fd(fd)))
++ return result;
++#endif
++ return result;
++}
+
+ char *
+ loader_get_driver_for_fd(int fd, unsigned driver_types)