/*
 * Copyright 2000-2001 VA Linux Systems, Inc.
 * 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
 * on 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
 * 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.
 */

/**
 * \file mgaioctl.c
 * MGA IOCTL related wrapper functions.
 *
 * \author Keith Whitwell <keith@tungstengraphics.com>
 * \author Gareth Hughes <gareth@valinux.com>
 */

#include <errno.h>
#include "mtypes.h"
#include "macros.h"
#include "dd.h"
#include "swrast/swrast.h"

#include "mm.h"
#include "drm.h"
#include "mga_drm.h"
#include "mgacontext.h"
#include "mgadd.h"
#include "mgastate.h"
#include "mgatex.h"
#include "mgavb.h"
#include "mgaioctl.h"
#include "mgatris.h"

#include "vblank.h"


static int
mgaSetFence( mgaContextPtr mmesa, uint32_t * fence )
{
    int ret = ENOSYS;

    if ( mmesa->driScreen->drm_version.minor >= 2 ) {
	ret = drmCommandWriteRead( mmesa->driScreen->fd, DRM_MGA_SET_FENCE,
				   fence, sizeof( uint32_t ));
	if (ret) {
	    fprintf(stderr, "drmMgaSetFence: %d\n", ret);
	    exit(1);
	}
    }

    return ret;
}


static int
mgaWaitFence( mgaContextPtr mmesa, uint32_t fence, uint32_t * curr_fence )
{
    int ret = ENOSYS;

    if ( mmesa->driScreen->drm_version.minor >= 2 ) {
	uint32_t temp = fence;
	
	ret = drmCommandWriteRead( mmesa->driScreen->fd,
				   DRM_MGA_WAIT_FENCE,
				   & temp, sizeof( uint32_t ));
	if (ret) {
	   fprintf(stderr, "drmMgaSetFence: %d\n", ret);
	    exit(1);
	}

	if ( curr_fence ) {
	    *curr_fence = temp;
	}
    }

    return ret;
}


static void mga_iload_dma_ioctl(mgaContextPtr mmesa,
				unsigned long dest,
				int length)
{
   drmBufPtr buf = mmesa->iload_buffer;
   drm_mga_iload_t iload;
   int ret, i;

   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
      fprintf(stderr, "DRM_IOCTL_MGA_ILOAD idx %d dst %x length %d\n",
	      buf->idx, (int) dest, length);

   if ( (length & MGA_ILOAD_MASK) != 0 ) {
      UNLOCK_HARDWARE( mmesa );
      fprintf( stderr, "%s: Invalid ILOAD datasize (%d), must be "
	       "multiple of %u.\n", __FUNCTION__, length, MGA_ILOAD_ALIGN );
      exit( 1 );
   }

   iload.idx = buf->idx;
   iload.dstorg = dest;
   iload.length = length;

   i = 0;
   do {
      ret = drmCommandWrite( mmesa->driFd, DRM_MGA_ILOAD, 
                             &iload, sizeof(iload) );
   } while ( ret == -EBUSY && i++ < DRM_MGA_IDLE_RETRY );

   if ( ret < 0 ) {
      printf("send iload retcode = %d\n", ret);
      exit(1);
   }

   mmesa->iload_buffer = 0;

   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
      fprintf(stderr, "finished iload dma put\n");

}

drmBufPtr mga_get_buffer_ioctl( mgaContextPtr mmesa )
{
   int idx = 0;
   int size = 0;
   drmDMAReq dma;
   int retcode;
   drmBufPtr buf;

   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
      fprintf(stderr,  "Getting dma buffer\n");

   dma.context = mmesa->hHWContext;
   dma.send_count = 0;
   dma.send_list = NULL;
   dma.send_sizes = NULL;
   dma.flags = 0;
   dma.request_count = 1;
   dma.request_size = MGA_BUFFER_SIZE;
   dma.request_list = &idx;
   dma.request_sizes = &size;
   dma.granted_count = 0;


   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
      fprintf(stderr, "drmDMA (get) ctx %d count %d size 0x%x\n",
	   dma.context, dma.request_count,
	   dma.request_size);

   while (1) {
      retcode = drmDMA(mmesa->driFd, &dma);

      if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
	 fprintf(stderr, "retcode %d sz %d idx %d count %d\n",
		 retcode,
		 dma.request_sizes[0],
		 dma.request_list[0],
		 dma.granted_count);

      if (retcode == 0 &&
	  dma.request_sizes[0] &&
	  dma.granted_count)
	 break;

      if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
	 fprintf(stderr, "\n\nflush");

      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT );
   }

   buf = &(mmesa->mgaScreen->bufs->list[idx]);
   buf->used = 0;

   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
      fprintf(stderr,
	   "drmDMA (get) returns size[0] 0x%x idx[0] %d\n"
	   "dma_buffer now: buf idx: %d size: %d used: %d addr %p\n",
	   dma.request_sizes[0], dma.request_list[0],
	   buf->idx, buf->total,
	   buf->used, buf->address);

   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
      fprintf(stderr, "finished getbuffer\n");

   return buf;
}




static void
mgaClear( GLcontext *ctx, GLbitfield mask )
{
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
   __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
   GLuint flags = 0;
   GLuint clear_color = mmesa->ClearColor;
   GLuint clear_depth = 0;
   GLuint color_mask = 0;
   GLuint depth_mask = 0;
   int ret;
   int i;
   static int nrclears;
   drm_mga_clear_t clear;
   GLint cx, cy, cw, ch;

   FLUSH_BATCH( mmesa );

   if ( mask & BUFFER_BIT_FRONT_LEFT ) {
      flags |= MGA_FRONT;
      color_mask = mmesa->setup.plnwt;
      mask &= ~BUFFER_BIT_FRONT_LEFT;
   }

   if ( mask & BUFFER_BIT_BACK_LEFT ) {
      flags |= MGA_BACK;
      color_mask = mmesa->setup.plnwt;
      mask &= ~BUFFER_BIT_BACK_LEFT;
   }

   if ( (mask & BUFFER_BIT_DEPTH) && ctx->Depth.Mask ) {
      flags |= MGA_DEPTH;
      clear_depth = (mmesa->ClearDepth & mmesa->depth_clear_mask);
      depth_mask |= mmesa->depth_clear_mask;
      mask &= ~BUFFER_BIT_DEPTH;
   }

   if ( (mask & BUFFER_BIT_STENCIL) && mmesa->hw_stencil ) {
      flags |= MGA_DEPTH;
      clear_depth |= (ctx->Stencil.Clear & mmesa->stencil_clear_mask);
      depth_mask |= mmesa->stencil_clear_mask;
      mask &= ~BUFFER_BIT_STENCIL;
   }

   if ( flags ) {
      LOCK_HARDWARE( mmesa );

      /* compute region after locking: */
      cx = ctx->DrawBuffer->_Xmin;
      cy = ctx->DrawBuffer->_Ymin;
      cw = ctx->DrawBuffer->_Xmax - cx;
      ch = ctx->DrawBuffer->_Ymax - cy;

      if ( mmesa->dirty_cliprects )
	 mgaUpdateRects( mmesa, (MGA_FRONT | MGA_BACK) );

      /* flip top to bottom */
      cy = dPriv->h-cy-ch;
      cx += mmesa->drawX;
      cy += mmesa->drawY;

      if ( MGA_DEBUG & DEBUG_VERBOSE_IOCTL )
	 fprintf( stderr, "Clear, bufs %x nbox %d\n",
		  (int)flags, (int)mmesa->numClipRects );

      for (i = 0 ; i < mmesa->numClipRects ; )
      {
	 int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, mmesa->numClipRects);
	 drm_clip_rect_t *box = mmesa->pClipRects;
	 drm_clip_rect_t *b = mmesa->sarea->boxes;
	 int n = 0;

	 if (cw != dPriv->w || ch != dPriv->h) {
            /* clear subregion */
	    for ( ; i < nr ; i++) {
	       GLint x = box[i].x1;
	       GLint y = box[i].y1;
	       GLint w = box[i].x2 - x;
	       GLint h = box[i].y2 - y;

	       if (x < cx) w -= cx - x, x = cx;
	       if (y < cy) h -= cy - y, y = cy;
	       if (x + w > cx + cw) w = cx + cw - x;
	       if (y + h > cy + ch) h = cy + ch - y;
	       if (w <= 0) continue;
	       if (h <= 0) continue;

	       b->x1 = x;
	       b->y1 = y;
	       b->x2 = x + w;
	       b->y2 = y + h;
	       b++;
	       n++;
	    }
	 } else {
            /* clear whole window */
	    for ( ; i < nr ; i++) {
	       *b++ = box[i];
	       n++;
	    }
	 }


	 if ( MGA_DEBUG & DEBUG_VERBOSE_IOCTL )
	    fprintf( stderr,
		     "DRM_IOCTL_MGA_CLEAR flag 0x%x color %x depth %x nbox %d\n",
		     flags, clear_color, clear_depth, mmesa->sarea->nbox );

	 mmesa->sarea->nbox = n;

         clear.flags = flags;
         clear.clear_color = clear_color;
         clear.clear_depth = clear_depth;
         clear.color_mask = color_mask;
         clear.depth_mask = depth_mask;
         ret = drmCommandWrite( mmesa->driFd, DRM_MGA_CLEAR,
                                 &clear, sizeof(clear));
	 if ( ret ) {
	    fprintf( stderr, "send clear retcode = %d\n", ret );
	    exit( 1 );
	 }
	 if ( MGA_DEBUG & DEBUG_VERBOSE_IOCTL )
	    fprintf( stderr, "finished clear %d\n", ++nrclears );
      }

      UNLOCK_HARDWARE( mmesa );
      mmesa->dirty |= MGA_UPLOAD_CLIPRECTS|MGA_UPLOAD_CONTEXT;
   }

   if (mask) 
      _swrast_Clear( ctx, mask );
}


/**
 * Wait for the previous frame of rendering has completed.
 * 
 * \param mmesa  Hardware context pointer.
 *
 * \bug
 * The loop in this function should have some sort of a timeout mechanism.
 *
 * \warning
 * This routine used to assume that the hardware lock was held on entry.  It
 * now assumes that the lock is \b not held on entry.
 */

static void mgaWaitForFrameCompletion( mgaContextPtr mmesa )
{
    if ( mgaWaitFence( mmesa, mmesa->last_frame_fence, NULL ) == ENOSYS ) {
	unsigned wait = 0;
	GLuint last_frame;
	GLuint last_wrap;


	LOCK_HARDWARE( mmesa );
	last_frame = mmesa->sarea->last_frame.head;
	last_wrap = mmesa->sarea->last_frame.wrap;

	/* The DMA routines in the kernel track a couple values in the SAREA
	 * that we use here.  The number of times that the primary DMA buffer
	 * has "wrapped" around is tracked in last_wrap.  In addition, the
	 * wrap count and the buffer position at the end of the last frame are
	 * stored in last_frame.wrap and last_frame.head.
	 * 
	 * By comparing the wrap counts and the current DMA pointer value
	 * (read directly from the hardware) to last_frame.head, we can
	 * determine when the graphics processor has processed all of the
	 * commands for the last frame.
	 * 
	 * In this case "last frame" means the frame of the *previous* swap-
	 * buffers call.  This is done to prevent queuing a second buffer swap
	 * before the previous swap is executed.
	 */
	while ( 1 ) {
	    if ( last_wrap < mmesa->sarea->last_wrap ||
		 ( last_wrap == mmesa->sarea->last_wrap &&
		   last_frame <= (MGA_READ( MGAREG_PRIMADDRESS ) -
				  mmesa->primary_offset) ) ) {
		break;
	    }
	    if ( 0 ) {
		wait++;
		fprintf( stderr, "   last: head=0x%06x wrap=%d\n",
			 last_frame, last_wrap );
		fprintf( stderr, "   head: head=0x%06lx wrap=%d\n",
			 (long)(MGA_READ( MGAREG_PRIMADDRESS ) - mmesa->primary_offset),
			 mmesa->sarea->last_wrap );
	    }
	    UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH );

	    UNLOCK_HARDWARE( mmesa );
	    DO_USLEEP( 1 );
	    LOCK_HARDWARE( mmesa );
	}
	if ( wait )
	  fprintf( stderr, "\n" );

	UNLOCK_HARDWARE( mmesa );
    }
}


/*
 * Copy the back buffer to the front buffer.
 */
void mgaCopyBuffer( __DRIdrawablePrivate *dPriv )
{
   mgaContextPtr mmesa;
   drm_clip_rect_t *pbox;
   GLint nbox;
   GLint ret;
   GLint i;
   GLboolean   missed_target;
   __DRIscreenPrivate *psp = dPriv->driScreenPriv;

   assert(dPriv);
   assert(dPriv->driContextPriv);
   assert(dPriv->driContextPriv->driverPrivate);

   mmesa = (mgaContextPtr) dPriv->driContextPriv->driverPrivate;

   FLUSH_BATCH( mmesa );

   mgaWaitForFrameCompletion( mmesa );
   driWaitForVBlank( dPriv, & missed_target );
   if ( missed_target ) {
      mmesa->swap_missed_count++;
      (void) (*psp->systemTime->getUST)( & mmesa->swap_missed_ust );
   }
   LOCK_HARDWARE( mmesa );

   /* Use the frontbuffer cliprects
    */
   if (mmesa->dirty_cliprects & MGA_FRONT)
      mgaUpdateRects( mmesa, MGA_FRONT );


   pbox = dPriv->pClipRects;
   nbox = dPriv->numClipRects;

   for (i = 0 ; i < nbox ; )
   {
      int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
      drm_clip_rect_t *b = mmesa->sarea->boxes;

      mmesa->sarea->nbox = nr - i;

      for ( ; i < nr ; i++)
	 *b++ = pbox[i];

      if (0)
	 fprintf(stderr, "DRM_IOCTL_MGA_SWAP\n");

      ret = drmCommandNone( mmesa->driFd, DRM_MGA_SWAP );
      if ( ret ) {
	 printf("send swap retcode = %d\n", ret);
	 exit(1);
      }
   }

   (void) mgaSetFence( mmesa, & mmesa->last_frame_fence );
   UNLOCK_HARDWARE( mmesa );

   mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
   mmesa->swap_count++;
   (void) (*psp->systemTime->getUST)( & mmesa->swap_ust );
}


/**
 * Implement the hardware-specific portion of \c glFinish.
 *
 * Flushes all pending commands to the hardware and wait for them to finish.
 * 
 * \param ctx  Context where the \c glFinish command was issued.
 *
 * \sa glFinish, mgaFlush, mgaFlushDMA
 */
static void mgaFinish( GLcontext *ctx  )
{
    mgaContextPtr mmesa = MGA_CONTEXT(ctx);
    uint32_t  fence;


    LOCK_HARDWARE( mmesa );
    if ( mmesa->vertex_dma_buffer != NULL ) {
	mgaFlushVerticesLocked( mmesa );
    }

    if ( mgaSetFence( mmesa, & fence ) == 0 ) {
	UNLOCK_HARDWARE( mmesa );
	(void) mgaWaitFence( mmesa, fence, NULL );
    }
    else {
	if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) {
	    fprintf(stderr, "mgaRegetLockQuiescent\n");
	}

	UPDATE_LOCK( mmesa, DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH );
	UNLOCK_HARDWARE( mmesa );
    }
}


/**
 * Flush all commands upto at least a certain point to the hardware.
 *
 * \note
 * The term "wait" in the name of this function is misleading.  It doesn't
 * actually wait for anything.  It just makes sure that the commands have
 * been flushed to the hardware.
 *
 * \warning
 * As the name implies, this function assumes that the hardware lock is
 * held on entry.
 */
void mgaWaitAgeLocked( mgaContextPtr mmesa, int age  )
{
   if (GET_DISPATCH_AGE(mmesa) < age) {
      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH );
   }
}


static GLboolean intersect_rect( drm_clip_rect_t *out,
				 const drm_clip_rect_t *a,
				 const drm_clip_rect_t *b )
{
   *out = *a;
   if (b->x1 > out->x1) out->x1 = b->x1;
   if (b->y1 > out->y1) out->y1 = b->y1;
   if (b->x2 < out->x2) out->x2 = b->x2;
   if (b->y2 < out->y2) out->y2 = b->y2;

   return ((out->x1 < out->x2) && (out->y1 < out->y2));
}




static void age_mmesa( mgaContextPtr mmesa, int age )
{
   if (mmesa->CurrentTexObj[0]) mmesa->CurrentTexObj[0]->age = age;
   if (mmesa->CurrentTexObj[1]) mmesa->CurrentTexObj[1]->age = age;
}


void mgaFlushVerticesLocked( mgaContextPtr mmesa )
{
   drm_clip_rect_t *pbox = mmesa->pClipRects;
   int nbox = mmesa->numClipRects;
   drmBufPtr buffer = mmesa->vertex_dma_buffer;
   drm_mga_vertex_t vertex;
   int i;

   mmesa->vertex_dma_buffer = 0;

   if (!buffer)
      return;

   if (mmesa->dirty_cliprects & mmesa->draw_buffer)
      mgaUpdateRects( mmesa, mmesa->draw_buffer );

   if (mmesa->dirty & ~MGA_UPLOAD_CLIPRECTS)
      mgaEmitHwStateLocked( mmesa );

   /* FIXME: Workaround bug in kernel module.
    */
   mmesa->sarea->dirty |= MGA_UPLOAD_CONTEXT;

   if (!nbox)
      buffer->used = 0;

   if (nbox >= MGA_NR_SAREA_CLIPRECTS)
      mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;

#if 0
   if (!buffer->used || !(mmesa->dirty & MGA_UPLOAD_CLIPRECTS))
   {
      if (nbox == 1)
	 mmesa->sarea->nbox = 0;
      else
	 mmesa->sarea->nbox = nbox;

      if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
	 fprintf(stderr, "Firing vertex -- case a nbox %d\n", nbox);

      vertex.idx = buffer->idx;
      vertex.used = buffer->used;
      vertex.discard = 1;
      drmCommandWrite( mmesa->driFd, DRM_MGA_VERTEX, 
                       &vertex, sizeof(drmMGAVertex) );

      age_mmesa(mmesa, mmesa->sarea->last_enqueue);
   }
   else
#endif
   {
      for (i = 0 ; i < nbox ; )
      {
	 int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, nbox);
	 drm_clip_rect_t *b = mmesa->sarea->boxes;
	 int discard = 0;

	 if (mmesa->scissor) {
	    mmesa->sarea->nbox = 0;

	    for ( ; i < nr ; i++) {
	       *b = pbox[i];
	       if (intersect_rect(b, b, &mmesa->scissor_rect)) {
		  mmesa->sarea->nbox++;
		  b++;
	       }
	    }

	    /* Culled?
	     */
	    if (!mmesa->sarea->nbox) {
	       if (nr < nbox) continue;
	       buffer->used = 0;
	    }
	 } else {
	    mmesa->sarea->nbox = nr - i;
	    for ( ; i < nr ; i++)
	       *b++ = pbox[i];
	 }

	 /* Finished with the buffer?
	  */
	 if (nr == nbox)
	    discard = 1;

	 mmesa->sarea->dirty |= MGA_UPLOAD_CLIPRECTS;

         vertex.idx = buffer->idx;
         vertex.used = buffer->used;
         vertex.discard = discard;
         drmCommandWrite( mmesa->driFd, DRM_MGA_VERTEX,
                          &vertex, sizeof(vertex) );

	 age_mmesa(mmesa, mmesa->sarea->last_enqueue);
      }
   }

   mmesa->dirty &= ~MGA_UPLOAD_CLIPRECTS;
}

void mgaFlushVertices( mgaContextPtr mmesa )
{
   LOCK_HARDWARE( mmesa );
   mgaFlushVerticesLocked( mmesa );
   UNLOCK_HARDWARE( mmesa );
}


void mgaFireILoadLocked( mgaContextPtr mmesa,
			 GLuint offset, GLuint length )
{
   if (!mmesa->iload_buffer) {
      fprintf(stderr, "mgaFireILoad: no buffer\n");
      return;
   }

   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
      fprintf(stderr, "mgaFireILoad idx %d ofs 0x%x length %d\n",
	      mmesa->iload_buffer->idx, (int)offset, (int)length );

   mga_iload_dma_ioctl( mmesa, offset, length );
}

void mgaGetILoadBufferLocked( mgaContextPtr mmesa )
{
   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
      fprintf(stderr, "mgaGetIloadBuffer (buffer now %p)\n",
              (void *) mmesa->iload_buffer);

   mmesa->iload_buffer = mga_get_buffer_ioctl( mmesa );
}


/**
 * Implement the hardware-specific portion of \c glFlush.
 *
 * \param ctx  Context to be flushed.
 *
 * \sa glFlush, mgaFinish, mgaFlushDMA
 */
static void mgaFlush( GLcontext *ctx )
{
    mgaContextPtr mmesa = MGA_CONTEXT( ctx );


    LOCK_HARDWARE( mmesa );
    if ( mmesa->vertex_dma_buffer != NULL ) {
	mgaFlushVerticesLocked( mmesa );
    }

    UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH );
    UNLOCK_HARDWARE( mmesa );
}


int mgaFlushDMA( int fd, drmLockFlags flags )
{
   drm_lock_t lock;
   int ret, i = 0;

   memset( &lock, 0, sizeof(lock) );

   lock.flags = flags & (DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH 
			 | DRM_LOCK_FLUSH_ALL);

   do {
      ret = drmCommandWrite( fd, DRM_MGA_FLUSH, &lock, sizeof(lock) );
   } while ( ret && errno == EBUSY && i++ < DRM_MGA_IDLE_RETRY );

   if ( ret == 0 )
      return 0;
   if ( errno != EBUSY )
      return -errno;

   if ( lock.flags & DRM_LOCK_QUIESCENT ) {
      /* Only keep trying if we need quiescence.
       */
      lock.flags &= ~(DRM_LOCK_FLUSH | DRM_LOCK_FLUSH_ALL);

      do {
         ret = drmCommandWrite( fd, DRM_MGA_FLUSH, &lock, sizeof(lock) );
      } while ( ret && errno == EBUSY && i++ < DRM_MGA_IDLE_RETRY );
   }

   if ( ret == 0 ) {
      return 0;
   } else {
      return -errno;
   }
}

void mgaInitIoctlFuncs( struct dd_function_table *functions )
{
   functions->Clear = mgaClear;
   functions->Flush = mgaFlush;
   functions->Finish = mgaFinish;
}
