diff options
| author | Brian Paul <brian.paul@tungstengraphics.com> | 2005-11-29 22:37:19 +0000 | 
|---|---|---|
| committer | Brian Paul <brian.paul@tungstengraphics.com> | 2005-11-29 22:37:19 +0000 | 
| commit | 126482a12f7053a96f3d667f696d057865376ef5 (patch) | |
| tree | 8dfeea03d4ee6bb68564003718d210036b3ec143 /src | |
| parent | 9790e641ef24859833c01a1fa7004a1c2b73ddd1 (diff) | |
use the files from the drm tree/package
Diffstat (limited to 'src')
| -rw-r--r-- | src/mesa/drivers/dri/dri_client/Makefile | 60 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/dri_client/imports/xf86drm.h | 636 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/dri_client/xf86drm.c | 2333 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/dri_client/xf86drmHash.c | 433 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/dri_client/xf86drmRandom.c | 217 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/dri_client/xf86drmSL.c | 488 | 
6 files changed, 0 insertions, 4167 deletions
| diff --git a/src/mesa/drivers/dri/dri_client/Makefile b/src/mesa/drivers/dri/dri_client/Makefile deleted file mode 100644 index 9ab60cdaf8..0000000000 --- a/src/mesa/drivers/dri/dri_client/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# src/mesa/drivers/dri/gamma/Makefile - -TOP = ../../../../.. -include $(TOP)/configs/current - -# Get rid of this: -# -DEFINES += -DGLX_DIRECT_RENDERING  - -C_SOURCES = \ -	xf86drm.c \ -	xf86drmHash.c \ -	xf86drmRandom.c \ -	xf86drmSL.c \ - - - -OBJECTS = $(C_SOURCES:.c=.o)   - -INCLUDES = \ -	-I$(TOP)/include \ -	-I$(DRM_SOURCE_PATH)/shared-core \ -	-I$(TOP)/include/GL/internal \ -	-I$(TOP)/src/mesa \ -	-I$(TOP)/src/mesa/main \ -	-I$(TOP)/src/mesa/glapi \ -	-Iimports - - -##### RULES ##### - -.c.o: -	$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ - - -##### TARGETS ##### - -default: depend dri.a - - -# Run 'make dep' to update the dependencies if you change -# what's included by any source file. -depend: $(C_SOURCES) $(ASM_SOURCES) -	touch depend -	$(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) \ -		$(C_SOURCES) $(ASM_SOURCES)  - - -dri.a:	$(OBJECTS) -	rm -f $@ -	ar rcv $@ $(OBJECTS) -	ranlib $@ - -# Remove .o and backup files -clean: -	-rm -f *.o */*.o *~ *.so *.a depend depend.bak - -install: - -include depend diff --git a/src/mesa/drivers/dri/dri_client/imports/xf86drm.h b/src/mesa/drivers/dri/dri_client/imports/xf86drm.h deleted file mode 100644 index d3d78eb84e..0000000000 --- a/src/mesa/drivers/dri/dri_client/imports/xf86drm.h +++ /dev/null @@ -1,636 +0,0 @@ -/** - * \file xf86drm.h  - * OS-independent header for DRM user-level library interface. - * - * \author Rickard E. (Rik) Faith <faith@valinux.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. - * - */ - -/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h,v 1.26 2003/08/16 19:26:37 dawes Exp $ */ - -#ifndef _XF86DRM_H_ -#define _XF86DRM_H_ - -#include <drm.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 backward 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) - -#define DRM_AGP_NO_HANDLE 0 - -typedef unsigned int  drmSize,     *drmSizePtr;	    /**< For mapped regions */ -typedef void          *drmAddress, **drmAddressPtr; /**< For mapped regions */ - -/** - * Driver version information. - * - * \sa drmGetVersion() and drmSetVersion(). - */ -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; - -/** - * \warning These values *MUST* match drm.h - */ -typedef enum { -    /** \name 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 */ -    /*@}*/ - -    /** \name 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. */ -} drm_context_tFlags, *drm_context_tFlagsPtr; - -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 the master buffer list */ -    int              total;	  /**< Buffer size */ -    int              used;	  /**< Amount of buffer in use (for DMA) */ -    drmAddress       address;	  /**< Address */ -} drmBuf, *drmBufPtr; - -/** - * Buffer mapping information. - * - * Used by drmMapBufs() and drmUnmapBufs() to store information about the - * mapped buffers. - */ -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; - -/** - * Indices here refer to the offset into - * list in drmBufInfo - */ -typedef struct _drmDMAReq { -    drm_context_t    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 { -    drm_handle_t     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 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; - -typedef struct _drmSetVersion { -	int drm_di_major; -	int drm_di_minor; -	int drm_dd_major; -	int drm_dd_minor; -} drmSetVersion, *drmSetVersionPtr; - - -#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(__amd64__) -				/* 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__) - -#ifdef __INTEL_COMPILER -/* this currently generates bad code (missing stop bits)... */ -#include <ia64intrin.h> - -#define DRM_CAS(lock,old,new,__ret)					      \ -	do {								      \ -		unsigned long __result, __old = (old) & 0xffffffff;		\ -		__mf();							      	\ -		__result = _InterlockedCompareExchange_acq(&__drm_dummy_lock(lock), (new), __old);\ -		__ret = (__result) != (__old);					\ -/*		__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" ((unsigned long)__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, drm_magic_t * magic); -extern char          *drmGetBusid(int fd); -extern int           drmGetInterruptFromBusID(int fd, int busnum, int devnum, -					      int funcnum); -extern int           drmGetMap(int fd, int idx, drm_handle_t *offset, -			       drmSize *size, drmMapType *type, -			       drmMapFlags *flags, drm_handle_t *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           drmSetInterfaceVersion(int fd, drmSetVersion *version); -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, drm_magic_t magic); -extern int           drmAddMap(int fd, -			       drm_handle_t offset, -			       drmSize size, -			       drmMapType type, -			       drmMapFlags flags, -			       drm_handle_t * handle); -extern int	     drmRmMap(int fd, drm_handle_t handle); -extern int	     drmAddContextPrivateMapping(int fd, drm_context_t ctx_id, -						 drm_handle_t 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, drm_context_t * handle); -extern int           drmSetContextFlags(int fd, drm_context_t context, -					drm_context_tFlags flags); -extern int           drmGetContextFlags(int fd, drm_context_t context, -					drm_context_tFlagsPtr flags); -extern int           drmAddContextTag(int fd, drm_context_t context, void *tag); -extern int           drmDelContextTag(int fd, drm_context_t context); -extern void          *drmGetContextTag(int fd, drm_context_t context); -extern drm_context_t * drmGetReservedContextList(int fd, int *count); -extern void          drmFreeReservedContextList(drm_context_t *); -extern int           drmSwitchToContext(int fd, drm_context_t context); -extern int           drmDestroyContext(int fd, drm_context_t handle); -extern int           drmCreateDrawable(int fd, drm_drawable_t * handle); -extern int           drmDestroyDrawable(int fd, drm_drawable_t 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, -			    drm_handle_t 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, -			        drm_context_t context, -			        drmLockFlags flags); -extern int           drmUnlock(int fd, drm_context_t context); -extern int           drmFinish(int fd, int context, drmLockFlags flags); -extern int	     drmGetContextPrivateMapping(int fd, drm_context_t ctx_id,  -						 drm_handle_t * 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 --git a/src/mesa/drivers/dri/dri_client/xf86drm.c b/src/mesa/drivers/dri/dri_client/xf86drm.c deleted file mode 100644 index dba0f98deb..0000000000 --- a/src/mesa/drivers/dri/dri_client/xf86drm.c +++ /dev/null @@ -1,2333 +0,0 @@ -/** - * \file xf86drm.c  - * User-level interface to DRM device - * - * \author Rickard E. (Rik) Faith <faith@valinux.com> - * \author Kevin E. Martin <martin@valinux.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. - */ - -/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.36 2003/08/24 17:35:35 tsi 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 -# 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" - -#ifdef __FreeBSD__ -#define DRM_MAJOR 145 -#endif - -#ifdef __NetBSD__ -#define DRM_MAJOR 34 -#endif - -# ifdef __OpenBSD__ -#  define DRM_MAJOR 81 -# endif - -#ifndef DRM_MAJOR -#define DRM_MAJOR 226		/* Linux */ -#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 - -/** - * Output a message to stderr. - * - * \param format printf() like format string. - * - * \internal - * This function is a wrapper around vfprintf(). - */ -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; -} - -/** - * Compare two busid strings - * - * \param first - * \param second - * - * \return 1 if matched. - * - * \internal - * This function compares two bus ID strings.  It understands the older - * 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) -{ -    /* First, check if the IDs are exactly the same */ -    if (strcasecmp(id1, id2) == 0) -	return 1; - -    /* Try to match old/new-style PCI bus IDs. */ -    if (strncasecmp(id1, "pci", 3) == 0) { -	int o1, b1, d1, f1; -	int o2, b2, d2, f2; -	int ret; - -	ret = sscanf(id1, "pci:%04x:%02x:%02x.%d", &o1, &b1, &d1, &f1); -	if (ret != 4) { -	    o1 = 0; -	    ret = sscanf(id1, "PCI:%d:%d:%d", &b1, &d1, &f1); -	    if (ret != 3) -		return 0; -	} - -	ret = sscanf(id2, "pci:%04x:%02x:%02x.%d", &o2, &b2, &d2, &f2); -	if (ret != 4) { -	    o2 = 0; -	    ret = sscanf(id2, "PCI:%d:%d:%d", &b2, &d2, &f2); -	    if (ret != 3) -		return 0; -	} - -	if ((o1 != o2) || (b1 != b2) || (d1 != d2) || (f1 != f2)) -	    return 0; -	else -	    return 1; -    } -    return 0; -} - -/** - * Open the DRM device, creating it if necessary. - * - * \param dev major and minor numbers of the device. - * \param minor minor number of the device. - *  - * \return a file descriptor on success, or a negative value on error. - * - * \internal - * Assembles the device name from \p minor and opens it, creating the device - * 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) -{ -    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 - -    sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor); -    drmMsg("drmOpenDevice: node name is %s\n", buf); - -#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); -    } - -    /* Check if the device node exists and create it if necessary. */ -    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; - -    /* Check if the device node is not what we expect it to be, and recreate it -     * and try again if so. -     */ -    if (st.st_rdev != dev) { -	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; - -    drmMsg("drmOpenDevice: Open failed\n"); -    remove(buf); -    return -errno; -} - - -/** - * Open the DRM device - * - * \param minor device minor number. - * \param create allow to create the device if set. - * - * \return a file descriptor on success, or a negative value on error. - *  - * \internal - * Calls drmOpenDevice() if \p create is set, otherwise assembles the device - * name from \p minor and opens it. - */ -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; -} - - -/** - * Determine whether the DRM kernel driver has been loaded. - *  - * \return 1 if the DRM driver is loaded, 0 otherwise. - * - * \internal  - * Determine the presence of the kernel driver by attempting to open the 0 - * minor and get version information.  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) { -#ifdef __linux__ -				/* Try proc for backward Linux compatibility */ -	if (!access("/proc/dri/0", R_OK)) return 1; -#endif -	return 0; -    } -     -    if ((version = drmGetVersion(fd))) { -	retval = 1; -	drmFreeVersion(version); -    } -    close(fd); - -    return retval; -} - - -/** - * Open the device by bus ID. - * - * \param busid bus ID. - * - * \return a file descriptor on success, or a negative value on error. - * - * \internal - * This function attempts to open every possible minor (up to DRM_MAX_MINOR), - * comparing the device bus ID with the one supplied. - * - * \sa drmOpenMinor() and drmGetBusid(). - */ -static int drmOpenByBusid(const char *busid) -{ -    int        i; -    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); -	drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd); -	if (fd >= 0) { -	    sv.drm_di_major = 1; -	    sv.drm_di_minor = 1; -	    sv.drm_dd_major = -1;	/* Don't care */ -	    drmSetInterfaceVersion(fd, &sv); -	    buf = drmGetBusid(fd); -	    drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf); -	    if (buf && drmMatchBusID(buf, busid)) { -		drmFreeBusid(buf); -		return fd; -	    } -	    if (buf) drmFreeBusid(buf); -	    close(fd); -	} -    } -    return -1; -} - - -/** - * Open the device by name. - * - * \param name driver name. - *  - * \return a file descriptor on success, or a negative value on error. - *  - * \internal - * This function opens the first minor number that matches the driver name and - * isn't already in use.  If it's in use it then it will already have a bus ID - * assigned. - *  - * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid(). - */ -static int drmOpenByName(const char *name) -{ -    int           i; -    int           fd; -    drmVersionPtr version; -    char *        id; -     -    if (!drmAvailable()) { -#if !defined(XFree86Server) -	return -1; -#else -        /* 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; -} - - -/** - * Open the DRM device. - * - * Looks up the specified name and bus ID, and opens the device found.  The - * entry in /dev/dri is created if necessary and if called by root. - * - * \param name driver name. Not referenced if bus ID is supplied. - * \param busid bus ID. Zero if not known. - *  - * \return a file descriptor on success, or a negative value on error. - *  - * \internal - * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName() - * otherwise. - */ -int drmOpen(const char *name, const char *busid) -{ -#ifdef XFree86Server -    if (!drmAvailable() && name != NULL) { -	/* try to load the kernel */ -	if (!xf86LoadKernelModule(name)) { -	    ErrorF("[drm] failed to load kernel module \"%s\"\n", -	           name); -	    return -1; -	} -    } -#endif - -    if (busid) { -	int fd; - -	fd = drmOpenByBusid(busid); -	if (fd >= 0) -	    return fd; -    } -    if (name) -	return drmOpenByName(name); -    return -1; -} - - -/** - * Free the version information returned by drmGetVersion(). - * - * \param v pointer to the version information. - * - * \internal - * It frees the memory pointed by \p %v as well as all the non-null strings - * pointers in it. - */ -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); -} - - -/** - * Free the non-public version information returned by the kernel. - * - * \param v pointer to the version information. - * - * \internal - * Used by drmGetVersion() to free the memory pointed by \p %v as well as all - * the non-null strings pointers in it. - */ -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); -} - - -/** - * Copy version information. - *  - * \param d destination pointer. - * \param s source pointer. - *  - * \internal - * Used by drmGetVersion() to translate the information returned by the ioctl - * interface in a private structure into the public structure counterpart. - */ -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); -} - - -/** - * Query the driver version information. - * - * \param fd file descriptor. - *  - * \return pointer to a drmVersion structure which should be freed with - * drmFreeVersion(). - *  - * \note Similar information is available via /proc/dri. - *  - * \internal - * It gets the version information via successive DRM_IOCTL_VERSION ioctls, - * first with zeros to get the string lengths, and then the actually strings. - * It also null-terminates them since they might not be already. - */ -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)) { -	drmMsg("DRM_IOCTL_VERSION: %s\n", strerror(errno)); -	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; -} - - -/** - * Get version information for the DRM user space library. - *  - * This version number is driver independent. - *  - * \param fd file descriptor. - * - * \return version information. - *  - * \internal - * This function allocates and fills a drm_version structure with a hard coded - * version number. - */ -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 -     *   revision 1.2.x = added drmSetInterfaceVersion -     *                    modified drmOpen to handle both busid and name -     */ -    version->version_major      = 1; -    version->version_minor      = 2; -    version->version_patchlevel = 0; - -    return (drmVersionPtr)version; -} - - -/** - * Free the bus ID information. - * - * \param busid bus ID information string as given by drmGetBusid(). - * - * \internal - * This function is just frees the memory pointed by \p busid. - */ -void drmFreeBusid(const char *busid) -{ -    drmFree((void *)busid); -} - - -/** - * Get the bus ID of the device. - * - * \param fd file descriptor. - * - * \return bus ID string. - * - * \internal - * This function gets the bus ID via successive DRM_IOCTL_GET_UNIQUE ioctls to - * get the string length and data, passing the arguments in a drm_unique - * structure. - */ -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; -} - - -/** - * Set the bus ID of the device. - * - * \param fd file descriptor. - * \param busid bus ID string. - * - * \return zero on success, negative on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_SET_UNIQUE ioctl, passing - * the arguments in a drm_unique structure. - */ -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, drm_magic_t * 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, drm_magic_t magic) -{ -    drm_auth_t auth; - -    auth.magic = magic; -    if (ioctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth)) return -errno; -    return 0; -} - -/** - * Specifies a range of memory that is available for mapping by a - * non-root process. - * - * \param fd file descriptor. - * \param offset usually the physical address. The actual meaning depends of - * the \p type parameter. See below. - * \param size of the memory in bytes. - * \param type type of the memory to be mapped. - * \param flags combination of several flags to modify the function actions. - * \param handle will be set to a value that may be used as the offset - * parameter for mmap(). - *  - * \return zero on success or a negative value on error. - * - * \par Mapping the frame buffer - * For the frame buffer - * - \p offset will be the physical address of the start of the frame buffer, - * - \p size will be the size of the frame buffer in bytes, and - * - \p type will be DRM_FRAME_BUFFER. - * - * \par - * The area mapped will be uncached. If MTRR support is available in the - * kernel, the frame buffer area will be set to write combining.  - * - * \par Mapping the MMIO register area - * For the MMIO register area, - * - \p offset will be the physical address of the start of the register area, - * - \p size will be the size of the register area bytes, and - * - \p type will be DRM_REGISTERS. - * \par - * The area mapped will be uncached.  - *  - * \par Mapping the SAREA - * For the SAREA, - * - \p offset will be ignored and should be set to zero, - * - \p size will be the desired size of the SAREA in bytes, - * - \p type will be DRM_SHM. - *  - * \par - * A shared memory area of the requested size will be created and locked in - * kernel memory. This area may be mapped into client-space by using the handle - * returned.  - *  - * \note May only be called by root. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_ADD_MAP ioctl, passing - * the arguments in a drm_map structure. - */ -int drmAddMap(int fd, -	      drm_handle_t offset, -	      drmSize size, -	      drmMapType type, -	      drmMapFlags flags, -	      drm_handle_t * 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 = (drm_handle_t)map.handle; -    return 0; -} - -int drmRmMap(int fd, drm_handle_t handle) -{ -    drm_map_t map; - -    map.handle = (void *)handle; - -    if(ioctl(fd, DRM_IOCTL_RM_MAP, &map)) return -errno; -    return 0; -} - -/** - * Make buffers available for DMA transfers. - *  - * \param fd file descriptor. - * \param count number of buffers. - * \param size size of each buffer. - * \param flags buffer allocation flags. - * \param agp_offset offset in the AGP aperture  - * - * \return number of buffers allocated, negative on error. - * - * \internal - * This function is a wrapper around DRM_IOCTL_ADD_BUFS ioctl. - * - * \sa drm_buf_desc. - */ -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; -} - -/** - * Free buffers. - * - * \param fd file descriptor. - * \param count number of buffers to free. - * \param list list of buffers to be freed. - * - * \return zero on success, or a negative value on failure. - *  - * \note This function is primarily used for debugging. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_FREE_BUFS ioctl, passing - * the arguments in a drm_buf_free structure. - */ -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; -} - - -/** - * Close the device. - * - * \param fd file descriptor. - * - * \internal - * This function closes the file descriptor. - */ -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); -} - - -/** - * Map a region of memory. - * - * \param fd file descriptor. - * \param handle handle returned by drmAddMap(). - * \param size size in bytes. Must match the size used by drmAddMap(). - * \param address will contain the user-space virtual address where the mapping - * begins. - * - * \return zero on success, or a negative value on failure. - *  - * \internal - * This function is a wrapper for mmap(). - */ -int drmMap(int fd, -	   drm_handle_t 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; -} - - -/** - * Unmap mappings obtained with drmMap(). - * - * \param address address as given by drmMap(). - * \param size size in bytes. Must match the size used by drmMap(). - *  - * \return zero on success, or a negative value on failure. - * - * \internal - * This function is a wrapper for unmap(). - */ -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; -} - -/** - * Map all DMA buffers into client-virtual space. - * - * \param fd file descriptor. - * - * \return a pointer to a ::drmBufMap structure. - * - * \note The client may not use these buffers until obtaining buffer indices - * with drmDMA(). - *  - * \internal - * This function calls the DRM_IOCTL_MAP_BUFS ioctl and copies the returned - * information about the buffers in a drm_buf_map structure into the - * client-visible data structures. - */  -drmBufMapPtr drmMapBufs(int fd) -{ -    drm_buf_map_t bufs; -    drmBufMapPtr  retval; -    int           i; - -    bufs.count = 0; -    bufs.list  = NULL; -    bufs.virtual = NULL; -    if (ioctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) return NULL; - -    if (!bufs.count) return NULL; - -	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; -	} - -	drmFree(bufs.list); -	 -	return retval; -} - - -/** - * Unmap buffers allocated with drmMapBufs(). - * - * \return zero on success, or negative value on failure. - * - * \internal - * Calls munmap() for every buffer stored in \p bufs and frees the - * memory allocated by drmMapBufs(). - */ -int drmUnmapBufs(drmBufMapPtr bufs) -{ -    int i; - -    for (i = 0; i < bufs->count; i++) { -	munmap(bufs->list[i].address, bufs->list[i].total); -    } - -    drmFree(bufs->list); -    drmFree(bufs); -	 -    return 0; -} - - -#define DRM_DMA_RETRY		16 - -/** - * Reserve DMA buffers. - * - * \param fd file descriptor. - * \param request  - *  - * \return zero on success, or a negative value on failure. - * - * \internal - * Assemble the arguments into a drm_dma structure and keeps issuing the - * DRM_IOCTL_DMA ioctl until success or until maximum number of retries. - */ -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; -    dma.granted_count   = 0; - -    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; -    } -} - - -/** - * Obtain heavyweight hardware lock. - * - * \param fd file descriptor. - * \param context context. - * \param flags flags that determine the sate of the hardware when the function - * returns. - *  - * \return always zero. - *  - * \internal - * This function translates the arguments into a drm_lock structure and issue - * the DRM_IOCTL_LOCK ioctl until the lock is successfully acquired. - */ -int drmGetLock(int fd, drm_context_t 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; -} - -/** - * Release the hardware lock. - * - * \param fd file descriptor. - * \param context context. - *  - * \return zero on success, or a negative value on failure. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_UNLOCK ioctl, passing the - * argument in a drm_lock structure. - */ -int drmUnlock(int fd, drm_context_t context) -{ -    drm_lock_t lock; - -    lock.context = context; -    lock.flags   = 0; -    return ioctl(fd, DRM_IOCTL_UNLOCK, &lock); -} - -drm_context_t * drmGetReservedContextList(int fd, int *count) -{ -    drm_ctx_res_t res; -    drm_ctx_t     *list; -    drm_context_t * 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(drm_context_t * pt) -{ -    drmFree(pt); -} - -/** - * Create context. - * - * Used by the X server during GLXContext initialization. This causes - * per-context kernel-level resources to be allocated. - * - * \param fd file descriptor. - * \param handle is set on success. To be used by the client when requesting DMA - * dispatch with drmDMA(). - *  - * \return zero on success, or a negative value on failure. - *  - * \note May only be called by root. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_ADD_CTX ioctl, passing the - * argument in a drm_ctx structure. - */ -int drmCreateContext(int fd, drm_context_t * 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, drm_context_t context) -{ -    drm_ctx_t ctx; - -    ctx.handle = context; -    if (ioctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx)) return -errno; -    return 0; -} - -int drmSetContextFlags(int fd, drm_context_t context, drm_context_tFlags 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, drm_context_t context, drm_context_tFlagsPtr 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; -} - -/** - * Destroy context. - * - * Free any kernel-level resources allocated with drmCreateContext() associated - * with the context. - *  - * \param fd file descriptor. - * \param handle handle given by drmCreateContext(). - *  - * \return zero on success, or a negative value on failure. - *  - * \note May only be called by root. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_RM_CTX ioctl, passing the - * argument in a drm_ctx structure. - */ -int drmDestroyContext(int fd, drm_context_t handle) -{ -    drm_ctx_t ctx; -    ctx.handle = handle; -    if (ioctl(fd, DRM_IOCTL_RM_CTX, &ctx)) return -errno; -    return 0; -} - -int drmCreateDrawable(int fd, drm_drawable_t * handle) -{ -    drm_draw_t draw; -    if (ioctl(fd, DRM_IOCTL_ADD_DRAW, &draw)) return -errno; -    *handle = draw.handle; -    return 0; -} - -int drmDestroyDrawable(int fd, drm_drawable_t handle) -{ -    drm_draw_t draw; -    draw.handle = handle; -    if (ioctl(fd, DRM_IOCTL_RM_DRAW, &draw)) return -errno; -    return 0; -} - -/** - * Acquire the AGP device. - * - * Must be called before any of the other AGP related calls. - * - * \param fd file descriptor. - *  - * \return zero on success, or a negative value on failure. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_ACQUIRE ioctl. - */ -int drmAgpAcquire(int fd) -{ -    if (ioctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL)) return -errno; -    return 0; -} - - -/** - * Release the AGP device. - * - * \param fd file descriptor. - *  - * \return zero on success, or a negative value on failure. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_RELEASE ioctl. - */ -int drmAgpRelease(int fd) -{ -    if (ioctl(fd, DRM_IOCTL_AGP_RELEASE, NULL)) return -errno; -    return 0; -} - - -/** - * Set the AGP mode. - * - * \param fd file descriptor. - * \param mode AGP mode. - *  - * \return zero on success, or a negative value on failure. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_ENABLE ioctl, passing the - * argument in a drm_agp_mode structure. - */ -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; -} - - -/** - * Allocate a chunk of AGP memory. - * - * \param fd file descriptor. - * \param size requested memory size in bytes. Will be rounded to page boundary. - * \param type type of memory to allocate. - * \param address if not zero, will be set to the physical address of the - * allocated memory. - * \param handle on success will be set to a handle of the allocated memory. - *  - * \return zero on success, or a negative value on failure. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_ALLOC ioctl, passing the - * arguments in a drm_agp_buffer structure. - */ -int drmAgpAlloc(int fd, unsigned long size, unsigned long type, -		unsigned long *address, unsigned long *handle) -{ -    drm_agp_buffer_t b; - -    *handle = DRM_AGP_NO_HANDLE; -    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; -} - - -/** - * Free a chunk of AGP memory. - * - * \param fd file descriptor. - * \param handle handle to the allocated memory, as given by drmAgpAllocate(). - *  - * \return zero on success, or a negative value on failure. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_FREE ioctl, passing the - * argument in a drm_agp_buffer structure. - */ -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; -} - - -/** - * Bind a chunk of AGP memory. - * - * \param fd file descriptor. - * \param handle handle to the allocated memory, as given by drmAgpAllocate(). - * \param offset offset in bytes. It will round to page boundary. - *  - * \return zero on success, or a negative value on failure. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_BIND ioctl, passing the - * argument in a drm_agp_binding structure. - */ -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; -} - - -/** - * Unbind a chunk of AGP memory. - * - * \param fd file descriptor. - * \param handle handle to the allocated memory, as given by drmAgpAllocate(). - *  - * \return zero on success, or a negative value on failure. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_UNBIND ioctl, passing - * the argument in a drm_agp_binding structure. - */ -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; -} - - -/** - * Get AGP driver major version number. - * - * \param fd file descriptor. - *  - * \return major version number on success, or a negative value on failure.. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the - * necessary information in a drm_agp_info structure. - */ -int drmAgpVersionMajor(int fd) -{ -    drm_agp_info_t i; - -    if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno; -    return i.agp_version_major; -} - - -/** - * Get AGP driver minor version number. - * - * \param fd file descriptor. - *  - * \return minor version number on success, or a negative value on failure. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the - * necessary information in a drm_agp_info structure. - */ -int drmAgpVersionMinor(int fd) -{ -    drm_agp_info_t i; - -    if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno; -    return i.agp_version_minor; -} - - -/** - * Get AGP mode. - * - * \param fd file descriptor. - *  - * \return mode on success, or zero on failure. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the - * necessary information in a drm_agp_info structure. - */ -unsigned long drmAgpGetMode(int fd) -{ -    drm_agp_info_t i; - -    if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; -    return i.mode; -} - - -/** - * Get AGP aperture base. - * - * \param fd file descriptor. - *  - * \return aperture base on success, zero on failure. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the - * necessary information in a drm_agp_info structure. - */ -unsigned long drmAgpBase(int fd) -{ -    drm_agp_info_t i; - -    if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; -    return i.aperture_base; -} - - -/** - * Get AGP aperture size. - * - * \param fd file descriptor. - *  - * \return aperture size on success, zero on failure. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the - * necessary information in a drm_agp_info structure. - */ -unsigned long drmAgpSize(int fd) -{ -    drm_agp_info_t i; - -    if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; -    return i.aperture_size; -} - - -/** - * Get used AGP memory. - * - * \param fd file descriptor. - *  - * \return memory used on success, or zero on failure. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the - * necessary information in a drm_agp_info structure. - */ -unsigned long drmAgpMemoryUsed(int fd) -{ -    drm_agp_info_t i; - -    if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; -    return i.memory_used; -} - - -/** - * Get available AGP memory. - * - * \param fd file descriptor. - *  - * \return memory available on success, or zero on failure. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the - * necessary information in a drm_agp_info structure. - */ -unsigned long drmAgpMemoryAvail(int fd) -{ -    drm_agp_info_t i; - -    if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; -    return i.memory_allowed; -} - - -/** - * Get hardware vendor ID. - * - * \param fd file descriptor. - *  - * \return vendor ID on success, or zero on failure. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the - * necessary information in a drm_agp_info structure. - */ -unsigned int drmAgpVendorId(int fd) -{ -    drm_agp_info_t i; - -    if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; -    return i.id_vendor; -} - - -/** - * Get hardware device ID. - * - * \param fd file descriptor. - *  - * \return zero on success, or zero on failure. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the - * necessary information in a drm_agp_info structure. - */ -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; -} - -/** - * Wait for VBLANK. - * - * \param fd file descriptor. - * \param vbl pointer to a drmVBlank structure. - *  - * \return zero on success, or a negative value on failure. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_WAIT_VBLANK ioctl. - */ -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; -} - -/** - * Install IRQ handler. - * - * \param fd file descriptor. - * \param irq IRQ number. - *  - * \return zero on success, or a negative value on failure. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the - * argument in a drm_control structure. - */ -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; -} - - -/** - * Uninstall IRQ handler. - * - * \param fd file descriptor. - *  - * \return zero on success, or a negative value on failure. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the - * argument in a drm_control structure. - */ -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; -} - -/** - * Get IRQ from bus ID. - * - * \param fd file descriptor. - * \param busnum bus number. - * \param devnum device number. - * \param funcnum function number. - *  - * \return IRQ number on success, or a negative value on failure. - *  - * \internal - * This function is a wrapper around the DRM_IOCTL_IRQ_BUSID ioctl, passing the - * arguments in a drm_irq_busid structure. - */ -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, drm_context_t 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, drm_context_t context) -{ -    drmHashEntry  *entry = drmGetEntry(fd); - -    return drmHashDelete(entry->tagTable, context); -} - -void *drmGetContextTag(int fd, drm_context_t context) -{ -    drmHashEntry  *entry = drmGetEntry(fd); -    void          *value; - -    if (drmHashLookup(entry->tagTable, context, &value)) return NULL; - -    return value; -} - -int drmAddContextPrivateMapping(int fd, drm_context_t ctx_id, drm_handle_t 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, drm_context_t ctx_id, drm_handle_t * 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 = (drm_handle_t)map.handle; - -    return 0; -} - -int drmGetMap(int fd, int idx, drm_handle_t *offset, drmSize *size, -	      drmMapType *type, drmMapFlags *flags, drm_handle_t *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; -} - -/** - * Issue a set-version ioctl. - * - * \param fd file descriptor. - * \param drmCommandIndex command index  - * \param data source pointer of the data to be read and written. - * \param size size of the data to be read and written. - *  - * \return zero on success, or a negative value on failure. - *  - * \internal - * It issues a read-write ioctl given by  - * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. - */ -int drmSetInterfaceVersion(int fd, drmSetVersion *version ) -{ -    int retcode = 0; -    drm_set_version_t sv; - -    sv.drm_di_major = version->drm_di_major; -    sv.drm_di_minor = version->drm_di_minor; -    sv.drm_dd_major = version->drm_dd_major; -    sv.drm_dd_minor = version->drm_dd_minor; - -    if (ioctl(fd, DRM_IOCTL_SET_VERSION, &sv)) { -	retcode = -errno; -    } - -    version->drm_di_major = sv.drm_di_major; -    version->drm_di_minor = sv.drm_di_minor; -    version->drm_dd_major = sv.drm_dd_major; -    version->drm_dd_minor = sv.drm_dd_minor; - -    return retcode; -} - -/** - * Send a device-specific command. - * - * \param fd file descriptor. - * \param drmCommandIndex command index  - *  - * \return zero on success, or a negative value on failure. - *  - * \internal - * It issues a ioctl given by  - * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. - */ -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; -} - - -/** - * Send a device-specific read command. - * - * \param fd file descriptor. - * \param drmCommandIndex command index  - * \param data destination pointer of the data to be read. - * \param size size of the data to be read. - *  - * \return zero on success, or a negative value on failure. - * - * \internal - * It issues a read ioctl given by  - * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. - */ -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; -} - - -/** - * Send a device-specific write command. - * - * \param fd file descriptor. - * \param drmCommandIndex command index  - * \param data source pointer of the data to be written. - * \param size size of the data to be written. - *  - * \return zero on success, or a negative value on failure. - *  - * \internal - * It issues a write ioctl given by  - * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. - */ -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; -} - - -/** - * Send a device-specific read-write command. - * - * \param fd file descriptor. - * \param drmCommandIndex command index  - * \param data source pointer of the data to be read and written. - * \param size size of the data to be read and written. - *  - * \return zero on success, or a negative value on failure. - *  - * \internal - * It issues a read-write ioctl given by  - * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. - */ -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) -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]; -    drm_context_t    old; -    drm_context_t    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))) > 0) { -		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 --git a/src/mesa/drivers/dri/dri_client/xf86drmHash.c b/src/mesa/drivers/dri/dri_client/xf86drmHash.c deleted file mode 100644 index 5f89d540dc..0000000000 --- a/src/mesa/drivers/dri/dri_client/xf86drmHash.c +++ /dev/null @@ -1,433 +0,0 @@ -/* 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 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 *drmHashCreate(void); -extern int  drmHashDestroy(void *t); -extern int  drmHashLookup(void *t, unsigned long key, unsigned long *value); -extern int  drmHashInsert(void *t, unsigned long key, unsigned long value); -extern int  drmHashDelete(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 *drmHashCreate(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 drmHashDestroy(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 drmHashLookup(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 drmHashInsert(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 drmHashDelete(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 drmHashNext(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 drmHashFirst(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 drmHashNext(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 = drmHashLookup(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 = drmHashCreate(); -    for (i = 0; i < 256; i++) drmHashInsert(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); -    drmHashDestroy(table); - -    printf("\n***** 1024 consecutive integers ****\n"); -    table = drmHashCreate(); -    for (i = 0; i < 1024; i++) drmHashInsert(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); -    drmHashDestroy(table); - -    printf("\n***** 1024 consecutive page addresses (4k pages) ****\n"); -    table = drmHashCreate(); -    for (i = 0; i < 1024; i++) drmHashInsert(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); -    drmHashDestroy(table); - -    printf("\n***** 1024 random integers ****\n"); -    table = drmHashCreate(); -    srandom(0xbeefbeef); -    for (i = 0; i < 1024; i++) drmHashInsert(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); -    drmHashDestroy(table); - -    printf("\n***** 5000 random integers ****\n"); -    table = drmHashCreate(); -    srandom(0xbeefbeef); -    for (i = 0; i < 5000; i++) drmHashInsert(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); -    drmHashDestroy(table); - -    return 0; -} -#endif diff --git a/src/mesa/drivers/dri/dri_client/xf86drmRandom.c b/src/mesa/drivers/dri/dri_client/xf86drmRandom.c deleted file mode 100644 index cca831d751..0000000000 --- a/src/mesa/drivers/dri/dri_client/xf86drmRandom.c +++ /dev/null @@ -1,217 +0,0 @@ -/* 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 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          *drmRandomCreate(unsigned long seed); -extern int           drmRandomDestroy(void *state); -extern unsigned long drmRandom(void *state); -extern double        drmRandomDouble(void *state); -#endif - -void *drmRandomCreate(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 drmRandomDestroy(void *state) -{ -    RANDOM_FREE(state); -    return 0; -} - -unsigned long drmRandom(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 drmRandomDouble(void *state) -{ -    RandomState *s = (RandomState *)state; -     -    return (double)drmRandom(state)/(double)s->m; -} - -#if RANDOM_MAIN -static void check_period(long seed) -{ -    unsigned long count = 0; -    unsigned long initial; -    void          *state; -     -    state = drmRandomCreate(seed); -    initial = drmRandom(state); -    ++count; -    while (initial != drmRandom(state)) { -	if (!++count) break; -    } -    printf("With seed of %10ld, period = %10lu (0x%08lx)\n", -	   seed, count, count); -    drmRandomDestroy(state); -} - -int main(void) -{ -    RandomState   *state; -    int           i; -    unsigned long rand; - -    state = drmRandomCreate(1); -    for (i = 0; i < 10000; i++) { -	rand = drmRandom(state); -    } -    printf("After 10000 iterations: %lu (%lu expected): %s\n", -	   rand, state->check, -	   rand - state->check ? "*INCORRECT*" : "CORRECT"); -    drmRandomDestroy(state); - -    printf("Checking periods...\n"); -    check_period(1); -    check_period(2); -    check_period(31415926); -     -    return 0; -} -#endif diff --git a/src/mesa/drivers/dri/dri_client/xf86drmSL.c b/src/mesa/drivers/dri/dri_client/xf86drmSL.c deleted file mode 100644 index a9d64c920f..0000000000 --- a/src/mesa/drivers/dri/dri_client/xf86drmSL.c +++ /dev/null @@ -1,488 +0,0 @@ -/* xf86drmSL.c -- Skip list support - * Created: Mon May 10 09: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/xf86drmSL.c,v 1.3 2000/06/17 00:03:34 martin Exp $ - * - * DESCRIPTION - * - * This file contains a straightforward skip list implementation.n - * - * FUTURE ENHANCEMENTS - * - * REFERENCES - * - * [Pugh90] William Pugh.  Skip Lists: A Probabilistic Alternative to - * Balanced Trees. CACM 33(6), June 1990, pp. 668-676. - * - */ - -#define SL_MAIN 0 - -#if SL_MAIN -# include <stdio.h> -# include <stdlib.h> -#  include <sys/time.h> -#else -# include "xf86drm.h" -# ifdef XFree86LOADER -#  include "xf86.h" -#  include "xf86_ansic.h" -# else -#  include <stdio.h> -#  include <stdlib.h> -# endif -#endif - -#define SL_LIST_MAGIC  0xfacade00LU -#define SL_ENTRY_MAGIC 0x00fab1edLU -#define SL_FREED_MAGIC 0xdecea5edLU -#define SL_MAX_LEVEL   16 -#define SL_DEBUG       0 -#define SL_RANDOM_SEED 0xc01055a1LU - -#if SL_MAIN -#define SL_ALLOC malloc -#define SL_FREE  free -#define SL_RANDOM_DECL        static int state = 0; -#define SL_RANDOM_INIT(seed)  if (!state) { srandom(seed); ++state; } -#define SL_RANDOM             random() -#else -#define SL_ALLOC drmMalloc -#define SL_FREE  drmFree -#define SL_RANDOM_DECL        static void *state = NULL -#define SL_RANDOM_INIT(seed)  if (!state) state = drmRandomCreate(seed) -#define SL_RANDOM             drmRandom(state) - -#endif - -typedef struct SLEntry { -    unsigned long     magic;	   /* SL_ENTRY_MAGIC */ -    unsigned long     key; -    void              *value; -    int               levels; -    struct SLEntry    *forward[1]; /* variable sized array */ -} SLEntry, *SLEntryPtr; - -typedef struct SkipList { -    unsigned long    magic;	/* SL_LIST_MAGIC */ -    int              level; -    int              count; -    SLEntryPtr       head; -    SLEntryPtr       p0;	/* Position for iteration */ -} SkipList, *SkipListPtr; - -#if SL_MAIN -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 - -static SLEntryPtr SLCreateEntry(int max_level, unsigned long key, void *value) -{ -    SLEntryPtr entry; -     -    if (max_level < 0 || max_level > SL_MAX_LEVEL) max_level = SL_MAX_LEVEL; - -    entry         = SL_ALLOC(sizeof(*entry) -			     + (max_level + 1) * sizeof(entry->forward[0])); -    if (!entry) return NULL; -    entry->magic  = SL_ENTRY_MAGIC; -    entry->key    = key; -    entry->value  = value; -    entry->levels = max_level + 1; - -    return entry; -} - -static int SLRandomLevel(void) -{ -    int level = 1; -    SL_RANDOM_DECL; - -    SL_RANDOM_INIT(SL_RANDOM_SEED); -     -    while ((SL_RANDOM & 0x01) && level < SL_MAX_LEVEL) ++level; -    return level; -} - -void *drmSLCreate(void) -{ -    SkipListPtr  list; -    int          i; - -    list           = SL_ALLOC(sizeof(*list)); -    if (!list) return NULL; -    list->magic    = SL_LIST_MAGIC; -    list->level    = 0; -    list->head     = SLCreateEntry(SL_MAX_LEVEL, 0, NULL); -    list->count    = 0; - -    for (i = 0; i <= SL_MAX_LEVEL; i++) list->head->forward[i] = NULL; -     -    return list; -} - -int drmSLDestroy(void *l) -{ -    SkipListPtr   list  = (SkipListPtr)l; -    SLEntryPtr    entry; -    SLEntryPtr    next; - -    if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */ - -    for (entry = list->head; entry; entry = next) { -	if (entry->magic != SL_ENTRY_MAGIC) return -1; /* Bad magic */ -	next         = entry->forward[0]; -	entry->magic = SL_FREED_MAGIC; -	SL_FREE(entry); -    } - -    list->magic = SL_FREED_MAGIC; -    SL_FREE(list); -    return 0; -} - -static SLEntryPtr SLLocate(void *l, unsigned long key, SLEntryPtr *update) -{ -    SkipListPtr   list  = (SkipListPtr)l; -    SLEntryPtr    entry; -    int           i; - -    if (list->magic != SL_LIST_MAGIC) return NULL; - -    for (i = list->level, entry = list->head; i >= 0; i--) { -	while (entry->forward[i] && entry->forward[i]->key < key) -	    entry = entry->forward[i]; -	update[i] = entry; -    } - -    return entry->forward[0]; -} - -int drmSLInsert(void *l, unsigned long key, void *value) -{ -    SkipListPtr   list  = (SkipListPtr)l; -    SLEntryPtr    entry; -    SLEntryPtr    update[SL_MAX_LEVEL + 1]; -    int           level; -    int           i; - -    if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */ - -    entry = SLLocate(list, key, update); - -    if (entry && entry->key == key) return 1; /* Already in list */ - - -    level = SLRandomLevel(); -    if (level > list->level) { -	level = ++list->level; -	update[level] = list->head; -    } - -    entry = SLCreateEntry(level, key, value); - -				/* Fix up forward pointers */ -    for (i = 0; i <= level; i++) { -	entry->forward[i]     = update[i]->forward[i]; -	update[i]->forward[i] = entry; -    } - -    ++list->count; -    return 0;			/* Added to table */ -} - -int drmSLDelete(void *l, unsigned long key) -{ -    SkipListPtr   list = (SkipListPtr)l; -    SLEntryPtr    update[SL_MAX_LEVEL + 1]; -    SLEntryPtr    entry; -    int           i; - -    if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */ - -    entry = SLLocate(list, key, update); - -    if (!entry || entry->key != key) return 1; /* Not found */ - -				/* Fix up forward pointers */ -    for (i = 0; i <= list->level; i++) { -	if (update[i]->forward[i] == entry) -	    update[i]->forward[i] = entry->forward[i]; -    } - -    entry->magic = SL_FREED_MAGIC; -    SL_FREE(entry); - -    while (list->level && !list->head->forward[list->level]) --list->level; -    --list->count; -    return 0; -} - -int drmSLLookup(void *l, unsigned long key, void **value) -{ -    SkipListPtr   list = (SkipListPtr)l; -    SLEntryPtr    update[SL_MAX_LEVEL + 1]; -    SLEntryPtr    entry; - -    entry = SLLocate(list, key, update); - -    if (entry && entry->key == key) { -	*value = entry; -	return 0; -    } -    *value = NULL; -    return -1; -} - -int drmSLLookupNeighbors(void *l, unsigned long key, -			 unsigned long *prev_key, void **prev_value, -			 unsigned long *next_key, void **next_value) -{ -    SkipListPtr   list = (SkipListPtr)l; -    SLEntryPtr    update[SL_MAX_LEVEL + 1]; -    SLEntryPtr    entry; -    int           retcode = 0; - -    entry = SLLocate(list, key, update); - -    *prev_key   = *next_key   = key; -    *prev_value = *next_value = NULL; -	 -    if (update[0]) { -	*prev_key   = update[0]->key; -	*prev_value = update[0]->value; -	++retcode; -	if (update[0]->forward[0]) { -	    *next_key   = update[0]->forward[0]->key; -	    *next_value = update[0]->forward[0]->value; -	    ++retcode; -	} -    } -    return retcode; -} - -int drmSLNext(void *l, unsigned long *key, void **value) -{ -    SkipListPtr   list = (SkipListPtr)l; -    SLEntryPtr    entry; -     -    if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */ - -    entry    = list->p0; - -    if (entry) { -	list->p0 = entry->forward[0]; -	*key     = entry->key; -	*value   = entry->value; -	return 1; -    } -    list->p0 = NULL; -    return 0; -} - -int drmSLFirst(void *l, unsigned long *key, void **value) -{ -    SkipListPtr   list = (SkipListPtr)l; -     -    if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */ -     -    list->p0 = list->head->forward[0]; -    return drmSLNext(list, key, value); -} - -/* Dump internal data structures for debugging. */ -void drmSLDump(void *l) -{ -    SkipListPtr   list = (SkipListPtr)l; -    SLEntryPtr    entry; -    int           i; -     -    if (list->magic != SL_LIST_MAGIC) { -	printf("Bad magic: 0x%08lx (expected 0x%08lx)\n", -	       list->magic, SL_LIST_MAGIC); -	return; -    } - -    printf("Level = %d, count = %d\n", list->level, list->count); -    for (entry = list->head; entry; entry = entry->forward[0]) { -	if (entry->magic != SL_ENTRY_MAGIC) { -	    printf("Bad magic: 0x%08lx (expected 0x%08lx)\n", -		   list->magic, SL_ENTRY_MAGIC); -	} -	printf("\nEntry %p <0x%08lx, %p> has %2d levels\n", -	       entry, entry->key, entry->value, entry->levels); -	for (i = 0; i < entry->levels; i++) { -	    if (entry->forward[i]) { -		printf("   %2d: %p <0x%08lx, %p>\n", -		       i, -		       entry->forward[i], -		       entry->forward[i]->key, -		       entry->forward[i]->value); -	    } else { -		printf("   %2d: %p\n", i, entry->forward[i]); -	    } -	} -    } -} - -#if SL_MAIN -static void print(SkipListPtr list) -{ -    unsigned long key; -    void          *value; -     -    if (drmSLFirst(list, &key, &value)) { -	do { -	    printf("key = %5lu, value = %p\n", key, value); -	} while (drmSLNext(list, &key, &value)); -    } -} - -static double do_time(int size, int iter) -{ -    SkipListPtr    list; -    int            i, j; -    unsigned long  keys[1000000]; -    unsigned long  previous; -    unsigned long  key; -    void           *value; -    struct timeval start, stop; -    double         usec; -    SL_RANDOM_DECL; - -    SL_RANDOM_INIT(12345); -     -    list = drmSLCreate(); - -    for (i = 0; i < size; i++) { -	keys[i] = SL_RANDOM; -	drmSLInsert(list, keys[i], NULL); -    } - -    previous = 0; -    if (drmSLFirst(list, &key, &value)) { -	do { -	    if (key <= previous) { -		printf( "%lu !< %lu\n", previous, key); -	    } -	    previous = key; -	} while (drmSLNext(list, &key, &value)); -    } -     -    gettimeofday(&start, NULL); -    for (j = 0; j < iter; j++) { -	for (i = 0; i < size; i++) { -	    if (drmSLLookup(list, keys[i], &value)) -		printf("Error %lu %d\n", keys[i], i); -	} -    } -    gettimeofday(&stop, NULL); -     -    usec = (double)(stop.tv_sec * 1000000 + stop.tv_usec -		    - start.tv_sec * 1000000 - start.tv_usec) / (size * iter); -     -    printf("%0.2f microseconds for list length %d\n", usec, size); - -    drmSLDestroy(list); -     -    return usec; -} - -static void print_neighbors(void *list, unsigned long key) -{ -    unsigned long prev_key = 0; -    unsigned long next_key = 0; -    void          *prev_value; -    void          *next_value; -    int           retval; - -    retval = drmSLLookupNeighbors(list, key, -				  &prev_key, &prev_value, -				  &next_key, &next_value); -    printf("Neighbors of %5lu: %d %5lu %5lu\n", -	   key, retval, prev_key, next_key); -} - -int main(void) -{ -    SkipListPtr    list; -    double         usec, usec2, usec3, usec4; - -    list = drmSLCreate(); -    printf( "list at %p\n", list); - -    print(list); -    printf("\n==============================\n\n"); - -    drmSLInsert(list, 123, NULL); -    drmSLInsert(list, 213, NULL); -    drmSLInsert(list, 50, NULL); -    print(list); -    printf("\n==============================\n\n"); -     -    print_neighbors(list, 0); -    print_neighbors(list, 50); -    print_neighbors(list, 51); -    print_neighbors(list, 123); -    print_neighbors(list, 200); -    print_neighbors(list, 213); -    print_neighbors(list, 256); -    printf("\n==============================\n\n");     -     -    drmSLDelete(list, 50); -    print(list); -    printf("\n==============================\n\n"); - -    drmSLDump(list); -    drmSLDestroy(list); -    printf("\n==============================\n\n"); - -    usec  = do_time(100, 10000); -    usec2 = do_time(1000, 500); -    printf("Table size increased by %0.2f, search time increased by %0.2f\n", -	   1000.0/100.0, usec2 / usec); -     -    usec3 = do_time(10000, 50); -    printf("Table size increased by %0.2f, search time increased by %0.2f\n", -	   10000.0/100.0, usec3 / usec); -     -    usec4 = do_time(100000, 4); -    printf("Table size increased by %0.2f, search time increased by %0.2f\n", -	   100000.0/100.0, usec4 / usec); - -    return 0; -} -#endif | 
