loader: allow attempting more than one method of PCI identification.

loader_get_pci_id_for_fd() and loader_get_device_name_for_fd() now attempt
all available strategies to identify the hardware, instead of conditionally
compiling in a single test.  The existing libudev and DRM approaches have
been retained, attempting first libudev (if available) and then DRM (if
necessary).

Signed-off-by: Gary Wong <gtw@gnu.org>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
This commit is contained in:
Gary Wong
2014-05-21 20:39:15 -06:00
parent febec73147
commit 090c772b8a

View File

@@ -113,8 +113,8 @@ udev_dlopen_handle(void)
udev_handle = dlopen("libudev.so.0", RTLD_LOCAL | RTLD_LAZY); udev_handle = dlopen("libudev.so.0", RTLD_LOCAL | RTLD_LAZY);
if (!udev_handle) { if (!udev_handle) {
log_(_LOADER_FATAL, "Couldn't dlopen libudev.so.1 or libudev.so.0, " log_(_LOADER_WARNING, "Couldn't dlopen libudev.so.1 or "
"driver detection may be broken.\n"); "libudev.so.0, driver detection may be broken.\n");
} }
} }
} }
@@ -122,16 +122,19 @@ udev_dlopen_handle(void)
return udev_handle; return udev_handle;
} }
static int dlsym_failed = 0;
static void * static void *
asserted_dlsym(void *dlopen_handle, const char *name) checked_dlsym(void *dlopen_handle, const char *name)
{ {
void *result = dlsym(dlopen_handle, name); void *result = dlsym(dlopen_handle, name);
assert(result); if (!result)
dlsym_failed = 1;
return result; return result;
} }
#define UDEV_SYMBOL(ret, name, args) \ #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 * static inline struct udev_device *
@@ -142,6 +145,9 @@ udev_device_new_from_fd(struct udev *udev, int fd)
UDEV_SYMBOL(struct udev_device *, udev_device_new_from_devnum, UDEV_SYMBOL(struct udev_device *, udev_device_new_from_devnum,
(struct udev *udev, char type, dev_t devnum)); (struct udev *udev, char type, dev_t devnum));
if (dlsym_failed)
return NULL;
if (fstat(fd, &buf) < 0) { if (fstat(fd, &buf) < 0) {
log_(_LOADER_WARNING, "MESA-LOADER: failed to stat fd %d\n", fd); log_(_LOADER_WARNING, "MESA-LOADER: failed to stat fd %d\n", fd);
return NULL; return NULL;
@@ -157,8 +163,8 @@ udev_device_new_from_fd(struct udev *udev, int fd)
return device; return device;
} }
int static int
loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id) libudev_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
{ {
struct udev *udev = NULL; struct udev *udev = NULL;
struct udev_device *device = NULL, *parent; struct udev_device *device = NULL, *parent;
@@ -174,6 +180,9 @@ loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
*chip_id = -1; *chip_id = -1;
if (dlsym_failed)
return 0;
udev = udev_new(); udev = udev_new();
device = udev_device_new_from_fd(udev, fd); device = udev_device_new_from_fd(udev, fd);
if (!device) if (!device)
@@ -201,16 +210,16 @@ out:
return (*chip_id >= 0); return (*chip_id >= 0);
} }
#endif
#elif !defined(__NOT_HAVE_DRM_H) #if !defined(__NOT_HAVE_DRM_H)
/* for i915 */ /* for i915 */
#include <i915_drm.h> #include <i915_drm.h>
/* for radeon */ /* for radeon */
#include <radeon_drm.h> #include <radeon_drm.h>
int static int
loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id) drm_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
{ {
drmVersionPtr version; drmVersionPtr version;
@@ -272,23 +281,29 @@ loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
return (*chip_id >= 0); return (*chip_id >= 0);
} }
#endif
#else
int int
loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id) 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 !defined(__NOT_HAVE_DRM_H)
if (drm_get_pci_id_for_fd(fd, vendor_id, chip_id))
return 1;
#endif
return 0; return 0;
} }
#endif
#ifdef HAVE_LIBUDEV
char * static char *
loader_get_device_name_for_fd(int fd) libudev_get_device_name_for_fd(int fd)
{ {
char *device_name = NULL; char *device_name = NULL;
#ifdef HAVE_LIBUDEV
struct udev *udev; struct udev *udev;
struct udev_device *device; struct udev_device *device;
const char *const_device_name; const char *const_device_name;
@@ -312,9 +327,22 @@ loader_get_device_name_for_fd(int fd)
out: out:
udev_device_unref(device); udev_device_unref(device);
udev_unref(udev); udev_unref(udev);
#endif
return device_name; 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
return result;
}
char * char *
loader_get_driver_for_fd(int fd, unsigned driver_types) loader_get_driver_for_fd(int fd, unsigned driver_types)