Home | History | Annotate | Download | only in dri2
      1 /*
      2  * Copyright  2011 Intel Corporation
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     18  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
     19  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     20  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     22  * DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors:
     25  *    Kristian Hgsberg <krh (at) bitplanet.net>
     26  *    Benjamin Franzke <benjaminfranzke (at) googlemail.com>
     27  */
     28 
     29 #include <stdio.h>
     30 #include <string.h>
     31 
     32 #include <sys/types.h>
     33 #include <sys/stat.h>
     34 #include <unistd.h>
     35 
     36 #include "egl_dri2.h"
     37 
     38 #ifdef HAVE_LIBUDEV
     39 
     40 #define DRIVER_MAP_DRI2_ONLY
     41 #include "pci_ids/pci_id_driver_map.h"
     42 
     43 #include <libudev.h>
     44 
     45 static struct udev_device *
     46 dri2_udev_device_new_from_fd(struct udev *udev, int fd)
     47 {
     48    struct udev_device *device;
     49    struct stat buf;
     50 
     51    if (fstat(fd, &buf) < 0) {
     52       _eglLog(_EGL_WARNING, "EGL-DRI2: failed to stat fd %d", fd);
     53       return NULL;
     54    }
     55 
     56    device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev);
     57    if (device == NULL) {
     58       _eglLog(_EGL_WARNING,
     59               "EGL-DRI2: could not create udev device for fd %d", fd);
     60       return NULL;
     61    }
     62 
     63    return device;
     64 }
     65 
     66 char *
     67 dri2_get_device_name_for_fd(int fd)
     68 {
     69    struct udev *udev;
     70    struct udev_device *device;
     71    const char *const_device_name;
     72    char *device_name = NULL;
     73 
     74    udev = udev_new();
     75    device = dri2_udev_device_new_from_fd(udev, fd);
     76    if (device == NULL)
     77       return NULL;
     78 
     79    const_device_name = udev_device_get_devnode(device);
     80    if (!const_device_name)
     81       goto out;
     82    device_name = strdup(const_device_name);
     83 
     84 out:
     85    udev_device_unref(device);
     86    udev_unref(udev);
     87 
     88    return device_name;
     89 }
     90 
     91 char *
     92 dri2_get_driver_for_fd(int fd)
     93 {
     94    struct udev *udev;
     95    struct udev_device *device, *parent;
     96    const char *pci_id;
     97    char *driver = NULL;
     98    int vendor_id, chip_id, i, j;
     99 
    100    udev = udev_new();
    101    device = dri2_udev_device_new_from_fd(udev, fd);
    102    if (device == NULL)
    103       return NULL;
    104 
    105    parent = udev_device_get_parent(device);
    106    if (parent == NULL) {
    107       _eglLog(_EGL_WARNING, "DRI2: could not get parent device");
    108       goto out;
    109    }
    110 
    111    pci_id = udev_device_get_property_value(parent, "PCI_ID");
    112    if (pci_id == NULL ||
    113        sscanf(pci_id, "%x:%x", &vendor_id, &chip_id) != 2) {
    114       _eglLog(_EGL_WARNING, "EGL-DRI2: malformed or no PCI ID");
    115       goto out;
    116    }
    117 
    118    for (i = 0; driver_map[i].driver; i++) {
    119       if (vendor_id != driver_map[i].vendor_id)
    120          continue;
    121       if (driver_map[i].num_chips_ids == -1) {
    122          driver = strdup(driver_map[i].driver);
    123          _eglLog(_EGL_DEBUG, "pci id for %d: %04x:%04x, driver %s",
    124                  fd, vendor_id, chip_id, driver);
    125          goto out;
    126       }
    127 
    128       for (j = 0; j < driver_map[i].num_chips_ids; j++)
    129          if (driver_map[i].chip_ids[j] == chip_id) {
    130             driver = strdup(driver_map[i].driver);
    131             _eglLog(_EGL_DEBUG, "pci id for %d: %04x:%04x, driver %s",
    132                     fd, vendor_id, chip_id, driver);
    133             goto out;
    134          }
    135    }
    136 
    137 out:
    138    udev_device_unref(device);
    139    udev_unref(udev);
    140 
    141    return driver;
    142 }
    143 
    144 #endif /* HAVE_LIBUDEV */
    145