summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2011-06-26 07:58:16 +0900
committerChia-I Wu <[email protected]>2011-06-26 08:17:52 +0900
commit450f48627684c6ea1472b4fdd51c6fc121f2bc9c (patch)
tree6f0225f688b0c1d280e0edf1ed295e6dec694046
parented47d65c7c05d7dd5a5b4cafaa32afbd4fff0bef (diff)
targets/egl-static: refactor drm_fd_get_screen_name
Add drm_fd_get_pci_id to get the PCI ID. Fix a leak with udev on error.
-rw-r--r--src/gallium/targets/egl-static/egl.c81
1 files changed, 53 insertions, 28 deletions
diff --git a/src/gallium/targets/egl-static/egl.c b/src/gallium/targets/egl-static/egl.c
index 2caad0e1ee0..9b59ebd60f2 100644
--- a/src/gallium/targets/egl-static/egl.c
+++ b/src/gallium/targets/egl-static/egl.c
@@ -31,7 +31,7 @@
#include "egllog.h"
#ifdef HAVE_LIBUDEV
-#include <stdio.h>
+#include <stdio.h> /* for sscanf */
#include <libudev.h>
#define DRIVER_MAP_GALLIUM_ONLY
#include "pci_ids/pci_id_driver_map.h"
@@ -60,27 +60,29 @@ get_st_api(enum st_api_type api)
return stmod->stapi;
}
-static const char *
-drm_fd_get_screen_name(int fd)
-{
#ifdef HAVE_LIBUDEV
- struct udev *udev;
- struct udev_device *device, *parent;
+
+static boolean
+drm_fd_get_pci_id(int fd, int *vendor_id, int *chip_id)
+{
+ struct udev *udev = NULL;
+ struct udev_device *device = NULL, *parent;
struct stat buf;
const char *pci_id;
- int vendor_id, chip_id, idx = -1, i;
+
+ *chip_id = -1;
udev = udev_new();
if (fstat(fd, &buf) < 0) {
_eglLog(_EGL_WARNING, "failed to stat fd %d", fd);
- return NULL;
+ goto out;
}
device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev);
if (device == NULL) {
_eglLog(_EGL_WARNING,
"could not create udev device for fd %d", fd);
- return NULL;
+ goto out;
}
parent = udev_device_get_parent(device);
@@ -91,41 +93,64 @@ drm_fd_get_screen_name(int fd)
pci_id = udev_device_get_property_value(parent, "PCI_ID");
if (pci_id == NULL ||
- sscanf(pci_id, "%x:%x", &vendor_id, &chip_id) != 2) {
+ sscanf(pci_id, "%x:%x", vendor_id, chip_id) != 2) {
_eglLog(_EGL_WARNING, "malformed or no PCI ID");
+ *chip_id = -1;
goto out;
}
- /* find the driver index */
+out:
+ if (device)
+ udev_device_unref(device);
+ if (udev)
+ udev_unref(udev);
+
+ return (*chip_id >= 0);
+}
+
+#else
+
+static boolean
+drm_fd_get_pci_id(int fd, int *vendor_id, int *chip_id)
+{
+ return FALSE;
+}
+
+#endif /* HAVE_LIBUDEV */
+
+static const char *
+drm_fd_get_screen_name(int fd)
+{
+ int vendor_id, chip_id;
+ int idx, i;
+
+ if (!drm_fd_get_pci_id(fd, &vendor_id, &chip_id)) {
+ _eglLog(_EGL_WARNING, "failed to get driver name for fd %d", fd);
+ return NULL;
+ }
+
for (idx = 0; driver_map[idx].driver; idx++) {
if (vendor_id != driver_map[idx].vendor_id)
continue;
+ /* done if no chip id */
if (driver_map[idx].num_chips_ids == -1)
- goto out;
+ break;
for (i = 0; i < driver_map[idx].num_chips_ids; i++) {
if (driver_map[idx].chip_ids[i] == chip_id)
- goto out;
+ break;
}
+ /* matched! */
+ if (i < driver_map[idx].num_chips_ids)
+ break;
}
-out:
- udev_device_unref(device);
- udev_unref(udev);
-
- if (idx >= 0) {
- _eglLog((driver_map[idx].driver) ? _EGL_INFO : _EGL_WARNING,
- "pci id for fd %d: %04x:%04x, driver %s",
- fd, vendor_id, chip_id, driver_map[idx].driver);
-
- return driver_map[idx].driver;
- }
-#endif
-
- _eglLog(_EGL_WARNING, "failed to get driver name for fd %d", fd);
+ _eglLog((driver_map[idx].driver) ? _EGL_INFO : _EGL_WARNING,
+ "pci id for fd %d: %04x:%04x, driver %s",
+ fd, vendor_id, chip_id, driver_map[idx].driver);
- return NULL;
+ return driver_map[idx].driver;
}
static struct pipe_screen *