targets/egl-static: refactor drm_fd_get_screen_name
authorChia-I Wu <olvaffe@gmail.com>
Sat, 25 Jun 2011 22:58:16 +0000 (07:58 +0900)
committerChia-I Wu <olv@lunarg.com>
Sat, 25 Jun 2011 23:17:52 +0000 (08:17 +0900)
Add drm_fd_get_pci_id to get the PCI ID.  Fix a leak with udev on error.

src/gallium/targets/egl-static/egl.c

index 2caad0e1ee0fd0e1ea46540c11013caa6d93604e..9b59ebd60f2054c78aa53a6f90127ba415c1c4f4 100644 (file)
@@ -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 *