OSDN Git Service

Fix gcc -Wextra warnings
[android-x86/external-libdrm.git] / xf86drm.c
index 06d645d..fb673b5 100644 (file)
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -48,7 +48,6 @@
 #include <sys/stat.h>
 #define stat_t struct stat
 #include <sys/ioctl.h>
-#include <sys/mman.h>
 #include <sys/time.h>
 #include <stdarg.h>
 
@@ -58,6 +57,7 @@
 #endif
 
 #include "xf86drm.h"
+#include "libdrm.h"
 
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
 #define DRM_MAJOR 145
@@ -86,7 +86,8 @@
 #define DRM_MSG_VERBOSITY 3
 
 #define DRM_NODE_CONTROL 0
-#define DRM_NODE_RENDER 1
+#define DRM_NODE_PRIMARY 1
+#define DRM_NODE_RENDER 2
 
 static drmServerInfoPtr drm_server_info;
 
@@ -104,12 +105,16 @@ void drmSetServerInfo(drmServerInfoPtr info)
  * This function is a wrapper around vfprintf().
  */
 
-static int drmDebugPrint(const char *format, va_list ap)
+static int DRM_PRINTFLIKE(1, 0)
+drmDebugPrint(const char *format, va_list ap)
 {
     return vfprintf(stderr, format, ap);
 }
 
-static int (*drm_debug_print)(const char *format, va_list ap) = drmDebugPrint;
+typedef int DRM_PRINTFLIKE(1, 0) (*debug_msg_func_t)(const char *format,
+                                                    va_list ap);
+
+static debug_msg_func_t drm_debug_print = drmDebugPrint;
 
 void
 drmMsg(const char *format, ...)
@@ -129,7 +134,7 @@ drmMsg(const char *format, ...)
 }
 
 void
-drmSetDebugMsgFunction(int (*debug_msg_ptr)(const char *format, va_list ap))
+drmSetDebugMsgFunction(debug_msg_func_t debug_msg_ptr)
 {
     drm_debug_print = debug_msg_ptr;
 }
@@ -155,23 +160,6 @@ void drmFree(void *pt)
        free(pt);
 }
 
-/* drmStrdup can't use strdup(3), since it doesn't call _DRM_MALLOC... */
-static char *drmStrdup(const char *s)
-{
-    char *retval;
-
-    if (!s)
-        return NULL;
-
-    retval = malloc(strlen(s)+1);
-    if (!retval)
-        return NULL;
-
-    strcpy(retval, s);
-
-    return retval;
-}
-
 /**
  * Call ioctl, restarting if it is interupted
  */
@@ -229,7 +217,7 @@ drmHashEntry *drmGetEntry(int fd)
  * PCI:b:d:f format and the newer pci:oooo:bb:dd.f format.  In the format, o is
  * domain, b is bus, d is device, f is function.
  */
-static int drmMatchBusID(const char *id1, const char *id2)
+static int drmMatchBusID(const char *id1, const char *id2, int pci_domain_ok)
 {
     /* First, check if the IDs are exactly the same */
     if (strcasecmp(id1, id2) == 0)
@@ -257,6 +245,13 @@ static int drmMatchBusID(const char *id1, const char *id2)
                return 0;
        }
 
+       /* If domains aren't properly supported by the kernel interface,
+        * just ignore them, which sucks less than picking a totally random
+        * card with "open by name"
+        */
+       if (!pci_domain_ok)
+               o1 = o2 = 0;
+
        if ((o1 != o2) || (b1 != b2) || (d1 != d2) || (f1 != f2))
            return 0;
        else
@@ -308,9 +303,10 @@ static int chown_check_return(const char *path, uid_t owner, gid_t group)
  * special file node with the major and minor numbers specified by \p dev and
  * parent directory if necessary and was called by root.
  */
-static int drmOpenDevice(long dev, int minor, int type)
+static int drmOpenDevice(dev_t dev, int minor, int type)
 {
     stat_t          st;
+    const char      *dev_name;
     char            buf[64];
     int             fd;
     mode_t          devmode = DRM_DEV_MODE, serv_mode;
@@ -318,7 +314,21 @@ static int drmOpenDevice(long dev, int minor, int type)
     uid_t           user    = DRM_DEV_UID;
     gid_t           group   = DRM_DEV_GID, serv_group;
     
-    sprintf(buf, type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor);
+    switch (type) {
+    case DRM_NODE_PRIMARY:
+           dev_name = DRM_DEV_NAME;
+           break;
+    case DRM_NODE_CONTROL:
+           dev_name = DRM_CONTROL_DEV_NAME;
+           break;
+    case DRM_NODE_RENDER:
+           dev_name = DRM_RENDER_DEV_NAME;
+           break;
+    default:
+           return -EINVAL;
+    };
+
+    sprintf(buf, dev_name, DRM_DIR_NAME, minor);
     drmMsg("drmOpenDevice: node name is %s\n", buf);
 
     if (drm_server_info) {
@@ -380,6 +390,7 @@ wait_for_udev:
     if (fd >= 0)
        return fd;
 
+#if !defined(UDEV)
     /* Check if the device node is not what we expect it to be, and recreate it
      * and try again if so.
      */
@@ -401,6 +412,7 @@ wait_for_udev:
 
     drmMsg("drmOpenDevice: Open failed\n");
     remove(buf);
+#endif
     return -errno;
 }
 
@@ -421,11 +433,26 @@ static int drmOpenMinor(int minor, int create, int type)
 {
     int  fd;
     char buf[64];
+    const char *dev_name;
     
     if (create)
        return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type);
     
-    sprintf(buf, type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor);
+    switch (type) {
+    case DRM_NODE_PRIMARY:
+           dev_name = DRM_DEV_NAME;
+           break;
+    case DRM_NODE_CONTROL:
+           dev_name = DRM_CONTROL_DEV_NAME;
+           break;
+    case DRM_NODE_RENDER:
+           dev_name = DRM_RENDER_DEV_NAME;
+           break;
+    default:
+           return -EINVAL;
+    };
+
+    sprintf(buf, dev_name, DRM_DIR_NAME, minor);
     if ((fd = open(buf, O_RDWR, 0)) >= 0)
        return fd;
     return -errno;
@@ -448,7 +475,7 @@ int drmAvailable(void)
     int           retval = 0;
     int           fd;
 
-    if ((fd = drmOpenMinor(0, 1, DRM_NODE_RENDER)) < 0) {
+    if ((fd = drmOpenMinor(0, 1, DRM_NODE_PRIMARY)) < 0) {
 #ifdef __linux__
        /* Try proc for backward Linux compatibility */
        if (!access("/proc/dri/0", R_OK))
@@ -482,24 +509,37 @@ int drmAvailable(void)
  */
 static int drmOpenByBusid(const char *busid)
 {
-    int        i;
+    int        i, pci_domain_ok = 1;
     int        fd;
     const char *buf;
     drmSetVersion sv;
 
     drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid);
     for (i = 0; i < DRM_MAX_MINOR; i++) {
-       fd = drmOpenMinor(i, 1, DRM_NODE_RENDER);
+       fd = drmOpenMinor(i, 1, DRM_NODE_PRIMARY);
        drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd);
        if (fd >= 0) {
+           /* We need to try for 1.4 first for proper PCI domain support
+            * and if that fails, we know the kernel is busted
+            */
            sv.drm_di_major = 1;
-           sv.drm_di_minor = 1;
+           sv.drm_di_minor = 4;
            sv.drm_dd_major = -1;       /* Don't care */
            sv.drm_dd_minor = -1;       /* Don't care */
-           drmSetInterfaceVersion(fd, &sv);
+           if (drmSetInterfaceVersion(fd, &sv)) {
+#ifndef __alpha__
+               pci_domain_ok = 0;
+#endif
+               sv.drm_di_major = 1;
+               sv.drm_di_minor = 1;
+               sv.drm_dd_major = -1;       /* Don't care */
+               sv.drm_dd_minor = -1;       /* Don't care */
+               drmMsg("drmOpenByBusid: Interface 1.4 failed, trying 1.1\n");
+               drmSetInterfaceVersion(fd, &sv);
+           }
            buf = drmGetBusid(fd);
            drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf);
-           if (buf && drmMatchBusID(buf, busid)) {
+           if (buf && drmMatchBusID(buf, busid, pci_domain_ok)) {
                drmFreeBusid(buf);
                return fd;
            }
@@ -532,26 +572,13 @@ static int drmOpenByName(const char *name)
     int           fd;
     drmVersionPtr version;
     char *        id;
-    
-    if (!drmAvailable()) {
-       if (!drm_server_info) {
-           return -1;
-       }
-       else {
-           /* try to load the kernel module now */
-           if (!drm_server_info->load_module(name)) {
-               drmMsg("[drm] failed to load kernel module \"%s\"\n", name);
-               return -1;
-           }
-       }
-    }
 
     /*
      * Open the first minor number that matches the driver name and isn't
      * already in use.  If it's in use it will have a busid assigned already.
      */
     for (i = 0; i < DRM_MAX_MINOR; i++) {
-       if ((fd = drmOpenMinor(i, 1, DRM_NODE_RENDER)) >= 0) {
+       if ((fd = drmOpenMinor(i, 1, DRM_NODE_PRIMARY)) >= 0) {
            if ((version = drmGetVersion(fd))) {
                if (!strcmp(version->name, name)) {
                    drmFreeVersion(version);
@@ -595,7 +622,7 @@ static int drmOpenByName(const char *name)
                        if (*pt) { /* Found busid */
                            return drmOpenByBusid(++pt);
                        } else { /* No busid */
-                           return drmOpenDevice(strtol(devstring, NULL, 0),i, DRM_NODE_RENDER);
+                           return drmOpenDevice(strtol(devstring, NULL, 0),i, DRM_NODE_PRIMARY);
                        }
                    }
                }
@@ -650,6 +677,11 @@ int drmOpenControl(int minor)
     return drmOpenMinor(minor, 0, DRM_NODE_CONTROL);
 }
 
+int drmOpenRender(int minor)
+{
+    return drmOpenMinor(minor, 0, DRM_NODE_RENDER);
+}
+
 /**
  * Free the version information returned by drmGetVersion().
  *
@@ -706,11 +738,11 @@ static void drmCopyVersion(drmVersionPtr d, const drm_version_t *s)
     d->version_minor      = s->version_minor;
     d->version_patchlevel = s->version_patchlevel;
     d->name_len           = s->name_len;
-    d->name               = drmStrdup(s->name);
+    d->name               = strdup(s->name);
     d->date_len           = s->date_len;
-    d->date               = drmStrdup(s->date);
+    d->date               = strdup(s->date);
     d->desc_len           = s->desc_len;
-    d->desc               = drmStrdup(s->desc);
+    d->desc               = strdup(s->desc);
 }
 
 
@@ -805,6 +837,25 @@ drmVersionPtr drmGetLibVersion(int fd)
     return (drmVersionPtr)version;
 }
 
+int drmGetCap(int fd, uint64_t capability, uint64_t *value)
+{
+       struct drm_get_cap cap = { capability, 0 };
+       int ret;
+
+       ret = drmIoctl(fd, DRM_IOCTL_GET_CAP, &cap);
+       if (ret)
+               return ret;
+
+       *value = cap.value;
+       return 0;
+}
+
+int drmSetClientCap(int fd, uint64_t capability, uint64_t value)
+{
+       struct drm_set_client_cap cap  = { capability, value };
+
+       return drmIoctl(fd, DRM_IOCTL_SET_CLIENT_CAP, &cap);
+}
 
 /**
  * Free the bus ID information.
@@ -959,7 +1010,7 @@ int drmAddMap(int fd, drm_handle_t offset, drmSize size, drmMapType type,
     if (drmIoctl(fd, DRM_IOCTL_ADD_MAP, &map))
        return -errno;
     if (handle)
-       *handle = (drm_handle_t)map.handle;
+       *handle = (drm_handle_t)(uintptr_t)map.handle;
     return 0;
 }
 
@@ -967,7 +1018,7 @@ int drmRmMap(int fd, drm_handle_t handle)
 {
     drm_map_t map;
 
-    map.handle = (void *)handle;
+    map.handle = (void *)(uintptr_t)handle;
 
     if(drmIoctl(fd, DRM_IOCTL_RM_MAP, &map))
        return -errno;
@@ -1122,7 +1173,7 @@ int drmMap(int fd, drm_handle_t handle, drmSize size, drmAddressPtr address)
 
     size = (size + pagesize_mask) & ~pagesize_mask;
 
-    *address = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle);
+    *address = drm_mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle);
     if (*address == MAP_FAILED)
        return -errno;
     return 0;
@@ -1142,7 +1193,7 @@ int drmMap(int fd, drm_handle_t handle, drmSize size, drmAddressPtr address)
  */
 int drmUnmap(drmAddress address, drmSize size)
 {
-    return munmap(address, size);
+    return drm_munmap(address, size);
 }
 
 drmBufInfoPtr drmGetBufInfo(int fd)
@@ -1249,7 +1300,7 @@ int drmUnmapBufs(drmBufMapPtr bufs)
     int i;
 
     for (i = 0; i < bufs->count; i++) {
-       munmap(bufs->list[i].address, bufs->list[i].total);
+       drm_munmap(bufs->list[i].address, bufs->list[i].total);
     }
 
     drmFree(bufs->list);
@@ -1929,7 +1980,7 @@ int drmWaitVBlank(int fd, drmVBlankPtr vbl)
 
     ret = clock_gettime(CLOCK_MONOTONIC, &timeout);
     if (ret < 0) {
-       fprintf(stderr, "clock_gettime failed: %s\n", strerror(ret));
+       fprintf(stderr, "clock_gettime failed: %s\n", strerror(errno));
        goto out;
     }
     timeout.tv_sec++;
@@ -2103,7 +2154,7 @@ int drmAddContextPrivateMapping(int fd, drm_context_t ctx_id,
     drm_ctx_priv_map_t map;
 
     map.ctx_id = ctx_id;
-    map.handle = (void *)handle;
+    map.handle = (void *)(uintptr_t)handle;
 
     if (drmIoctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map))
        return -errno;
@@ -2120,7 +2171,7 @@ int drmGetContextPrivateMapping(int fd, drm_context_t ctx_id,
     if (drmIoctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map))
        return -errno;
     if (handle)
-       *handle = (drm_handle_t)map.handle;
+       *handle = (drm_handle_t)(uintptr_t)map.handle;
 
     return 0;
 }
@@ -2162,7 +2213,7 @@ int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid,
 int drmGetStats(int fd, drmStatsT *stats)
 {
     drm_stats_t s;
-    int         i;
+    unsigned    i;
 
     if (drmIoctl(fd, DRM_IOCTL_GET_STATS, &s))
        return -errno;
@@ -2492,19 +2543,12 @@ void drmCloseOnce(int fd)
 
 int drmSetMaster(int fd)
 {
-       int ret;
-
-       fprintf(stderr,"Setting master \n");
-       ret = ioctl(fd, DRM_IOCTL_SET_MASTER, 0);
-       return ret;
+       return ioctl(fd, DRM_IOCTL_SET_MASTER, 0);
 }
 
 int drmDropMaster(int fd)
 {
-       int ret;
-       fprintf(stderr,"Dropping master \n");
-       ret = ioctl(fd, DRM_IOCTL_DROP_MASTER, 0);
-       return ret;
+       return ioctl(fd, DRM_IOCTL_DROP_MASTER, 0);
 }
 
 char *drmGetDeviceNameFromFd(int fd)
@@ -2530,5 +2574,36 @@ char *drmGetDeviceNameFromFd(int fd)
        if (i == DRM_MAX_MINOR)
                return NULL;
 
-       return drmStrdup(name);
+       return strdup(name);
 }
+
+int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd)
+{
+       struct drm_prime_handle args;
+       int ret;
+
+       args.handle = handle;
+       args.flags = flags;
+       ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args);
+       if (ret)
+               return ret;
+
+       *prime_fd = args.fd;
+       return 0;
+}
+
+int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle)
+{
+       struct drm_prime_handle args;
+       int ret;
+
+       args.fd = prime_fd;
+       args.flags = 0;
+       ret = drmIoctl(fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args);
+       if (ret)
+               return ret;
+
+       *handle = args.handle;
+       return 0;
+}
+