diff options
author | Michael Fitzpatrick <leahcim@gentoo.org> | 2003-04-24 19:02:29 +0000 |
---|---|---|
committer | Michael Fitzpatrick <leahcim@gentoo.org> | 2003-04-24 19:02:29 +0000 |
commit | 9b625d58d43fb324821fab455912b6730982bc32 (patch) | |
tree | f32c24248b6135240e08c41343a39a8ca5a6a3da /x11-base/xfree-drm | |
parent | Added support for xinerama USE flag. Tidied ebuild. (diff) | |
download | gentoo-2-9b625d58d43fb324821fab455912b6730982bc32.tar.gz gentoo-2-9b625d58d43fb324821fab455912b6730982bc32.tar.bz2 gentoo-2-9b625d58d43fb324821fab455912b6730982bc32.zip |
Add dristat, fix slot
Diffstat (limited to 'x11-base/xfree-drm')
-rw-r--r-- | x11-base/xfree-drm/ChangeLog | 6 | ||||
-rw-r--r-- | x11-base/xfree-drm/files/xfree-drm-4.3.0-r2-dristat.patch | 2799 | ||||
-rw-r--r-- | x11-base/xfree-drm/xfree-drm-4.3.0-r2.ebuild | 8 |
3 files changed, 2810 insertions, 3 deletions
diff --git a/x11-base/xfree-drm/ChangeLog b/x11-base/xfree-drm/ChangeLog index 14ac616f087a..23dcc92bb8dc 100644 --- a/x11-base/xfree-drm/ChangeLog +++ b/x11-base/xfree-drm/ChangeLog @@ -1,6 +1,10 @@ # ChangeLog for x11-base/xfree-drm # Copyright 2002-2003 Gentoo Technologies, Inc.; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/x11-base/xfree-drm/ChangeLog,v 1.17 2003/04/23 02:27:18 lu_zero Exp $ +# $Header: /var/cvsroot/gentoo-x86/x11-base/xfree-drm/ChangeLog,v 1.18 2003/04/24 19:02:29 leahcim Exp $ + + 24 Apr 2003; Michael Fitzpatrick <leahcim@gentoo.org> + xfree-drm-4.3.0-r2.ebuild, files/xfree-drm-4.3.0-r2-dristat.patch: Add + dristat (modified patch from Mathias Hasselmann) bug #18799. Fixed slot. 23 Apr 2003; Luca Barbato <lu_zero@gentoo.org> xfree-drm-4.3.0-r2.ebuild, xfree-drm-4.3.0.ebuild: diff --git a/x11-base/xfree-drm/files/xfree-drm-4.3.0-r2-dristat.patch b/x11-base/xfree-drm/files/xfree-drm-4.3.0-r2-dristat.patch new file mode 100644 index 000000000000..df892359d1b5 --- /dev/null +++ b/x11-base/xfree-drm/files/xfree-drm-4.3.0-r2-dristat.patch @@ -0,0 +1,2799 @@ +diff -ruN modules/drm-trunk/dristat.c modules-dristat/drm-trunk/dristat.c +--- modules/drm-trunk/dristat.c 2002-12-12 12:08:17.000000000 +0100 ++++ modules-dristat/drm-trunk/dristat.c 2003-04-06 10:48:49.000000000 +0200 +@@ -30,10 +30,10 @@ + #include <stdio.h> + #include <stdlib.h> + #include <unistd.h> +-#include "../../../xf86drm.h" +-#include "../xf86drmRandom.c" +-#include "../xf86drmHash.c" +-#include "../xf86drm.c" ++#include "xf86drm.h" ++#include "xf86drmRandom.c" ++#include "xf86drmHash.c" ++#include "xf86drm.c" + + #define DRM_VERSION 0x00000001 + #define DRM_MEMORY 0x00000002 +diff -ruN modules/drm-trunk/xf86drm.c modules-dristat/drm-trunk/xf86drm.c +--- modules/drm-trunk/xf86drm.c 1970-01-01 01:00:00.000000000 +0100 ++++ modules-dristat/drm-trunk/xf86drm.c 2003-04-06 10:48:30.000000000 +0200 +@@ -0,0 +1,1504 @@ ++/* xf86drm.c -- User-level interface to DRM device ++ * Created: Tue Jan 5 08:16:21 1999 by faith@precisioninsight.com ++ * ++ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. ++ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Rickard E. (Rik) Faith <faith@valinux.com> ++ * Kevin E. Martin <martin@valinux.com> ++ * ++ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.31 2003/02/04 03:01:59 dawes Exp $ ++ * ++ */ ++ ++#ifdef XFree86Server ++# include "xf86.h" ++# include "xf86_OSproc.h" ++# include "drm.h" ++# include "xf86_ansic.h" ++# define _DRM_MALLOC xalloc ++# define _DRM_FREE xfree ++# ifndef XFree86LOADER ++# include <sys/mman.h> ++# endif ++#else ++# include <stdio.h> ++# include <stdlib.h> ++# include <unistd.h> ++# include <string.h> ++# include <ctype.h> ++# include <fcntl.h> ++# include <errno.h> ++# include <signal.h> ++# include <sys/types.h> ++# include <sys/stat.h> ++# define stat_t struct stat ++# include <sys/ioctl.h> ++# include <sys/mman.h> ++# include <sys/time.h> ++# include <stdarg.h> ++# ifdef DRM_USE_MALLOC ++# define _DRM_MALLOC malloc ++# define _DRM_FREE free ++extern int xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *); ++extern int xf86RemoveSIGIOHandler(int fd); ++# else ++# include <X11/Xlibint.h> ++# define _DRM_MALLOC Xmalloc ++# define _DRM_FREE Xfree ++# endif ++# include "drm.h" ++#endif ++ ++/* No longer needed with CVS kernel modules on alpha ++#if defined(__alpha__) && defined(__linux__) ++extern unsigned long _bus_base(void); ++#define BUS_BASE _bus_base() ++#endif ++*/ ++ ++/* Not all systems have MAP_FAILED defined */ ++#ifndef MAP_FAILED ++#define MAP_FAILED ((void *)-1) ++#endif ++ ++#include "xf86drm.h" ++ ++#ifndef DRM_MAJOR ++#define DRM_MAJOR 226 /* Linux */ ++#endif ++ ++#ifndef __linux__ ++#undef DRM_MAJOR ++#define DRM_MAJOR 145 /* Should set in drm.h for *BSD */ ++#endif ++ ++#ifndef DRM_MAX_MINOR ++#define DRM_MAX_MINOR 16 ++#endif ++ ++#ifdef __linux__ ++#include <sys/sysmacros.h> /* for makedev() */ ++#endif ++ ++#ifndef makedev ++ /* This definition needs to be changed on ++ some systems if dev_t is a structure. ++ If there is a header file we can get it ++ from, there would be best. */ ++#define makedev(x,y) ((dev_t)(((x) << 8) | (y))) ++#endif ++ ++#define DRM_MSG_VERBOSITY 3 ++ ++static void ++drmMsg(const char *format, ...) ++{ ++ va_list ap; ++ ++#ifndef XFree86Server ++ const char *env; ++ if ((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) ++#endif ++ { ++ va_start(ap, format); ++#ifdef XFree86Server ++ xf86VDrvMsgVerb(-1, X_NONE, DRM_MSG_VERBOSITY, format, ap); ++#else ++ vfprintf(stderr, format, ap); ++#endif ++ va_end(ap); ++ } ++} ++ ++static void *drmHashTable = NULL; /* Context switch callbacks */ ++ ++typedef struct drmHashEntry { ++ int fd; ++ void (*f)(int, void *, void *); ++ void *tagTable; ++} drmHashEntry; ++ ++void *drmMalloc(int size) ++{ ++ void *pt; ++ if ((pt = _DRM_MALLOC(size))) memset(pt, 0, size); ++ return pt; ++} ++ ++void drmFree(void *pt) ++{ ++ if (pt) _DRM_FREE(pt); ++} ++ ++/* drmStrdup can't use strdup(3), since it doesn't call _DRM_MALLOC... */ ++static char *drmStrdup(const char *s) ++{ ++ char *retval = NULL; ++ ++ if (s) { ++ retval = _DRM_MALLOC(strlen(s)+1); ++ strcpy(retval, s); ++ } ++ return retval; ++} ++ ++ ++static unsigned long drmGetKeyFromFd(int fd) ++{ ++ stat_t st; ++ ++ st.st_rdev = 0; ++ fstat(fd, &st); ++ return st.st_rdev; ++} ++ ++static drmHashEntry *drmGetEntry(int fd) ++{ ++ unsigned long key = drmGetKeyFromFd(fd); ++ void *value; ++ drmHashEntry *entry; ++ ++ if (!drmHashTable) drmHashTable = drmHashCreate(); ++ ++ if (drmHashLookup(drmHashTable, key, &value)) { ++ entry = drmMalloc(sizeof(*entry)); ++ entry->fd = fd; ++ entry->f = NULL; ++ entry->tagTable = drmHashCreate(); ++ drmHashInsert(drmHashTable, key, entry); ++ } else { ++ entry = value; ++ } ++ return entry; ++} ++ ++static int drmOpenDevice(long dev, int minor) ++{ ++ stat_t st; ++ char buf[64]; ++ int fd; ++ mode_t devmode = DRM_DEV_MODE; ++ int isroot = !geteuid(); ++#if defined(XFree86Server) ++ uid_t user = DRM_DEV_UID; ++ gid_t group = DRM_DEV_GID; ++#endif ++ ++ drmMsg("drmOpenDevice: minor is %d\n", minor); ++ ++#if defined(XFree86Server) ++ devmode = xf86ConfigDRI.mode ? xf86ConfigDRI.mode : DRM_DEV_MODE; ++ devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH); ++ group = (xf86ConfigDRI.group >= 0) ? xf86ConfigDRI.group : DRM_DEV_GID; ++#endif ++ ++ if (stat(DRM_DIR_NAME, &st)) { ++ if (!isroot) return DRM_ERR_NOT_ROOT; ++ mkdir(DRM_DIR_NAME, DRM_DEV_DIRMODE); ++ chown(DRM_DIR_NAME, 0, 0); /* root:root */ ++ chmod(DRM_DIR_NAME, DRM_DEV_DIRMODE); ++ } ++ ++ sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor); ++ drmMsg("drmOpenDevice: node name is %s\n", buf); ++ if (stat(buf, &st)) { ++ if (!isroot) return DRM_ERR_NOT_ROOT; ++ remove(buf); ++ mknod(buf, S_IFCHR | devmode, dev); ++ } ++#if defined(XFree86Server) ++ chown(buf, user, group); ++ chmod(buf, devmode); ++#endif ++ ++ fd = open(buf, O_RDWR, 0); ++ drmMsg("drmOpenDevice: open result is %d, (%s)\n", ++ fd, fd < 0 ? strerror(errno) : "OK"); ++ if (fd >= 0) return fd; ++ ++ if (st.st_rdev != dev) { ++ if (!isroot) return DRM_ERR_NOT_ROOT; ++ remove(buf); ++ mknod(buf, S_IFCHR | devmode, dev); ++ } ++ fd = open(buf, O_RDWR, 0); ++ drmMsg("drmOpenDevice: open result is %d, (%s)\n", ++ fd, fd < 0 ? strerror(errno) : "OK"); ++ if (fd >= 0) return fd; ++ ++ drmMsg("drmOpenDevice: Open failed\n"); ++ remove(buf); ++ return -errno; ++} ++ ++static int drmOpenMinor(int minor, int create) ++{ ++ int fd; ++ char buf[64]; ++ ++ if (create) return drmOpenDevice(makedev(DRM_MAJOR, minor), minor); ++ ++ sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor); ++ if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd; ++ return -errno; ++} ++ ++/* drmAvailable looks for (DRM_MAJOR, 0) and returns 1 if it returns ++ information for DRM_IOCTL_VERSION. For backward compatibility with ++ older Linux implementations, /proc/dri is also checked. */ ++ ++int drmAvailable(void) ++{ ++ drmVersionPtr version; ++ int retval = 0; ++ int fd; ++ ++ if ((fd = drmOpenMinor(0, 1)) < 0) { ++ /* Try proc for backward Linux compatibility */ ++ if (!access("/proc/dri/0", R_OK)) return 1; ++ return 0; ++ } ++ ++ if ((version = drmGetVersion(fd))) { ++ retval = 1; ++ drmFreeVersion(version); ++ } ++ close(fd); ++ ++ return retval; ++} ++ ++static int drmOpenByBusid(const char *busid) ++{ ++ int i; ++ int fd; ++ const char *buf; ++ ++ drmMsg("drmOpenByBusid: busid is %s\n", busid); ++ for (i = 0; i < DRM_MAX_MINOR; i++) { ++ fd = drmOpenMinor(i, 1); ++ drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd); ++ if (fd >= 0) { ++ buf = drmGetBusid(fd); ++ drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf); ++ if (buf && !strcmp(buf, busid)) { ++ drmFreeBusid(buf); ++ return fd; ++ } ++ if (buf) drmFreeBusid(buf); ++ close(fd); ++ } ++ } ++ return -1; ++} ++ ++static int drmOpenByName(const char *name) ++{ ++ int i; ++ int fd; ++ drmVersionPtr version; ++ char * id; ++ ++ if (!drmAvailable()) { ++#if !defined(XFree86Server) ++ return -1; ++#else ++ if (!xf86LoadKernelModule("agpgart")) { ++ ErrorF("[drm] failed to load kernel module \"agpgart\"\n"); ++ } ++ /* try to load the kernel module now */ ++ if (!xf86LoadKernelModule(name)) { ++ ErrorF("[drm] failed to load kernel module \"%s\"\n", ++ name); ++ return -1; ++ } ++#endif ++ } ++ ++ /* ++ * 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)) >= 0) { ++ if ((version = drmGetVersion(fd))) { ++ if (!strcmp(version->name, name)) { ++ drmFreeVersion(version); ++ id = drmGetBusid(fd); ++ drmMsg("drmGetBusid returned '%s'\n", id ? id : "NULL"); ++ if (!id || !*id) { ++ if (id) { ++ drmFreeBusid(id); ++ } ++ return fd; ++ } else { ++ drmFreeBusid(id); ++ } ++ } else { ++ drmFreeVersion(version); ++ } ++ } ++ close(fd); ++ } ++ } ++ ++#ifdef __linux__ ++ /* Backward-compatibility /proc support */ ++ for (i = 0; i < 8; i++) { ++ char proc_name[64], buf[512]; ++ char *driver, *pt, *devstring; ++ int retcode; ++ ++ sprintf(proc_name, "/proc/dri/%d/name", i); ++ if ((fd = open(proc_name, 0, 0)) >= 0) { ++ retcode = read(fd, buf, sizeof(buf)-1); ++ close(fd); ++ if (retcode) { ++ buf[retcode-1] = '\0'; ++ for (driver = pt = buf; *pt && *pt != ' '; ++pt) ++ ; ++ if (*pt) { /* Device is next */ ++ *pt = '\0'; ++ if (!strcmp(driver, name)) { /* Match */ ++ for (devstring = ++pt; *pt && *pt != ' '; ++pt) ++ ; ++ if (*pt) { /* Found busid */ ++ return drmOpenByBusid(++pt); ++ } else { /* No busid */ ++ return drmOpenDevice(strtol(devstring, NULL, 0),i); ++ } ++ } ++ } ++ } ++ } ++ } ++#endif ++ ++ return -1; ++} ++ ++/* drmOpen looks up the specified name and busid, and opens the device ++ found. The entry in /dev/dri is created if necessary (and if root). ++ A file descriptor is returned. On error, the return value is ++ negative. */ ++ ++int drmOpen(const char *name, const char *busid) ++{ ++ ++ if (busid) return drmOpenByBusid(busid); ++ return drmOpenByName(name); ++} ++ ++void drmFreeVersion(drmVersionPtr v) ++{ ++ if (!v) return; ++ if (v->name) drmFree(v->name); ++ if (v->date) drmFree(v->date); ++ if (v->desc) drmFree(v->desc); ++ drmFree(v); ++} ++ ++static void drmFreeKernelVersion(drm_version_t *v) ++{ ++ if (!v) return; ++ if (v->name) drmFree(v->name); ++ if (v->date) drmFree(v->date); ++ if (v->desc) drmFree(v->desc); ++ drmFree(v); ++} ++ ++static void drmCopyVersion(drmVersionPtr d, const drm_version_t *s) ++{ ++ d->version_major = s->version_major; ++ d->version_minor = s->version_minor; ++ d->version_patchlevel = s->version_patchlevel; ++ d->name_len = s->name_len; ++ d->name = drmStrdup(s->name); ++ d->date_len = s->date_len; ++ d->date = drmStrdup(s->date); ++ d->desc_len = s->desc_len; ++ d->desc = drmStrdup(s->desc); ++} ++ ++/* drmGet Version obtains the driver version information via an ioctl. Similar ++ * information is available via /proc/dri. */ ++ ++drmVersionPtr drmGetVersion(int fd) ++{ ++ drmVersionPtr retval; ++ drm_version_t *version = drmMalloc(sizeof(*version)); ++ ++ /* First, get the lengths */ ++ version->name_len = 0; ++ version->name = NULL; ++ version->date_len = 0; ++ version->date = NULL; ++ version->desc_len = 0; ++ version->desc = NULL; ++ ++ if (ioctl(fd, DRM_IOCTL_VERSION, version)) { ++ drmFreeKernelVersion(version); ++ return NULL; ++ } ++ ++ /* Now, allocate space and get the data */ ++ if (version->name_len) ++ version->name = drmMalloc(version->name_len + 1); ++ if (version->date_len) ++ version->date = drmMalloc(version->date_len + 1); ++ if (version->desc_len) ++ version->desc = drmMalloc(version->desc_len + 1); ++ ++ if (ioctl(fd, DRM_IOCTL_VERSION, version)) { ++ drmFreeKernelVersion(version); ++ return NULL; ++ } ++ ++ /* The results might not be null-terminated ++ strings, so terminate them. */ ++ ++ if (version->name_len) version->name[version->name_len] = '\0'; ++ if (version->date_len) version->date[version->date_len] = '\0'; ++ if (version->desc_len) version->desc[version->desc_len] = '\0'; ++ ++ /* Now, copy it all back into the ++ client-visible data structure... */ ++ retval = drmMalloc(sizeof(*retval)); ++ drmCopyVersion(retval, version); ++ drmFreeKernelVersion(version); ++ return retval; ++} ++ ++/* drmGetLibVersion set version information for the drm user space library. ++ * this version number is driver indepedent */ ++ ++drmVersionPtr drmGetLibVersion(int fd) ++{ ++ drm_version_t *version = drmMalloc(sizeof(*version)); ++ ++ /* Version history: ++ * revision 1.0.x = original DRM interface with no drmGetLibVersion ++ * entry point and many drm<Device> extensions ++ * revision 1.1.x = added drmCommand entry points for device extensions ++ * added drmGetLibVersion to identify libdrm.a version ++ */ ++ version->version_major = 1; ++ version->version_minor = 1; ++ version->version_patchlevel = 0; ++ ++ return (drmVersionPtr)version; ++} ++ ++void drmFreeBusid(const char *busid) ++{ ++ drmFree((void *)busid); ++} ++ ++char *drmGetBusid(int fd) ++{ ++ drm_unique_t u; ++ ++ u.unique_len = 0; ++ u.unique = NULL; ++ ++ if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) return NULL; ++ u.unique = drmMalloc(u.unique_len + 1); ++ if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) return NULL; ++ u.unique[u.unique_len] = '\0'; ++ return u.unique; ++} ++ ++int drmSetBusid(int fd, const char *busid) ++{ ++ drm_unique_t u; ++ ++ u.unique = (char *)busid; ++ u.unique_len = strlen(busid); ++ ++ if (ioctl(fd, DRM_IOCTL_SET_UNIQUE, &u)) { ++ return -errno; ++ } ++ return 0; ++} ++ ++int drmGetMagic(int fd, drmMagicPtr magic) ++{ ++ drm_auth_t auth; ++ ++ *magic = 0; ++ if (ioctl(fd, DRM_IOCTL_GET_MAGIC, &auth)) return -errno; ++ *magic = auth.magic; ++ return 0; ++} ++ ++int drmAuthMagic(int fd, drmMagic magic) ++{ ++ drm_auth_t auth; ++ ++ auth.magic = magic; ++ if (ioctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth)) return -errno; ++ return 0; ++} ++ ++int drmAddMap(int fd, ++ drmHandle offset, ++ drmSize size, ++ drmMapType type, ++ drmMapFlags flags, ++ drmHandlePtr handle) ++{ ++ drm_map_t map; ++ ++ map.offset = offset; ++/* No longer needed with CVS kernel modules on alpha ++#ifdef __alpha__ ++ if (type != DRM_SHM) ++ map.offset += BUS_BASE; ++#endif ++*/ ++ map.size = size; ++ map.handle = 0; ++ map.type = type; ++ map.flags = flags; ++ if (ioctl(fd, DRM_IOCTL_ADD_MAP, &map)) return -errno; ++ if (handle) *handle = (drmHandle)map.handle; ++ return 0; ++} ++ ++int drmRmMap(int fd, drmHandle handle) ++{ ++ drm_map_t map; ++ ++ map.handle = (void *)handle; ++ ++ if(ioctl(fd, DRM_IOCTL_RM_MAP, &map)) return -errno; ++ return 0; ++} ++ ++int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags, ++ int agp_offset) ++{ ++ drm_buf_desc_t request; ++ ++ request.count = count; ++ request.size = size; ++ request.low_mark = 0; ++ request.high_mark = 0; ++ request.flags = flags; ++ request.agp_start = agp_offset; ++ ++ if (ioctl(fd, DRM_IOCTL_ADD_BUFS, &request)) return -errno; ++ return request.count; ++} ++ ++int drmMarkBufs(int fd, double low, double high) ++{ ++ drm_buf_info_t info; ++ int i; ++ ++ info.count = 0; ++ info.list = NULL; ++ ++ if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) return -EINVAL; ++ ++ if (!info.count) return -EINVAL; ++ ++ if (!(info.list = drmMalloc(info.count * sizeof(*info.list)))) ++ return -ENOMEM; ++ ++ if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) { ++ int retval = -errno; ++ drmFree(info.list); ++ return retval; ++ } ++ ++ for (i = 0; i < info.count; i++) { ++ info.list[i].low_mark = low * info.list[i].count; ++ info.list[i].high_mark = high * info.list[i].count; ++ if (ioctl(fd, DRM_IOCTL_MARK_BUFS, &info.list[i])) { ++ int retval = -errno; ++ drmFree(info.list); ++ return retval; ++ } ++ } ++ drmFree(info.list); ++ ++ return 0; ++} ++ ++int drmFreeBufs(int fd, int count, int *list) ++{ ++ drm_buf_free_t request; ++ ++ request.count = count; ++ request.list = list; ++ if (ioctl(fd, DRM_IOCTL_FREE_BUFS, &request)) return -errno; ++ return 0; ++} ++ ++int drmClose(int fd) ++{ ++ unsigned long key = drmGetKeyFromFd(fd); ++ drmHashEntry *entry = drmGetEntry(fd); ++ ++ drmHashDestroy(entry->tagTable); ++ entry->fd = 0; ++ entry->f = NULL; ++ entry->tagTable = NULL; ++ ++ drmHashDelete(drmHashTable, key); ++ drmFree(entry); ++ ++ return close(fd); ++} ++ ++int drmMap(int fd, ++ drmHandle handle, ++ drmSize size, ++ drmAddressPtr address) ++{ ++ static unsigned long pagesize_mask = 0; ++ ++ if (fd < 0) return -EINVAL; ++ ++ if (!pagesize_mask) ++ pagesize_mask = getpagesize() - 1; ++ ++ size = (size + pagesize_mask) & ~pagesize_mask; ++ ++ *address = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle); ++ if (*address == MAP_FAILED) return -errno; ++ return 0; ++} ++ ++int drmUnmap(drmAddress address, drmSize size) ++{ ++ return munmap(address, size); ++} ++ ++drmBufInfoPtr drmGetBufInfo(int fd) ++{ ++ drm_buf_info_t info; ++ drmBufInfoPtr retval; ++ int i; ++ ++ info.count = 0; ++ info.list = NULL; ++ ++ if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) return NULL; ++ ++ if (info.count) { ++ if (!(info.list = drmMalloc(info.count * sizeof(*info.list)))) ++ return NULL; ++ ++ if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) { ++ drmFree(info.list); ++ return NULL; ++ } ++ /* Now, copy it all back into the ++ client-visible data structure... */ ++ retval = drmMalloc(sizeof(*retval)); ++ retval->count = info.count; ++ retval->list = drmMalloc(info.count * sizeof(*retval->list)); ++ for (i = 0; i < info.count; i++) { ++ retval->list[i].count = info.list[i].count; ++ retval->list[i].size = info.list[i].size; ++ retval->list[i].low_mark = info.list[i].low_mark; ++ retval->list[i].high_mark = info.list[i].high_mark; ++ } ++ drmFree(info.list); ++ return retval; ++ } ++ return NULL; ++} ++ ++drmBufMapPtr drmMapBufs(int fd) ++{ ++ drm_buf_map_t bufs; ++ drmBufMapPtr retval; ++ int i; ++ ++ bufs.count = 0; ++ bufs.list = NULL; ++ if (ioctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) return NULL; ++ ++ if (bufs.count) { ++ if (!(bufs.list = drmMalloc(bufs.count * sizeof(*bufs.list)))) ++ return NULL; ++ ++ if (ioctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) { ++ drmFree(bufs.list); ++ return NULL; ++ } ++ /* Now, copy it all back into the ++ client-visible data structure... */ ++ retval = drmMalloc(sizeof(*retval)); ++ retval->count = bufs.count; ++ retval->list = drmMalloc(bufs.count * sizeof(*retval->list)); ++ for (i = 0; i < bufs.count; i++) { ++ retval->list[i].idx = bufs.list[i].idx; ++ retval->list[i].total = bufs.list[i].total; ++ retval->list[i].used = 0; ++ retval->list[i].address = bufs.list[i].address; ++ } ++ return retval; ++ } ++ return NULL; ++} ++ ++int drmUnmapBufs(drmBufMapPtr bufs) ++{ ++ int i; ++ ++ for (i = 0; i < bufs->count; i++) { ++ munmap(bufs->list[i].address, bufs->list[i].total); ++ } ++ return 0; ++} ++ ++#define DRM_DMA_RETRY 16 ++ ++int drmDMA(int fd, drmDMAReqPtr request) ++{ ++ drm_dma_t dma; ++ int ret, i = 0; ++ ++ /* Copy to hidden structure */ ++ dma.context = request->context; ++ dma.send_count = request->send_count; ++ dma.send_indices = request->send_list; ++ dma.send_sizes = request->send_sizes; ++ dma.flags = request->flags; ++ dma.request_count = request->request_count; ++ dma.request_size = request->request_size; ++ dma.request_indices = request->request_list; ++ dma.request_sizes = request->request_sizes; ++ ++ do { ++ ret = ioctl( fd, DRM_IOCTL_DMA, &dma ); ++ } while ( ret && errno == EAGAIN && i++ < DRM_DMA_RETRY ); ++ ++ if ( ret == 0 ) { ++ request->granted_count = dma.granted_count; ++ return 0; ++ } else { ++ return -errno; ++ } ++} ++ ++int drmGetLock(int fd, drmContext context, drmLockFlags flags) ++{ ++ drm_lock_t lock; ++ ++ lock.context = context; ++ lock.flags = 0; ++ if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY; ++ if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT; ++ if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH; ++ if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL; ++ if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES; ++ if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES; ++ ++ while (ioctl(fd, DRM_IOCTL_LOCK, &lock)) ++ ; ++ return 0; ++} ++ ++int drmUnlock(int fd, drmContext context) ++{ ++ drm_lock_t lock; ++ ++ lock.context = context; ++ lock.flags = 0; ++ return ioctl(fd, DRM_IOCTL_UNLOCK, &lock); ++} ++ ++drmContextPtr drmGetReservedContextList(int fd, int *count) ++{ ++ drm_ctx_res_t res; ++ drm_ctx_t *list; ++ drmContextPtr retval; ++ int i; ++ ++ res.count = 0; ++ res.contexts = NULL; ++ if (ioctl(fd, DRM_IOCTL_RES_CTX, &res)) return NULL; ++ ++ if (!res.count) return NULL; ++ ++ if (!(list = drmMalloc(res.count * sizeof(*list)))) return NULL; ++ if (!(retval = drmMalloc(res.count * sizeof(*retval)))) { ++ drmFree(list); ++ return NULL; ++ } ++ ++ res.contexts = list; ++ if (ioctl(fd, DRM_IOCTL_RES_CTX, &res)) return NULL; ++ ++ for (i = 0; i < res.count; i++) retval[i] = list[i].handle; ++ drmFree(list); ++ ++ *count = res.count; ++ return retval; ++} ++ ++void drmFreeReservedContextList(drmContextPtr pt) ++{ ++ drmFree(pt); ++} ++ ++int drmCreateContext(int fd, drmContextPtr handle) ++{ ++ drm_ctx_t ctx; ++ ++ ctx.flags = 0; /* Modified with functions below */ ++ if (ioctl(fd, DRM_IOCTL_ADD_CTX, &ctx)) return -errno; ++ *handle = ctx.handle; ++ return 0; ++} ++ ++int drmSwitchToContext(int fd, drmContext context) ++{ ++ drm_ctx_t ctx; ++ ++ ctx.handle = context; ++ if (ioctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx)) return -errno; ++ return 0; ++} ++ ++int drmSetContextFlags(int fd, drmContext context, drmContextFlags flags) ++{ ++ drm_ctx_t ctx; ++ ++ /* Context preserving means that no context ++ switched are done between DMA buffers ++ from one context and the next. This is ++ suitable for use in the X server (which ++ promises to maintain hardware context, ++ or in the client-side library when ++ buffers are swapped on behalf of two ++ threads. */ ++ ctx.handle = context; ++ ctx.flags = 0; ++ if (flags & DRM_CONTEXT_PRESERVED) ctx.flags |= _DRM_CONTEXT_PRESERVED; ++ if (flags & DRM_CONTEXT_2DONLY) ctx.flags |= _DRM_CONTEXT_2DONLY; ++ if (ioctl(fd, DRM_IOCTL_MOD_CTX, &ctx)) return -errno; ++ return 0; ++} ++ ++int drmGetContextFlags(int fd, drmContext context, drmContextFlagsPtr flags) ++{ ++ drm_ctx_t ctx; ++ ++ ctx.handle = context; ++ if (ioctl(fd, DRM_IOCTL_GET_CTX, &ctx)) return -errno; ++ *flags = 0; ++ if (ctx.flags & _DRM_CONTEXT_PRESERVED) *flags |= DRM_CONTEXT_PRESERVED; ++ if (ctx.flags & _DRM_CONTEXT_2DONLY) *flags |= DRM_CONTEXT_2DONLY; ++ return 0; ++} ++ ++int drmDestroyContext(int fd, drmContext handle) ++{ ++ drm_ctx_t ctx; ++ ctx.handle = handle; ++ if (ioctl(fd, DRM_IOCTL_RM_CTX, &ctx)) return -errno; ++ return 0; ++} ++ ++int drmCreateDrawable(int fd, drmDrawablePtr handle) ++{ ++ drm_draw_t draw; ++ if (ioctl(fd, DRM_IOCTL_ADD_DRAW, &draw)) return -errno; ++ *handle = draw.handle; ++ return 0; ++} ++ ++int drmDestroyDrawable(int fd, drmDrawable handle) ++{ ++ drm_draw_t draw; ++ draw.handle = handle; ++ if (ioctl(fd, DRM_IOCTL_RM_DRAW, &draw)) return -errno; ++ return 0; ++} ++ ++int drmAgpAcquire(int fd) ++{ ++ if (ioctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL)) return -errno; ++ return 0; ++} ++ ++int drmAgpRelease(int fd) ++{ ++ if (ioctl(fd, DRM_IOCTL_AGP_RELEASE, NULL)) return -errno; ++ return 0; ++} ++ ++int drmAgpEnable(int fd, unsigned long mode) ++{ ++ drm_agp_mode_t m; ++ ++ m.mode = mode; ++ if (ioctl(fd, DRM_IOCTL_AGP_ENABLE, &m)) return -errno; ++ return 0; ++} ++ ++int drmAgpAlloc(int fd, unsigned long size, unsigned long type, ++ unsigned long *address, unsigned long *handle) ++{ ++ drm_agp_buffer_t b; ++ *handle = 0; ++ b.size = size; ++ b.handle = 0; ++ b.type = type; ++ if (ioctl(fd, DRM_IOCTL_AGP_ALLOC, &b)) return -errno; ++ if (address != 0UL) *address = b.physical; ++ *handle = b.handle; ++ return 0; ++} ++ ++int drmAgpFree(int fd, unsigned long handle) ++{ ++ drm_agp_buffer_t b; ++ ++ b.size = 0; ++ b.handle = handle; ++ if (ioctl(fd, DRM_IOCTL_AGP_FREE, &b)) return -errno; ++ return 0; ++} ++ ++int drmAgpBind(int fd, unsigned long handle, unsigned long offset) ++{ ++ drm_agp_binding_t b; ++ ++ b.handle = handle; ++ b.offset = offset; ++ if (ioctl(fd, DRM_IOCTL_AGP_BIND, &b)) return -errno; ++ return 0; ++} ++ ++int drmAgpUnbind(int fd, unsigned long handle) ++{ ++ drm_agp_binding_t b; ++ ++ b.handle = handle; ++ b.offset = 0; ++ if (ioctl(fd, DRM_IOCTL_AGP_UNBIND, &b)) return -errno; ++ return 0; ++} ++ ++int drmAgpVersionMajor(int fd) ++{ ++ drm_agp_info_t i; ++ ++ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno; ++ return i.agp_version_major; ++} ++ ++int drmAgpVersionMinor(int fd) ++{ ++ drm_agp_info_t i; ++ ++ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno; ++ return i.agp_version_minor; ++} ++ ++unsigned long drmAgpGetMode(int fd) ++{ ++ drm_agp_info_t i; ++ ++ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; ++ return i.mode; ++} ++ ++unsigned long drmAgpBase(int fd) ++{ ++ drm_agp_info_t i; ++ ++ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; ++ return i.aperture_base; ++} ++ ++unsigned long drmAgpSize(int fd) ++{ ++ drm_agp_info_t i; ++ ++ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; ++ return i.aperture_size; ++} ++ ++unsigned long drmAgpMemoryUsed(int fd) ++{ ++ drm_agp_info_t i; ++ ++ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; ++ return i.memory_used; ++} ++ ++unsigned long drmAgpMemoryAvail(int fd) ++{ ++ drm_agp_info_t i; ++ ++ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; ++ return i.memory_allowed; ++} ++ ++unsigned int drmAgpVendorId(int fd) ++{ ++ drm_agp_info_t i; ++ ++ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; ++ return i.id_vendor; ++} ++ ++unsigned int drmAgpDeviceId(int fd) ++{ ++ drm_agp_info_t i; ++ ++ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; ++ return i.id_device; ++} ++ ++int drmScatterGatherAlloc(int fd, unsigned long size, unsigned long *handle) ++{ ++ drm_scatter_gather_t sg; ++ ++ *handle = 0; ++ sg.size = size; ++ sg.handle = 0; ++ if (ioctl(fd, DRM_IOCTL_SG_ALLOC, &sg)) return -errno; ++ *handle = sg.handle; ++ return 0; ++} ++ ++int drmScatterGatherFree(int fd, unsigned long handle) ++{ ++ drm_scatter_gather_t sg; ++ ++ sg.size = 0; ++ sg.handle = handle; ++ if (ioctl(fd, DRM_IOCTL_SG_FREE, &sg)) return -errno; ++ return 0; ++} ++ ++int drmWaitVBlank(int fd, drmVBlankPtr vbl) ++{ ++ int ret; ++ ++ do { ++ ret = ioctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl); ++ vbl->request.type &= ~DRM_VBLANK_RELATIVE; ++ } while (ret && errno == EINTR); ++ ++ return ret; ++} ++ ++int drmError(int err, const char *label) ++{ ++ switch (err) { ++ case DRM_ERR_NO_DEVICE: fprintf(stderr, "%s: no device\n", label); break; ++ case DRM_ERR_NO_ACCESS: fprintf(stderr, "%s: no access\n", label); break; ++ case DRM_ERR_NOT_ROOT: fprintf(stderr, "%s: not root\n", label); break; ++ case DRM_ERR_INVALID: fprintf(stderr, "%s: invalid args\n", label);break; ++ default: ++ if (err < 0) err = -err; ++ fprintf( stderr, "%s: error %d (%s)\n", label, err, strerror(err) ); ++ break; ++ } ++ ++ return 1; ++} ++ ++int drmCtlInstHandler(int fd, int irq) ++{ ++ drm_control_t ctl; ++ ++ ctl.func = DRM_INST_HANDLER; ++ ctl.irq = irq; ++ if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl)) return -errno; ++ return 0; ++} ++ ++int drmCtlUninstHandler(int fd) ++{ ++ drm_control_t ctl; ++ ++ ctl.func = DRM_UNINST_HANDLER; ++ ctl.irq = 0; ++ if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl)) return -errno; ++ return 0; ++} ++ ++int drmFinish(int fd, int context, drmLockFlags flags) ++{ ++ drm_lock_t lock; ++ ++ lock.context = context; ++ lock.flags = 0; ++ if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY; ++ if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT; ++ if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH; ++ if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL; ++ if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES; ++ if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES; ++ if (ioctl(fd, DRM_IOCTL_FINISH, &lock)) return -errno; ++ return 0; ++} ++ ++int drmGetInterruptFromBusID(int fd, int busnum, int devnum, int funcnum) ++{ ++ drm_irq_busid_t p; ++ ++ p.busnum = busnum; ++ p.devnum = devnum; ++ p.funcnum = funcnum; ++ if (ioctl(fd, DRM_IOCTL_IRQ_BUSID, &p)) return -errno; ++ return p.irq; ++} ++ ++int drmAddContextTag(int fd, drmContext context, void *tag) ++{ ++ drmHashEntry *entry = drmGetEntry(fd); ++ ++ if (drmHashInsert(entry->tagTable, context, tag)) { ++ drmHashDelete(entry->tagTable, context); ++ drmHashInsert(entry->tagTable, context, tag); ++ } ++ return 0; ++} ++ ++int drmDelContextTag(int fd, drmContext context) ++{ ++ drmHashEntry *entry = drmGetEntry(fd); ++ ++ return drmHashDelete(entry->tagTable, context); ++} ++ ++void *drmGetContextTag(int fd, drmContext context) ++{ ++ drmHashEntry *entry = drmGetEntry(fd); ++ void *value; ++ ++ if (drmHashLookup(entry->tagTable, context, &value)) return NULL; ++ ++ return value; ++} ++ ++int drmAddContextPrivateMapping(int fd, drmContext ctx_id, drmHandle handle) ++{ ++ drm_ctx_priv_map_t map; ++ ++ map.ctx_id = ctx_id; ++ map.handle = (void *)handle; ++ ++ if (ioctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map)) return -errno; ++ return 0; ++} ++ ++int drmGetContextPrivateMapping(int fd, drmContext ctx_id, drmHandlePtr handle) ++{ ++ drm_ctx_priv_map_t map; ++ ++ map.ctx_id = ctx_id; ++ ++ if (ioctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map)) return -errno; ++ if (handle) *handle = (drmHandle)map.handle; ++ ++ return 0; ++} ++ ++int drmGetMap(int fd, int idx, drmHandle *offset, drmSize *size, ++ drmMapType *type, drmMapFlags *flags, drmHandle *handle, ++ int *mtrr) ++{ ++ drm_map_t map; ++ ++ map.offset = idx; ++ if (ioctl(fd, DRM_IOCTL_GET_MAP, &map)) return -errno; ++ *offset = map.offset; ++ *size = map.size; ++ *type = map.type; ++ *flags = map.flags; ++ *handle = (unsigned long)map.handle; ++ *mtrr = map.mtrr; ++ return 0; ++} ++ ++int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid, ++ unsigned long *magic, unsigned long *iocs) ++{ ++ drm_client_t client; ++ ++ client.idx = idx; ++ if (ioctl(fd, DRM_IOCTL_GET_CLIENT, &client)) return -errno; ++ *auth = client.auth; ++ *pid = client.pid; ++ *uid = client.uid; ++ *magic = client.magic; ++ *iocs = client.iocs; ++ return 0; ++} ++ ++int drmGetStats(int fd, drmStatsT *stats) ++{ ++ drm_stats_t s; ++ int i; ++ ++ if (ioctl(fd, DRM_IOCTL_GET_STATS, &s)) return -errno; ++ ++ stats->count = 0; ++ memset(stats, 0, sizeof(*stats)); ++ if (s.count > sizeof(stats->data)/sizeof(stats->data[0])) ++ return -1; ++ ++#define SET_VALUE \ ++ stats->data[i].long_format = "%-20.20s"; \ ++ stats->data[i].rate_format = "%8.8s"; \ ++ stats->data[i].isvalue = 1; \ ++ stats->data[i].verbose = 0 ++ ++#define SET_COUNT \ ++ stats->data[i].long_format = "%-20.20s"; \ ++ stats->data[i].rate_format = "%5.5s"; \ ++ stats->data[i].isvalue = 0; \ ++ stats->data[i].mult_names = "kgm"; \ ++ stats->data[i].mult = 1000; \ ++ stats->data[i].verbose = 0 ++ ++#define SET_BYTE \ ++ stats->data[i].long_format = "%-20.20s"; \ ++ stats->data[i].rate_format = "%5.5s"; \ ++ stats->data[i].isvalue = 0; \ ++ stats->data[i].mult_names = "KGM"; \ ++ stats->data[i].mult = 1024; \ ++ stats->data[i].verbose = 0 ++ ++ ++ stats->count = s.count; ++ for (i = 0; i < s.count; i++) { ++ stats->data[i].value = s.data[i].value; ++ switch (s.data[i].type) { ++ case _DRM_STAT_LOCK: ++ stats->data[i].long_name = "Lock"; ++ stats->data[i].rate_name = "Lock"; ++ SET_VALUE; ++ break; ++ case _DRM_STAT_OPENS: ++ stats->data[i].long_name = "Opens"; ++ stats->data[i].rate_name = "O"; ++ SET_COUNT; ++ stats->data[i].verbose = 1; ++ break; ++ case _DRM_STAT_CLOSES: ++ stats->data[i].long_name = "Closes"; ++ stats->data[i].rate_name = "Lock"; ++ SET_COUNT; ++ stats->data[i].verbose = 1; ++ break; ++ case _DRM_STAT_IOCTLS: ++ stats->data[i].long_name = "Ioctls"; ++ stats->data[i].rate_name = "Ioc/s"; ++ SET_COUNT; ++ break; ++ case _DRM_STAT_LOCKS: ++ stats->data[i].long_name = "Locks"; ++ stats->data[i].rate_name = "Lck/s"; ++ SET_COUNT; ++ break; ++ case _DRM_STAT_UNLOCKS: ++ stats->data[i].long_name = "Unlocks"; ++ stats->data[i].rate_name = "Unl/s"; ++ SET_COUNT; ++ break; ++ case _DRM_STAT_IRQ: ++ stats->data[i].long_name = "IRQs"; ++ stats->data[i].rate_name = "IRQ/s"; ++ SET_COUNT; ++ break; ++ case _DRM_STAT_PRIMARY: ++ stats->data[i].long_name = "Primary Bytes"; ++ stats->data[i].rate_name = "PB/s"; ++ SET_BYTE; ++ break; ++ case _DRM_STAT_SECONDARY: ++ stats->data[i].long_name = "Secondary Bytes"; ++ stats->data[i].rate_name = "SB/s"; ++ SET_BYTE; ++ break; ++ case _DRM_STAT_DMA: ++ stats->data[i].long_name = "DMA"; ++ stats->data[i].rate_name = "DMA/s"; ++ SET_COUNT; ++ break; ++ case _DRM_STAT_SPECIAL: ++ stats->data[i].long_name = "Special DMA"; ++ stats->data[i].rate_name = "dma/s"; ++ SET_COUNT; ++ break; ++ case _DRM_STAT_MISSED: ++ stats->data[i].long_name = "Miss"; ++ stats->data[i].rate_name = "Ms/s"; ++ SET_COUNT; ++ break; ++ case _DRM_STAT_VALUE: ++ stats->data[i].long_name = "Value"; ++ stats->data[i].rate_name = "Value"; ++ SET_VALUE; ++ break; ++ case _DRM_STAT_BYTE: ++ stats->data[i].long_name = "Bytes"; ++ stats->data[i].rate_name = "B/s"; ++ SET_BYTE; ++ break; ++ case _DRM_STAT_COUNT: ++ default: ++ stats->data[i].long_name = "Count"; ++ stats->data[i].rate_name = "Cnt/s"; ++ SET_COUNT; ++ break; ++ } ++ } ++ return 0; ++} ++ ++int drmCommandNone(int fd, unsigned long drmCommandIndex) ++{ ++ void *data = NULL; /* dummy */ ++ unsigned long request; ++ ++ request = DRM_IO( DRM_COMMAND_BASE + drmCommandIndex); ++ ++ if (ioctl(fd, request, data)) { ++ return -errno; ++ } ++ return 0; ++} ++ ++int drmCommandRead(int fd, unsigned long drmCommandIndex, ++ void *data, unsigned long size ) ++{ ++ unsigned long request; ++ ++ request = DRM_IOC( DRM_IOC_READ, DRM_IOCTL_BASE, ++ DRM_COMMAND_BASE + drmCommandIndex, size); ++ ++ if (ioctl(fd, request, data)) { ++ return -errno; ++ } ++ return 0; ++} ++ ++int drmCommandWrite(int fd, unsigned long drmCommandIndex, ++ void *data, unsigned long size ) ++{ ++ unsigned long request; ++ ++ request = DRM_IOC( DRM_IOC_WRITE, DRM_IOCTL_BASE, ++ DRM_COMMAND_BASE + drmCommandIndex, size); ++ ++ if (ioctl(fd, request, data)) { ++ return -errno; ++ } ++ return 0; ++} ++ ++int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, ++ void *data, unsigned long size ) ++{ ++ unsigned long request; ++ ++ request = DRM_IOC( DRM_IOC_READ|DRM_IOC_WRITE, DRM_IOCTL_BASE, ++ DRM_COMMAND_BASE + drmCommandIndex, size); ++ ++ if (ioctl(fd, request, data)) { ++ return -errno; ++ } ++ return 0; ++} ++ ++#if defined(XFree86Server) || defined(DRM_USE_MALLOC) ++static void drmSIGIOHandler(int interrupt, void *closure) ++{ ++ unsigned long key; ++ void *value; ++ ssize_t count; ++ drm_ctx_t ctx; ++ typedef void (*_drmCallback)(int, void *, void *); ++ char buf[256]; ++ drmContext old; ++ drmContext new; ++ void *oldctx; ++ void *newctx; ++ char *pt; ++ drmHashEntry *entry; ++ ++ if (!drmHashTable) return; ++ if (drmHashFirst(drmHashTable, &key, &value)) { ++ entry = value; ++ do { ++#if 0 ++ fprintf(stderr, "Trying %d\n", entry->fd); ++#endif ++ if ((count = read(entry->fd, buf, sizeof(buf)))) { ++ buf[count] = '\0'; ++#if 0 ++ fprintf(stderr, "Got %s\n", buf); ++#endif ++ ++ for (pt = buf; *pt != ' '; ++pt); /* Find first space */ ++ ++pt; ++ old = strtol(pt, &pt, 0); ++ new = strtol(pt, NULL, 0); ++ oldctx = drmGetContextTag(entry->fd, old); ++ newctx = drmGetContextTag(entry->fd, new); ++#if 0 ++ fprintf(stderr, "%d %d %p %p\n", old, new, oldctx, newctx); ++#endif ++ ((_drmCallback)entry->f)(entry->fd, oldctx, newctx); ++ ctx.handle = new; ++ ioctl(entry->fd, DRM_IOCTL_NEW_CTX, &ctx); ++ } ++ } while (drmHashNext(drmHashTable, &key, &value)); ++ } ++} ++ ++int drmInstallSIGIOHandler(int fd, void (*f)(int, void *, void *)) ++{ ++ drmHashEntry *entry; ++ ++ entry = drmGetEntry(fd); ++ entry->f = f; ++ ++ return xf86InstallSIGIOHandler(fd, drmSIGIOHandler, 0); ++} ++ ++int drmRemoveSIGIOHandler(int fd) ++{ ++ drmHashEntry *entry = drmGetEntry(fd); ++ ++ entry->f = NULL; ++ ++ return xf86RemoveSIGIOHandler(fd); ++} ++#endif +diff -ruN modules/drm-trunk/xf86drm.h modules-dristat/drm-trunk/xf86drm.h +--- modules/drm-trunk/xf86drm.h 1970-01-01 01:00:00.000000000 +0100 ++++ modules-dristat/drm-trunk/xf86drm.h 2003-04-06 10:48:07.000000000 +0200 +@@ -0,0 +1,607 @@ ++/* xf86drm.h -- OS-independent header for DRM user-level library interface ++ * Created: Tue Jan 5 08:17:23 1999 by faith@precisioninsight.com ++ * ++ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. ++ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ * ++ * Author: Rickard E. (Rik) Faith <faith@valinux.com> ++ * ++ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h,v 1.21 2002/12/24 17:42:59 tsi Exp $ ++ * ++ */ ++ ++#ifndef _XF86DRM_H_ ++#define _XF86DRM_H_ ++ ++ /* Defaults, if nothing set in xf86config */ ++#define DRM_DEV_UID 0 ++#define DRM_DEV_GID 0 ++/* Default /dev/dri directory permissions 0755 */ ++#define DRM_DEV_DIRMODE \ ++ (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) ++#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) ++ ++#define DRM_DIR_NAME "/dev/dri" ++#define DRM_DEV_NAME "%s/card%d" ++#define DRM_PROC_NAME "/proc/dri/" /* For backware Linux compatibility */ ++ ++#define DRM_ERR_NO_DEVICE (-1001) ++#define DRM_ERR_NO_ACCESS (-1002) ++#define DRM_ERR_NOT_ROOT (-1003) ++#define DRM_ERR_INVALID (-1004) ++#define DRM_ERR_NO_FD (-1005) ++ ++typedef unsigned long drmHandle, *drmHandlePtr; /* To mapped regions */ ++typedef unsigned int drmSize, *drmSizePtr; /* For mapped regions */ ++typedef void *drmAddress, **drmAddressPtr; /* For mapped regions */ ++typedef unsigned int drmContext, *drmContextPtr; /* GLXContext handle */ ++typedef unsigned int drmDrawable, *drmDrawablePtr; /* Unused */ ++typedef unsigned int drmMagic, *drmMagicPtr; /* Magic for auth */ ++ ++typedef struct _drmVersion { ++ int version_major; /* Major version */ ++ int version_minor; /* Minor version */ ++ int version_patchlevel; /* Patch level */ ++ int name_len; /* Length of name buffer */ ++ char *name; /* Name of driver */ ++ int date_len; /* Length of date buffer */ ++ char *date; /* User-space buffer to hold date */ ++ int desc_len; /* Length of desc buffer */ ++ char *desc; /* User-space buffer to hold desc */ ++} drmVersion, *drmVersionPtr; ++ ++typedef struct _drmStats { ++ unsigned long count; /* Number of data */ ++ struct { ++ unsigned long value; /* Value from kernel */ ++ const char *long_format; /* Suggested format for long_name */ ++ const char *long_name; /* Long name for value */ ++ const char *rate_format; /* Suggested format for rate_name */ ++ const char *rate_name; /* Short name for value per second */ ++ int isvalue; /* True if value (vs. counter) */ ++ const char *mult_names; /* Multiplier names (e.g., "KGM") */ ++ int mult; /* Multiplier value (e.g., 1024) */ ++ int verbose; /* Suggest only in verbose output */ ++ } data[15]; ++} drmStatsT; ++ ++ ++ /* All of these enums *MUST* match with the ++ kernel implementation -- so do *NOT* ++ change them! (The drmlib implementation ++ will just copy the flags instead of ++ translating them.) */ ++typedef enum { ++ DRM_FRAME_BUFFER = 0, /* WC, no caching, no core dump */ ++ DRM_REGISTERS = 1, /* no caching, no core dump */ ++ DRM_SHM = 2, /* shared, cached */ ++ DRM_AGP = 3, /* AGP/GART */ ++ DRM_SCATTER_GATHER = 4 /* PCI scatter/gather */ ++} drmMapType; ++ ++typedef enum { ++ DRM_RESTRICTED = 0x0001, /* Cannot be mapped to client-virtual */ ++ DRM_READ_ONLY = 0x0002, /* Read-only in client-virtual */ ++ DRM_LOCKED = 0x0004, /* Physical pages locked */ ++ DRM_KERNEL = 0x0008, /* Kernel requires access */ ++ DRM_WRITE_COMBINING = 0x0010, /* Use write-combining, if available */ ++ DRM_CONTAINS_LOCK = 0x0020, /* SHM page that contains lock */ ++ DRM_REMOVABLE = 0x0040 /* Removable mapping */ ++} drmMapFlags; ++ ++typedef enum { /* These values *MUST* match drm.h */ ++ /* Flags for DMA buffer dispatch */ ++ DRM_DMA_BLOCK = 0x01, /* Block until buffer dispatched. Note, ++ the buffer may not yet have been ++ processed by the hardware -- getting a ++ hardware lock with the hardware ++ quiescent will ensure that the buffer ++ has been processed. */ ++ DRM_DMA_WHILE_LOCKED = 0x02, /* Dispatch while lock held */ ++ DRM_DMA_PRIORITY = 0x04, /* High priority dispatch */ ++ ++ /* Flags for DMA buffer request */ ++ DRM_DMA_WAIT = 0x10, /* Wait for free buffers */ ++ DRM_DMA_SMALLER_OK = 0x20, /* Smaller-than-requested buffers ok */ ++ DRM_DMA_LARGER_OK = 0x40 /* Larger-than-requested buffers ok */ ++} drmDMAFlags; ++ ++typedef enum { ++ DRM_PAGE_ALIGN = 0x01, ++ DRM_AGP_BUFFER = 0x02, ++ DRM_SG_BUFFER = 0x04 ++} drmBufDescFlags; ++ ++typedef enum { ++ DRM_LOCK_READY = 0x01, /* Wait until hardware is ready for DMA */ ++ DRM_LOCK_QUIESCENT = 0x02, /* Wait until hardware quiescent */ ++ DRM_LOCK_FLUSH = 0x04, /* Flush this context's DMA queue first */ ++ DRM_LOCK_FLUSH_ALL = 0x08, /* Flush all DMA queues first */ ++ /* These *HALT* flags aren't supported yet ++ -- they will be used to support the ++ full-screen DGA-like mode. */ ++ DRM_HALT_ALL_QUEUES = 0x10, /* Halt all current and future queues */ ++ DRM_HALT_CUR_QUEUES = 0x20 /* Halt all current queues */ ++} drmLockFlags; ++ ++typedef enum { ++ DRM_CONTEXT_PRESERVED = 0x01, /* This context is preserved and ++ never swapped. */ ++ DRM_CONTEXT_2DONLY = 0x02 /* This context is for 2D rendering only. */ ++} drmContextFlags, *drmContextFlagsPtr; ++ ++typedef struct _drmBufDesc { ++ int count; /* Number of buffers of this size */ ++ int size; /* Size in bytes */ ++ int low_mark; /* Low water mark */ ++ int high_mark; /* High water mark */ ++} drmBufDesc, *drmBufDescPtr; ++ ++typedef struct _drmBufInfo { ++ int count; /* Number of buffers described in list */ ++ drmBufDescPtr list; /* List of buffer descriptions */ ++} drmBufInfo, *drmBufInfoPtr; ++ ++typedef struct _drmBuf { ++ int idx; /* Index into master buflist */ ++ int total; /* Buffer size */ ++ int used; /* Amount of buffer in use (for DMA) */ ++ drmAddress address; /* Address */ ++} drmBuf, *drmBufPtr; ++ ++typedef struct _drmBufMap { ++ int count; /* Number of buffers mapped */ ++ drmBufPtr list; /* Buffers */ ++} drmBufMap, *drmBufMapPtr; ++ ++typedef struct _drmLock { ++ volatile unsigned int lock; ++ char padding[60]; ++ /* This is big enough for most current (and future?) architectures: ++ DEC Alpha: 32 bytes ++ Intel Merced: ? ++ Intel P5/PPro/PII/PIII: 32 bytes ++ Intel StrongARM: 32 bytes ++ Intel i386/i486: 16 bytes ++ MIPS: 32 bytes (?) ++ Motorola 68k: 16 bytes ++ Motorola PowerPC: 32 bytes ++ Sun SPARC: 32 bytes ++ */ ++} drmLock, *drmLockPtr; ++ ++typedef struct _drmDMAReq { ++ /* Indices here refer to the offset into ++ list in drmBufInfo */ ++ drmContext context; /* Context handle */ ++ int send_count; /* Number of buffers to send */ ++ int *send_list; /* List of handles to buffers */ ++ int *send_sizes; /* Lengths of data to send, in bytes */ ++ drmDMAFlags flags; /* Flags */ ++ int request_count; /* Number of buffers requested */ ++ int request_size; /* Desired size of buffers requested */ ++ int *request_list; /* Buffer information */ ++ int *request_sizes; /* Minimum acceptable sizes */ ++ int granted_count; /* Number of buffers granted at this size */ ++} drmDMAReq, *drmDMAReqPtr; ++ ++typedef struct _drmRegion { ++ drmHandle handle; ++ unsigned int offset; ++ drmSize size; ++ drmAddress map; ++} drmRegion, *drmRegionPtr; ++ ++typedef struct _drmTextureRegion { ++ unsigned char next; ++ unsigned char prev; ++ unsigned char in_use; ++ unsigned char padding; /* Explicitly pad this out */ ++ unsigned int age; ++} drmTextureRegion, *drmTextureRegionPtr; ++ ++ ++typedef struct _drmClipRect { ++ unsigned short x1; /* Upper left: inclusive */ ++ unsigned short y1; ++ unsigned short x2; /* Lower right: exclusive */ ++ unsigned short y2; ++} drmClipRect, *drmClipRectPtr; ++ ++ ++typedef enum { ++ DRM_VBLANK_ABSOLUTE = 0x0, /* Wait for specific vblank sequence number */ ++ DRM_VBLANK_RELATIVE = 0x1, /* Wait for given number of vblanks */ ++ DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */ ++} drmVBlankSeqType; ++ ++typedef struct _drmVBlankReq { ++ drmVBlankSeqType type; ++ unsigned int sequence; ++ unsigned long signal; ++} drmVBlankReq, *drmVBlankReqPtr; ++ ++typedef struct _drmVBlankReply { ++ drmVBlankSeqType type; ++ unsigned int sequence; ++ long tval_sec; ++ long tval_usec; ++} drmVBlankReply, *drmVBlankReplyPtr; ++ ++typedef union _drmVBlank { ++ drmVBlankReq request; ++ drmVBlankReply reply; ++} drmVBlank, *drmVBlankPtr; ++ ++ ++ ++#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) ++ ++#define DRM_LOCK_HELD 0x80000000 /* Hardware lock is held */ ++#define DRM_LOCK_CONT 0x40000000 /* Hardware lock is contended */ ++ ++#if defined(__GNUC__) && (__GNUC__ >= 2) ++# if defined(__i386) || defined(__x86_64__) ++ /* Reflect changes here to drmP.h */ ++#define DRM_CAS(lock,old,new,__ret) \ ++ do { \ ++ int __dummy; /* Can't mark eax as clobbered */ \ ++ __asm__ __volatile__( \ ++ "lock ; cmpxchg %4,%1\n\t" \ ++ "setnz %0" \ ++ : "=d" (__ret), \ ++ "=m" (__drm_dummy_lock(lock)), \ ++ "=a" (__dummy) \ ++ : "2" (old), \ ++ "r" (new)); \ ++ } while (0) ++ ++#elif defined(__alpha__) ++ ++#define DRM_CAS(lock, old, new, ret) \ ++ do { \ ++ int old32; \ ++ int cur32; \ ++ __asm__ __volatile__( \ ++ " mb\n" \ ++ " zap %4, 0xF0, %0\n" \ ++ " ldl_l %1, %2\n" \ ++ " zap %1, 0xF0, %1\n" \ ++ " cmpeq %0, %1, %1\n" \ ++ " beq %1, 1f\n" \ ++ " bis %5, %5, %1\n" \ ++ " stl_c %1, %2\n" \ ++ "1: xor %1, 1, %1\n" \ ++ " stl %1, %3" \ ++ : "+r" (old32), \ ++ "+&r" (cur32), \ ++ "=m" (__drm_dummy_lock(lock)),\ ++ "=m" (ret) \ ++ : "r" (old), \ ++ "r" (new)); \ ++ } while(0) ++ ++#elif defined(__sparc__) ++ ++#define DRM_CAS(lock,old,new,__ret) \ ++do { register unsigned int __old __asm("o0"); \ ++ register unsigned int __new __asm("o1"); \ ++ register volatile unsigned int *__lock __asm("o2"); \ ++ __old = old; \ ++ __new = new; \ ++ __lock = (volatile unsigned int *)lock; \ ++ __asm__ __volatile__( \ ++ /*"cas [%2], %3, %0"*/ \ ++ ".word 0xd3e29008\n\t" \ ++ /*"membar #StoreStore | #StoreLoad"*/ \ ++ ".word 0x8143e00a" \ ++ : "=&r" (__new) \ ++ : "0" (__new), \ ++ "r" (__lock), \ ++ "r" (__old) \ ++ : "memory"); \ ++ __ret = (__new != __old); \ ++} while(0) ++ ++#elif defined(__ia64__) ++ ++#if 0 ++/* this currently generates bad code (missing stop bits)... */ ++#include <ia64intrin.h> ++ ++#define DRM_CAS(lock,old,new,__ret) \ ++ do { \ ++ __ret = (__sync_val_compare_and_swap(&__drm_dummy_lock(lock), \ ++ (old), (new)) \ ++ != (old)); \ ++ } while (0) ++ ++#else ++#define DRM_CAS(lock,old,new,__ret) \ ++ do { \ ++ unsigned int __result, __old = (old); \ ++ __asm__ __volatile__( \ ++ "mf\n" \ ++ "mov ar.ccv=%2\n" \ ++ ";;\n" \ ++ "cmpxchg4.acq %0=%1,%3,ar.ccv" \ ++ : "=r" (__result), "=m" (__drm_dummy_lock(lock)) \ ++ : "r" (__old), "r" (new) \ ++ : "memory"); \ ++ __ret = (__result) != (__old); \ ++ } while (0) ++ ++#endif ++ ++#elif defined(__powerpc__) ++ ++#define DRM_CAS(lock,old,new,__ret) \ ++ do { \ ++ __asm__ __volatile__( \ ++ "sync;" \ ++ "0: lwarx %0,0,%1;" \ ++ " xor. %0,%3,%0;" \ ++ " bne 1f;" \ ++ " stwcx. %2,0,%1;" \ ++ " bne- 0b;" \ ++ "1: " \ ++ "sync;" \ ++ : "=&r"(__ret) \ ++ : "r"(lock), "r"(new), "r"(old) \ ++ : "cr0", "memory"); \ ++ } while (0) ++ ++#endif /* architecture */ ++#endif /* __GNUC__ >= 2 */ ++ ++#ifndef DRM_CAS ++#define DRM_CAS(lock,old,new,ret) do { ret=1; } while (0) /* FAST LOCK FAILS */ ++#endif ++ ++#if defined(__alpha__) || defined(__powerpc__) ++#define DRM_CAS_RESULT(_result) int _result ++#else ++#define DRM_CAS_RESULT(_result) char _result ++#endif ++ ++#define DRM_LIGHT_LOCK(fd,lock,context) \ ++ do { \ ++ DRM_CAS_RESULT(__ret); \ ++ DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \ ++ if (__ret) drmGetLock(fd,context,0); \ ++ } while(0) ++ ++ /* This one counts fast locks -- for ++ benchmarking only. */ ++#define DRM_LIGHT_LOCK_COUNT(fd,lock,context,count) \ ++ do { \ ++ DRM_CAS_RESULT(__ret); \ ++ DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \ ++ if (__ret) drmGetLock(fd,context,0); \ ++ else ++count; \ ++ } while(0) ++ ++#define DRM_LOCK(fd,lock,context,flags) \ ++ do { \ ++ if (flags) drmGetLock(fd,context,flags); \ ++ else DRM_LIGHT_LOCK(fd,lock,context); \ ++ } while(0) ++ ++#define DRM_UNLOCK(fd,lock,context) \ ++ do { \ ++ DRM_CAS_RESULT(__ret); \ ++ DRM_CAS(lock,DRM_LOCK_HELD|context,context,__ret); \ ++ if (__ret) drmUnlock(fd,context); \ ++ } while(0) ++ ++ /* Simple spin locks */ ++#define DRM_SPINLOCK(spin,val) \ ++ do { \ ++ DRM_CAS_RESULT(__ret); \ ++ do { \ ++ DRM_CAS(spin,0,val,__ret); \ ++ if (__ret) while ((spin)->lock); \ ++ } while (__ret); \ ++ } while(0) ++ ++#define DRM_SPINLOCK_TAKE(spin,val) \ ++ do { \ ++ DRM_CAS_RESULT(__ret); \ ++ int cur; \ ++ do { \ ++ cur = (*spin).lock; \ ++ DRM_CAS(spin,cur,val,__ret); \ ++ } while (__ret); \ ++ } while(0) ++ ++#define DRM_SPINLOCK_COUNT(spin,val,count,__ret) \ ++ do { \ ++ int __i; \ ++ __ret = 1; \ ++ for (__i = 0; __ret && __i < count; __i++) { \ ++ DRM_CAS(spin,0,val,__ret); \ ++ if (__ret) for (;__i < count && (spin)->lock; __i++); \ ++ } \ ++ } while(0) ++ ++#define DRM_SPINUNLOCK(spin,val) \ ++ do { \ ++ DRM_CAS_RESULT(__ret); \ ++ if ((*spin).lock == val) { /* else server stole lock */ \ ++ do { \ ++ DRM_CAS(spin,val,0,__ret); \ ++ } while (__ret); \ ++ } \ ++ } while(0) ++ ++/* General user-level programmer's API: unprivileged */ ++extern int drmAvailable(void); ++extern int drmOpen(const char *name, const char *busid); ++extern int drmClose(int fd); ++extern drmVersionPtr drmGetVersion(int fd); ++extern drmVersionPtr drmGetLibVersion(int fd); ++extern void drmFreeVersion(drmVersionPtr); ++extern int drmGetMagic(int fd, drmMagicPtr magic); ++extern char *drmGetBusid(int fd); ++extern int drmGetInterruptFromBusID(int fd, int busnum, int devnum, ++ int funcnum); ++extern int drmGetMap(int fd, int idx, drmHandle *offset, ++ drmSize *size, drmMapType *type, ++ drmMapFlags *flags, drmHandle *handle, ++ int *mtrr); ++extern int drmGetClient(int fd, int idx, int *auth, int *pid, ++ int *uid, unsigned long *magic, ++ unsigned long *iocs); ++extern int drmGetStats(int fd, drmStatsT *stats); ++extern int drmCommandNone(int fd, unsigned long drmCommandIndex); ++extern int drmCommandRead(int fd, unsigned long drmCommandIndex, ++ void *data, unsigned long size); ++extern int drmCommandWrite(int fd, unsigned long drmCommandIndex, ++ void *data, unsigned long size); ++extern int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, ++ void *data, unsigned long size); ++ ++/* General user-level programmer's API: X server (root) only */ ++extern void drmFreeBusid(const char *busid); ++extern int drmSetBusid(int fd, const char *busid); ++extern int drmAuthMagic(int fd, drmMagic magic); ++extern int drmAddMap(int fd, ++ drmHandle offset, ++ drmSize size, ++ drmMapType type, ++ drmMapFlags flags, ++ drmHandlePtr handle); ++extern int drmRmMap(int fd, drmHandle handle); ++extern int drmAddContextPrivateMapping(int fd, drmContext ctx_id, ++ drmHandle handle); ++ ++extern int drmAddBufs(int fd, int count, int size, ++ drmBufDescFlags flags, ++ int agp_offset); ++extern int drmMarkBufs(int fd, double low, double high); ++extern int drmCreateContext(int fd, drmContextPtr handle); ++extern int drmSetContextFlags(int fd, drmContext context, ++ drmContextFlags flags); ++extern int drmGetContextFlags(int fd, drmContext context, ++ drmContextFlagsPtr flags); ++extern int drmAddContextTag(int fd, drmContext context, void *tag); ++extern int drmDelContextTag(int fd, drmContext context); ++extern void *drmGetContextTag(int fd, drmContext context); ++extern drmContextPtr drmGetReservedContextList(int fd, int *count); ++extern void drmFreeReservedContextList(drmContextPtr); ++extern int drmSwitchToContext(int fd, drmContext context); ++extern int drmDestroyContext(int fd, drmContext handle); ++extern int drmCreateDrawable(int fd, drmDrawablePtr handle); ++extern int drmDestroyDrawable(int fd, drmDrawable handle); ++extern int drmCtlInstHandler(int fd, int irq); ++extern int drmCtlUninstHandler(int fd); ++extern int drmInstallSIGIOHandler(int fd, ++ void (*f)(int fd, ++ void *oldctx, ++ void *newctx)); ++extern int drmRemoveSIGIOHandler(int fd); ++ ++/* General user-level programmer's API: authenticated client and/or X */ ++extern int drmMap(int fd, ++ drmHandle handle, ++ drmSize size, ++ drmAddressPtr address); ++extern int drmUnmap(drmAddress address, drmSize size); ++extern drmBufInfoPtr drmGetBufInfo(int fd); ++extern drmBufMapPtr drmMapBufs(int fd); ++extern int drmUnmapBufs(drmBufMapPtr bufs); ++extern int drmDMA(int fd, drmDMAReqPtr request); ++extern int drmFreeBufs(int fd, int count, int *list); ++extern int drmGetLock(int fd, ++ drmContext context, ++ drmLockFlags flags); ++extern int drmUnlock(int fd, drmContext context); ++extern int drmFinish(int fd, int context, drmLockFlags flags); ++extern int drmGetContextPrivateMapping(int fd, drmContext ctx_id, ++ drmHandlePtr handle); ++ ++/* AGP/GART support: X server (root) only */ ++extern int drmAgpAcquire(int fd); ++extern int drmAgpRelease(int fd); ++extern int drmAgpEnable(int fd, unsigned long mode); ++extern int drmAgpAlloc(int fd, unsigned long size, ++ unsigned long type, unsigned long *address, ++ unsigned long *handle); ++extern int drmAgpFree(int fd, unsigned long handle); ++extern int drmAgpBind(int fd, unsigned long handle, ++ unsigned long offset); ++extern int drmAgpUnbind(int fd, unsigned long handle); ++ ++/* AGP/GART info: authenticated client and/or X */ ++extern int drmAgpVersionMajor(int fd); ++extern int drmAgpVersionMinor(int fd); ++extern unsigned long drmAgpGetMode(int fd); ++extern unsigned long drmAgpBase(int fd); /* Physical location */ ++extern unsigned long drmAgpSize(int fd); /* Bytes */ ++extern unsigned long drmAgpMemoryUsed(int fd); ++extern unsigned long drmAgpMemoryAvail(int fd); ++extern unsigned int drmAgpVendorId(int fd); ++extern unsigned int drmAgpDeviceId(int fd); ++ ++/* PCI scatter/gather support: X server (root) only */ ++extern int drmScatterGatherAlloc(int fd, unsigned long size, ++ unsigned long *handle); ++extern int drmScatterGatherFree(int fd, unsigned long handle); ++ ++extern int drmWaitVBlank(int fd, drmVBlankPtr vbl); ++ ++/* Support routines */ ++extern int drmError(int err, const char *label); ++extern void *drmMalloc(int size); ++extern void drmFree(void *pt); ++ ++/* Hash table routines */ ++extern void *drmHashCreate(void); ++extern int drmHashDestroy(void *t); ++extern int drmHashLookup(void *t, unsigned long key, void **value); ++extern int drmHashInsert(void *t, unsigned long key, void *value); ++extern int drmHashDelete(void *t, unsigned long key); ++extern int drmHashFirst(void *t, unsigned long *key, void **value); ++extern int drmHashNext(void *t, unsigned long *key, void **value); ++ ++/* PRNG routines */ ++extern void *drmRandomCreate(unsigned long seed); ++extern int drmRandomDestroy(void *state); ++extern unsigned long drmRandom(void *state); ++extern double drmRandomDouble(void *state); ++ ++/* Skip list routines */ ++ ++extern void *drmSLCreate(void); ++extern int drmSLDestroy(void *l); ++extern int drmSLLookup(void *l, unsigned long key, void **value); ++extern int drmSLInsert(void *l, unsigned long key, void *value); ++extern int drmSLDelete(void *l, unsigned long key); ++extern int drmSLNext(void *l, unsigned long *key, void **value); ++extern int drmSLFirst(void *l, unsigned long *key, void **value); ++extern void drmSLDump(void *l); ++extern int drmSLLookupNeighbors(void *l, unsigned long key, ++ unsigned long *prev_key, void **prev_value, ++ unsigned long *next_key, void **next_value); ++ ++#endif +diff -ruN modules/drm-trunk/xf86drmHash.c modules-dristat/drm-trunk/xf86drmHash.c +--- modules/drm-trunk/xf86drmHash.c 1970-01-01 01:00:00.000000000 +0100 ++++ modules-dristat/drm-trunk/xf86drmHash.c 2003-04-06 10:48:37.000000000 +0200 +@@ -0,0 +1,435 @@ ++/* xf86drmHash.c -- Small hash table support for integer -> integer mapping ++ * Created: Sun Apr 18 09:35:45 1999 by faith@precisioninsight.com ++ * ++ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Rickard E. (Rik) Faith <faith@valinux.com> ++ * ++ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmHash.c,v 1.4 2001/03/21 18:08:54 dawes Exp $ ++ * ++ * DESCRIPTION ++ * ++ * This file contains a straightforward implementation of a fixed-sized ++ * hash table using self-organizing linked lists [Knuth73, pp. 398-399] for ++ * collision resolution. There are two potentially interesting things ++ * about this implementation: ++ * ++ * 1) The table is power-of-two sized. Prime sized tables are more ++ * traditional, but do not have a significant advantage over power-of-two ++ * sized table, especially when double hashing is not used for collision ++ * resolution. ++ * ++ * 2) The hash computation uses a table of random integers [Hanson97, ++ * pp. 39-41]. ++ * ++ * FUTURE ENHANCEMENTS ++ * ++ * With a table size of 512, the current implementation is sufficient for a ++ * few hundred keys. Since this is well above the expected size of the ++ * tables for which this implementation was designed, the implementation of ++ * dynamic hash tables was postponed until the need arises. A common (and ++ * naive) approach to dynamic hash table implementation simply creates a ++ * new hash table when necessary, rehashes all the data into the new table, ++ * and destroys the old table. The approach in [Larson88] is superior in ++ * two ways: 1) only a portion of the table is expanded when needed, ++ * distributing the expansion cost over several insertions, and 2) portions ++ * of the table can be locked, enabling a scalable thread-safe ++ * implementation. ++ * ++ * REFERENCES ++ * ++ * [Hanson97] David R. Hanson. C Interfaces and Implementations: ++ * Techniques for Creating Reusable Software. Reading, Massachusetts: ++ * Addison-Wesley, 1997. ++ * ++ * [Knuth73] Donald E. Knuth. The Art of Computer Programming. Volume 3: ++ * Sorting and Searching. Reading, Massachusetts: Addison-Wesley, 1973. ++ * ++ * [Larson88] Per-Ake Larson. "Dynamic Hash Tables". CACM 31(4), April ++ * 1988, pp. 446-457. ++ * ++ */ ++ ++#define HASH_MAIN 0 ++ ++#if HASH_MAIN ++# include <stdio.h> ++# include <stdlib.h> ++#else ++# include "xf86drm.h" ++# ifdef XFree86LOADER ++# include "xf86.h" ++# include "xf86_ansic.h" ++# else ++# include <stdio.h> ++# include <stdlib.h> ++# endif ++#endif ++ ++#define N(x) drm##x ++ ++#define HASH_MAGIC 0xdeadbeef ++#define HASH_DEBUG 0 ++#define HASH_SIZE 512 /* Good for about 100 entries */ ++ /* If you change this value, you probably ++ have to change the HashHash hashing ++ function! */ ++ ++#if HASH_MAIN ++#define HASH_ALLOC malloc ++#define HASH_FREE free ++#define HASH_RANDOM_DECL ++#define HASH_RANDOM_INIT(seed) srandom(seed) ++#define HASH_RANDOM random() ++#else ++#define HASH_ALLOC drmMalloc ++#define HASH_FREE drmFree ++#define HASH_RANDOM_DECL void *state ++#define HASH_RANDOM_INIT(seed) state = drmRandomCreate(seed) ++#define HASH_RANDOM drmRandom(state) ++ ++#endif ++ ++typedef struct HashBucket { ++ unsigned long key; ++ void *value; ++ struct HashBucket *next; ++} HashBucket, *HashBucketPtr; ++ ++typedef struct HashTable { ++ unsigned long magic; ++ unsigned long entries; ++ unsigned long hits; /* At top of linked list */ ++ unsigned long partials; /* Not at top of linked list */ ++ unsigned long misses; /* Not in table */ ++ HashBucketPtr buckets[HASH_SIZE]; ++ int p0; ++ HashBucketPtr p1; ++} HashTable, *HashTablePtr; ++ ++#if HASH_MAIN ++extern void *N(HashCreate)(void); ++extern int N(HashDestroy)(void *t); ++extern int N(HashLookup)(void *t, unsigned long key, unsigned long *value); ++extern int N(HashInsert)(void *t, unsigned long key, unsigned long value); ++extern int N(HashDelete)(void *t, unsigned long key); ++#endif ++ ++static unsigned long HashHash(unsigned long key) ++{ ++ unsigned long hash = 0; ++ unsigned long tmp = key; ++ static int init = 0; ++ static unsigned long scatter[256]; ++ int i; ++ ++ if (!init) { ++ HASH_RANDOM_DECL; ++ HASH_RANDOM_INIT(37); ++ for (i = 0; i < 256; i++) scatter[i] = HASH_RANDOM; ++ ++init; ++ } ++ ++ while (tmp) { ++ hash = (hash << 1) + scatter[tmp & 0xff]; ++ tmp >>= 8; ++ } ++ ++ hash %= HASH_SIZE; ++#if HASH_DEBUG ++ printf( "Hash(%d) = %d\n", key, hash); ++#endif ++ return hash; ++} ++ ++void *N(HashCreate)(void) ++{ ++ HashTablePtr table; ++ int i; ++ ++ table = HASH_ALLOC(sizeof(*table)); ++ if (!table) return NULL; ++ table->magic = HASH_MAGIC; ++ table->entries = 0; ++ table->hits = 0; ++ table->partials = 0; ++ table->misses = 0; ++ ++ for (i = 0; i < HASH_SIZE; i++) table->buckets[i] = NULL; ++ return table; ++} ++ ++int N(HashDestroy)(void *t) ++{ ++ HashTablePtr table = (HashTablePtr)t; ++ HashBucketPtr bucket; ++ HashBucketPtr next; ++ int i; ++ ++ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */ ++ ++ for (i = 0; i < HASH_SIZE; i++) { ++ for (bucket = table->buckets[i]; bucket;) { ++ next = bucket->next; ++ HASH_FREE(bucket); ++ bucket = next; ++ } ++ } ++ HASH_FREE(table); ++ return 0; ++} ++ ++/* Find the bucket and organize the list so that this bucket is at the ++ top. */ ++ ++static HashBucketPtr HashFind(HashTablePtr table, ++ unsigned long key, unsigned long *h) ++{ ++ unsigned long hash = HashHash(key); ++ HashBucketPtr prev = NULL; ++ HashBucketPtr bucket; ++ ++ if (h) *h = hash; ++ ++ for (bucket = table->buckets[hash]; bucket; bucket = bucket->next) { ++ if (bucket->key == key) { ++ if (prev) { ++ /* Organize */ ++ prev->next = bucket->next; ++ bucket->next = table->buckets[hash]; ++ table->buckets[hash] = bucket; ++ ++table->partials; ++ } else { ++ ++table->hits; ++ } ++ return bucket; ++ } ++ prev = bucket; ++ } ++ ++table->misses; ++ return NULL; ++} ++ ++int N(HashLookup)(void *t, unsigned long key, void **value) ++{ ++ HashTablePtr table = (HashTablePtr)t; ++ HashBucketPtr bucket; ++ ++ if (!table || table->magic != HASH_MAGIC) return -1; /* Bad magic */ ++ ++ bucket = HashFind(table, key, NULL); ++ if (!bucket) return 1; /* Not found */ ++ *value = bucket->value; ++ return 0; /* Found */ ++} ++ ++int N(HashInsert)(void *t, unsigned long key, void *value) ++{ ++ HashTablePtr table = (HashTablePtr)t; ++ HashBucketPtr bucket; ++ unsigned long hash; ++ ++ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */ ++ ++ if (HashFind(table, key, &hash)) return 1; /* Already in table */ ++ ++ bucket = HASH_ALLOC(sizeof(*bucket)); ++ if (!bucket) return -1; /* Error */ ++ bucket->key = key; ++ bucket->value = value; ++ bucket->next = table->buckets[hash]; ++ table->buckets[hash] = bucket; ++#if HASH_DEBUG ++ printf("Inserted %d at %d/%p\n", key, hash, bucket); ++#endif ++ return 0; /* Added to table */ ++} ++ ++int N(HashDelete)(void *t, unsigned long key) ++{ ++ HashTablePtr table = (HashTablePtr)t; ++ unsigned long hash; ++ HashBucketPtr bucket; ++ ++ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */ ++ ++ bucket = HashFind(table, key, &hash); ++ ++ if (!bucket) return 1; /* Not found */ ++ ++ table->buckets[hash] = bucket->next; ++ HASH_FREE(bucket); ++ return 0; ++} ++ ++int N(HashNext)(void *t, unsigned long *key, void **value) ++{ ++ HashTablePtr table = (HashTablePtr)t; ++ ++ for (; table->p0 < HASH_SIZE; ++ ++table->p0, table->p1 = table->buckets[table->p0]) { ++ if (table->p1) { ++ *key = table->p1->key; ++ *value = table->p1->value; ++ table->p1 = table->p1->next; ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++int N(HashFirst)(void *t, unsigned long *key, void **value) ++{ ++ HashTablePtr table = (HashTablePtr)t; ++ ++ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */ ++ ++ table->p0 = 0; ++ table->p1 = table->buckets[0]; ++ return N(HashNext)(table, key, value); ++} ++ ++#if HASH_MAIN ++#define DIST_LIMIT 10 ++static int dist[DIST_LIMIT]; ++ ++static void clear_dist(void) { ++ int i; ++ ++ for (i = 0; i < DIST_LIMIT; i++) dist[i] = 0; ++} ++ ++static int count_entries(HashBucketPtr bucket) ++{ ++ int count = 0; ++ ++ for (; bucket; bucket = bucket->next) ++count; ++ return count; ++} ++ ++static void update_dist(int count) ++{ ++ if (count >= DIST_LIMIT) ++dist[DIST_LIMIT-1]; ++ else ++dist[count]; ++} ++ ++static void compute_dist(HashTablePtr table) ++{ ++ int i; ++ HashBucketPtr bucket; ++ ++ printf("Entries = %ld, hits = %ld, partials = %ld, misses = %ld\n", ++ table->entries, table->hits, table->partials, table->misses); ++ clear_dist(); ++ for (i = 0; i < HASH_SIZE; i++) { ++ bucket = table->buckets[i]; ++ update_dist(count_entries(bucket)); ++ } ++ for (i = 0; i < DIST_LIMIT; i++) { ++ if (i != DIST_LIMIT-1) printf("%5d %10d\n", i, dist[i]); ++ else printf("other %10d\n", dist[i]); ++ } ++} ++ ++static void check_table(HashTablePtr table, ++ unsigned long key, unsigned long value) ++{ ++ unsigned long retval = 0; ++ int retcode = N(HashLookup)(table, key, &retval); ++ ++ switch (retcode) { ++ case -1: ++ printf("Bad magic = 0x%08lx:" ++ " key = %lu, expected = %lu, returned = %lu\n", ++ table->magic, key, value, retval); ++ break; ++ case 1: ++ printf("Not found: key = %lu, expected = %lu returned = %lu\n", ++ key, value, retval); ++ break; ++ case 0: ++ if (value != retval) ++ printf("Bad value: key = %lu, expected = %lu, returned = %lu\n", ++ key, value, retval); ++ break; ++ default: ++ printf("Bad retcode = %d: key = %lu, expected = %lu, returned = %lu\n", ++ retcode, key, value, retval); ++ break; ++ } ++} ++ ++int main(void) ++{ ++ HashTablePtr table; ++ int i; ++ ++ printf("\n***** 256 consecutive integers ****\n"); ++ table = N(HashCreate)(); ++ for (i = 0; i < 256; i++) N(HashInsert)(table, i, i); ++ for (i = 0; i < 256; i++) check_table(table, i, i); ++ for (i = 256; i >= 0; i--) check_table(table, i, i); ++ compute_dist(table); ++ N(HashDestroy)(table); ++ ++ printf("\n***** 1024 consecutive integers ****\n"); ++ table = N(HashCreate)(); ++ for (i = 0; i < 1024; i++) N(HashInsert)(table, i, i); ++ for (i = 0; i < 1024; i++) check_table(table, i, i); ++ for (i = 1024; i >= 0; i--) check_table(table, i, i); ++ compute_dist(table); ++ N(HashDestroy)(table); ++ ++ printf("\n***** 1024 consecutive page addresses (4k pages) ****\n"); ++ table = N(HashCreate)(); ++ for (i = 0; i < 1024; i++) N(HashInsert)(table, i*4096, i); ++ for (i = 0; i < 1024; i++) check_table(table, i*4096, i); ++ for (i = 1024; i >= 0; i--) check_table(table, i*4096, i); ++ compute_dist(table); ++ N(HashDestroy)(table); ++ ++ printf("\n***** 1024 random integers ****\n"); ++ table = N(HashCreate)(); ++ srandom(0xbeefbeef); ++ for (i = 0; i < 1024; i++) N(HashInsert)(table, random(), i); ++ srandom(0xbeefbeef); ++ for (i = 0; i < 1024; i++) check_table(table, random(), i); ++ srandom(0xbeefbeef); ++ for (i = 0; i < 1024; i++) check_table(table, random(), i); ++ compute_dist(table); ++ N(HashDestroy)(table); ++ ++ printf("\n***** 5000 random integers ****\n"); ++ table = N(HashCreate)(); ++ srandom(0xbeefbeef); ++ for (i = 0; i < 5000; i++) N(HashInsert)(table, random(), i); ++ srandom(0xbeefbeef); ++ for (i = 0; i < 5000; i++) check_table(table, random(), i); ++ srandom(0xbeefbeef); ++ for (i = 0; i < 5000; i++) check_table(table, random(), i); ++ compute_dist(table); ++ N(HashDestroy)(table); ++ ++ return 0; ++} ++#endif +diff -ruN modules/drm-trunk/xf86drmRandom.c modules-dristat/drm-trunk/xf86drmRandom.c +--- modules/drm-trunk/xf86drmRandom.c 1970-01-01 01:00:00.000000000 +0100 ++++ modules-dristat/drm-trunk/xf86drmRandom.c 2003-04-06 10:48:41.000000000 +0200 +@@ -0,0 +1,219 @@ ++/* xf86drmRandom.c -- "Minimal Standard" PRNG Implementation ++ * Created: Mon Apr 19 08:28:13 1999 by faith@precisioninsight.com ++ * ++ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Rickard E. (Rik) Faith <faith@valinux.com> ++ * ++ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRandom.c,v 1.4 2000/06/17 00:03:34 martin Exp $ ++ * ++ * DESCRIPTION ++ * ++ * This file contains a simple, straightforward implementation of the Park ++ * & Miller "Minimal Standard" PRNG [PM88, PMS93], which is a Lehmer ++ * multiplicative linear congruential generator (MLCG) with a period of ++ * 2^31-1. ++ * ++ * This implementation is intended to provide a reliable, portable PRNG ++ * that is suitable for testing a hash table implementation and for ++ * implementing skip lists. ++ * ++ * FUTURE ENHANCEMENTS ++ * ++ * If initial seeds are not selected randomly, two instances of the PRNG ++ * can be correlated. [Knuth81, pp. 32-33] describes a shuffling technique ++ * that can eliminate this problem. ++ * ++ * If PRNGs are used for simulation, the period of the current ++ * implementation may be too short. [LE88] discusses methods of combining ++ * MLCGs to produce much longer periods, and suggests some alternative ++ * values for A and M. [LE90 and Sch92] also provide information on ++ * long-period PRNGs. ++ * ++ * REFERENCES ++ * ++ * [Knuth81] Donald E. Knuth. The Art of Computer Programming. Volume 2: ++ * Seminumerical Algorithms. Reading, Massachusetts: Addison-Wesley, 1981. ++ * ++ * [LE88] Pierre L'Ecuyer. "Efficient and Portable Combined Random Number ++ * Generators". CACM 31(6), June 1988, pp. 742-774. ++ * ++ * [LE90] Pierre L'Ecuyer. "Random Numbers for Simulation". CACM 33(10, ++ * October 1990, pp. 85-97. ++ * ++ * [PM88] Stephen K. Park and Keith W. Miller. "Random Number Generators: ++ * Good Ones are Hard to Find". CACM 31(10), October 1988, pp. 1192-1201. ++ * ++ * [Sch92] Bruce Schneier. "Pseudo-Ransom Sequence Generator for 32-Bit ++ * CPUs". Dr. Dobb's Journal 17(2), February 1992, pp. 34, 37-38, 40. ++ * ++ * [PMS93] Stephen K. Park, Keith W. Miller, and Paul K. Stockmeyer. In ++ * "Technical Correspondence: Remarks on Choosing and Implementing Random ++ * Number Generators". CACM 36(7), July 1993, pp. 105-110. ++ * ++ */ ++ ++#define RANDOM_MAIN 0 ++ ++#if RANDOM_MAIN ++# include <stdio.h> ++# include <stdlib.h> ++#else ++# include "xf86drm.h" ++# ifdef XFree86LOADER ++# include "xf86.h" ++# include "xf86_ansic.h" ++# else ++# include <stdio.h> ++# include <stdlib.h> ++# endif ++#endif ++ ++#define N(x) drm##x ++ ++#define RANDOM_MAGIC 0xfeedbeef ++#define RANDOM_DEBUG 0 ++ ++#if RANDOM_MAIN ++#define RANDOM_ALLOC malloc ++#define RANDOM_FREE free ++#else ++#define RANDOM_ALLOC drmMalloc ++#define RANDOM_FREE drmFree ++#endif ++ ++typedef struct RandomState { ++ unsigned long magic; ++ unsigned long a; ++ unsigned long m; ++ unsigned long q; /* m div a */ ++ unsigned long r; /* m mod a */ ++ unsigned long check; ++ long seed; ++} RandomState; ++ ++#if RANDOM_MAIN ++extern void *N(RandomCreate)(unsigned long seed); ++extern int N(RandomDestroy)(void *state); ++extern unsigned long N(Random)(void *state); ++extern double N(RandomDouble)(void *state); ++#endif ++ ++void *N(RandomCreate)(unsigned long seed) ++{ ++ RandomState *state; ++ ++ state = RANDOM_ALLOC(sizeof(*state)); ++ if (!state) return NULL; ++ state->magic = RANDOM_MAGIC; ++#if 0 ++ /* Park & Miller, October 1988 */ ++ state->a = 16807; ++ state->m = 2147483647; ++ state->check = 1043618065; /* After 10000 iterations */ ++#else ++ /* Park, Miller, and Stockmeyer, July 1993 */ ++ state->a = 48271; ++ state->m = 2147483647; ++ state->check = 399268537; /* After 10000 iterations */ ++#endif ++ state->q = state->m / state->a; ++ state->r = state->m % state->a; ++ ++ state->seed = seed; ++ /* Check for illegal boundary conditions, ++ and choose closest legal value. */ ++ if (state->seed <= 0) state->seed = 1; ++ if (state->seed >= state->m) state->seed = state->m - 1; ++ ++ return state; ++} ++ ++int N(RandomDestroy)(void *state) ++{ ++ RANDOM_FREE(state); ++ return 0; ++} ++ ++unsigned long N(Random)(void *state) ++{ ++ RandomState *s = (RandomState *)state; ++ long hi; ++ long lo; ++ ++ hi = s->seed / s->q; ++ lo = s->seed % s->q; ++ s->seed = s->a * lo - s->r * hi; ++ if (s->seed <= 0) s->seed += s->m; ++ ++ return s->seed; ++} ++ ++double N(RandomDouble)(void *state) ++{ ++ RandomState *s = (RandomState *)state; ++ ++ return (double)N(Random)(state)/(double)s->m; ++} ++ ++#if RANDOM_MAIN ++static void check_period(long seed) ++{ ++ unsigned long count = 0; ++ unsigned long initial; ++ void *state; ++ ++ state = N(RandomCreate)(seed); ++ initial = N(Random)(state); ++ ++count; ++ while (initial != N(Random)(state)) { ++ if (!++count) break; ++ } ++ printf("With seed of %10ld, period = %10lu (0x%08lx)\n", ++ seed, count, count); ++ N(RandomDestroy)(state); ++} ++ ++int main(void) ++{ ++ RandomState *state; ++ int i; ++ unsigned long rand; ++ ++ state = N(RandomCreate)(1); ++ for (i = 0; i < 10000; i++) { ++ rand = N(Random)(state); ++ } ++ printf("After 10000 iterations: %lu (%lu expected): %s\n", ++ rand, state->check, ++ rand - state->check ? "*INCORRECT*" : "CORRECT"); ++ N(RandomDestroy)(state); ++ ++ printf("Checking periods...\n"); ++ check_period(1); ++ check_period(2); ++ check_period(31415926); ++ ++ return 0; ++} ++#endif diff --git a/x11-base/xfree-drm/xfree-drm-4.3.0-r2.ebuild b/x11-base/xfree-drm/xfree-drm-4.3.0-r2.ebuild index ca83fd111f15..819486d50bf2 100644 --- a/x11-base/xfree-drm/xfree-drm-4.3.0-r2.ebuild +++ b/x11-base/xfree-drm/xfree-drm-4.3.0-r2.ebuild @@ -1,6 +1,6 @@ # Copyright 1999-2003 Gentoo Technologies, Inc. # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/x11-base/xfree-drm/xfree-drm-4.3.0-r2.ebuild,v 1.2 2003/04/23 02:27:18 lu_zero Exp $ +# $Header: /var/cvsroot/gentoo-x86/x11-base/xfree-drm/xfree-drm-4.3.0-r2.ebuild,v 1.3 2003/04/24 19:02:29 leahcim Exp $ # Small note: we should prob consider using a DRM only tarball, as it will ease # some of the overhead on older systems, and will enable us to @@ -27,7 +27,7 @@ SRC_URI="mirror://gentoo/linux-drm-${PV}-kernelsource-${SNAPSHOT}.tar.gz" # LICENSE="X11" -SLOT="0" +SLOT="${KV}" KEYWORDS="~x86 ~ppc ~alpha" DEPEND=">=x11-base/xfree-${PV} @@ -78,6 +78,7 @@ src_unpack() { epatch ${FILESDIR}/${PF}-gentoo-Makefile-fixup.patch epatch ${FILESDIR}/${PF}-drm-ioremap.patch epatch ${FILESDIR}/${PF}-radeon-resume-v8.patch + epatch ${FILESDIR}/${PF}-dristat.patch } src_compile() { @@ -92,6 +93,7 @@ src_compile() { make ${VIDCARDS} \ TREE="/usr/src/linux/include" KV="${KV}" fi + make dristat || die } src_install() { @@ -113,6 +115,8 @@ src_install() { install || die fi dodoc README* + exeinto /usr/X11R6/bin + doexe dristat } pkg_postinst() { |