diff options
Diffstat (limited to 'src/VBox/Additions/solaris/DRM/include')
-rw-r--r-- | src/VBox/Additions/solaris/DRM/include/drm.h | 820 | ||||
-rw-r--r-- | src/VBox/Additions/solaris/DRM/include/drmP.h | 908 | ||||
-rw-r--r-- | src/VBox/Additions/solaris/DRM/include/drm_atomic.h | 94 | ||||
-rw-r--r-- | src/VBox/Additions/solaris/DRM/include/drm_linux_list.h | 71 | ||||
-rw-r--r-- | src/VBox/Additions/solaris/DRM/include/queue.h | 585 |
5 files changed, 2478 insertions, 0 deletions
diff --git a/src/VBox/Additions/solaris/DRM/include/drm.h b/src/VBox/Additions/solaris/DRM/include/drm.h new file mode 100644 index 00000000..5bff1e1e --- /dev/null +++ b/src/VBox/Additions/solaris/DRM/include/drm.h @@ -0,0 +1,820 @@ +/* BEGIN CSTYLED */ + +/** + * \file drm.h + * Header for the Direct Rendering Manager + * + * \author Rickard E. (Rik) Faith <faith@valinux.com> + * + * \par Acknowledgments: + * Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic \c cmpxchg. + */ + +/* + * 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 + * VA LINUX SYSTEMS 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. + */ + +/** + * \mainpage + * + * The Direct Rendering Manager (DRM) is a device-independent kernel-level + * device driver that provides support for the XFree86 Direct Rendering + * Infrastructure (DRI). + * + * The DRM supports the Direct Rendering Infrastructure (DRI) in four major + * ways: + * -# The DRM provides synchronized access to the graphics hardware via + * the use of an optimized two-tiered lock. + * -# The DRM enforces the DRI security policy for access to the graphics + * hardware by only allowing authenticated X11 clients access to + * restricted regions of memory. + * -# The DRM provides a generic DMA engine, complete with multiple + * queues and the ability to detect the need for an OpenGL context + * switch. + * -# The DRM is extensible via the use of small device-specific modules + * that rely extensively on the API exported by the DRM module. + * + */ + +/* + * Copyright 2009-2010 Oracle Corporation + * All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _DRM_H_ +#define _DRM_H_ + +#include <sys/types32.h> + +#ifndef __user +#define __user +#endif + +#ifdef __GNUC__ +# define DEPRECATED __attribute__ ((deprecated)) +#else +# define DEPRECATED +# define __volatile__ volatile +#endif + +#if defined(__linux__) +#include <asm/ioctl.h> /* For _IO* macros */ +#define DRM_IOCTL_NR(n) _IOC_NR(n) +#define DRM_IOC_VOID _IOC_NONE +#define DRM_IOC_READ _IOC_READ +#define DRM_IOC_WRITE _IOC_WRITE +#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE +#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && defined(IN_MODULE) +/* Prevent name collision when including sys/ioccom.h */ +#undef ioctl +#include <sys/ioccom.h> +#define ioctl(a,b,c) xf86ioctl(a,b,c) +#else +#include <sys/ioccom.h> +#endif /* __FreeBSD__ && xf86ioctl */ +#define DRM_IOCTL_NR(n) ((n) & 0xff) +#define DRM_IOC_VOID IOC_VOID +#define DRM_IOC_READ IOC_OUT +#define DRM_IOC_WRITE IOC_IN +#define DRM_IOC_READWRITE IOC_INOUT +#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) +#endif + +/* Solaris-specific. */ +#if defined(__SOLARIS__) || defined(sun) +#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) + +#define _IOC_NRBITS 8 +#define _IOC_TYPEBITS 8 +#define _IOC_SIZEBITS 14 +#define _IOC_DIRBITS 2 + +#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) +#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) +#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) +#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) + +#define _IOC_NRSHIFT 0 +#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) +#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) +#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) + +#define _IOC_NONE 0U +#define _IOC_WRITE 1U +#define _IOC_READ 2U + +#define _IOC(dir, type, nr, size) \ + (((dir) << _IOC_DIRSHIFT) | \ + ((type) << _IOC_TYPESHIFT) | \ + ((nr) << _IOC_NRSHIFT) | \ + ((size) << _IOC_SIZESHIFT)) + +/* used for X server compile */ +#if !defined(_KERNEL) +#define _IO(type, nr) _IOC(_IOC_NONE, (type), (nr), 0) +#define _IOR(type, nr, size) _IOC(_IOC_READ, (type), (nr), sizeof (size)) +#define _IOW(type, nr, size) _IOC(_IOC_WRITE, (type), (nr), sizeof (size)) +#define _IOWR(type, nr, size) _IOC(_IOC_READ|_IOC_WRITE, \ + (type), (nr), sizeof (size)) + +#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) +#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) +#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) +#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) + +#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) +#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) +#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) +#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) +#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) +#endif /* _KERNEL */ + +#define DRM_IOCTL_NR(n) _IOC_NR(n) +#define DRM_IOC_VOID IOC_VOID +#define DRM_IOC_READ IOC_OUT +#define DRM_IOC_WRITE IOC_IN +#define DRM_IOC_READWRITE IOC_INOUT +#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) + +#endif /* __Solaris__ or sun */ +#define XFREE86_VERSION(major,minor,patch,snap) \ + ((major << 16) | (minor << 8) | patch) + +#ifndef CONFIG_XFREE86_VERSION +#define CONFIG_XFREE86_VERSION XFREE86_VERSION(4,1,0,0) +#endif + +#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0) +#define DRM_PROC_DEVICES "/proc/devices" +#define DRM_PROC_MISC "/proc/misc" +#define DRM_PROC_DRM "/proc/drm" +#define DRM_DEV_DRM "/dev/drm" +#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) +#define DRM_DEV_UID 0 +#define DRM_DEV_GID 0 +#endif + +#if CONFIG_XFREE86_VERSION >= XFREE86_VERSION(4,1,0,0) +#ifdef __OpenBSD__ +#define DRM_MAJOR 81 +#endif +#if defined(__linux__) || defined(__NetBSD__) +#define DRM_MAJOR 226 +#endif +#define DRM_MAX_MINOR 15 +#endif +#define DRM_NAME "drm" /**< Name in kernel, /dev, and /proc */ +#define DRM_MIN_ORDER 5 /**< At least 2^5 bytes = 32 bytes */ +#define DRM_MAX_ORDER 22 /**< Up to 2^22 bytes = 4MB */ +#define DRM_RAM_PERCENT 10 /**< How much system ram can we lock? */ + +#define _DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */ +#define _DRM_LOCK_CONT 0x40000000U /**< Hardware lock is contended */ +#define _DRM_LOCK_IS_HELD(lock) ((lock) & _DRM_LOCK_HELD) +#define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT) +#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT)) + +#if defined(__linux__) +#if defined(__KERNEL__) +typedef __u64 drm_u64_t; +#else +typedef unsigned long long drm_u64_t; +#endif + +typedef unsigned int drm_handle_t; +#else +#include <sys/types.h> +typedef uint64_t drm_u64_t; +typedef unsigned long long drm_handle_t; /**< To mapped regions */ +#endif +typedef unsigned int drm_context_t; /**< GLXContext handle */ +typedef unsigned int drm_drawable_t; +typedef unsigned int drm_magic_t; /**< Magic for authentication */ + +/** + * Cliprect. + * + * \warning If you change this structure, make sure you change + * XF86DRIClipRectRec in the server as well + * + * \note KW: Actually it's illegal to change either for + * backwards-compatibility reasons. + */ +typedef struct drm_clip_rect { + unsigned short x1; + unsigned short y1; + unsigned short x2; + unsigned short y2; +} drm_clip_rect_t; + +/** + * Drawable information. + */ +typedef struct drm_drawable_info { + unsigned int num_rects; + drm_clip_rect_t *rects; +} drm_drawable_info_t; + +/** + * Texture region, + */ +typedef struct drm_tex_region { + unsigned char next; + unsigned char prev; + unsigned char in_use; + unsigned char padding; + unsigned int age; +} drm_tex_region_t; + +/** + * Hardware lock. + * + * The lock structure is a simple cache-line aligned integer. To avoid + * processor bus contention on a multiprocessor system, there should not be any + * other data stored in the same cache line. + */ +typedef struct drm_hw_lock { + __volatile__ unsigned int lock; /**< lock variable */ + char padding[60]; /**< Pad to cache line */ +} drm_hw_lock_t; + +/* This is beyond ugly, and only works on GCC. However, it allows me to use + * drm.h in places (i.e., in the X-server) where I can't use size_t. The real + * fix is to use uint32_t instead of size_t, but that fix will break existing + * LP64 (i.e., PowerPC64, SPARC64, IA-64, Alpha, etc.) systems. That *will* + * eventually happen, though. I chose 'unsigned long' to be the fallback type + * because that works on all the platforms I know about. Hopefully, the + * real fix will happen before that bites us. + */ + +#ifdef __SIZE_TYPE__ +# define DRM_SIZE_T __SIZE_TYPE__ +#else +#if !defined(__SOLARIS__) && !defined(sun) +# warning "__SIZE_TYPE__ not defined. Assuming sizeof(size_t) == sizeof(unsigned long)!" +#endif +# define DRM_SIZE_T unsigned long +#endif + +/** + * DRM_IOCTL_VERSION ioctl argument type. + * + * \sa drmGetVersion(). + */ +typedef struct drm_version { + int version_major; /**< Major version */ + int version_minor; /**< Minor version */ + int version_patchlevel; /**< Patch level */ + DRM_SIZE_T name_len; /**< Length of name buffer */ + char __user *name; /**< Name of driver */ + DRM_SIZE_T date_len; /**< Length of date buffer */ + char __user *date; /**< User-space buffer to hold date */ + DRM_SIZE_T desc_len; /**< Length of desc buffer */ + char __user *desc; /**< User-space buffer to hold desc */ +} drm_version_t; + +/** + * DRM_IOCTL_GET_UNIQUE ioctl argument type. + * + * \sa drmGetBusid() and drmSetBusId(). + */ +typedef struct drm_unique { + DRM_SIZE_T unique_len; /**< Length of unique */ + char __user *unique; /**< Unique name for driver instantiation */ +} drm_unique_t; + +#undef DRM_SIZE_T + +typedef struct drm_list { + int count; /**< Length of user-space structures */ + drm_version_t __user *version; +} drm_list_t; + +typedef struct drm_block { + int unused; +} drm_block_t; + +/** + * DRM_IOCTL_CONTROL ioctl argument type. + * + * \sa drmCtlInstHandler() and drmCtlUninstHandler(). + */ +typedef struct drm_control { + enum { + DRM_ADD_COMMAND, + DRM_RM_COMMAND, + DRM_INST_HANDLER, + DRM_UNINST_HANDLER + } func; + int irq; +} drm_control_t; + +/** + * Type of memory to map. + */ +typedef enum drm_map_type { + _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, /**< Scatter/gather memory for PCI DMA */ + _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */ + _DRM_TTM = 6 +} drm_map_type_t; + +/** + * Memory mapping flags. + */ +typedef enum drm_map_flags { + _DRM_RESTRICTED = 0x01, /**< Cannot be mapped to user-virtual */ + _DRM_READ_ONLY = 0x02, + _DRM_LOCKED = 0x04, /**< shared, cached, locked */ + _DRM_KERNEL = 0x08, /**< kernel requires access */ + _DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */ + _DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */ + _DRM_REMOVABLE = 0x40, /**< Removable mapping */ + _DRM_DRIVER = 0x80 /**< Managed by driver */ +} drm_map_flags_t; + +typedef struct drm_ctx_priv_map { + unsigned int ctx_id; /**< Context requesting private mapping */ + void *handle; /**< Handle of map */ +} drm_ctx_priv_map_t; + +/** + * DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls + * argument type. + * + * \sa drmAddMap(). + */ +typedef struct drm_map { + unsigned long long offset; /**< Requested physical address (0 for SAREA)*/ + unsigned long long handle; + /**< User-space: "Handle" to pass to mmap() */ + /**< Kernel-space: kernel-virtual address */ + unsigned long size; /**< Requested physical size (bytes) */ + drm_map_type_t type; /**< Type of memory to map */ + drm_map_flags_t flags; /**< Flags */ + int mtrr; /**< MTRR slot used */ + /* Private data */ +} drm_map_t; + +/** + * DRM_IOCTL_GET_CLIENT ioctl argument type. + */ +typedef struct drm_client { + int idx; /**< Which client desired? */ + int auth; /**< Is client authenticated? */ + unsigned long pid; /**< Process ID */ + unsigned long uid; /**< User ID */ + unsigned long magic; /**< Magic */ + unsigned long iocs; /**< Ioctl count */ +} drm_client_t; + +typedef enum { + _DRM_STAT_LOCK, + _DRM_STAT_OPENS, + _DRM_STAT_CLOSES, + _DRM_STAT_IOCTLS, + _DRM_STAT_LOCKS, + _DRM_STAT_UNLOCKS, + _DRM_STAT_VALUE, /**< Generic value */ + _DRM_STAT_BYTE, /**< Generic byte counter (1024bytes/K) */ + _DRM_STAT_COUNT, /**< Generic non-byte counter (1000/k) */ + + _DRM_STAT_IRQ, /**< IRQ */ + _DRM_STAT_PRIMARY, /**< Primary DMA bytes */ + _DRM_STAT_SECONDARY, /**< Secondary DMA bytes */ + _DRM_STAT_DMA, /**< DMA */ + _DRM_STAT_SPECIAL, /**< Special DMA (e.g., priority or polled) */ + _DRM_STAT_MISSED /**< Missed DMA opportunity */ + /* Add to the *END* of the list */ +} drm_stat_type_t; + +/** + * DRM_IOCTL_GET_STATS ioctl argument type. + */ +typedef struct drm_stats { + unsigned long count; + struct { + unsigned long value; + drm_stat_type_t type; + } data[15]; +} drm_stats_t; + +/** + * Hardware locking flags. + */ +typedef enum drm_lock_flags { + _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 */ +} drm_lock_flags_t; + +/** + * DRM_IOCTL_LOCK, DRM_IOCTL_UNLOCK and DRM_IOCTL_FINISH ioctl argument type. + * + * \sa drmGetLock() and drmUnlock(). + */ +typedef struct drm_lock { + int context; + drm_lock_flags_t flags; +} drm_lock_t; + +/** + * DMA flags + * + * \warning + * These values \e must match xf86drm.h. + * + * \sa drm_dma. + */ +typedef enum drm_dma_flags { + /* Flags for DMA buffer dispatch */ + _DRM_DMA_BLOCK = 0x01, /**< + * Block until buffer dispatched. + * + * \note The buffer may not yet have + * been processed by the hardware -- + * getting a hardware lock with the + * hardware quiescent will ensure + * that the buffer has been + * processed. + */ + _DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */ + _DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */ + + /* Flags for DMA buffer request */ + _DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */ + _DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */ + _DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */ +} drm_dma_flags_t; + +/** + * DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type. + * + * \sa drmAddBufs(). + */ +typedef enum { + _DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */ + _DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */ + _DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */ + _DRM_FB_BUFFER = 0x08, /**< Buffer is in frame buffer */ + _DRM_PCI_BUFFER_RO = 0x10 /**< Map PCI DMA buffer read-only */ +} drm_buf_flag; +typedef struct drm_buf_desc { + 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 */ + drm_buf_flag flags; + unsigned long agp_start; /**< + * Start address of where the AGP buffers are + * in the AGP aperture + */ +} drm_buf_desc_t; + +/** + * DRM_IOCTL_INFO_BUFS ioctl argument type. + */ +typedef struct drm_buf_info { + int count; /**< Number of buffers described in list */ + drm_buf_desc_t __user *list; /**< List of buffer descriptions */ +} drm_buf_info_t; + +/** + * DRM_IOCTL_FREE_BUFS ioctl argument type. + */ +typedef struct drm_buf_free { + int count; + int __user *list; +} drm_buf_free_t; + +/** + * Buffer information + * + * \sa drm_buf_map. + */ +typedef struct drm_buf_pub { + int idx; /**< Index into the master buffer list */ + int total; /**< Buffer size */ + int used; /**< Amount of buffer in use (for DMA) */ + void __user *address; /**< Address of buffer */ +} drm_buf_pub_t; + +/** + * DRM_IOCTL_MAP_BUFS ioctl argument type. + */ +typedef struct drm_buf_map { + int count; /**< Length of the buffer list */ +#if defined(__cplusplus) + void __user *c_virtual; +#else + void __user *virtual; /**< Mmap'd area in user-virtual */ +#endif + drm_buf_pub_t __user *list; /**< Buffer information */ + int fd; +} drm_buf_map_t; + +/** + * DRM_IOCTL_DMA ioctl argument type. + * + * Indices here refer to the offset into the buffer list in drm_buf_get. + * + * \sa drmDMA(). + */ +typedef struct drm_dma { + int context; /**< Context handle */ + int send_count; /**< Number of buffers to send */ + int __user *send_indices; /**< List of handles to buffers */ + int __user *send_sizes; /**< Lengths of data to send */ + drm_dma_flags_t flags; /**< Flags */ + int request_count; /**< Number of buffers requested */ + int request_size; /**< Desired size for buffers */ + int __user *request_indices; /**< Buffer information */ + int __user *request_sizes; + int granted_count; /**< Number of buffers granted */ +} drm_dma_t; + +typedef enum { + _DRM_CONTEXT_PRESERVED = 0x01, + _DRM_CONTEXT_2DONLY = 0x02 +} drm_ctx_flags_t; + +/** + * DRM_IOCTL_ADD_CTX ioctl argument type. + * + * \sa drmCreateContext() and drmDestroyContext(). + */ +typedef struct drm_ctx { + drm_context_t handle; + drm_ctx_flags_t flags; +} drm_ctx_t; + +/** + * DRM_IOCTL_RES_CTX ioctl argument type. + */ +typedef struct drm_ctx_res { + int count; + drm_ctx_t __user *contexts; +} drm_ctx_res_t; + + +/** + * DRM_IOCTL_ADD_DRAW and DRM_IOCTL_RM_DRAW ioctl argument type. + */ +typedef struct drm_draw { + drm_drawable_t handle; +} drm_draw_t; + +/** + * DRM_IOCTL_UPDATE_DRAW ioctl argument type. + */ +typedef enum { + DRM_DRAWABLE_CLIPRECTS, +} drm_drawable_info_type_t; + +typedef struct drm_update_draw { + drm_drawable_t handle; + unsigned int type; + unsigned int num; + unsigned long long data; +} drm_update_draw_t; + +/** + * DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type. + */ +typedef struct drm_auth { + drm_magic_t magic; +} drm_auth_t; + +/** + * DRM_IOCTL_IRQ_BUSID ioctl argument type. + * + * \sa drmGetInterruptFromBusID(). + */ +typedef struct drm_irq_busid { + int irq; /**< IRQ number */ + int busnum; /**< bus number */ + int devnum; /**< device number */ + int funcnum; /**< function number */ +} drm_irq_busid_t; + +typedef enum { + _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ + _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ + _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */ + _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ + _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ + _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */ +} drm_vblank_seq_type_t; + +#define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE) +#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_SIGNAL | _DRM_VBLANK_SECONDARY | \ + _DRM_VBLANK_NEXTONMISS) + +struct drm_wait_vblank_request { + drm_vblank_seq_type_t type; + unsigned int sequence; + unsigned long signal; +}; + +struct drm_wait_vblank_reply { + drm_vblank_seq_type_t type; + unsigned int sequence; + long tval_sec; + long tval_usec; +}; + +/** + * DRM_IOCTL_WAIT_VBLANK ioctl argument type. + * + * \sa drmWaitVBlank(). + */ +typedef union drm_wait_vblank { + struct drm_wait_vblank_request request; + struct drm_wait_vblank_reply reply; +} drm_wait_vblank_t; + +/** + * DRM_IOCTL_AGP_ENABLE ioctl argument type. + * + * \sa drmAgpEnable(). + */ +typedef struct drm_agp_mode { + unsigned long mode; /**< AGP mode */ +} drm_agp_mode_t; + +/** + * DRM_IOCTL_AGP_ALLOC and DRM_IOCTL_AGP_FREE ioctls argument type. + * + * \sa drmAgpAlloc() and drmAgpFree(). + */ +typedef struct drm_agp_buffer { + unsigned long size; /**< In bytes -- will round to page boundary */ + unsigned long handle; /**< Used for binding / unbinding */ + unsigned long type; /**< Type of memory to allocate */ + unsigned long physical; /**< Physical used by i810 */ +} drm_agp_buffer_t; + +/** + * DRM_IOCTL_AGP_BIND and DRM_IOCTL_AGP_UNBIND ioctls argument type. + * + * \sa drmAgpBind() and drmAgpUnbind(). + */ +typedef struct drm_agp_binding { + unsigned long handle; /**< From drm_agp_buffer */ + unsigned long offset; /**< In bytes -- will round to page boundary */ +} drm_agp_binding_t; + +/** + * DRM_IOCTL_AGP_INFO ioctl argument type. + * + * \sa drmAgpVersionMajor(), drmAgpVersionMinor(), drmAgpGetMode(), + * drmAgpBase(), drmAgpSize(), drmAgpMemoryUsed(), drmAgpMemoryAvail(), + * drmAgpVendorId() and drmAgpDeviceId(). + */ +typedef struct drm_agp_info { + int agp_version_major; + int agp_version_minor; + unsigned long mode; + unsigned long aperture_base; /**< physical address */ + unsigned long aperture_size; /**< bytes */ + unsigned long memory_allowed; /**< bytes */ + unsigned long memory_used; + + /** \name PCI information */ + /*@{ */ + unsigned short id_vendor; + unsigned short id_device; + /*@} */ +} drm_agp_info_t; + +/** + * DRM_IOCTL_SG_ALLOC ioctl argument type. + */ +typedef struct drm_scatter_gather { + unsigned long size; /**< In bytes -- will round to page boundary */ + unsigned long handle; /**< Used for mapping / unmapping */ +} drm_scatter_gather_t; + +/** + * DRM_IOCTL_SET_VERSION ioctl argument type. + */ +typedef struct drm_set_version { + int drm_di_major; + int drm_di_minor; + int drm_dd_major; + int drm_dd_minor; +} drm_set_version_t; + +/** + * \name Ioctls Definitions + */ +/*@{*/ + +#define DRM_IOCTL_BASE 'd' +#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) +#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) +#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type) +#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type) + +#define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t) +#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t) +#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, drm_auth_t) +#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, drm_irq_busid_t) +#define DRM_IOCTL_GET_MAP DRM_IOWR(0x04, drm_map_t) +#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, drm_client_t) +#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, drm_stats_t) +#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, drm_set_version_t) + +#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t) +#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, drm_auth_t) +#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, drm_block_t) +#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, drm_block_t) +#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, drm_control_t) +#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, drm_map_t) +#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, drm_buf_desc_t) +#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, drm_buf_desc_t) +#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm_buf_info_t) +#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t) +#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t) + +#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, drm_map_t) + +#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, drm_ctx_priv_map_t) +#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, drm_ctx_priv_map_t) + +#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t) +#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t) +#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t) +#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, drm_ctx_t) +#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, drm_ctx_t) +#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, drm_ctx_t) +#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, drm_ctx_res_t) +#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, drm_draw_t) +#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, drm_draw_t) +#define DRM_IOCTL_DMA DRM_IOWR(0x29, drm_dma_t) +#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, drm_lock_t) +#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t) +#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t) + +#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30) +#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31) +#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, drm_agp_mode_t) +#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, drm_agp_info_t) +#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t) +#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t) +#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t) +#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t) + +#define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t) +#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t) + +#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, drm_wait_vblank_t) + +#define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, drm_update_draw_t) +/*@}*/ + +/** + * Device specific ioctls should only be in their respective headers + * The device specific ioctl range is from 0x40 to 0x99. + * Generic IOCTLS restart at 0xA0. + * + * \sa drmCommandNone(), drmCommandRead(), drmCommandWrite(), and + * drmCommandReadWrite(). + */ +#define DRM_COMMAND_BASE 0x40 +#define DRM_COMMAND_END 0xA0 + +#endif /* _DRM_H_ */ diff --git a/src/VBox/Additions/solaris/DRM/include/drmP.h b/src/VBox/Additions/solaris/DRM/include/drmP.h new file mode 100644 index 00000000..0763e708 --- /dev/null +++ b/src/VBox/Additions/solaris/DRM/include/drmP.h @@ -0,0 +1,908 @@ +/* + * drmP.h -- Private header for Direct Rendering Manager -*- linux-c -*- + * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com + */ +/* + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS 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> + * Gareth Hughes <gareth@valinux.com> + * + */ + +/* + * Copyright 2009-2010 Oracle Corporation + * All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _DRMP_H +#define _DRMP_H + +#include <sys/types.h> +#include <sys/conf.h> +#include <sys/modctl.h> +#include <sys/stat.h> +#include <sys/file.h> +#include <sys/cmn_err.h> +#include <sys/varargs.h> +#include <sys/pci.h> +#include <sys/ddi.h> +#include <sys/sunddi.h> +#include <sys/sunldi.h> +#include <sys/pmem.h> +#include <sys/agpgart.h> +#include <sys/time.h> +#include "drm_atomic.h" +#include "drm.h" +#if !defined(VBOX_WITH_SYSTEM_QUEUE_H) +# include "queue.h" +#endif +#include "drm_linux_list.h" + +#ifndef __inline__ +#define __inline__ inline +#endif + +#if !defined(__FUNCTION__) +#if defined(C99) +#define __FUNCTION__ __func__ +#else +#define __FUNCTION__ " " +#endif +#endif + +/* DRM space units */ +#define DRM_PAGE_SHIFT PAGESHIFT +#define DRM_PAGE_SIZE (1 << DRM_PAGE_SHIFT) +#define DRM_PAGE_OFFSET (DRM_PAGE_SIZE - 1) +#define DRM_PAGE_MASK ~(DRM_PAGE_SIZE - 1) +#define DRM_MB2PAGES(x) ((x) << 8) +#define DRM_PAGES2BYTES(x) ((x) << DRM_PAGE_SHIFT) +#define DRM_BYTES2PAGES(x) ((x) >> DRM_PAGE_SHIFT) +#define DRM_PAGES2KB(x) ((x) << 2) +#define DRM_ALIGNED(offset) (((offset) & DRM_PAGE_OFFSET) == 0) + +#define PAGE_SHIFT DRM_PAGE_SHIFT +#define PAGE_SIZE DRM_PAGE_SIZE + +#define DRM_MAX_INSTANCES 8 +#define DRM_DEVNODE "drm" +#define DRM_UNOPENED 0 +#define DRM_OPENED 1 + +#define DRM_HASH_SIZE 16 /* Size of key hash table */ +#define DRM_KERNEL_CONTEXT 0 /* Change drm_resctx if changed */ +#define DRM_RESERVED_CONTEXTS 1 /* Change drm_resctx if changed */ + +#define DRM_MEM_DMA 0 +#define DRM_MEM_SAREA 1 +#define DRM_MEM_DRIVER 2 +#define DRM_MEM_MAGIC 3 +#define DRM_MEM_IOCTLS 4 +#define DRM_MEM_MAPS 5 +#define DRM_MEM_BUFS 6 +#define DRM_MEM_SEGS 7 +#define DRM_MEM_PAGES 8 +#define DRM_MEM_FILES 9 +#define DRM_MEM_QUEUES 10 +#define DRM_MEM_CMDS 11 +#define DRM_MEM_MAPPINGS 12 +#define DRM_MEM_BUFLISTS 13 +#define DRM_MEM_DRMLISTS 14 +#define DRM_MEM_TOTALDRM 15 +#define DRM_MEM_BOUNDDRM 16 +#define DRM_MEM_CTXBITMAP 17 +#define DRM_MEM_STUB 18 +#define DRM_MEM_SGLISTS 19 +#define DRM_MEM_AGPLISTS 20 +#define DRM_MEM_CTXLIST 21 +#define DRM_MEM_MM 22 +#define DRM_MEM_HASHTAB 23 +#define DRM_MEM_OBJECTS 24 + +#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) +#define DRM_MAP_HASH_OFFSET 0x10000000 +#define DRM_MAP_HASH_ORDER 12 +#define DRM_OBJECT_HASH_ORDER 12 +#define DRM_FILE_PAGE_OFFSET_START ((0xFFFFFFFFUL >> PAGE_SHIFT) + 1) +#define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFFFFFFUL >> PAGE_SHIFT) * 16) +#define DRM_MM_INIT_MAX_PAGES 256 + + +/* Internal types and structures */ +#define DRM_ARRAY_SIZE(x) (sizeof (x) / sizeof (x[0])) +#define DRM_MIN(a, b) ((a) < (b) ? (a) : (b)) +#define DRM_MAX(a, b) ((a) > (b) ? (a) : (b)) + +#define DRM_IF_VERSION(maj, min) (maj << 16 | min) + +#define __OS_HAS_AGP 1 + +#define DRM_DEV_MOD (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) +#define DRM_DEV_UID 0 +#define DRM_DEV_GID 0 + +#define DRM_CURRENTPID ddi_get_pid() +#define DRM_SPINLOCK(l) mutex_enter(l) +#define DRM_SPINUNLOCK(u) mutex_exit(u) +#define DRM_SPINLOCK_ASSERT(l) +#define DRM_LOCK() mutex_enter(&dev->dev_lock) +#define DRM_UNLOCK() mutex_exit(&dev->dev_lock) +#define DRM_LOCK_OWNED() ASSERT(mutex_owned(&dev->dev_lock)) +#define spin_lock_irqsave(l, flag) mutex_enter(l) +#define spin_unlock_irqrestore(u, flag) mutex_exit(u) +#define spin_lock(l) mutex_enter(l) +#define spin_unlock(u) mutex_exit(u) + +#define DRM_UDELAY(sec) delay(drv_usectohz(sec *1000)) +#define DRM_MEMORYBARRIER() + +typedef struct drm_file drm_file_t; +typedef struct drm_device drm_device_t; +typedef struct drm_driver_info drm_driver_t; + +#define DRM_DEVICE drm_device_t *dev = dev1 +#define DRM_IOCTL_ARGS \ + drm_device_t *dev1, intptr_t data, drm_file_t *fpriv, int mode + +#define DRM_COPYFROM_WITH_RETURN(dest, src, size) \ + if (ddi_copyin(src, dest, size, 0)) \ + return (EFAULT) + +#define DRM_COPYTO_WITH_RETURN(dest, src, size) \ + if (ddi_copyout((src), (dest), (size), 0)) \ + return (EFAULT) + +#define DRM_COPY_FROM_USER(dest, src, size) \ + ddi_copyin((src), (dest), (size), 0) /* flag for src */ + +#define DRM_COPY_TO_USER(dest, src, size) \ + ddi_copyout((src), (dest), (size), 0) /* flags for dest */ + +#define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) \ + ddi_copyin((arg2), (arg1), (arg3), 0) + +#define DRM_COPY_TO_USER_UNCHECKED(arg1, arg2, arg3) \ + ddi_copyout((arg2), arg1, arg3, 0) + +#define DRM_READ8(map, offset) \ + *(uint8_t *)((uintptr_t)((map)->dev_addr) + (offset)) +#define DRM_READ16(map, offset) \ + *(uint16_t *)((uintptr_t)((map)->dev_addr) + (offset)) +#define DRM_READ32(map, offset) \ + *(uint32_t *)((uintptr_t)((map)->dev_addr) + (offset)) +#define DRM_WRITE8(map, offset, val) \ + *(uint8_t *)((uintptr_t)((map)->dev_addr) + (offset)) = (val) +#define DRM_WRITE16(map, offset, val) \ + *(uint16_t *)((uintptr_t)((map)->dev_addr) + (offset)) = (val) +#define DRM_WRITE32(map, offset, val) \ + *(uint32_t *)((uintptr_t)((map)->dev_addr) + (offset)) = (val) + +typedef struct drm_wait_queue { + kcondvar_t cv; + kmutex_t lock; +}wait_queue_head_t; + +#define DRM_INIT_WAITQUEUE(q, pri) \ +{ \ + mutex_init(&(q)->lock, NULL, MUTEX_DRIVER, pri); \ + cv_init(&(q)->cv, NULL, CV_DRIVER, NULL); \ +} + +#define DRM_FINI_WAITQUEUE(q) \ +{ \ + mutex_destroy(&(q)->lock); \ + cv_destroy(&(q)->cv); \ +} + +#define DRM_WAKEUP(q) \ +{ \ + mutex_enter(&(q)->lock); \ + cv_broadcast(&(q)->cv); \ + mutex_exit(&(q)->lock); \ +} + +#define jiffies ddi_get_lbolt() +#define DRM_WAIT_ON(ret, q, timeout, condition) \ +mutex_enter(&(q)->lock); \ +while (!(condition)) { \ + ret = cv_timedwait_sig(&(q)->cv, &(q)->lock, jiffies + timeout); \ + if (ret == -1) { \ + ret = EBUSY; \ + break; \ + } else if (ret == 0) { \ + ret = EINTR; \ + break; \ + } else { \ + ret = 0; \ + } \ +} \ +mutex_exit(&(q)->lock); + +#define DRM_GETSAREA() \ +{ \ + drm_local_map_t *map; \ + DRM_SPINLOCK_ASSERT(&dev->dev_lock); \ + TAILQ_FOREACH(map, &dev->maplist, link) { \ + if (map->type == _DRM_SHM && \ + map->flags & _DRM_CONTAINS_LOCK) { \ + dev_priv->sarea = map; \ + break; \ + } \ + } \ +} + +#define LOCK_TEST_WITH_RETURN(dev, fpriv) \ + if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) || \ + dev->lock.filp != fpriv) { \ + DRM_ERROR("called without lock held"); \ + return (EINVAL); \ + } + +#define DRM_IRQ_ARGS caddr_t arg +#define IRQ_HANDLED DDI_INTR_CLAIMED +#define IRQ_NONE DDI_INTR_UNCLAIMED + +enum { + DRM_IS_NOT_AGP, + DRM_IS_AGP, + DRM_MIGHT_BE_AGP +}; + +/* Capabilities taken from src/sys/dev/pci/pcireg.h. */ +#ifndef PCIY_AGP +#define PCIY_AGP 0x02 +#endif + +#ifndef PCIY_EXPRESS +#define PCIY_EXPRESS 0x10 +#endif + +#define PAGE_ALIGN(addr) (((addr) + DRM_PAGE_SIZE - 1) & DRM_PAGE_MASK) +#define DRM_SUSER(p) (crgetgid(p) == 0 || crgetuid(p) == 0) + +/* + * wait for 400 milliseconds + */ +#define DRM_HZ drv_usectohz(400000) + +typedef unsigned long dma_addr_t; +typedef uint64_t u64; +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; +typedef uint_t irqreturn_t; + +#define DRM_SUPPORT 1 +#define DRM_UNSUPPORT 0 + +#define __OS_HAS_AGP 1 + +#define __offsetof(type, field) ((size_t)(&((type *)0)->field)) +#define offsetof(type, field) __offsetof(type, field) + +typedef struct drm_pci_id_list +{ + int vendor; + int device; + long driver_private; + char *name; +} drm_pci_id_list_t; + +#define DRM_AUTH 0x1 +#define DRM_MASTER 0x2 +#define DRM_ROOT_ONLY 0x4 +typedef int drm_ioctl_t(DRM_IOCTL_ARGS); +typedef struct drm_ioctl_desc { + int (*func)(DRM_IOCTL_ARGS); + int flags; +} drm_ioctl_desc_t; + +typedef struct drm_magic_entry { + drm_magic_t magic; + struct drm_file *priv; + struct drm_magic_entry *next; +} drm_magic_entry_t; + +typedef struct drm_magic_head { + struct drm_magic_entry *head; + struct drm_magic_entry *tail; +} drm_magic_head_t; + +typedef struct drm_buf { + int idx; /* Index into master buflist */ + int total; /* Buffer size */ + int order; /* log-base-2(total) */ + int used; /* Amount of buffer in use (for DMA) */ + unsigned long offset; /* Byte offset (used internally) */ + void *address; /* Address of buffer */ + unsigned long bus_address; /* Bus address of buffer */ + struct drm_buf *next; /* Kernel-only: used for free list */ + volatile int pending; /* On hardware DMA queue */ + drm_file_t *filp; + /* Uniq. identifier of holding process */ + int context; /* Kernel queue for this buffer */ + enum { + DRM_LIST_NONE = 0, + DRM_LIST_FREE = 1, + DRM_LIST_WAIT = 2, + DRM_LIST_PEND = 3, + DRM_LIST_PRIO = 4, + DRM_LIST_RECLAIM = 5 + } list; /* Which list we're on */ + + int dev_priv_size; /* Size of buffer private storage */ + void *dev_private; /* Per-buffer private storage */ +} drm_buf_t; + +typedef struct drm_freelist { + int initialized; /* Freelist in use */ + uint32_t count; /* Number of free buffers */ + drm_buf_t *next; /* End pointer */ + + int low_mark; /* Low water mark */ + int high_mark; /* High water mark */ +} drm_freelist_t; + +typedef struct drm_buf_entry { + int buf_size; + int buf_count; + drm_buf_t *buflist; + int seg_count; + int page_order; + + uint32_t *seglist; + unsigned long *seglist_bus; + + drm_freelist_t freelist; +} drm_buf_entry_t; + +typedef TAILQ_HEAD(drm_file_list, drm_file) drm_file_list_t; +struct drm_file { + TAILQ_ENTRY(drm_file) link; + int authenticated; + int master; + int minor; + pid_t pid; + uid_t uid; + int refs; + drm_magic_t magic; + unsigned long ioctl_count; + void *driver_priv; +}; + +typedef struct drm_lock_data { + drm_hw_lock_t *hw_lock; /* Hardware lock */ + drm_file_t *filp; + /* Uniq. identifier of holding process */ + kcondvar_t lock_cv; /* lock queue - SOLARIS Specific */ + kmutex_t lock_mutex; /* lock - SOLARIS Specific */ + unsigned long lock_time; /* Time of last lock in jiffies */ +} drm_lock_data_t; + +/* + * This structure, in drm_device_t, is always initialized while the device + * is open. dev->dma_lock protects the incrementing of dev->buf_use, which + * when set marks that no further bufs may be allocated until device teardown + * occurs (when the last open of the device has closed). The high/low + * watermarks of bufs are only touched by the X Server, and thus not + * concurrently accessed, so no locking is needed. + */ +typedef struct drm_device_dma { + drm_buf_entry_t bufs[DRM_MAX_ORDER+1]; + int buf_count; + drm_buf_t **buflist; /* Vector of pointers info bufs */ + int seg_count; + int page_count; + unsigned long *pagelist; + unsigned long byte_count; + enum { + _DRM_DMA_USE_AGP = 0x01, + _DRM_DMA_USE_SG = 0x02 + } flags; +} drm_device_dma_t; + +typedef struct drm_agp_mem { + void *handle; + unsigned long bound; /* address */ + int pages; + caddr_t phys_addr; + struct drm_agp_mem *prev; + struct drm_agp_mem *next; +} drm_agp_mem_t; + +typedef struct drm_agp_head { + agp_info_t agp_info; + const char *chipset; + drm_agp_mem_t *memory; + unsigned long mode; + int enabled; + int acquired; + unsigned long base; + int mtrr; + int cant_use_aperture; + unsigned long page_mask; + ldi_ident_t agpgart_li; + ldi_handle_t agpgart_lh; +} drm_agp_head_t; + + +typedef struct drm_dma_handle { + ddi_dma_handle_t dma_hdl; + ddi_acc_handle_t acc_hdl; + ddi_dma_cookie_t cookie; + uint_t cookie_num; + uintptr_t vaddr; /* virtual addr */ + uintptr_t paddr; /* physical addr */ + size_t real_sz; /* real size of memory */ +} drm_dma_handle_t; + +typedef struct drm_sg_mem { + unsigned long handle; + void *virtual; + int pages; + dma_addr_t *busaddr; + ddi_umem_cookie_t *umem_cookie; + drm_dma_handle_t *dmah_sg; + drm_dma_handle_t *dmah_gart; /* Handle to PCI memory */ +} drm_sg_mem_t; + +typedef TAILQ_HEAD(drm_map_list, drm_local_map) drm_map_list_t; + +/* BEGIN CSTYLED */ +typedef struct drm_local_map { + unsigned long offset; /* Physical address (0 for SAREA) */ + unsigned long size; /* Physical size (bytes) */ + drm_map_type_t type; /* Type of memory mapped */ + drm_map_flags_t flags; /* Flags */ + void *handle; /* User-space: "Handle" to pass to mmap */ + /* Kernel-space: kernel-virtual address */ + int mtrr; /* Boolean: MTRR used */ + /* Private data */ + int rid; /* PCI resource ID for bus_space */ + int kernel_owned; /* Boolean: 1= initmapped, 0= addmapped */ + caddr_t dev_addr; /* base device address */ + ddi_acc_handle_t dev_handle; /* The data access handle */ + ddi_umem_cookie_t drm_umem_cookie; /* For SAREA alloc and free */ + TAILQ_ENTRY(drm_local_map) link; +} drm_local_map_t; +/* END CSTYLED */ + +typedef TAILQ_HEAD(drm_vbl_sig_list, drm_vbl_sig) drm_vbl_sig_list_t; +typedef struct drm_vbl_sig { + TAILQ_ENTRY(drm_vbl_sig) link; + unsigned int sequence; + int signo; + int pid; +} drm_vbl_sig_t; + + +/* used for clone device */ +typedef TAILQ_HEAD(drm_cminor_list, drm_cminor) drm_cminor_list_t; +typedef struct drm_cminor { + TAILQ_ENTRY(drm_cminor) link; + drm_file_t *fpriv; + int minor; +} drm_cminor_t; + +/* location of GART table */ +#define DRM_ATI_GART_MAIN 1 +#define DRM_ATI_GART_FB 2 + +typedef struct ati_pcigart_info { + int gart_table_location; + int is_pcie; + void *addr; + dma_addr_t bus_addr; + drm_local_map_t mapping; +} drm_ati_pcigart_info; + +/* DRM device structure */ +struct drm_device; +struct drm_driver_info { + int (*load)(struct drm_device *, unsigned long); + int (*firstopen)(struct drm_device *); + int (*open)(struct drm_device *, drm_file_t *); + void (*preclose)(struct drm_device *, drm_file_t *); + void (*postclose)(struct drm_device *, drm_file_t *); + void (*lastclose)(struct drm_device *); + int (*unload)(struct drm_device *); + void (*reclaim_buffers_locked)(struct drm_device *, drm_file_t *); + int (*presetup)(struct drm_device *); + int (*postsetup)(struct drm_device *); + int (*open_helper)(struct drm_device *, drm_file_t *); + void (*free_filp_priv)(struct drm_device *, drm_file_t *); + void (*release)(struct drm_device *, void *); + int (*dma_ioctl)(DRM_IOCTL_ARGS); + void (*dma_ready)(struct drm_device *); + int (*dma_quiescent)(struct drm_device *); + int (*dma_flush_block_and_flush)(struct drm_device *, + int, drm_lock_flags_t); + int (*dma_flush_unblock)(struct drm_device *, int, + drm_lock_flags_t); + int (*context_ctor)(struct drm_device *, int); + int (*context_dtor)(struct drm_device *, int); + int (*kernel_context_switch)(struct drm_device *, int, int); + int (*kernel_context_switch_unlock)(struct drm_device *); + int (*device_is_agp) (struct drm_device *); + int (*irq_preinstall)(struct drm_device *); + void (*irq_postinstall)(struct drm_device *); + void (*irq_uninstall)(struct drm_device *dev); + uint_t (*irq_handler)(DRM_IRQ_ARGS); + int (*vblank_wait)(struct drm_device *, unsigned int *); + int (*vblank_wait2)(struct drm_device *, unsigned int *); + /* added for intel minimized vblank */ + u32 (*get_vblank_counter)(struct drm_device *dev, int crtc); + int (*enable_vblank)(struct drm_device *dev, int crtc); + void (*disable_vblank)(struct drm_device *dev, int crtc); + + drm_ioctl_desc_t *driver_ioctls; + int max_driver_ioctl; + + int buf_priv_size; + int driver_major; + int driver_minor; + int driver_patchlevel; + const char *driver_name; /* Simple driver name */ + const char *driver_desc; /* Longer driver name */ + const char *driver_date; /* Date of last major changes. */ + + unsigned use_agp :1; + unsigned require_agp :1; + unsigned use_sg :1; + unsigned use_dma :1; + unsigned use_pci_dma :1; + unsigned use_dma_queue :1; + unsigned use_irq :1; + unsigned use_vbl_irq :1; + unsigned use_vbl_irq2 :1; + unsigned use_mtrr :1; +}; + +/* + * hardware-specific code needs to initialize mutexes which + * can be used in interrupt context, so they need to know + * the interrupt priority. Interrupt cookie in drm_device + * structure is the intr_block field. + */ +#define DRM_INTR_PRI(dev) \ + DDI_INTR_PRI((dev)->intr_block) + +struct drm_device { + drm_driver_t *driver; + drm_cminor_list_t minordevs; + dev_info_t *dip; + void *drm_handle; + int drm_supported; + const char *desc; /* current driver description */ + kmutex_t *irq_mutex; + kcondvar_t *irq_cv; + + ddi_iblock_cookie_t intr_block; + uint32_t pci_device; /* PCI device id */ + uint32_t pci_vendor; + char *unique; /* Unique identifier: e.g., busid */ + int unique_len; /* Length of unique field */ + int if_version; /* Highest interface version set */ + int flags; /* Flags to open(2) */ + + /* Locks */ + kmutex_t vbl_lock; /* protects vblank operations */ + kmutex_t dma_lock; /* protects dev->dma */ + kmutex_t irq_lock; /* protects irq condition checks */ + kmutex_t dev_lock; /* protects everything else */ + drm_lock_data_t lock; /* Information on hardware lock */ + + /* Usage Counters */ + int open_count; /* Outstanding files open */ + int buf_use; /* Buffers in use -- cannot alloc */ + + /* Performance counters */ + unsigned long counters; + drm_stat_type_t types[15]; + uint32_t counts[15]; + + /* Authentication */ + drm_file_list_t files; + drm_magic_head_t magiclist[DRM_HASH_SIZE]; + + /* Linked list of mappable regions. Protected by dev_lock */ + drm_map_list_t maplist; + + drm_local_map_t **context_sareas; + int max_context; + + /* DMA queues (contexts) */ + drm_device_dma_t *dma; /* Optional pointer for DMA support */ + + /* Context support */ + int irq; /* Interrupt used by board */ + int irq_enabled; /* True if the irq handler is enabled */ + int pci_domain; + int pci_bus; + int pci_slot; + int pci_func; + atomic_t context_flag; /* Context swapping flag */ + int last_context; /* Last current context */ + + /* Only used for Radeon */ + atomic_t vbl_received; + atomic_t vbl_received2; + + drm_vbl_sig_list_t vbl_sig_list; + drm_vbl_sig_list_t vbl_sig_list2; + + wait_queue_head_t vbl_queue; /* vbl wait channel */ + /* vbl wait channel array */ + wait_queue_head_t *vbl_queues; + + /* number of VBLANK interrupts */ + /* (driver must alloc the right number of counters) */ + atomic_t *_vblank_count; + /* signal list to send on VBLANK */ + struct drm_vbl_sig_list *vbl_sigs; + + /* number of signals pending on all crtcs */ + atomic_t vbl_signal_pending; + /* number of users of vblank interrupts per crtc */ + atomic_t *vblank_refcount; + /* protected by dev->vbl_lock, used for wraparound handling */ + u32 *last_vblank; + /* so we don't call enable more than */ + atomic_t *vblank_enabled; + /* for compensation of spurious wraparounds */ + u32 *vblank_premodeset; + /* Don't wait while crtc is likely disabled */ + int *vblank_suspend; + /* size of vblank counter register */ + u32 max_vblank_count; + int num_crtcs; + kmutex_t tasklet_lock; + void (*locked_tasklet_func)(struct drm_device *dev); + + pid_t buf_pgid; + drm_agp_head_t *agp; + drm_sg_mem_t *sg; /* Scatter gather memory */ + uint32_t *ctx_bitmap; + void *dev_private; + unsigned int agp_buffer_token; + drm_local_map_t *agp_buffer_map; + + kstat_t *asoft_ksp; /* kstat support */ + + /* name Drawable information */ + kmutex_t drw_lock; + unsigned int drw_bitfield_length; + u32 *drw_bitfield; + unsigned int drw_info_length; + drm_drawable_info_t **drw_info; + /* + * Saving S3 context + */ + void *s3_private; +}; + +/* Memory management support (drm_memory.c) */ +void drm_mem_init(void); +void drm_mem_uninit(void); +void *drm_alloc(size_t, int); +void *drm_calloc(size_t, size_t, int); +void *drm_realloc(void *, size_t, size_t, int); +void drm_free(void *, size_t, int); +int drm_ioremap(drm_device_t *, drm_local_map_t *); +void drm_ioremapfree(drm_local_map_t *); + +void drm_core_ioremap(struct drm_local_map *, struct drm_device *); +void drm_core_ioremapfree(struct drm_local_map *, struct drm_device *); + +void drm_pci_free(drm_device_t *, drm_dma_handle_t *); +void *drm_pci_alloc(drm_device_t *, size_t, size_t, dma_addr_t, int); + +struct drm_local_map *drm_core_findmap(struct drm_device *, unsigned long); + +int drm_context_switch(drm_device_t *, int, int); +int drm_context_switch_complete(drm_device_t *, int); +int drm_ctxbitmap_init(drm_device_t *); +void drm_ctxbitmap_cleanup(drm_device_t *); +void drm_ctxbitmap_free(drm_device_t *, int); +int drm_ctxbitmap_next(drm_device_t *); + +/* Locking IOCTL support (drm_lock.c) */ +int drm_lock_take(drm_lock_data_t *, unsigned int); +int drm_lock_transfer(drm_device_t *, + drm_lock_data_t *, unsigned int); +int drm_lock_free(drm_device_t *, + volatile unsigned int *, unsigned int); + +/* Buffer management support (drm_bufs.c) */ +unsigned long drm_get_resource_start(drm_device_t *, unsigned int); +unsigned long drm_get_resource_len(drm_device_t *, unsigned int); +int drm_initmap(drm_device_t *, unsigned long, unsigned long, + unsigned int, int, int); +void drm_rmmap(drm_device_t *, drm_local_map_t *); +int drm_addmap(drm_device_t *, unsigned long, unsigned long, + drm_map_type_t, drm_map_flags_t, drm_local_map_t **); +int drm_order(unsigned long); + +/* DMA support (drm_dma.c) */ +int drm_dma_setup(drm_device_t *); +void drm_dma_takedown(drm_device_t *); +void drm_free_buffer(drm_device_t *, drm_buf_t *); +void drm_reclaim_buffers(drm_device_t *, drm_file_t *); +#define drm_core_reclaim_buffers drm_reclaim_buffers + +/* IRQ support (drm_irq.c) */ +int drm_irq_install(drm_device_t *); +int drm_irq_uninstall(drm_device_t *); +uint_t drm_irq_handler(DRM_IRQ_ARGS); +void drm_driver_irq_preinstall(drm_device_t *); +void drm_driver_irq_postinstall(drm_device_t *); +void drm_driver_irq_uninstall(drm_device_t *); +int drm_vblank_wait(drm_device_t *, unsigned int *); +void drm_vbl_send_signals(drm_device_t *); +void drm_handle_vblank(struct drm_device *dev, int crtc); +u32 drm_vblank_count(struct drm_device *dev, int crtc); +int drm_vblank_get(struct drm_device *dev, int crtc); +void drm_vblank_put(struct drm_device *dev, int crtc); +int drm_vblank_init(struct drm_device *dev, int num_crtcs); +void drm_locked_tasklet(drm_device_t *, void(*func)(drm_device_t *)); + +/* AGP/GART support (drm_agpsupport.c) */ +int drm_device_is_agp(drm_device_t *); +int drm_device_is_pcie(drm_device_t *); +drm_agp_head_t *drm_agp_init(drm_device_t *); +void drm_agp_fini(drm_device_t *); +int drm_agp_do_release(drm_device_t *); +void *drm_agp_allocate_memory(size_t, uint32_t); +int drm_agp_free_memory(void *); +int drm_agp_bind_memory(unsigned int, uint32_t, drm_device_t *); +int drm_agp_unbind_memory(unsigned long, drm_device_t *); + +/* kstat support (drm_kstats.c) */ +int drm_init_kstats(drm_device_t *); +void drm_fini_kstats(drm_device_t *); + +/* Scatter Gather Support (drm_scatter.c) */ +void drm_sg_cleanup(drm_device_t *, drm_sg_mem_t *); + +/* ATI PCIGART support (ati_pcigart.c) */ +int drm_ati_pcigart_init(drm_device_t *, drm_ati_pcigart_info *); +int drm_ati_pcigart_cleanup(drm_device_t *, drm_ati_pcigart_info *); + +/* Locking IOCTL support (drm_drv.c) */ +int drm_lock(DRM_IOCTL_ARGS); +int drm_unlock(DRM_IOCTL_ARGS); +int drm_version(DRM_IOCTL_ARGS); +int drm_setversion(DRM_IOCTL_ARGS); + +/* Misc. IOCTL support (drm_ioctl.c) */ +int drm_irq_by_busid(DRM_IOCTL_ARGS); +int drm_getunique(DRM_IOCTL_ARGS); +int drm_setunique(DRM_IOCTL_ARGS); +int drm_getmap(DRM_IOCTL_ARGS); +int drm_getclient(DRM_IOCTL_ARGS); +int drm_getstats(DRM_IOCTL_ARGS); +int drm_noop(DRM_IOCTL_ARGS); + +/* Context IOCTL support (drm_context.c) */ +int drm_resctx(DRM_IOCTL_ARGS); +int drm_addctx(DRM_IOCTL_ARGS); +int drm_modctx(DRM_IOCTL_ARGS); +int drm_getctx(DRM_IOCTL_ARGS); +int drm_switchctx(DRM_IOCTL_ARGS); +int drm_newctx(DRM_IOCTL_ARGS); +int drm_rmctx(DRM_IOCTL_ARGS); +int drm_setsareactx(DRM_IOCTL_ARGS); +int drm_getsareactx(DRM_IOCTL_ARGS); + +/* Drawable IOCTL support (drm_drawable.c) */ +int drm_adddraw(DRM_IOCTL_ARGS); +int drm_rmdraw(DRM_IOCTL_ARGS); +int drm_update_draw(DRM_IOCTL_ARGS); + +/* Authentication IOCTL support (drm_auth.c) */ +int drm_getmagic(DRM_IOCTL_ARGS); +int drm_authmagic(DRM_IOCTL_ARGS); +int drm_remove_magic(drm_device_t *, drm_magic_t); +drm_file_t *drm_find_file(drm_device_t *, drm_magic_t); +/* Buffer management support (drm_bufs.c) */ +int drm_addmap_ioctl(DRM_IOCTL_ARGS); +int drm_rmmap_ioctl(DRM_IOCTL_ARGS); +int drm_addbufs_ioctl(DRM_IOCTL_ARGS); +int drm_infobufs(DRM_IOCTL_ARGS); +int drm_markbufs(DRM_IOCTL_ARGS); +int drm_freebufs(DRM_IOCTL_ARGS); +int drm_mapbufs(DRM_IOCTL_ARGS); + +/* DMA support (drm_dma.c) */ +int drm_dma(DRM_IOCTL_ARGS); + +/* IRQ support (drm_irq.c) */ +int drm_control(DRM_IOCTL_ARGS); +int drm_wait_vblank(DRM_IOCTL_ARGS); + +/* AGP/GART support (drm_agpsupport.c) */ +int drm_agp_acquire(DRM_IOCTL_ARGS); +int drm_agp_release(DRM_IOCTL_ARGS); +int drm_agp_enable(DRM_IOCTL_ARGS); +int drm_agp_info(DRM_IOCTL_ARGS); +int drm_agp_alloc(DRM_IOCTL_ARGS); +int drm_agp_free(DRM_IOCTL_ARGS); +int drm_agp_unbind(DRM_IOCTL_ARGS); +int drm_agp_bind(DRM_IOCTL_ARGS); + +/* Scatter Gather Support (drm_scatter.c) */ +int drm_sg_alloc(DRM_IOCTL_ARGS); +int drm_sg_free(DRM_IOCTL_ARGS); + +extern int drm_debug_flag; + + +/* We add function to support DRM_DEBUG,DRM_ERROR,DRM_INFO */ +extern void drm_debug(const char *fmt, ...); +extern void drm_error(const char *fmt, ...); +extern void drm_info(const char *fmt, ...); + +#ifdef DEBUG +#define DRM_DEBUG if (drm_debug_flag >= 2) drm_debug +#define DRM_INFO if (drm_debug_flag >= 1) drm_info +#else +#define DRM_DEBUG(...) +#define DRM_INFO(...) +#endif + +#define DRM_ERROR drm_error + + +#define MAX_INSTNUMS 16 + +extern int drm_dev_to_instance(dev_t); +extern int drm_dev_to_minor(dev_t); +extern void *drm_supp_register(dev_info_t *, drm_device_t *); +extern int drm_supp_unregister(void *); + +extern int drm_open(drm_device_t *, drm_cminor_t *, int, int, cred_t *); +extern int drm_close(drm_device_t *, int, int, int, cred_t *); +extern int drm_attach(drm_device_t *); +extern int drm_detach(drm_device_t *); +extern int drm_probe(drm_device_t *, drm_pci_id_list_t *); + +extern int drm_pci_init(drm_device_t *); +extern void drm_pci_end(drm_device_t *); +extern int pci_get_info(drm_device_t *, int *, int *, int *); +extern int pci_get_irq(drm_device_t *); +extern int pci_get_vendor(drm_device_t *); +extern int pci_get_device(drm_device_t *); + +extern struct drm_drawable_info *drm_get_drawable_info(drm_device_t *, + drm_drawable_t); +/* File Operations helpers (drm_fops.c) */ +extern drm_file_t *drm_find_file_by_proc(drm_device_t *, cred_t *); +extern drm_cminor_t *drm_find_file_by_minor(drm_device_t *, int); +extern int drm_open_helper(drm_device_t *, drm_cminor_t *, int, int, + cred_t *); + +#endif /* _DRMP_H */ diff --git a/src/VBox/Additions/solaris/DRM/include/drm_atomic.h b/src/VBox/Additions/solaris/DRM/include/drm_atomic.h new file mode 100644 index 00000000..05401cc4 --- /dev/null +++ b/src/VBox/Additions/solaris/DRM/include/drm_atomic.h @@ -0,0 +1,94 @@ +/* + * Copyright 2009-2010 Oracle Corporation + * All rights reserved. + * Use is subject to license terms. + */ +/* + * \file drm_atomic.h + * Atomic operations used in the DRM which may or may not be provided by the OS. + * + * \author Eric Anholt <anholt@FreeBSD.org> + */ + +/* + * Copyright 2004 Eric Anholt + * 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 + * VA LINUX SYSTEMS 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. + */ + +/* Many of these implementations are rather fake, but good enough. */ + + + +#ifndef _SYS_DRM_ATOMIC_H_ +#define _SYS_DRM_ATOMIC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <sys/atomic.h> + +#ifdef __LINT__ +#undef inline +#define inline +#endif +typedef uint32_t atomic_t; + +#define atomic_set(p, v) (*(p) = (v)) +#define atomic_read(p) (*(p)) +#define atomic_inc(p) atomic_add_int(p, 1) +#define atomic_dec(p) atomic_dec_uint(p) +#define atomic_add(n, p) atomic_add_int(p, n) +#define atomic_sub(n, p) atomic_dec_uint(p, n) +#define atomic_set_int(p, bits) atomic_or_uint(p, bits) +#define atomic_clear_int(p, bits) atomic_and_uint(p, ~(bits)) +#define atomic_cmpset_int(p, c, n) \ + ((c == atomic_cas_uint(p, c, n)) ? 1 : 0) + +#define set_bit(b, p) \ + atomic_set_int(((volatile uint_t *)(void *)p) + (b >> 5), \ + 1 << (b & 0x1f)) + +#define clear_bit(b, p) \ + atomic_clear_int(((volatile uint_t *)(void *)p) + (b >> 5), \ + 1 << (b & 0x1f)) + +#define test_bit(b, p) \ + (((volatile uint_t *)(void *)p)[b >> 5] & (1 << (b & 0x1f))) + +/* + * Note: this routine doesn't return old value. It return + * 0 when succeeds, or -1 when fails. + */ +#ifdef _LP64 +#define test_and_set_bit(b, p) \ + atomic_set_long_excl(((ulong_t *)(void *)p) + (b >> 6), (b & 0x3f)) +#else +#define test_and_set_bit(b, p) \ + atomic_set_long_excl(((ulong_t *)(void *)p) + (b >> 5), (b & 0x1f)) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_DRM_ATOMIC_H_ */ diff --git a/src/VBox/Additions/solaris/DRM/include/drm_linux_list.h b/src/VBox/Additions/solaris/DRM/include/drm_linux_list.h new file mode 100644 index 00000000..e811c9fe --- /dev/null +++ b/src/VBox/Additions/solaris/DRM/include/drm_linux_list.h @@ -0,0 +1,71 @@ +/* + * drm_linux_list.h -- linux list functions for the BSDs. + * Created: Mon Apr 7 14:30:16 1999 by anholt@FreeBSD.org + */ +/* + * - + * Copyright 2003 Eric Anholt + * 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 + * VA LINUX SYSTEMS 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: + * Eric Anholt <anholt@FreeBSD.org> + * + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifndef _DRM_LINUX_LIST_H_ +#define _DRM_LINUX_LIST_H_ + +struct list_head { + struct list_head *next, *prev; +}; + +/* Cheat, assume the list_head is at the start of the struct */ +#define list_entry(entry, type, member) (type *)(entry) + +#define INIT_LIST_HEAD(head) { \ + (head)->next = head; \ + (head)->prev = head; \ +} + +#define list_add_tail(entry, head) { \ + (entry)->prev = (head)->prev; \ + (entry)->next = head; \ + (head)->prev->next = entry; \ + (head)->prev = entry; \ +} + +#define list_del(entry) { \ + (entry)->next->prev = (entry)->prev; \ + (entry)->prev->next = (entry)->next; \ +} + +#define list_for_each(entry, head) \ + for (entry = (head)->next; entry != head; entry = (entry)->next) + +#define list_for_each_safe(entry, temp, head) \ + for (entry = (head)->next, temp = (entry)->next; \ + temp != head; \ + entry = temp, temp = temp->next) + +#endif /* _DRM_LINUX_LIST_H_ */ diff --git a/src/VBox/Additions/solaris/DRM/include/queue.h b/src/VBox/Additions/solaris/DRM/include/queue.h new file mode 100644 index 00000000..4994209e --- /dev/null +++ b/src/VBox/Additions/solaris/DRM/include/queue.h @@ -0,0 +1,585 @@ +/* BEGIN CSTYLED */ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + * $FreeBSD: /repoman/r/ncvs/src/sys/sys/queue.h,v 1.66 2006/05/26 18:17:53 emaste Exp $ + */ + +#ifndef _SYS_QUEUE_H_ +#define _SYS_QUEUE_H_ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * This file defines four types of data structures: singly-linked lists, + * singly-linked tail queues, lists and tail queues. + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A singly-linked tail queue is headed by a pair of pointers, one to the + * head of the list and the other to the tail of the list. The elements are + * singly linked for minimum space and pointer manipulation overhead at the + * expense of O(n) removal for arbitrary elements. New elements can be added + * to the list after an existing element, at the head of the list, or at the + * end of the list. Elements being removed from the head of the tail queue + * should use the explicit macro for this purpose for optimum efficiency. + * A singly-linked tail queue may only be traversed in the forward direction. + * Singly-linked tail queues are ideal for applications with large datasets + * and few or no removals or for implementing a FIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * For details on the use of these macros, see the queue(3) manual page. + * + * + * SLIST LIST STAILQ TAILQ + * _HEAD + + + + + * _HEAD_INITIALIZER + + + + + * _ENTRY + + + + + * _INIT + + + + + * _EMPTY + + + + + * _FIRST + + + + + * _NEXT + + + + + * _PREV - - - + + * _LAST - - + + + * _FOREACH + + + + + * _FOREACH_SAFE + + + + + * _FOREACH_REVERSE - - - + + * _FOREACH_REVERSE_SAFE - - - + + * _INSERT_HEAD + + + + + * _INSERT_BEFORE - + - + + * _INSERT_AFTER + + + + + * _INSERT_TAIL - - + + + * _CONCAT - - + + + * _REMOVE_HEAD + - + - + * _REMOVE + + + + + * + */ +#ifdef QUEUE_MACRO_DEBUG +/* Store the last 2 places the queue element or head was altered */ +struct qm_trace { + char * lastfile; + int lastline; + char * prevfile; + int prevline; +}; + +#define TRACEBUF struct qm_trace trace; +#define TRASHIT(x) do {(x) = (void *)-1;} while (*"\0") + +#define QMD_TRACE_HEAD(head) do { \ + (head)->trace.prevline = (head)->trace.lastline; \ + (head)->trace.prevfile = (head)->trace.lastfile; \ + (head)->trace.lastline = __LINE__; \ + (head)->trace.lastfile = __FILE__; \ +} while (*"\0") + +#define QMD_TRACE_ELEM(elem) do { \ + (elem)->trace.prevline = (elem)->trace.lastline; \ + (elem)->trace.prevfile = (elem)->trace.lastfile; \ + (elem)->trace.lastline = __LINE__; \ + (elem)->trace.lastfile = __FILE__; \ +} while (*"\0") + +#else +#define QMD_TRACE_ELEM(elem) +#define QMD_TRACE_HEAD(head) +#define TRACEBUF +#define TRASHIT(x) +#endif /* QUEUE_MACRO_DEBUG */ + +/* + * Singly-linked List declarations. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List functions. + */ +#define SLIST_EMPTY(head) ((head)->slh_first == NULL) + +#define SLIST_FIRST(head) ((head)->slh_first) + +#define SLIST_FOREACH(var, head, field) \ + for ((var) = SLIST_FIRST((head)); \ + (var); \ + (var) = SLIST_NEXT((var), field)) + +#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = SLIST_FIRST((head)); \ + (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ + for ((varp) = &SLIST_FIRST((head)); \ + ((var) = *(varp)) != NULL; \ + (varp) = &SLIST_NEXT((var), field)) + +#define SLIST_INIT(head) do { \ + SLIST_FIRST((head)) = NULL; \ +} while (*"\0") + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ + SLIST_NEXT((slistelm), field) = (elm); \ +} while (*"\0") + +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ + SLIST_FIRST((head)) = (elm); \ +} while (*"\0") + +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define SLIST_REMOVE(head, elm, type, field) do { \ + if (SLIST_FIRST((head)) == (elm)) { \ + SLIST_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = SLIST_FIRST((head)); \ + while (SLIST_NEXT(curelm, field) != (elm)) \ + curelm = SLIST_NEXT(curelm, field); \ + SLIST_NEXT(curelm, field) = \ + SLIST_NEXT(SLIST_NEXT(curelm, field), field); \ + } \ + TRASHIT((elm)->field.sle_next); \ +} while (*"\0") + +#define SLIST_REMOVE_HEAD(head, field) do { \ + SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ +} while (*"\0") + +/* + * Singly-linked Tail queue declarations. + */ +#define STAILQ_HEAD(name, type) \ +struct name { \ + struct type *stqh_first;/* first element */ \ + struct type **stqh_last;/* addr of last next element */ \ +} + +#define STAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).stqh_first } + +#define STAILQ_ENTRY(type) \ +struct { \ + struct type *stqe_next; /* next element */ \ +} + +/* + * Singly-linked Tail queue functions. + */ +#define STAILQ_CONCAT(head1, head2) do { \ + if (!STAILQ_EMPTY((head2))) { \ + *(head1)->stqh_last = (head2)->stqh_first; \ + (head1)->stqh_last = (head2)->stqh_last; \ + STAILQ_INIT((head2)); \ + } \ +} while (*"\0") + +#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) + +#define STAILQ_FIRST(head) ((head)->stqh_first) + +#define STAILQ_FOREACH(var, head, field) \ + for((var) = STAILQ_FIRST((head)); \ + (var); \ + (var) = STAILQ_NEXT((var), field)) + + +#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = STAILQ_FIRST((head)); \ + (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define STAILQ_INIT(head) do { \ + STAILQ_FIRST((head)) = NULL; \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (*"\0") + +#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_NEXT((tqelm), field) = (elm); \ +} while (*"\0") + +#define STAILQ_INSERT_HEAD(head, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_FIRST((head)) = (elm); \ +} while (*"\0") + +#define STAILQ_INSERT_TAIL(head, elm, field) do { \ + STAILQ_NEXT((elm), field) = NULL; \ + *(head)->stqh_last = (elm); \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ +} while (*"\0") + +#define STAILQ_LAST(head, type, field) \ + (STAILQ_EMPTY((head)) ? \ + NULL : \ + ((struct type *)(void *) \ + ((char *)((head)->stqh_last) - __offsetof(struct type, field)))) + +#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) + +#define STAILQ_REMOVE(head, elm, type, field) do { \ + if (STAILQ_FIRST((head)) == (elm)) { \ + STAILQ_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = STAILQ_FIRST((head)); \ + while (STAILQ_NEXT(curelm, field) != (elm)) \ + curelm = STAILQ_NEXT(curelm, field); \ + if ((STAILQ_NEXT(curelm, field) = \ + STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\ + (head)->stqh_last = &STAILQ_NEXT((curelm), field);\ + } \ + TRASHIT((elm)->field.stqe_next); \ +} while (*"\0") + +#define STAILQ_REMOVE_HEAD(head, field) do { \ + if ((STAILQ_FIRST((head)) = \ + STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (*"\0") + +#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \ + if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (*"\0") + +/* + * List declarations. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List functions. + */ + +#if (defined(_KERNEL) && defined(INVARIANTS)) +#define QMD_LIST_CHECK_HEAD(head, field) do { \ + if (LIST_FIRST((head)) != NULL && \ + LIST_FIRST((head))->field.le_prev != \ + &LIST_FIRST((head))) \ + panic("Bad list head %p first->prev != head", (head)); \ +} while (*"\0") + +#define QMD_LIST_CHECK_NEXT(elm, field) do { \ + if (LIST_NEXT((elm), field) != NULL && \ + LIST_NEXT((elm), field)->field.le_prev != \ + &((elm)->field.le_next)) \ + panic("Bad link elm %p next->prev != elm", (elm)); \ +} while (*"\0") + +#define QMD_LIST_CHECK_PREV(elm, field) do { \ + if (*(elm)->field.le_prev != (elm)) \ + panic("Bad link elm %p prev->next != elm", (elm)); \ +} while (*"\0") +#else +#define QMD_LIST_CHECK_HEAD(head, field) +#define QMD_LIST_CHECK_NEXT(elm, field) +#define QMD_LIST_CHECK_PREV(elm, field) +#endif /* (_KERNEL && INVARIANTS) */ + +#define LIST_EMPTY(head) ((head)->lh_first == NULL) + +#define LIST_FIRST(head) ((head)->lh_first) + +#define LIST_FOREACH(var, head, field) \ + for ((var) = LIST_FIRST((head)); \ + (var); \ + (var) = LIST_NEXT((var), field)) + +#define LIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = LIST_FIRST((head)); \ + (var) && ((tvar) = LIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define LIST_INIT(head) do { \ + LIST_FIRST((head)) = NULL; \ +} while (*"\0") + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ + QMD_LIST_CHECK_NEXT(listelm, field); \ + if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ + LIST_NEXT((listelm), field)->field.le_prev = \ + &LIST_NEXT((elm), field); \ + LIST_NEXT((listelm), field) = (elm); \ + (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ +} while (*"\0") + +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + QMD_LIST_CHECK_PREV(listelm, field); \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + LIST_NEXT((elm), field) = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ +} while (*"\0") + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + QMD_LIST_CHECK_HEAD((head), field); \ + if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ + LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ + LIST_FIRST((head)) = (elm); \ + (elm)->field.le_prev = &LIST_FIRST((head)); \ +} while (*"\0") + +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_REMOVE(elm, field) do { \ + QMD_LIST_CHECK_NEXT(elm, field); \ + QMD_LIST_CHECK_PREV(elm, field); \ + if (LIST_NEXT((elm), field) != NULL) \ + LIST_NEXT((elm), field)->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = LIST_NEXT((elm), field); \ + TRASHIT((elm)->field.le_next); \ + TRASHIT((elm)->field.le_prev); \ +} while (*"\0") + +/* + * Tail queue declarations. + */ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ + TRACEBUF \ +} + +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first } + +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ + TRACEBUF \ +} + +/* + * Tail queue functions. + */ +#if (defined(_KERNEL) && defined(INVARIANTS)) +#define QMD_TAILQ_CHECK_HEAD(head, field) do { \ + if (!TAILQ_EMPTY(head) && \ + TAILQ_FIRST((head))->field.tqe_prev != \ + &TAILQ_FIRST((head))) \ + panic("Bad tailq head %p first->prev != head", (head)); \ +} while (*"\0") + +#define QMD_TAILQ_CHECK_TAIL(head, field) do { \ + if (*(head)->tqh_last != NULL) \ + panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); \ +} while (*"\0") + +#define QMD_TAILQ_CHECK_NEXT(elm, field) do { \ + if (TAILQ_NEXT((elm), field) != NULL && \ + TAILQ_NEXT((elm), field)->field.tqe_prev != \ + &((elm)->field.tqe_next)) \ + panic("Bad link elm %p next->prev != elm", (elm)); \ +} while (*"\0") + +#define QMD_TAILQ_CHECK_PREV(elm, field) do { \ + if (*(elm)->field.tqe_prev != (elm)) \ + panic("Bad link elm %p prev->next != elm", (elm)); \ +} while (*"\0") +#else +#define QMD_TAILQ_CHECK_HEAD(head, field) +#define QMD_TAILQ_CHECK_TAIL(head, headname) +#define QMD_TAILQ_CHECK_NEXT(elm, field) +#define QMD_TAILQ_CHECK_PREV(elm, field) +#endif /* (_KERNEL && INVARIANTS) */ + +#define TAILQ_CONCAT(head1, head2, field) do { \ + if (!TAILQ_EMPTY(head2)) { \ + *(head1)->tqh_last = (head2)->tqh_first; \ + (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ + (head1)->tqh_last = (head2)->tqh_last; \ + TAILQ_INIT((head2)); \ + QMD_TRACE_HEAD(head1); \ + QMD_TRACE_HEAD(head2); \ + } \ +} while (*"\0") + +#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) + +#define TAILQ_FIRST(head) ((head)->tqh_first) + +#define TAILQ_FOREACH(var, head, field) \ + for ((var) = TAILQ_FIRST((head)); \ + (var); \ + (var) = TAILQ_NEXT((var), field)) + +#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = TAILQ_FIRST((head)); \ + (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ + for ((var) = TAILQ_LAST((head), headname); \ + (var); \ + (var) = TAILQ_PREV((var), headname, field)) + +#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ + for ((var) = TAILQ_LAST((head), headname); \ + (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ + (var) = (tvar)) + +#define TAILQ_INIT(head) do { \ + TAILQ_FIRST((head)) = NULL; \ + (head)->tqh_last = &TAILQ_FIRST((head)); \ + QMD_TRACE_HEAD(head); \ +} while (*"\0") + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + QMD_TAILQ_CHECK_NEXT(listelm, field); \ + if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ + &TAILQ_NEXT((elm), field); \ + else { \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_HEAD(head); \ + } \ + TAILQ_NEXT((listelm), field) = (elm); \ + (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ + QMD_TRACE_ELEM(&(elm)->field); \ + QMD_TRACE_ELEM(&listelm->field); \ +} while (*"\0") + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + QMD_TAILQ_CHECK_PREV(listelm, field); \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + TAILQ_NEXT((elm), field) = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_ELEM(&(elm)->field); \ + QMD_TRACE_ELEM(&listelm->field); \ +} while (*"\0") + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ + QMD_TAILQ_CHECK_HEAD(head, field); \ + if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ + TAILQ_FIRST((head))->field.tqe_prev = \ + &TAILQ_NEXT((elm), field); \ + else \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + TAILQ_FIRST((head)) = (elm); \ + (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ + QMD_TRACE_HEAD(head); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (*"\0") + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + QMD_TAILQ_CHECK_TAIL(head, field); \ + TAILQ_NEXT((elm), field) = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_HEAD(head); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (*"\0") + +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) + +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) + +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) + +#define TAILQ_REMOVE(head, elm, field) do { \ + QMD_TAILQ_CHECK_NEXT(elm, field); \ + QMD_TAILQ_CHECK_PREV(elm, field); \ + if ((TAILQ_NEXT((elm), field)) != NULL) \ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else { \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + QMD_TRACE_HEAD(head); \ + } \ + *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ + TRASHIT((elm)->field.tqe_next); \ + TRASHIT((elm)->field.tqe_prev); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (*"\0") + + +#ifdef _KERNEL + +#endif /* _KERNEL */ + +#endif /* !_SYS_QUEUE_H_ */ + +/* END CSTYLED */ |