diff options
author | marha <marha@users.sourceforge.net> | 2014-06-08 14:33:00 +0200 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2014-06-08 14:33:00 +0200 |
commit | 2acb86c9b086bdb9a3897db0b93820652e07cb59 (patch) | |
tree | 02a43a0005c991c736f03de9a1c8ba98f0bbdf28 /mesalib/src/loader/loader.c | |
parent | 816a5430313e07083c5325f0a430126a2e10ec41 (diff) | |
download | vcxsrv-2acb86c9b086bdb9a3897db0b93820652e07cb59.tar.gz vcxsrv-2acb86c9b086bdb9a3897db0b93820652e07cb59.tar.bz2 vcxsrv-2acb86c9b086bdb9a3897db0b93820652e07cb59.zip |
xwininfo libX11 mesa mkfontscale xserver git updated 8 June 2014
xserver commit e27a839bf0488d5b1cc2e2a887f2ea0e3d790790
libxcb commit d978a4f69b30b630f28d07f1003cf290284d24d8
libxcb/xcb-proto commit 389889e2f95af19e7fc7ac89e7faeb2f28652415
xkeyboard-config commit bc3ac1b0d152e929b3532a541596cf9fe286bb9e
libX11 commit d81fed46144d089bdfa1d916a28dffc9ebffe1e4
libXdmcp commit fe8eab93e9bcdbe8bb8052434bb5e676e3a0ee8f
libXext commit 11aad96bd689d54156064d2e81213dc827a689d1
libfontenc commit 0037a42107b952c9d903719615747e760e4e7247
libXinerama commit edd95182b26eb5d576d4878c559e0f17dddaa909
libXau commit 1e4635be11154dd8262f37b379511bd627defa2a
xkbcomp commit d4e02a09258063c6d024c3ccd42d6b22212e6e18
pixman commit 9cd283b2eb8279824406bfd47b020d21fc00cf82
xextproto commit 66afec3f49e8eb0d4c2e9af7088fc3116d4bafd7
randrproto commit a4a6694c059d74247c16527eef4a0ec9f56bbef6
glproto commit f84853d97d5749308992412a215fa518b6536eb3
mkfontscale commit 48e541dc2f2fc3f4e99d3e168c28241ff5adff4d
xwininfo commit 017b3736489985999d8dcf4d9e473e1fd6dd3647
libXft commit 214f9b5306d833e2787c75fe41dfdc9228fcb738
libXmu commit 22d9c590901e121936f50dee97dc60c4f7defb63
libxtrans commit a57a7f62242e1ea972b81414741729bf3dbae0a4
fontconfig commit f44bfad235e63bb792c38e16ae1fbd281ec1453b
mesa commit eb58aa9cf015e79a0fcf2e088676e6aa1d5dabce
Diffstat (limited to 'mesalib/src/loader/loader.c')
-rw-r--r-- | mesalib/src/loader/loader.c | 172 |
1 files changed, 156 insertions, 16 deletions
diff --git a/mesalib/src/loader/loader.c b/mesalib/src/loader/loader.c index 666d0158a..0f262653b 100644 --- a/mesalib/src/loader/loader.c +++ b/mesalib/src/loader/loader.c @@ -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_dlopen_handle(void) 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 @@ udev_dlopen_handle(void) 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_device_new_from_fd(struct udev *udev, int fd) 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 @@ udev_device_new_from_fd(struct udev *udev, int fd) 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 @@ loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id) *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 @@ out: 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]; + + if (dev_node_from_fd(fd, &maj, &min) < 0) { + *chip_id = -1; + return 0; + } -#elif !defined(__NOT_HAVE_DRM_H) + 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 @@ loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id) 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 @@ loader_get_device_name_for_fd(int fd) 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) |