X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=xf86drm.c;h=d900b4bd7340dc9cfda615f807b7eb28e046423c;hb=3d95accc1690494e931f92d49726873d99a0b39e;hp=220aaa16c1d6a555168a4fe95a3e0e4d73df6130;hpb=2f7f7ceccab4176217c399502b3ff95df1517627;p=platform%2Fupstream%2Flibdrm.git diff --git a/xf86drm.c b/xf86drm.c index 220aaa1..d900b4b 100644 --- a/xf86drm.c +++ b/xf86drm.c @@ -48,7 +48,6 @@ #include #define stat_t struct stat #include -#include #include #include @@ -58,6 +57,7 @@ #endif #include "xf86drm.h" +#include "libdrm.h" #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) #define DRM_MAJOR 145 @@ -104,12 +104,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 +133,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 +159,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 +216,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 +244,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 @@ -380,6 +374,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 +396,7 @@ wait_for_udev: drmMsg("drmOpenDevice: Open failed\n"); remove(buf); +#endif return -errno; } @@ -482,7 +478,7 @@ int drmAvailable(void) */ static int drmOpenByBusid(const char *busid) { - int i; + int i, pci_domain_ok = 1; int fd; const char *buf; drmSetVersion sv; @@ -492,14 +488,27 @@ static int drmOpenByBusid(const char *busid) fd = drmOpenMinor(i, 1, DRM_NODE_RENDER); 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,19 +541,6 @@ 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 @@ -706,11 +702,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 +801,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 +974,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 +982,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 +1137,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 +1157,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 +1264,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 +1944,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 +2118,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 +2135,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; } @@ -2523,5 +2538,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; +} +