OSDN Git Service

tests/kmstest: support atmel-hlcdc
[android-x86/external-libdrm.git] / xf86drm.c
index e73cddd..49da9c7 100644 (file)
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -62,7 +62,8 @@
 #endif
 
 #include "xf86drm.h"
-#include "libdrm.h"
+#include "libdrm_macros.h"
+#include "libudev.h"
 
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
 #define DRM_MAJOR 145
@@ -140,16 +141,12 @@ void *drmGetHashTable(void)
 
 void *drmMalloc(int size)
 {
-    void *pt;
-    if ((pt = malloc(size)))
-       memset(pt, 0, size);
-    return pt;
+    return calloc(1, size);
 }
 
 void drmFree(void *pt)
 {
-    if (pt)
-       free(pt);
+    free(pt);
 }
 
 /**
@@ -352,7 +349,7 @@ static int drmOpenDevice(dev_t dev, int minor, int type)
     }
 
     if (drm_server_info) {
-       group = (serv_group >= 0) ? serv_group : DRM_DEV_GID;
+       group = ((int)serv_group >= 0) ? serv_group : DRM_DEV_GID;
        chown_check_return(buf, user, group);
        chmod(buf, devmode);
     }
@@ -1719,7 +1716,7 @@ int drmAgpEnable(int fd, unsigned long mode)
 {
     drm_agp_mode_t m;
 
-    memclear(mode);
+    memclear(m);
     m.mode = mode;
     if (drmIoctl(fd, DRM_IOCTL_AGP_ENABLE, &m))
        return -errno;
@@ -2724,6 +2721,8 @@ int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd)
        struct drm_prime_handle args;
        int ret;
 
+       memclear(args);
+       args.fd = -1;
        args.handle = handle;
        args.flags = flags;
        ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args);
@@ -2739,8 +2738,8 @@ int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle)
        struct drm_prime_handle args;
        int ret;
 
+       memclear(args);
        args.fd = prime_fd;
-       args.flags = 0;
        ret = drmIoctl(fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args);
        if (ret)
                return ret;
@@ -2817,3 +2816,102 @@ char *drmGetRenderDeviceNameFromFd(int fd)
 {
        return drmGetMinorNameForFD(fd, DRM_NODE_RENDER);
 }
+
+/**
+* Enumerate the GPU devices on the system
+*
+* \param devs device array set to return the device information
+* (if NULL, the number of device is returned)
+* \param vendor the vendor ID for GPU devices to list
+* (optional, if not specified, all GPU devices are returned)
+*
+* \return the number of GPU devices
+*/
+int drmGetPciDevices(drmPciDevicePtr devSet, uint16_t vendorId)
+{
+       struct udev *udev = NULL;
+       struct udev_enumerate *udev_enumerate;
+       struct udev_list_entry *list_entry;
+       struct udev_device *device;
+       int drmDevCount = 0;
+       int vendor = 0;
+       int devid = 0;
+       int subvendor = 0;
+       int subdevid = 0;
+       int revid = 0xff;
+       int domain = 0;
+       int bus = 0;
+       int dev = 0;
+       int func = 0;
+       char config[64] = {0};
+       char node[128] = {'\0'};
+       char slot[] = "0000:00:00.0";
+       const char *info = NULL;
+       int fd = 0;
+       int ret = 0;
+
+       udev = udev_new();
+       if (udev == NULL) {
+               fprintf(stderr, "no context\n");
+               return -EINVAL;
+       }
+       udev_enumerate = udev_enumerate_new(udev);
+       if (udev_enumerate == NULL)
+               return -EINVAL;
+       udev_enumerate_add_match_subsystem(udev_enumerate, "drm");
+       udev_enumerate_add_match_property(udev_enumerate, "DEVTYPE", "drm_minor");
+
+       udev_enumerate_scan_devices(udev_enumerate);
+
+       udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(udev_enumerate)) {
+               device = udev_device_new_from_syspath(udev_enumerate_get_udev(udev_enumerate),
+                                                     udev_list_entry_get_name(list_entry));
+               if (device != NULL) {
+                       info = udev_device_get_property_value(device, "MINOR");
+                       if (!strcmp(info, "0")) {
+                       strcpy(node, udev_device_get_syspath(device));
+                       info = strstr(node, "/drm");
+                       strncpy(slot, info - strlen(slot), strlen(slot));
+                       if (sscanf(slot, "%4x:%2x:%2x.%1x", &domain, &bus, &dev, &func) != 4) {
+                               domain = 0;
+                               bus = 0;
+                               dev = 0;
+                               func = 0;
+                       }
+                       strcpy(node + strlen(node), "/device/config");
+
+                       fd = open(node, O_RDONLY);
+                       if (fd >= 0) {
+                               ret = read(fd, config, 64);
+                               if (ret == 64) {
+                                       vendor = config[0] + (config[1] << 8);
+                                       devid = config[2] + (config[3] << 8);
+                                       revid = config[8];
+                                       subdevid = config[44] + (config[45] << 8);
+                               }
+                               close(fd);
+                       }
+
+                       if((vendorId == 0) || (vendorId == vendor)) {
+                               if(devSet != NULL) {
+                                       devSet[drmDevCount].domain = domain;
+                                       devSet[drmDevCount].bus = bus;
+                                       devSet[drmDevCount].dev = dev;
+                                       devSet[drmDevCount].func = func;
+                                       devSet[drmDevCount].vendor_id = vendor;
+                                       devSet[drmDevCount].device_id = devid;
+                                       devSet[drmDevCount].subdevice_id = subdevid;
+                                       devSet[drmDevCount].subvendor_id = subvendor;
+                                       devSet[drmDevCount].revision_id = revid;
+                               }
+                               drmDevCount++;
+                       }
+               }
+               }
+               udev_device_unref(device);
+       }
+       udev_enumerate_unref(udev_enumerate);
+       udev_unref(udev);
+
+       return drmDevCount;
+}