patch-2.4.8 linux/drivers/char/drm/radeon_cp.c

Next file: linux/drivers/char/drm/radeon_drm.h
Previous file: linux/drivers/char/drm/radeon_context.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.7/linux/drivers/char/drm/radeon_cp.c linux/drivers/char/drm/radeon_cp.c
@@ -24,12 +24,12 @@
  * DEALINGS IN THE SOFTWARE.
  *
  * Authors:
- *   Kevin E. Martin <martin@valinux.com>
- *   Gareth Hughes <gareth@valinux.com>
- *
+ *    Kevin E. Martin <martin@valinux.com>
+ *    Gareth Hughes <gareth@valinux.com>
  */
 
 #define __NO_VERSION__
+#include "radeon.h"
 #include "drmP.h"
 #include "radeon_drv.h"
 
@@ -38,6 +38,12 @@
 
 #define RADEON_FIFO_DEBUG	0
 
+#if defined(__alpha__)
+# define PCIGART_ENABLED
+#else
+# undef PCIGART_ENABLED
+#endif
+
 
 /* CP microcode (from ATI) */
 static u32 radeon_cp_microcode[][2] = {
@@ -300,26 +306,6 @@
 };
 
 
-#define DO_IOREMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size)
-
-#define DO_IOREMAPFREE(_m)						\
-	do {								\
-		if ((_m)->handle && (_m)->size)				\
-			drm_ioremapfree((_m)->handle, (_m)->size);	\
-	} while (0)
-
-#define DO_FIND_MAP(_m, _o)						\
-	do {								\
-		int _i;							\
-		for (_i = 0; _i < dev->map_count; _i++) {		\
-			if (dev->maplist[_i]->offset == _o) {		\
-				_m = dev->maplist[_i];			\
-				break;					\
-			}						\
-		}							\
-	} while (0)
-
-
 int RADEON_READ_PLL(drm_device_t *dev, int addr)
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -338,6 +324,16 @@
 		(unsigned int)RADEON_READ( RADEON_CP_RB_RPTR ) );
 	printk( "CP_RB_WTPR = 0x%08x\n",
 		(unsigned int)RADEON_READ( RADEON_CP_RB_WPTR ) );
+	printk( "AIC_CNTL = 0x%08x\n",
+		(unsigned int)RADEON_READ( RADEON_AIC_CNTL ) );
+	printk( "AIC_STAT = 0x%08x\n",
+		(unsigned int)RADEON_READ( RADEON_AIC_STAT ) );
+	printk( "AIC_PT_BASE = 0x%08x\n",
+		(unsigned int)RADEON_READ( RADEON_AIC_PT_BASE ) );
+	printk( "TLB_ADDR = 0x%08x\n",
+		(unsigned int)RADEON_READ( RADEON_AIC_TLB_ADDR ) );
+	printk( "TLB_DATA = 0x%08x\n",
+		(unsigned int)RADEON_READ( RADEON_AIC_TLB_DATA ) );
 }
 #endif
 
@@ -421,6 +417,7 @@
 static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv )
 {
 	int i;
+	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
 	radeon_do_wait_for_idle( dev_priv );
 
@@ -439,6 +436,7 @@
  */
 static void radeon_do_cp_flush( drm_radeon_private_t *dev_priv )
 {
+	DRM_DEBUG( "%s\n", __FUNCTION__ );
 #if 0
 	u32 tmp;
 
@@ -452,6 +450,7 @@
 int radeon_do_cp_idle( drm_radeon_private_t *dev_priv )
 {
 	RING_LOCALS;
+	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
 	BEGIN_RING( 6 );
 
@@ -469,6 +468,7 @@
 static void radeon_do_cp_start( drm_radeon_private_t *dev_priv )
 {
 	RING_LOCALS;
+	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
 	radeon_do_wait_for_idle( dev_priv );
 
@@ -492,6 +492,7 @@
 static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv )
 {
 	u32 cur_read_ptr;
+	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
 	cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR );
 	RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr );
@@ -505,6 +506,8 @@
  */
 static void radeon_do_cp_stop( drm_radeon_private_t *dev_priv )
 {
+	DRM_DEBUG( "%s\n", __FUNCTION__ );
+
 	RADEON_WRITE( RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS );
 
 	dev_priv->cp_running = 0;
@@ -523,8 +526,13 @@
 	clock_cntl_index = RADEON_READ( RADEON_CLOCK_CNTL_INDEX );
 	mclk_cntl = RADEON_READ_PLL( dev, RADEON_MCLK_CNTL );
 
-	/* FIXME: remove magic number here and in radeon ddx driver!!! */
-	RADEON_WRITE_PLL( RADEON_MCLK_CNTL, mclk_cntl | 0x003f00000 );
+	RADEON_WRITE_PLL( RADEON_MCLK_CNTL, ( mclk_cntl |
+					      RADEON_FORCEON_MCLKA |
+					      RADEON_FORCEON_MCLKB |
+ 					      RADEON_FORCEON_YCLKA |
+					      RADEON_FORCEON_YCLKB |
+					      RADEON_FORCEON_MC |
+					      RADEON_FORCEON_AIC ) );
 
 	rbbm_soft_reset = RADEON_READ( RADEON_RBBM_SOFT_RESET );
 
@@ -566,23 +574,33 @@
 	return 0;
 }
 
-static void radeon_cp_init_ring_buffer( drm_device_t *dev )
+static void radeon_cp_init_ring_buffer( drm_device_t *dev,
+				        drm_radeon_private_t *dev_priv )
 {
-	drm_radeon_private_t *dev_priv = dev->dev_private;
 	u32 ring_start, cur_read_ptr;
 	u32 tmp;
 
 	/* Initialize the memory controller */
 	RADEON_WRITE( RADEON_MC_FB_LOCATION,
 		      (dev_priv->agp_vm_start - 1) & 0xffff0000 );
-	RADEON_WRITE( RADEON_MC_AGP_LOCATION,
-		      (((dev_priv->agp_vm_start - 1 +
-			 dev_priv->agp_size) & 0xffff0000) |
-		       (dev_priv->agp_vm_start >> 16)) );
-
-	ring_start = (dev_priv->cp_ring->offset
-		      - dev->agp->base
-		      + dev_priv->agp_vm_start);
+
+	if ( !dev_priv->is_pci ) {
+		RADEON_WRITE( RADEON_MC_AGP_LOCATION,
+			      (((dev_priv->agp_vm_start - 1 +
+				 dev_priv->agp_size) & 0xffff0000) |
+			       (dev_priv->agp_vm_start >> 16)) );
+	}
+
+#if __REALLY_HAVE_AGP
+	if ( !dev_priv->is_pci )
+		ring_start = (dev_priv->cp_ring->offset
+			      - dev->agp->base
+			      + dev_priv->agp_vm_start);
+       else
+#endif
+		ring_start = (dev_priv->cp_ring->offset
+			      - dev->sg->handle
+			      + dev_priv->agp_vm_start);
 
 	RADEON_WRITE( RADEON_CP_RB_BASE, ring_start );
 
@@ -595,17 +613,29 @@
 	*dev_priv->ring.head = cur_read_ptr;
 	dev_priv->ring.tail = cur_read_ptr;
 
-	RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, dev_priv->ring_rptr->offset );
+	if ( !dev_priv->is_pci ) {
+		RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
+			      dev_priv->ring_rptr->offset );
+	} else {
+		drm_sg_mem_t *entry = dev->sg;
+		unsigned long tmp_ofs, page_ofs;
+
+		tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle;
+		page_ofs = tmp_ofs >> PAGE_SHIFT;
+
+		RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
+			      virt_to_bus(entry->pagelist[page_ofs]->virtual));
+
+		DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n",
+			   virt_to_bus(entry->pagelist[page_ofs]->virtual),
+			   entry->handle + tmp_ofs );
+	}
 
 	/* Set ring buffer size */
 	RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw );
 
 	radeon_do_wait_for_idle( dev_priv );
 
-	/* Turn off PCI GART */
-	tmp = RADEON_READ( RADEON_AIC_CNTL ) & ~RADEON_PCIGART_TRANSLATE_EN;
-	RADEON_WRITE( RADEON_AIC_CNTL, tmp );
-
 	/* Turn on bus mastering */
 	tmp = RADEON_READ( RADEON_BUS_CNTL ) & ~RADEON_BUS_MASTER_DIS;
 	RADEON_WRITE( RADEON_BUS_CNTL, tmp );
@@ -621,32 +651,42 @@
 static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
 {
 	drm_radeon_private_t *dev_priv;
-        int i;
+	struct list_head *list;
+	u32 tmp;
+	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-	dev_priv = drm_alloc( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
+	dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
 	if ( dev_priv == NULL )
 		return -ENOMEM;
-	dev->dev_private = (void *)dev_priv;
 
 	memset( dev_priv, 0, sizeof(drm_radeon_private_t) );
 
 	dev_priv->is_pci = init->is_pci;
 
-	/* We don't support PCI cards until PCI GART is implemented.
-	 * Fail here so we can remove all checks for PCI cards around
-	 * the CP ring code.
+#if !defined(PCIGART_ENABLED)
+	/* PCI support is not 100% working, so we disable it here.
 	 */
 	if ( dev_priv->is_pci ) {
-		drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
-		dev->dev_private = NULL;
+		DRM_ERROR( "PCI GART not yet supported for Radeon!\n" );
+		dev->dev_private = (void *)dev_priv;
+		radeon_do_cleanup_cp(dev);
+		return -EINVAL;
+	}
+#endif
+
+	if ( dev_priv->is_pci && !dev->sg ) {
+		DRM_ERROR( "PCI GART memory not allocated!\n" );
+		dev->dev_private = (void *)dev_priv;
+		radeon_do_cleanup_cp(dev);
 		return -EINVAL;
 	}
 
 	dev_priv->usec_timeout = init->usec_timeout;
 	if ( dev_priv->usec_timeout < 1 ||
 	     dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT ) {
-		drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
-		dev->dev_private = NULL;
+		DRM_DEBUG( "TIMEOUT problem!\n" );
+		dev->dev_private = (void *)dev_priv;
+		radeon_do_cleanup_cp(dev);
 		return -EINVAL;
 	}
 
@@ -662,8 +702,9 @@
 	 */
 	if ( ( init->cp_mode != RADEON_CSQ_PRIBM_INDDIS ) &&
 	     ( init->cp_mode != RADEON_CSQ_PRIBM_INDBM ) ) {
-		drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
-		dev->dev_private = NULL;
+		DRM_DEBUG( "BAD cp_mode (%x)!\n", init->cp_mode );
+		dev->dev_private = (void *)dev_priv;
+		radeon_do_cleanup_cp(dev);
 		return -EINVAL;
 	}
 
@@ -722,55 +763,128 @@
 					 RADEON_BFACE_SOLID |
 					 RADEON_FFACE_SOLID |
 					 RADEON_FLAT_SHADE_VTX_LAST |
-
 					 RADEON_DIFFUSE_SHADE_FLAT |
 					 RADEON_ALPHA_SHADE_FLAT |
 					 RADEON_SPECULAR_SHADE_FLAT |
 					 RADEON_FOG_SHADE_FLAT |
-
 					 RADEON_VTX_PIX_CENTER_OGL |
 					 RADEON_ROUND_MODE_TRUNC |
 					 RADEON_ROUND_PREC_8TH_PIX);
 
-	/* FIXME: We want multiple shared areas, including one shared
-	 * only by the X Server and kernel module.
-	 */
-	for ( i = 0 ; i < dev->map_count ; i++ ) {
-		if ( dev->maplist[i]->type == _DRM_SHM ) {
-			dev_priv->sarea = dev->maplist[i];
-			break;
-		}
+	list_for_each(list, &dev->maplist->head) {
+		drm_map_list_t *r_list = (drm_map_list_t *)list;
+		if( r_list->map &&
+		    r_list->map->type == _DRM_SHM &&
+		    r_list->map->flags & _DRM_CONTAINS_LOCK ) {
+			dev_priv->sarea = r_list->map;
+ 			break;
+ 		}
+ 	}
+	if(!dev_priv->sarea) {
+		DRM_ERROR("could not find sarea!\n");
+		dev->dev_private = (void *)dev_priv;
+		radeon_do_cleanup_cp(dev);
+		return -EINVAL;
 	}
 
-	DO_FIND_MAP( dev_priv->fb, init->fb_offset );
-	DO_FIND_MAP( dev_priv->mmio, init->mmio_offset );
-	DO_FIND_MAP( dev_priv->cp_ring, init->ring_offset );
-	DO_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset );
-	DO_FIND_MAP( dev_priv->buffers, init->buffers_offset );
+	DRM_FIND_MAP( dev_priv->fb, init->fb_offset );
+	if(!dev_priv->fb) {
+		DRM_ERROR("could not find framebuffer!\n");
+		dev->dev_private = (void *)dev_priv;
+		radeon_do_cleanup_cp(dev);
+		return -EINVAL;
+	}
+	DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset );
+	if(!dev_priv->mmio) {
+		DRM_ERROR("could not find mmio region!\n");
+		dev->dev_private = (void *)dev_priv;
+		radeon_do_cleanup_cp(dev);
+		return -EINVAL;
+	}
+	DRM_FIND_MAP( dev_priv->cp_ring, init->ring_offset );
+	if(!dev_priv->cp_ring) {
+		DRM_ERROR("could not find cp ring region!\n");
+		dev->dev_private = (void *)dev_priv;
+		radeon_do_cleanup_cp(dev);
+		return -EINVAL;
+	}
+	DRM_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset );
+	if(!dev_priv->ring_rptr) {
+		DRM_ERROR("could not find ring read pointer!\n");
+		dev->dev_private = (void *)dev_priv;
+		radeon_do_cleanup_cp(dev);
+		return -EINVAL;
+	}
+	DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset );
+	if(!dev_priv->buffers) {
+		DRM_ERROR("could not find dma buffer region!\n");
+		dev->dev_private = (void *)dev_priv;
+		radeon_do_cleanup_cp(dev);
+		return -EINVAL;
+	}
 
 	if ( !dev_priv->is_pci ) {
-		DO_FIND_MAP( dev_priv->agp_textures,
-			     init->agp_textures_offset );
+		DRM_FIND_MAP( dev_priv->agp_textures,
+			      init->agp_textures_offset );
+		if(!dev_priv->agp_textures) {
+			DRM_ERROR("could not find agp texture region!\n");
+			dev->dev_private = (void *)dev_priv;
+			radeon_do_cleanup_cp(dev);
+			return -EINVAL;
+		}
 	}
 
 	dev_priv->sarea_priv =
 		(drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle +
 				       init->sarea_priv_offset);
 
-	DO_IOREMAP( dev_priv->cp_ring );
-	DO_IOREMAP( dev_priv->ring_rptr );
-	DO_IOREMAP( dev_priv->buffers );
-#if 0
 	if ( !dev_priv->is_pci ) {
-		DO_IOREMAP( dev_priv->agp_textures );
+		DRM_IOREMAP( dev_priv->cp_ring );
+		DRM_IOREMAP( dev_priv->ring_rptr );
+		DRM_IOREMAP( dev_priv->buffers );
+		if(!dev_priv->cp_ring->handle ||
+		   !dev_priv->ring_rptr->handle ||
+		   !dev_priv->buffers->handle) {
+			DRM_ERROR("could not find ioremap agp regions!\n");
+			dev->dev_private = (void *)dev_priv;
+			radeon_do_cleanup_cp(dev);
+			return -EINVAL;
+		}
+	} else {
+		dev_priv->cp_ring->handle =
+			(void *)dev_priv->cp_ring->offset;
+		dev_priv->ring_rptr->handle =
+			(void *)dev_priv->ring_rptr->offset;
+		dev_priv->buffers->handle = (void *)dev_priv->buffers->offset;
+
+		DRM_DEBUG( "dev_priv->cp_ring->handle %p\n",
+			   dev_priv->cp_ring->handle );
+		DRM_DEBUG( "dev_priv->ring_rptr->handle %p\n",
+			   dev_priv->ring_rptr->handle );
+		DRM_DEBUG( "dev_priv->buffers->handle %p\n",
+			   dev_priv->buffers->handle );
 	}
-#endif
+
 
 	dev_priv->agp_size = init->agp_size;
 	dev_priv->agp_vm_start = RADEON_READ( RADEON_CONFIG_APER_SIZE );
-	dev_priv->agp_buffers_offset = (dev_priv->buffers->offset
-					- dev->agp->base
-					+ dev_priv->agp_vm_start);
+#if __REALLY_HAVE_AGP
+	if ( !dev_priv->is_pci )
+		dev_priv->agp_buffers_offset = (dev_priv->buffers->offset
+						- dev->agp->base
+						+ dev_priv->agp_vm_start);
+	else
+#endif
+		dev_priv->agp_buffers_offset = (dev_priv->buffers->offset
+						- dev->sg->handle
+						+ dev_priv->agp_vm_start);
+
+	DRM_DEBUG( "dev_priv->agp_size %d\n",
+		   dev_priv->agp_size );
+	DRM_DEBUG( "dev_priv->agp_vm_start 0x%x\n",
+		   dev_priv->agp_vm_start );
+	DRM_DEBUG( "dev_priv->agp_buffers_offset 0x%lx\n",
+		   dev_priv->agp_buffers_offset );
 
 	dev_priv->ring.head = ((__volatile__ u32 *)
 			       dev_priv->ring_rptr->handle);
@@ -779,11 +893,13 @@
 	dev_priv->ring.end = ((u32 *)dev_priv->cp_ring->handle
 			      + init->ring_size / sizeof(u32));
 	dev_priv->ring.size = init->ring_size;
-	dev_priv->ring.size_l2qw = drm_order( init->ring_size / 8 );
+	dev_priv->ring.size_l2qw = DRM(order)( init->ring_size / 8 );
 
 	dev_priv->ring.tail_mask =
 		(dev_priv->ring.size / sizeof(u32)) - 1;
 
+	dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
+
 #if 0
 	/* Initialize the scratch register pointer.  This will cause
 	 * the scratch register values to be written out to memory
@@ -812,33 +928,72 @@
 	RADEON_WRITE( RADEON_LAST_CLEAR_REG,
 		      dev_priv->sarea_priv->last_clear );
 
+	if ( dev_priv->is_pci ) {
+		dev_priv->phys_pci_gart = DRM(ati_pcigart_init)( dev );
+		if ( !dev_priv->phys_pci_gart ) {
+			DRM_ERROR( "failed to init PCI GART!\n" );
+			dev->dev_private = (void *)dev_priv;
+			radeon_do_cleanup_cp(dev);
+			return -ENOMEM;
+		}
+		/* Turn on PCI GART
+		 */
+		tmp = RADEON_READ( RADEON_AIC_CNTL )
+		      | RADEON_PCIGART_TRANSLATE_EN;
+		RADEON_WRITE( RADEON_AIC_CNTL, tmp );
+
+		/* set PCI GART page-table base address
+		 */
+		RADEON_WRITE( RADEON_AIC_PT_BASE,
+			      virt_to_bus( (void *)dev_priv->phys_pci_gart ) );
+
+		/* set address range for PCI address translate
+		 */
+		RADEON_WRITE( RADEON_AIC_LO_ADDR, dev_priv->agp_vm_start );
+		RADEON_WRITE( RADEON_AIC_HI_ADDR, dev_priv->agp_vm_start
+						  + dev_priv->agp_size - 1);
+
+		/* Turn off AGP aperture -- is this required for PCIGART?
+		 */
+		RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */
+		RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */
+	} else {
+		/* Turn off PCI GART
+		 */
+		tmp = RADEON_READ( RADEON_AIC_CNTL )
+		      & ~RADEON_PCIGART_TRANSLATE_EN;
+		RADEON_WRITE( RADEON_AIC_CNTL, tmp );
+	}
+
 	radeon_cp_load_microcode( dev_priv );
-	radeon_cp_init_ring_buffer( dev );
-	radeon_do_engine_reset( dev );
+	radeon_cp_init_ring_buffer( dev, dev_priv );
 
 #if ROTATE_BUFS
 	dev_priv->last_buf = 0;
 #endif
 
+	dev->dev_private = (void *)dev_priv;
+
+	radeon_do_engine_reset( dev );
+
 	return 0;
 }
 
-static int radeon_do_cleanup_cp( drm_device_t *dev )
+int radeon_do_cleanup_cp( drm_device_t *dev )
 {
+	DRM_DEBUG( "%s\n", __FUNCTION__ );
+
 	if ( dev->dev_private ) {
 		drm_radeon_private_t *dev_priv = dev->dev_private;
 
-		DO_IOREMAPFREE( dev_priv->cp_ring );
-		DO_IOREMAPFREE( dev_priv->ring_rptr );
-		DO_IOREMAPFREE( dev_priv->buffers );
-#if 0
 		if ( !dev_priv->is_pci ) {
-			DO_IOREMAPFREE( dev_priv->agp_textures );
+			DRM_IOREMAPFREE( dev_priv->cp_ring );
+			DRM_IOREMAPFREE( dev_priv->ring_rptr );
+			DRM_IOREMAPFREE( dev_priv->buffers );
 		}
-#endif
 
-		drm_free( dev->dev_private, sizeof(drm_radeon_private_t),
-			  DRM_MEM_DRIVER );
+		DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t),
+			   DRM_MEM_DRIVER );
 		dev->dev_private = NULL;
 	}
 
@@ -873,11 +1028,8 @@
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-	if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-	     dev->lock.pid != current->pid ) {
-		DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN( dev );
+
 	if ( dev_priv->cp_running ) {
 		DRM_DEBUG( "%s while CP running\n", __FUNCTION__ );
 		return 0;
@@ -906,11 +1058,7 @@
 	int ret;
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-	if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-	     dev->lock.pid != current->pid ) {
-		DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN( dev );
 
 	if ( copy_from_user( &stop, (drm_radeon_init_t *)arg, sizeof(stop) ) )
 		return -EFAULT;
@@ -952,11 +1100,8 @@
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-	if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-	     dev->lock.pid != current->pid ) {
-		DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN( dev );
+
 	if ( !dev_priv ) {
 		DRM_DEBUG( "%s called before init done\n", __FUNCTION__ );
 		return -EINVAL;
@@ -978,11 +1123,7 @@
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-	if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-	     dev->lock.pid != current->pid ) {
-		DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN( dev );
 
 	return radeon_do_cp_idle( dev_priv );
 }
@@ -994,11 +1135,7 @@
         drm_device_t *dev = priv->dev;
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-	if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-	     dev->lock.pid != current->pid ) {
-		DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN( dev );
 
 	return radeon_do_engine_reset( dev );
 }
@@ -1048,11 +1185,7 @@
         drm_device_t *dev = priv->dev;
 	drm_radeon_fullscreen_t fs;
 
-	if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-	     dev->lock.pid != current->pid ) {
-		DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN( dev );
 
 	if ( copy_from_user( &fs, (drm_radeon_fullscreen_t *)arg,
 			     sizeof(fs) ) )
@@ -1085,8 +1218,8 @@
 	drm_radeon_freelist_t *entry;
 	int i;
 
-	dev_priv->head = drm_alloc( sizeof(drm_radeon_freelist_t),
-				    DRM_MEM_DRIVER );
+	dev_priv->head = DRM(alloc)( sizeof(drm_radeon_freelist_t),
+				     DRM_MEM_DRIVER );
 	if ( dev_priv->head == NULL )
 		return -ENOMEM;
 
@@ -1097,8 +1230,8 @@
 		buf = dma->buflist[i];
 		buf_priv = buf->dev_private;
 
-		entry = drm_alloc( sizeof(drm_radeon_freelist_t),
-				   DRM_MEM_DRIVER );
+		entry = DRM(alloc)( sizeof(drm_radeon_freelist_t),
+				    DRM_MEM_DRIVER );
 		if ( !entry ) return -ENOMEM;
 
 		entry->age = RADEON_BUFFER_FREE;
@@ -1218,32 +1351,20 @@
 	int i;
 
 	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
-		ring->space = *ring->head - ring->tail;
-		if ( ring->space <= 0 )
-			ring->space += ring->size;
-
-		if ( ring->space >= n )
+		radeon_update_ring_snapshot( ring );
+		if ( ring->space > n )
 			return 0;
-
 		udelay( 1 );
 	}
 
 	/* FIXME: This return value is ignored in the BEGIN_RING macro! */
+#if RADEON_FIFO_DEBUG
+	radeon_status( dev_priv );
 	DRM_ERROR( "failed!\n" );
+#endif
 	return -EBUSY;
 }
 
-void radeon_update_ring_snapshot( drm_radeon_private_t *dev_priv )
-{
-	drm_radeon_ring_buffer_t *ring = &dev_priv->ring;
-
-	ring->space = *ring->head - ring->tail;
-	if ( ring->space == 0 )
-		atomic_inc( &dev_priv->idle_count );
-	if ( ring->space <= 0 )
-		ring->space += ring->size;
-}
-
 static int radeon_cp_get_buffers( drm_device_t *dev, drm_dma_t *d )
 {
 	int i;
@@ -1276,14 +1397,10 @@
 	int ret = 0;
 	drm_dma_t d;
 
-	if ( copy_from_user( &d, (drm_dma_t *) arg, sizeof(d) ) )
-		return -EFAULT;
+	LOCK_TEST_WITH_RETURN( dev );
 
-	if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-	     dev->lock.pid != current->pid ) {
-		DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-		return -EINVAL;
-	}
+	if ( copy_from_user( &d, (drm_dma_t *)arg, sizeof(d) ) )
+		return -EFAULT;
 
 	/* Please don't send us buffers.
 	 */
@@ -1307,7 +1424,7 @@
 		ret = radeon_cp_get_buffers( dev, &d );
 	}
 
-	if ( copy_to_user( (drm_dma_t *) arg, &d, sizeof(d) ) )
+	if ( copy_to_user( (drm_dma_t *)arg, &d, sizeof(d) ) )
 		return -EFAULT;
 
 	return ret;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)