/************************************************************************** * * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA * 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, sub license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS, AUTHORS 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. * **************************************************************************/ #ifndef __VMWGFX_DRM_H__ #define __VMWGFX_DRM_H__ #define DRM_VMW_MAX_SURFACE_FACES 6 #define DRM_VMW_MAX_MIP_LEVELS 24 #define DRM_VMW_EXT_NAME_LEN 128 #define DRM_VMW_GET_PARAM 0 #define DRM_VMW_ALLOC_DMABUF 1 #define DRM_VMW_UNREF_DMABUF 2 #define DRM_VMW_CURSOR_BYPASS 3 /* guarded by DRM_VMW_PARAM_NUM_STREAMS != 0*/ #define DRM_VMW_CONTROL_STREAM 4 #define DRM_VMW_CLAIM_STREAM 5 #define DRM_VMW_UNREF_STREAM 6 /* guarded by DRM_VMW_PARAM_3D == 1 */ #define DRM_VMW_CREATE_CONTEXT 7 #define DRM_VMW_UNREF_CONTEXT 8 #define DRM_VMW_CREATE_SURFACE 9 #define DRM_VMW_UNREF_SURFACE 10 #define DRM_VMW_REF_SURFACE 11 #define DRM_VMW_EXECBUF 12 #define DRM_VMW_FIFO_DEBUG 13 #define DRM_VMW_FENCE_WAIT 14 /* guarded by minor version >= 2 */ #define DRM_VMW_UPDATE_LAYOUT 15 /*************************************************************************/ /** * DRM_VMW_GET_PARAM - get device information. * * DRM_VMW_PARAM_FIFO_OFFSET: * Offset to use to map the first page of the FIFO read-only. * The fifo is mapped using the mmap() system call on the drm device. * * DRM_VMW_PARAM_OVERLAY_IOCTL: * Does the driver support the overlay ioctl. */ #define DRM_VMW_PARAM_NUM_STREAMS 0 #define DRM_VMW_PARAM_NUM_FREE_STREAMS 1 #define DRM_VMW_PARAM_3D 2 #define DRM_VMW_PARAM_FIFO_OFFSET 3 #define DRM_VMW_PARAM_HW_CAPS 4 #define DRM_VMW_PARAM_FIFO_CAPS 5 /** * struct drm_vmw_getparam_arg * * @value: Returned value. //Out * @param: Parameter to query. //In. * * Argument to the DRM_VMW_GET_PARAM Ioctl. */ struct drm_vmw_getparam_arg { uint64_t value; uint32_t param; uint32_t pad64; }; /*************************************************************************/ /** * DRM_VMW_EXTENSION - Query device extensions. */ /** * struct drm_vmw_extension_rep * * @exists: The queried extension exists. * @driver_ioctl_offset: Ioctl number of the first ioctl in the extension. * @driver_sarea_offset: Offset to any space in the DRI SAREA * used by the extension. * @major: Major version number of the extension. * @minor: Minor version number of the extension. * @pl: Patch level version number of the extension. * * Output argument to the DRM_VMW_EXTENSION Ioctl. */ struct drm_vmw_extension_rep { int32_t exists; uint32_t driver_ioctl_offset; uint32_t driver_sarea_offset; uint32_t major; uint32_t minor; uint32_t pl; uint32_t pad64; }; /** * union drm_vmw_extension_arg * * @extension - Ascii name of the extension to be queried. //In * @rep - Reply as defined above. //Out * * Argument to the DRM_VMW_EXTENSION Ioctl. */ union drm_vmw_extension_arg { char extension[DRM_VMW_EXT_NAME_LEN]; struct drm_vmw_extension_rep rep; }; /*************************************************************************/ /** * DRM_VMW_CREATE_CONTEXT - Create a host context. * * Allocates a device unique context id, and queues a create context command * for the host. Does not wait for host completion. */ /** * struct drm_vmw_context_arg * * @cid: Device unique context ID. * * Output argument to the DRM_VMW_CREATE_CONTEXT Ioctl. * Input argument to the DRM_VMW_UNREF_CONTEXT Ioctl. */ struct drm_vmw_context_arg { int32_t cid; uint32_t pad64; }; /*************************************************************************/ /** * DRM_VMW_UNREF_CONTEXT - Create a host context. * * Frees a global context id, and queues a destroy host command for the host. * Does not wait for host completion. The context ID can be used directly * in the command stream and shows up as the same context ID on the host. */ /*************************************************************************/ /** * DRM_VMW_CREATE_SURFACE - Create a host suface. * * Allocates a device unique surface id, and queues a create surface command * for the host. Does not wait for host completion. The surface ID can be * used directly in the command stream and shows up as the same surface * ID on the host. */ /** * struct drm_wmv_surface_create_req * * @flags: Surface flags as understood by the host. * @format: Surface format as understood by the host. * @mip_levels: Number of mip levels for each face. * An unused face should have 0 encoded. * @size_addr: Address of a user-space array of sruct drm_vmw_size * cast to an uint64_t for 32-64 bit compatibility. * The size of the array should equal the total number of mipmap levels. * @shareable: Boolean whether other clients (as identified by file descriptors) * may reference this surface. * @scanout: Boolean whether the surface is intended to be used as a * scanout. * * Input data to the DRM_VMW_CREATE_SURFACE Ioctl. * Output data from the DRM_VMW_REF_SURFACE Ioctl. */ struct drm_vmw_surface_create_req { uint32_t flags; uint32_t format; uint32_t mip_levels[DRM_VMW_MAX_SURFACE_FACES]; uint64_t size_addr; int32_t shareable; int32_t scanout; }; /** * struct drm_wmv_surface_arg * * @sid: Surface id of created surface or surface to destroy or reference. * * Output data from the DRM_VMW_CREATE_SURFACE Ioctl. * Input argument to the DRM_VMW_UNREF_SURFACE Ioctl. * Input argument to the DRM_VMW_REF_SURFACE Ioctl. */ struct drm_vmw_surface_arg { int32_t sid; uint32_t pad64; }; /** * struct drm_vmw_size ioctl. * * @width - mip level width * @height - mip level height * @depth - mip level depth * * Description of a mip level. * Input data to the DRM_WMW_CREATE_SURFACE Ioctl. */ struct drm_vmw_size { uint32_t width; uint32_t height; uint32_t depth; uint32_t pad64; }; /** * union drm_vmw_surface_create_arg * * @rep: Output data as described above. * @req: Input data as described above. * * Argument to the DRM_VMW_CREATE_SURFACE Ioctl. */ union drm_vmw_surface_create_arg { struct drm_vmw_surface_arg rep; struct drm_vmw_surface_create_req req; }; /*************************************************************************/ /** * DRM_VMW_REF_SURFACE - Reference a host surface. * * Puts a reference on a host surface with a give sid, as previously * returned by the DRM_VMW_CREATE_SURFACE ioctl. * A reference will make sure the surface isn't destroyed while we hold * it and will allow the calling client to use the surface ID in the command * stream. * * On successful return, the Ioctl returns the surface information given * in the DRM_VMW_CREATE_SURFACE ioctl. */ /** * union drm_vmw_surface_reference_arg * * @rep: Output data as described above. * @req: Input data as described above. * * Argument to the DRM_VMW_REF_SURFACE Ioctl. */ union drm_vmw_surface_reference_arg { struct drm_vmw_surface_create_req rep; struct drm_vmw_surface_arg req; }; /*************************************************************************/ /** * DRM_VMW_UNREF_SURFACE - Unreference a host surface. * * Clear a reference previously put on a host surface. * When all references are gone, including the one implicitly placed * on creation, * a destroy surface command will be queued for the host. * Does not wait for completion. */ /*************************************************************************/ /** * DRM_VMW_EXECBUF * * Submit a command buffer for execution on the host, and return a * fence sequence that when signaled, indicates that the command buffer has * executed. */ /** * struct drm_vmw_execbuf_arg * * @commands: User-space address of a command buffer cast to an uint64_t. * @command-size: Size in bytes of the command buffer. * @throttle-us: Sleep until software is less than @throttle_us * microseconds ahead of hardware. The driver may round this value * to the nearest kernel tick. * @fence_rep: User-space address of a struct drm_vmw_fence_rep cast to an * uint64_t. * @version: Allows expanding the execbuf ioctl parameters without breaking * backwards compatibility, since user-space will always tell the kernel * which version it uses. * @flags: Execbuf flags. None currently. * * Argument to the DRM_VMW_EXECBUF Ioctl. */ #define DRM_VMW_EXECBUF_VERSION 0 struct drm_vmw_execbuf_arg { uint64_t commands; uint32_t command_size; uint32_t throttle_us; uint64_t fence_rep; uint32_t version; uint32_t flags; }; /** * struct drm_vmw_fence_rep * * @fence_seq: Fence sequence associated with a command submission. * @error: This member should've been set to -EFAULT on submission. * The following actions should be take on completion: * error == -EFAULT: Fence communication failed. The host is synchronized. * Use the last fence id read from the FIFO fence register. * error != 0 && error != -EFAULT: * Fence submission failed. The host is synchronized. Use the fence_seq member. * error == 0: All is OK, The host may not be synchronized. * Use the fence_seq member. * * Input / Output data to the DRM_VMW_EXECBUF Ioctl. */ struct drm_vmw_fence_rep { uint64_t fence_seq; int32_t error; uint32_t pad64; }; /*************************************************************************/ /** * DRM_VMW_ALLOC_DMABUF * * Allocate a DMA buffer that is visible also to the host. * NOTE: The buffer is * identified by a handle and an offset, which are private to the guest, but * useable in the command stream. The guest kernel may translate these * and patch up the command stream accordingly. In the future, the offset may * be zero at all times, or it may disappear from the interface before it is * fixed. * * The DMA buffer may stay user-space mapped in the guest at all times, * and is thus suitable for sub-allocation. * * DMA buffers are mapped using the mmap() syscall on the drm device. */ /** * struct drm_vmw_alloc_dmabuf_req * * @size: Required minimum size of the buffer. * * Input data to the DRM_VMW_ALLOC_DMABUF Ioctl. */ struct drm_vmw_alloc_dmabuf_req { uint32_t size; uint32_t pad64; }; /** * struct drm_vmw_dmabuf_rep * * @map_handle: Offset to use in the mmap() call used to map the buffer. * @handle: Handle unique to this buffer. Used for unreferencing. * @cur_gmr_id: GMR id to use in the command stream when this buffer is * referenced. See not above. * @cur_gmr_offset: Offset to use in the command stream when this buffer is * referenced. See note above. * * Output data from the DRM_VMW_ALLOC_DMABUF Ioctl. */ struct drm_vmw_dmabuf_rep { uint64_t map_handle; uint32_t handle; uint32_t cur_gmr_id; uint32_t cur_gmr_offset; uint32_t pad64; }; /** * union drm_vmw_dmabuf_arg * * @req: Input data as described above. * @rep: Output data as described above. * * Argument to the DRM_VMW_ALLOC_DMABUF Ioctl. */ union drm_vmw_alloc_dmabuf_arg { struct drm_vmw_alloc_dmabuf_req req; struct drm_vmw_dmabuf_rep rep; }; /*************************************************************************/ /** * DRM_VMW_UNREF_DMABUF - Free a DMA buffer. * */ /** * struct drm_vmw_unref_dmabuf_arg * * @handle: Handle indicating what buffer to free. Obtained from the * DRM_VMW_ALLOC_DMABUF Ioctl. * * Argument to the DRM_VMW_UNREF_DMABUF Ioctl. */ struct drm_vmw_unref_dmabuf_arg { uint32_t handle; uint32_t pad64; }; /*************************************************************************/ /** * DRM_VMW_FIFO_DEBUG - Get last FIFO submission. * * This IOCTL copies the last FIFO submission directly out of the FIFO buffer. */ /** * struct drm_vmw_fifo_debug_arg * * @debug_buffer: User space address of a debug_buffer cast to an uint64_t //In * @debug_buffer_size: Size in bytes of debug buffer //In * @used_size: Number of bytes copied to the buffer // Out * @did_not_fit: Boolean indicating that the fifo contents did not fit. //Out * * Argument to the DRM_VMW_FIFO_DEBUG Ioctl. */ struct drm_vmw_fifo_debug_arg { uint64_t debug_buffer; uint32_t debug_buffer_size; uint32_t used_size; int32_t did_not_fit; uint32_t pad64; }; struct drm_vmw_fence_wait_arg { uint64_t sequence; uint64_t kernel_cookie; int32_t cookie_valid; int32_t pad64; }; /*************************************************************************/ /** * DRM_VMW_CONTROL_STREAM - Control overlays, aka streams. * * This IOCTL controls the overlay units of the svga device. * The SVGA overlay units does not work like regular hardware units in * that they do not automaticaly read back the contents of the given dma * buffer. But instead only read back for each call to this ioctl, and * at any point between this call being made and a following call that * either changes the buffer or disables the stream. */ /** * struct drm_vmw_rect * * Defines a rectangle. Used in the overlay ioctl to define * source and destination rectangle. */ struct drm_vmw_rect { int32_t x; int32_t y; uint32_t w; uint32_t h; }; /** * struct drm_vmw_control_stream_arg * * @stream_id: Stearm to control * @enabled: If false all following arguments are ignored. * @handle: Handle to buffer for getting data from. * @format: Format of the overlay as understood by the host. * @width: Width of the overlay. * @height: Height of the overlay. * @size: Size of the overlay in bytes. * @pitch: Array of pitches, the two last are only used for YUV12 formats. * @offset: Offset from start of dma buffer to overlay. * @src: Source rect, must be within the defined area above. * @dst: Destination rect, x and y may be negative. * * Argument to the DRM_VMW_CONTROL_STREAM Ioctl. */ struct drm_vmw_control_stream_arg { uint32_t stream_id; uint32_t enabled; uint32_t flags; uint32_t color_key; uint32_t handle; uint32_t offset; int32_t format; uint32_t size; uint32_t width; uint32_t height; uint32_t pitch[3]; uint32_t pad64; struct drm_vmw_rect src; struct drm_vmw_rect dst; }; /*************************************************************************/ /** * DRM_VMW_CURSOR_BYPASS - Give extra information about cursor bypass. * */ #define DRM_VMW_CURSOR_BYPASS_ALL (1 << 0) #define DRM_VMW_CURSOR_BYPASS_FLAGS (1) /** * struct drm_vmw_cursor_bypass_arg * * @flags: Flags. * @crtc_id: Crtc id, only used if DMR_CURSOR_BYPASS_ALL isn't passed. * @xpos: X position of cursor. * @ypos: Y position of cursor. * @xhot: X hotspot. * @yhot: Y hotspot. * * Argument to the DRM_VMW_CURSOR_BYPASS Ioctl. */ struct drm_vmw_cursor_bypass_arg { uint32_t flags; uint32_t crtc_id; int32_t xpos; int32_t ypos; int32_t xhot; int32_t yhot; }; /*************************************************************************/ /** * DRM_VMW_CLAIM_STREAM - Claim a single stream. */ /** * struct drm_vmw_context_arg * * @stream_id: Device unique context ID. * * Output argument to the DRM_VMW_CREATE_CONTEXT Ioctl. * Input argument to the DRM_VMW_UNREF_CONTEXT Ioctl. */ struct drm_vmw_stream_arg { uint32_t stream_id; uint32_t pad64; }; /*************************************************************************/ /** * DRM_VMW_UNREF_STREAM - Unclaim a stream. * * Return a single stream that was claimed by this process. Also makes * sure that the stream has been stopped. */ /*************************************************************************/ /** * DRM_VMW_UPDATE_LAYOUT - Update layout * * Updates the prefered modes and connection status for connectors. The * command conisits of one drm_vmw_update_layout_arg pointing out a array * of num_outputs drm_vmw_rect's. */ /** * struct drm_vmw_update_layout_arg * * @num_outputs: number of active * @rects: pointer to array of drm_vmw_rect * * Input argument to the DRM_VMW_UPDATE_LAYOUT Ioctl. */ struct drm_vmw_update_layout_arg { uint32_t num_outputs; uint32_t pad64; uint64_t rects; }; #endif ' href='#n425'>425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675
/**
 * \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 */
    DRM_CONSISTENT      = 5	  /**< PCI consistent */
} 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,
    DRM_FB_BUFFER        = 0x08
} 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;

typedef struct _drmFence{
        unsigned handle;
        int class;
        unsigned type; 
        unsigned signaled;
} drmFence;

typedef struct _drmTTM{
        unsigned handle;
        drm_handle_t user_token;
        unsigned flags;
        unsigned long size;
        void *virtual;
        int mapCount;
} drmTTM;

#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock)

#define DRM_LOCK_HELD  0x80000000U /**< Hardware lock is held */
#define DRM_LOCK_CONT  0x40000000U /**< Hardware lock is contended */

#if defined(__GNUC__) && (__GNUC__ >= 2)
# if defined(__i386) || defined(__AMD64__) || defined(__x86_64__) || 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);

/* 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,
				 drm_handle_t *handle);
extern int           drmAgpFree(int fd, drm_handle_t handle);
extern int 	     drmAgpBind(int fd, drm_handle_t handle,
				unsigned long offset);
extern int           drmAgpUnbind(int fd, drm_handle_t 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,
					   drm_handle_t *handle);
extern int           drmScatterGatherFree(int fd, drm_handle_t handle);

extern int           drmWaitVBlank(int fd, drmVBlankPtr vbl);

/* Fencing */

extern int           drmFenceCreate(int fd, int shareable, int class,
				    unsigned type, int emit, 
				    drmFence *fence);
extern int           drmFenceDestroy(int fd, const drmFence *fence);
extern int           drmFenceReference(int fd, unsigned handle, drmFence *fence);
extern int           drmFenceUnreference(int fd, const drmFence *fence);
extern int           drmFenceFlush(int fd, drmFence *fence, unsigned flush_type);
extern int           drmFenceSignaled(int fd, drmFence *fence);
extern int           drmFenceWait(int fd, drmFence *fence, unsigned flush_type, 
				  int lazy, int ignore_signals);
extern int           drmFenceEmit(int fd, drmFence *fence, unsigned emit_type);

/* TTMS */
extern int           drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, 
				  unsigned flags);
extern int           drmTTMDestroy(int fd, const drmTTM *ttm);
extern int           drmTTMReference(int fd, unsigned handle, drmTTM *ttm);
extern int           drmTTMUnreference(int fd, const drmTTM *ttm);
extern drm_handle_t  drmTTMMapHandle(int fd, const drmTTM *ttm);


/* 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);

#include "xf86mm.h"

#endif