diff options
author | Gareth Hughes <gareth@users.sourceforge.net> | 2001-02-12 10:45:03 +0000 |
---|---|---|
committer | Gareth Hughes <gareth@users.sourceforge.net> | 2001-02-12 10:45:03 +0000 |
commit | 6038ace5dca200c48d4a28a1130b396e378e763e (patch) | |
tree | 3591d2d88cc03678dbb738316e3b95a108dc91bc | |
parent | b381e69d450ad7bec4ceb648d98e9d75ea4e1bcd (diff) |
Right, I've had it. Interrupts are gone...
This commit will temporarily break the gamma driver. I'll fix it up
tonight.
-rw-r--r-- | linux-core/drm_dma.c | 5 | ||||
-rw-r--r-- | linux-core/drm_drv.c | 79 | ||||
-rw-r--r-- | linux-core/mga_drv.c | 84 | ||||
-rw-r--r-- | linux/Makefile.linux | 4 | ||||
-rw-r--r-- | linux/drm_dma.h | 5 | ||||
-rw-r--r-- | linux/drm_drv.h | 79 | ||||
-rw-r--r-- | linux/mga.h | 1 | ||||
-rw-r--r-- | linux/mga_dma.c | 1102 | ||||
-rw-r--r-- | linux/mga_drv.c | 84 | ||||
-rw-r--r-- | linux/mga_drv.h | 150 | ||||
-rw-r--r-- | linux/mga_state.c | 155 |
11 files changed, 353 insertions, 1395 deletions
diff --git a/linux-core/drm_dma.c b/linux-core/drm_dma.c index 83766d54..f4220196 100644 --- a/linux-core/drm_dma.c +++ b/linux-core/drm_dma.c @@ -114,6 +114,7 @@ void DRM(dma_takedown)(drm_device_t *dev) dev->dma = NULL; } + #if DRM_DMA_HISTOGRAM /* This is slow, but is useful for debugging. */ int DRM(histogram_slot)(unsigned long count) @@ -220,6 +221,8 @@ void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid) } } +#if __HAVE_OLD_DMA + #if 0 int drm_context_switch(drm_device_t *dev, int old, int new) { @@ -562,3 +565,5 @@ int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma) } #endif + +#endif diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index ae57b068..225c6127 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -75,8 +75,8 @@ #ifndef __HAVE_DMA_QUIESCENT #define __HAVE_DMA_QUIESCENT 0 #endif -#ifndef __HAVE_DRIVER_RELEASE -#define __HAVE_DRIVER_RELEASE 0 +#ifndef __HAVE_RELEASE +#define __HAVE_RELEASE 0 #endif #ifndef __HAVE_COUNTERS #define __HAVE_COUNTERS 0 @@ -91,6 +91,9 @@ #ifndef DRIVER_PRETAKEDOWN #define DRIVER_PRETAKEDOWN() #endif +#ifndef DRIVER_IOCTLS +#define DRIVER_IOCTLS +#endif static drm_device_t DRM(device); @@ -111,6 +114,68 @@ static struct file_operations DRM(fops) = { poll: DRM(poll), }; + +static drm_ioctl_desc_t DRM(ioctls)[] = { + [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { DRM(version), 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { DRM(getunique), 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { DRM(getmagic), 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { DRM(irq_busid), 0, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { DRM(getmap), 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { DRM(getclient), 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { DRM(getstats), 0, 0 }, + + [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { DRM(setunique), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { DRM(block), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { DRM(unblock), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { DRM(authmagic), 1, 1 }, + + [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { DRM(addmap), 1, 1 }, + + [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { DRM(addctx), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { DRM(rmctx), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { DRM(modctx), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { DRM(getctx), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { DRM(switchctx), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { DRM(newctx), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { DRM(resctx), 1, 0 }, + + [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { DRM(adddraw), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { DRM(rmdraw), 1, 1 }, + + [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { DRM(lock), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { DRM(unlock), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { DRM(finish), 1, 0 }, + +#if __HAVE_DMA + [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { DRM(addbufs), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { DRM(markbufs), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { DRM(infobufs), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { DRM(mapbufs), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { DRM(freebufs), 1, 0 }, + + /* The DRM_IOCTL_DMA ioctl should be defined by the driver. + */ +#if __HAVE_DMA_IRQ + [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { DRM(control), 1, 1 }, +#endif +#endif + +#if __REALLY_HAVE_AGP + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { DRM(agp_acquire), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { DRM(agp_release), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { DRM(agp_enable), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { DRM(agp_info), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { DRM(agp_alloc), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { DRM(agp_free), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { DRM(agp_bind), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { DRM(agp_unbind), 1, 1 }, +#endif + + DRIVER_IOCTLS +}; + +#define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( DRM(ioctls) ) + #ifdef MODULE static char *drm_opts = NULL; #endif @@ -186,7 +251,7 @@ static int DRM(setup)( drm_device_t *dev ) #ifdef __HAVE_COUNTER15 dev->types[14] = __HAVE_COUNTER14; #endif - + for (i = 0; i < DRM_ARRAY_SIZE(dev->counts); i++) atomic_set(&dev->counts[i], 0); @@ -463,8 +528,7 @@ static void __exit drm_cleanup( void ) DRM(ctxbitmap_cleanup)( dev ); #endif -#if __REALLY_HAVE_MTRR -#if __REALLY_HAVE_AGP +#if __REALLY_HAVE_AGP && __REALLY_HAVE_MTRR if ( dev->agp && dev->agp->agp_mtrr ) { int retval; retval = mtrr_del( dev->agp->agp_mtrr, @@ -473,7 +537,6 @@ static void __exit drm_cleanup( void ) DRM_DEBUG( "mtrr_del=%d\n", retval ); } #endif -#endif DRM(takedown)( dev ); @@ -573,7 +636,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) DRM_ERROR( "Process %d dead, freeing lock for context %d\n", current->pid, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) ); -#if __HAVE_DRIVER_RELEASE +#if __HAVE_RELEASE DRIVER_RELEASE(); #endif DRM(lock_free)( dev, &dev->lock.hw_lock->lock, @@ -584,7 +647,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) processed via a callback to the X server. */ } -#if __HAVE_DRIVER_RELEASE +#if __HAVE_RELEASE else if ( dev->lock.hw_lock ) { /* The lock is required to reclaim buffers */ DECLARE_WAITQUEUE( entry, current ); diff --git a/linux-core/mga_drv.c b/linux-core/mga_drv.c index d458afb4..fdba9c5f 100644 --- a/linux-core/mga_drv.c +++ b/linux-core/mga_drv.c @@ -38,85 +38,23 @@ #define DRIVER_NAME "mga" #define DRIVER_DESC "Matrox G200/G400" -#define DRIVER_DATE "20010206" +#define DRIVER_DATE "20010212" #define DRIVER_MAJOR 3 #define DRIVER_MINOR 0 #define DRIVER_PATCHLEVEL 0 -/* Now that we do this, we can move the DRM(ioctls) array into a - * template file and have a DRIVER_IOCTLS block at the end. - */ -static drm_ioctl_desc_t mga_ioctls[] = { - [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { mga_version, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { mga_getunique, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { mga_getmagic, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { mga_irq_busid, 0, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { mga_getmap, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { mga_getclient, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { mga_getstats, 0, 0 }, - - [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { mga_setunique, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { mga_block, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { mga_unblock, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { mga_control, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { mga_authmagic, 1, 1 }, - - [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { mga_addmap, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { mga_addbufs, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { mga_markbufs, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { mga_infobufs, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { mga_mapbufs, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { mga_freebufs, 1, 0 }, - - [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { mga_addctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { mga_rmctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { mga_modctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { mga_getctx, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { mga_switchctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { mga_newctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { mga_resctx, 1, 0 }, - - [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { mga_adddraw, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { mga_rmdraw, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { mga_lock, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { mga_unlock, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { mga_finish, 1, 0 }, - -#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { mga_agp_acquire, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { mga_agp_release, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { mga_agp_enable, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { mga_agp_info, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { mga_agp_alloc, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { mga_agp_free, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { mga_agp_bind, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { mga_agp_unbind, 1, 1 }, -#endif - - [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_dma_flush, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)] = { mga_dma_reset, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_dma_swap, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_dma_clear, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 }, +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_dma_flush, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)] = { mga_dma_reset, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_dma_swap, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_dma_clear, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_dma_indices, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_dma_iload, 1, 0 }, -#if 0 - [DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_indices, 1, 0 }, -#endif -}; - -#define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( mga_ioctls ) - -#define __HAVE_AGP 1 -#define __MUST_HAVE_AGP 1 - -#define __HAVE_MTRR 1 - -#define __HAVE_CTX_BITMAP 1 -#define __HAVE_DMA 1 #define __HAVE_DMA_IRQ 1 #define __HAVE_COUNTERS 3 @@ -137,7 +75,7 @@ do { \ } while (0) #if 0 -#define __HAVE_DRIVER_RELEASE 1 +#define __HAVE_RELEASE 1 #define DRIVER_RELEASE() do { \ mga_reclaim_buffers( dev, priv->pid ); \ if ( dev->dev_private ) { \ diff --git a/linux/Makefile.linux b/linux/Makefile.linux index fa5ea894..75aadd45 100644 --- a/linux/Makefile.linux +++ b/linux/Makefile.linux @@ -136,7 +136,7 @@ endif ifeq ($(AGP),1) MODCFLAGS += -DCONFIG_AGP -DCONFIG_AGP_MODULE #DRMOBJS += agpsupport.o -MODS += mga.o gamma.o +MODS += mga.o #ifeq ($(MACHINE),i386) #MODS += i810.o #endif @@ -211,7 +211,7 @@ dristat: dristat.c gamma_drv.o: gamma_drv.c $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ -gamma.o: $(GAMMAOBJS) +gamma.o: $(GAMMAOBJS) $(LD) -r $^ -o $@ tdfx_drv.o: tdfx_drv.c diff --git a/linux/drm_dma.h b/linux/drm_dma.h index 83766d54..f4220196 100644 --- a/linux/drm_dma.h +++ b/linux/drm_dma.h @@ -114,6 +114,7 @@ void DRM(dma_takedown)(drm_device_t *dev) dev->dma = NULL; } + #if DRM_DMA_HISTOGRAM /* This is slow, but is useful for debugging. */ int DRM(histogram_slot)(unsigned long count) @@ -220,6 +221,8 @@ void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid) } } +#if __HAVE_OLD_DMA + #if 0 int drm_context_switch(drm_device_t *dev, int old, int new) { @@ -562,3 +565,5 @@ int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma) } #endif + +#endif diff --git a/linux/drm_drv.h b/linux/drm_drv.h index ae57b068..225c6127 100644 --- a/linux/drm_drv.h +++ b/linux/drm_drv.h @@ -75,8 +75,8 @@ #ifndef __HAVE_DMA_QUIESCENT #define __HAVE_DMA_QUIESCENT 0 #endif -#ifndef __HAVE_DRIVER_RELEASE -#define __HAVE_DRIVER_RELEASE 0 +#ifndef __HAVE_RELEASE +#define __HAVE_RELEASE 0 #endif #ifndef __HAVE_COUNTERS #define __HAVE_COUNTERS 0 @@ -91,6 +91,9 @@ #ifndef DRIVER_PRETAKEDOWN #define DRIVER_PRETAKEDOWN() #endif +#ifndef DRIVER_IOCTLS +#define DRIVER_IOCTLS +#endif static drm_device_t DRM(device); @@ -111,6 +114,68 @@ static struct file_operations DRM(fops) = { poll: DRM(poll), }; + +static drm_ioctl_desc_t DRM(ioctls)[] = { + [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { DRM(version), 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { DRM(getunique), 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { DRM(getmagic), 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { DRM(irq_busid), 0, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { DRM(getmap), 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { DRM(getclient), 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { DRM(getstats), 0, 0 }, + + [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { DRM(setunique), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { DRM(block), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { DRM(unblock), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { DRM(authmagic), 1, 1 }, + + [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { DRM(addmap), 1, 1 }, + + [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { DRM(addctx), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { DRM(rmctx), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { DRM(modctx), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { DRM(getctx), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { DRM(switchctx), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { DRM(newctx), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { DRM(resctx), 1, 0 }, + + [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { DRM(adddraw), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { DRM(rmdraw), 1, 1 }, + + [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { DRM(lock), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { DRM(unlock), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { DRM(finish), 1, 0 }, + +#if __HAVE_DMA + [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { DRM(addbufs), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { DRM(markbufs), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { DRM(infobufs), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { DRM(mapbufs), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { DRM(freebufs), 1, 0 }, + + /* The DRM_IOCTL_DMA ioctl should be defined by the driver. + */ +#if __HAVE_DMA_IRQ + [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { DRM(control), 1, 1 }, +#endif +#endif + +#if __REALLY_HAVE_AGP + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { DRM(agp_acquire), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { DRM(agp_release), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { DRM(agp_enable), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { DRM(agp_info), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { DRM(agp_alloc), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { DRM(agp_free), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { DRM(agp_bind), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { DRM(agp_unbind), 1, 1 }, +#endif + + DRIVER_IOCTLS +}; + +#define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( DRM(ioctls) ) + #ifdef MODULE static char *drm_opts = NULL; #endif @@ -186,7 +251,7 @@ static int DRM(setup)( drm_device_t *dev ) #ifdef __HAVE_COUNTER15 dev->types[14] = __HAVE_COUNTER14; #endif - + for (i = 0; i < DRM_ARRAY_SIZE(dev->counts); i++) atomic_set(&dev->counts[i], 0); @@ -463,8 +528,7 @@ static void __exit drm_cleanup( void ) DRM(ctxbitmap_cleanup)( dev ); #endif -#if __REALLY_HAVE_MTRR -#if __REALLY_HAVE_AGP +#if __REALLY_HAVE_AGP && __REALLY_HAVE_MTRR if ( dev->agp && dev->agp->agp_mtrr ) { int retval; retval = mtrr_del( dev->agp->agp_mtrr, @@ -473,7 +537,6 @@ static void __exit drm_cleanup( void ) DRM_DEBUG( "mtrr_del=%d\n", retval ); } #endif -#endif DRM(takedown)( dev ); @@ -573,7 +636,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) DRM_ERROR( "Process %d dead, freeing lock for context %d\n", current->pid, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) ); -#if __HAVE_DRIVER_RELEASE +#if __HAVE_RELEASE DRIVER_RELEASE(); #endif DRM(lock_free)( dev, &dev->lock.hw_lock->lock, @@ -584,7 +647,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) processed via a callback to the X server. */ } -#if __HAVE_DRIVER_RELEASE +#if __HAVE_RELEASE else if ( dev->lock.hw_lock ) { /* The lock is required to reclaim buffers */ DECLARE_WAITQUEUE( entry, current ); diff --git a/linux/mga.h b/linux/mga.h index 6c0ed961..9b222404 100644 --- a/linux/mga.h +++ b/linux/mga.h @@ -42,6 +42,5 @@ #define __HAVE_CTX_BITMAP 1 #define __HAVE_DMA 1 -#define __HAVE_DMA_IRQ 1 #endif diff --git a/linux/mga_dma.c b/linux/mga_dma.c index 7b66e887..e99745d2 100644 --- a/linux/mga_dma.c +++ b/linux/mga_dma.c @@ -68,955 +68,6 @@ do { \ -#if 0 - - -#define MGA_REG(reg) 2 -#define MGA_BASE(reg) ((unsigned long) \ - ((drm_device_t *)dev)->maplist[MGA_REG(reg)]->handle) -#define MGA_ADDR(reg) (MGA_BASE(reg) + reg) -#define MGA_DEREF(reg) *(__volatile__ int *)MGA_ADDR(reg) -#define MGA_READ(reg) MGA_DEREF(reg) -#define MGA_WRITE(reg,val) do { MGA_DEREF(reg) = val; } while (0) - -#define PDEA_pagpxfer_enable 0x2 - -static int mga_flush_queue(drm_device_t *dev); - -static unsigned long mga_alloc_page(drm_device_t *dev) -{ - unsigned long address; - - address = __get_free_page(GFP_KERNEL); - if(address == 0UL) { - return 0; - } - atomic_inc(&virt_to_page(address)->count); - set_bit(PG_reserved, &virt_to_page(address)->flags); - - return address; -} - -static void mga_free_page(drm_device_t *dev, unsigned long page) -{ - if(!page) return; - atomic_dec(&virt_to_page(page)->count); - clear_bit(PG_reserved, &virt_to_page(page)->flags); - free_page(page); - return; -} - -static void mga_delay(void) -{ - return; -} - -/* These are two age tags that will never be sent to - * the hardware */ -#define MGA_BUF_USED 0xffffffff -#define MGA_BUF_FREE 0 - -static int mga_freelist_init(drm_device_t *dev) -{ - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf; - drm_mga_buf_priv_t *buf_priv; - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; - drm_mga_freelist_t *item; - int i; - - dev_priv->head = DRM(alloc)(sizeof(drm_mga_freelist_t), - DRM_MEM_DRIVER); - if(dev_priv->head == NULL) return -ENOMEM; - memset(dev_priv->head, 0, sizeof(drm_mga_freelist_t)); - dev_priv->head->age = MGA_BUF_USED; - - for (i = 0; i < dma->buf_count; i++) { - buf = dma->buflist[ i ]; - buf_priv = buf->dev_private; - item = drm_alloc(sizeof(drm_mga_freelist_t), - DRM_MEM_DRIVER); - if(item == NULL) return -ENOMEM; - memset(item, 0, sizeof(drm_mga_freelist_t)); - item->age = MGA_BUF_FREE; - item->prev = dev_priv->head; - item->next = dev_priv->head->next; - if(dev_priv->head->next != NULL) - dev_priv->head->next->prev = item; - if(item->next == NULL) dev_priv->tail = item; - item->buf = buf; - buf_priv->my_freelist = item; - buf_priv->discard = 0; - buf_priv->dispatched = 0; - dev_priv->head->next = item; - } - - return 0; -} - -static void mga_freelist_cleanup(drm_device_t *dev) -{ - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; - drm_mga_freelist_t *item; - drm_mga_freelist_t *prev; - - item = dev_priv->head; - while(item) { - prev = item; - item = item->next; - drm_free(prev, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER); - } - - dev_priv->head = dev_priv->tail = NULL; -} - -/* Frees dispatch lock */ -static inline void mga_dma_quiescent(drm_device_t *dev) -{ - drm_device_dma_t *dma = dev->dma; - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned long end; - int i; - - DRM_DEBUG("dispatch_status = 0x%02x\n", dev_priv->dispatch_status); - end = jiffies + (HZ*3); - while(1) { - if(!test_and_set_bit(MGA_IN_DISPATCH, - &dev_priv->dispatch_status)) { - break; - } - if((signed)(end - jiffies) <= 0) { - DRM_ERROR("irqs: %d wanted %d\n", - atomic_read(&dev->total_irq), - atomic_read(&dma->total_lost)); - DRM_ERROR("lockup: dispatch_status = 0x%02x," - " jiffies = %lu, end = %lu\n", - dev_priv->dispatch_status, jiffies, end); - return; - } - for (i = 0 ; i < 2000 ; i++) mga_delay(); - } - end = jiffies + (HZ*3); - DRM_DEBUG("quiescent status : %x\n", MGA_READ(MGAREG_STATUS)); - while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) { - if((signed)(end - jiffies) <= 0) { - DRM_ERROR("irqs: %d wanted %d\n", - atomic_read(&dev->total_irq), - atomic_read(&dma->total_lost)); - DRM_ERROR("lockup\n"); - clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status); - return; - } - for (i = 0 ; i < 2000 ; i++) mga_delay(); - } - sarea_priv->dirty |= MGA_DMA_FLUSH; - - clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status); - DRM_DEBUG("exit, dispatch_status = 0x%02x\n", - dev_priv->dispatch_status); -} - -static void mga_reset_freelist(drm_device_t *dev) -{ - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf; - drm_mga_buf_priv_t *buf_priv; - int i; - - for (i = 0; i < dma->buf_count; i++) { - buf = dma->buflist[ i ]; - buf_priv = buf->dev_private; - buf_priv->my_freelist->age = MGA_BUF_FREE; - } -} - -/* Least recently used : - * These operations are not atomic b/c they are protected by the - * hardware lock */ - -drm_buf_t *mga_freelist_get(drm_device_t *dev) -{ - DECLARE_WAITQUEUE(entry, current); - drm_mga_private_t *dev_priv = - (drm_mga_private_t *) dev->dev_private; - drm_mga_freelist_t *prev; - drm_mga_freelist_t *next; - static int failed = 0; - int return_null = 0; - - if(failed >= 1000 && dev_priv->tail->age >= dev_priv->last_prim_age) { - DRM_DEBUG("Waiting on freelist," - " tail->age = %d, last_prim_age= %d\n", - dev_priv->tail->age, - dev_priv->last_prim_age); - add_wait_queue(&dev_priv->buf_queue, &entry); - set_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status); - for (;;) { - current->state = TASK_INTERRUPTIBLE; - mga_dma_schedule(dev, 0); - if(dev_priv->tail->age < dev_priv->last_prim_age) - break; - atomic_inc(&dev->total_sleeps); - schedule(); - if (signal_pending(current)) { - ++return_null; - break; - } - } - clear_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status); - current->state = TASK_RUNNING; - remove_wait_queue(&dev_priv->buf_queue, &entry); - if (return_null) return NULL; - } - - if(dev_priv->tail->age < dev_priv->last_prim_age) { - prev = dev_priv->tail->prev; - next = dev_priv->tail; - prev->next = NULL; - next->prev = next->next = NULL; - dev_priv->tail = prev; - next->age = MGA_BUF_USED; - failed = 0; - return next->buf; - } - - failed++; - return NULL; -} - -int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf) -{ - drm_mga_private_t *dev_priv = - (drm_mga_private_t *) dev->dev_private; - drm_mga_buf_priv_t *buf_priv = buf->dev_private; - drm_mga_freelist_t *prev; - drm_mga_freelist_t *head; - drm_mga_freelist_t *next; - - if(buf_priv->my_freelist->age == MGA_BUF_USED) { - /* Discarded buffer, put it on the tail */ - next = buf_priv->my_freelist; - next->age = MGA_BUF_FREE; - prev = dev_priv->tail; - prev->next = next; - next->prev = prev; - next->next = NULL; - dev_priv->tail = next; - } else { - /* Normally aged buffer, put it on the head + 1, - * as the real head is a sentinal element - */ - next = buf_priv->my_freelist; - head = dev_priv->head; - prev = head->next; - head->next = next; - prev->prev = next; - next->prev = head; - next->next = prev; - } - - return 0; -} - -static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_prim_buf_t *prim_buffer; - int i, temp, size_of_buf; - int offset = init->reserved_map_agpstart; - - dev_priv->primary_size = ((init->primary_size + PAGE_SIZE - 1) / - PAGE_SIZE) * PAGE_SIZE; - size_of_buf = dev_priv->primary_size / MGA_NUM_PRIM_BUFS; - dev_priv->warp_ucode_size = init->warp_ucode_size; - dev_priv->prim_bufs = drm_alloc(sizeof(drm_mga_prim_buf_t *) * - (MGA_NUM_PRIM_BUFS + 1), - DRM_MEM_DRIVER); - if(dev_priv->prim_bufs == NULL) { - DRM_ERROR("Unable to allocate memory for prim_buf\n"); - return -ENOMEM; - } - memset(dev_priv->prim_bufs, - 0, sizeof(drm_mga_prim_buf_t *) * (MGA_NUM_PRIM_BUFS + 1)); - - temp = init->warp_ucode_size + dev_priv->primary_size; - temp = ((temp + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE; - - dev_priv->ioremap = drm_ioremap(dev->agp->base + offset, - temp); - if(dev_priv->ioremap == NULL) { - DRM_ERROR("Ioremap failed\n"); - return -ENOMEM; - } - init_waitqueue_head(&dev_priv->wait_queue); - - for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) { - prim_buffer = drm_alloc(sizeof(drm_mga_prim_buf_t), - DRM_MEM_DRIVER); - if(prim_buffer == NULL) return -ENOMEM; - memset(prim_buffer, 0, sizeof(drm_mga_prim_buf_t)); - prim_buffer->phys_head = offset + dev->agp->base; - prim_buffer->current_dma_ptr = - prim_buffer->head = - (u32 *) (dev_priv->ioremap + - offset - - init->reserved_map_agpstart); - prim_buffer->num_dwords = 0; - prim_buffer->max_dwords = size_of_buf / sizeof(u32); - prim_buffer->max_dwords -= 5; /* Leave room for the softrap */ - prim_buffer->sec_used = 0; - prim_buffer->idx = i; - prim_buffer->prim_age = i + 1; - offset = offset + size_of_buf; - dev_priv->prim_bufs[i] = prim_buffer; - } - dev_priv->current_prim_idx = 0; - dev_priv->next_prim = - dev_priv->last_prim = - dev_priv->current_prim = - dev_priv->prim_bufs[0]; - dev_priv->next_prim_age = 2; - dev_priv->last_prim_age = 1; - set_bit(MGA_BUF_IN_USE, &dev_priv->current_prim->buffer_status); - return 0; -} - -void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_device_dma_t *dma = dev->dma; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - int use_agp = PDEA_pagpxfer_enable; - unsigned long end; - int i; - int next_idx; - PRIMLOCALS; - - dev_priv->last_prim = prim; - - /* We never check for overflow, b/c there is always room */ - PRIMPTR(prim); - if(num_dwords <= 0) { - DRM_ERROR("num_dwords == 0 when dispatched\n"); - goto out_prim_wait; - } - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_SOFTRAP, 0); - PRIMFINISH(prim); - - end = jiffies + (HZ*3); - if(sarea_priv->dirty & MGA_DMA_FLUSH) { - while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) { - if((signed)(end - jiffies) <= 0) { - DRM_ERROR("irqs: %d wanted %d\n", - atomic_read(&dev->total_irq), - atomic_read(&dma->total_lost)); - DRM_ERROR("lockup (flush)\n"); - goto out_prim_wait; - } - - for (i = 0 ; i < 4096 ; i++) mga_delay(); - } - sarea_priv->dirty &= ~(MGA_DMA_FLUSH); - } else { - while((MGA_READ(MGAREG_STATUS) & 0x00020001) != 0x00020000) { - if((signed)(end - jiffies) <= 0) { - DRM_ERROR("irqs: %d wanted %d\n", - atomic_read(&dev->total_irq), - atomic_read(&dma->total_lost)); - DRM_ERROR("lockup (wait)\n"); - goto out_prim_wait; - } - - for (i = 0 ; i < 4096 ; i++) mga_delay(); - } - } - - mga_flush_write_combine(); - atomic_inc(&dev_priv->pending_bufs); - MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL); - MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp); - prim->num_dwords = 0; - sarea_priv->last_enqueue = prim->prim_age; - - next_idx = prim->idx + 1; - if(next_idx >= MGA_NUM_PRIM_BUFS) - next_idx = 0; - - dev_priv->next_prim = dev_priv->prim_bufs[next_idx]; - return; - - out_prim_wait: - prim->num_dwords = 0; - prim->sec_used = 0; - clear_bit(MGA_BUF_IN_USE, &prim->buffer_status); - wake_up_interruptible(&dev_priv->wait_queue); - clear_bit(MGA_BUF_SWAP_PENDING, &prim->buffer_status); - clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status); -} - -int mga_advance_primary(drm_device_t *dev) -{ - DECLARE_WAITQUEUE(entry, current); - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_prim_buf_t *prim_buffer; - drm_device_dma_t *dma = dev->dma; - int next_prim_idx; - int ret = 0; - - /* This needs to reset the primary buffer if available, - * we should collect stats on how many times it bites - * it's tail */ - - next_prim_idx = dev_priv->current_prim_idx + 1; - if(next_prim_idx >= MGA_NUM_PRIM_BUFS) - next_prim_idx = 0; - prim_buffer = dev_priv->prim_bufs[next_prim_idx]; - set_bit(MGA_IN_WAIT, &dev_priv->dispatch_status); - - /* In use is cleared in interrupt handler */ - - if(test_and_set_bit(MGA_BUF_IN_USE, &prim_buffer->buffer_status)) { - add_wait_queue(&dev_priv->wait_queue, &entry); - for (;;) { - current->state = TASK_INTERRUPTIBLE; - mga_dma_schedule(dev, 0); - if(!test_and_set_bit(MGA_BUF_IN_USE, - &prim_buffer->buffer_status)) - break; - atomic_inc(&dev->total_sleeps); - atomic_inc(&dma->total_missed_sched); - schedule(); - if (signal_pending(current)) { - ret = -ERESTARTSYS; - break; - } - } - current->state = TASK_RUNNING; - remove_wait_queue(&dev_priv->wait_queue, &entry); - if(ret) return ret; - } - clear_bit(MGA_IN_WAIT, &dev_priv->dispatch_status); - - /* This primary buffer is now free to use */ - prim_buffer->current_dma_ptr = prim_buffer->head; - prim_buffer->num_dwords = 0; - prim_buffer->sec_used = 0; - prim_buffer->prim_age = dev_priv->next_prim_age++; - if(prim_buffer->prim_age == 0 || prim_buffer->prim_age == 0xffffffff) { - mga_flush_queue(dev); - mga_dma_quiescent(dev); - mga_reset_freelist(dev); - prim_buffer->prim_age = (dev_priv->next_prim_age += 2); - } - - /* Reset all buffer status stuff */ - clear_bit(MGA_BUF_NEEDS_OVERFLOW, &prim_buffer->buffer_status); - clear_bit(MGA_BUF_FORCE_FIRE, &prim_buffer->buffer_status); - clear_bit(MGA_BUF_SWAP_PENDING, &prim_buffer->buffer_status); - - dev_priv->current_prim = prim_buffer; - dev_priv->current_prim_idx = next_prim_idx; - return 0; -} - -/* More dynamic performance decisions */ -static inline int mga_decide_to_fire(drm_device_t *dev) -{ - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; - - if(test_bit(MGA_BUF_FORCE_FIRE, &dev_priv->next_prim->buffer_status)) { - return 1; - } - - if (test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status) && - dev_priv->next_prim->num_dwords) { - return 1; - } - - if (test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) && - dev_priv->next_prim->num_dwords) { - return 1; - } - - if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS - 1) { - if(test_bit(MGA_BUF_SWAP_PENDING, - &dev_priv->next_prim->buffer_status)) { - return 1; - } - } - - if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS / 2) { - if(dev_priv->next_prim->sec_used >= MGA_DMA_BUF_NR / 8) { - return 1; - } - } - - if(atomic_read(&dev_priv->pending_bufs) >= MGA_NUM_PRIM_BUFS / 2) { - if(dev_priv->next_prim->sec_used >= MGA_DMA_BUF_NR / 4) { - return 1; - } - } - - return 0; -} - -int mga_dma_schedule(drm_device_t *dev, int locked) -{ - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; - int retval = 0; - - if (!dev_priv) return -EBUSY; - - if (test_and_set_bit(0, &dev->dma_flag)) { - retval = -EBUSY; - goto sch_out_wakeup; - } - - if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) || - test_bit(MGA_IN_WAIT, &dev_priv->dispatch_status) || - test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)) { - locked = 1; - } - - if (!locked && - !drm_lock_take(&dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) { - clear_bit(0, &dev->dma_flag); - retval = -EBUSY; - goto sch_out_wakeup; - } - - if(!test_and_set_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status)) { - /* Fire dma buffer */ - if(mga_decide_to_fire(dev)) { - clear_bit(MGA_BUF_FORCE_FIRE, - &dev_priv->next_prim->buffer_status); - if(dev_priv->current_prim == dev_priv->next_prim) { - /* Schedule overflow for a later time */ - set_bit(MGA_BUF_NEEDS_OVERFLOW, - &dev_priv->next_prim->buffer_status); - } - mga_fire_primary(dev, dev_priv->next_prim); - } else { - clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status); - } - } - - if (!locked) { - if (drm_lock_free(dev, &dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT)) { - DRM_ERROR("\n"); - } - } - - clear_bit(0, &dev->dma_flag); - -sch_out_wakeup: - if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) && - atomic_read(&dev_priv->pending_bufs) == 0) { - /* Everything has been processed by the hardware */ - clear_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status); - wake_up_interruptible(&dev_priv->flush_queue); - } - - if(test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status) - && dev_priv->tail->age < dev_priv->last_prim_age) - wake_up_interruptible(&dev_priv->buf_queue); - - return retval; -} - -static void mga_dma_service(int irq, void *device, struct pt_regs *regs) -{ - drm_device_t *dev = (drm_device_t *)device; - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; - drm_mga_prim_buf_t *last_prim_buffer; - - atomic_inc(&dev->total_irq); - if((MGA_READ(MGAREG_STATUS) & 0x00000001) != 0x00000001) return; - MGA_WRITE(MGAREG_ICLEAR, 0x00000001); - last_prim_buffer = dev_priv->last_prim; - last_prim_buffer->num_dwords = 0; - last_prim_buffer->sec_used = 0; - dev_priv->sarea_priv->last_dispatch = - dev_priv->last_prim_age = last_prim_buffer->prim_age; - clear_bit(MGA_BUF_IN_USE, &last_prim_buffer->buffer_status); - clear_bit(MGA_BUF_SWAP_PENDING, &last_prim_buffer->buffer_status); - clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status); - atomic_dec(&dev_priv->pending_bufs); - queue_task(&dev->tq, &tq_immediate); - mark_bh(IMMEDIATE_BH); - wake_up_interruptible(&dev_priv->wait_queue); -} - -static void mga_dma_task_queue(void *device) -{ - mga_dma_schedule((drm_device_t *)device, 0); -} - -int mga_dma_cleanup(drm_device_t *dev) -{ - if(dev->dev_private) { - drm_mga_private_t *dev_priv = - (drm_mga_private_t *) dev->dev_private; - - if (dev->irq) mga_flush_queue(dev); - mga_dma_quiescent(dev); - - if(dev_priv->ioremap) { - int temp = (dev_priv->warp_ucode_size + - dev_priv->primary_size + - PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE; - - drm_ioremapfree((void *) dev_priv->ioremap, temp); - } - if(dev_priv->status_page != NULL) { - iounmap(dev_priv->status_page); - } - if(dev_priv->real_status_page != 0UL) { - mga_free_page(dev, dev_priv->real_status_page); - } - if(dev_priv->prim_bufs != NULL) { - int i; - for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) { - if(dev_priv->prim_bufs[i] != NULL) { - drm_free(dev_priv->prim_bufs[i], - sizeof(drm_mga_prim_buf_t), - DRM_MEM_DRIVER); - } - } - drm_free(dev_priv->prim_bufs, sizeof(void *) * - (MGA_NUM_PRIM_BUFS + 1), - DRM_MEM_DRIVER); - } - if(dev_priv->head != NULL) { - mga_freelist_cleanup(dev); - } - - - drm_free(dev->dev_private, sizeof(drm_mga_private_t), - DRM_MEM_DRIVER); - dev->dev_private = NULL; - } - - return 0; -} - -static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) { - drm_mga_private_t *dev_priv; - drm_map_t *sarea_map = NULL; - - dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER); - if(dev_priv == NULL) return -ENOMEM; - dev->dev_private = (void *) dev_priv; - - memset(dev_priv, 0, sizeof(drm_mga_private_t)); - - if((init->reserved_map_idx >= dev->map_count) || - (init->buffer_map_idx >= dev->map_count)) { - mga_dma_cleanup(dev); - return -EINVAL; - } - - dev_priv->reserved_map_idx = init->reserved_map_idx; - dev_priv->buffer_map_idx = init->buffer_map_idx; - sarea_map = dev->maplist[0]; - dev_priv->sarea_priv = (drm_mga_sarea_t *) - ((u8 *)sarea_map->handle + - init->sarea_priv_offset); - - /* Scale primary size to the next page */ - dev_priv->chipset = init->chipset; - dev_priv->frontOffset = init->frontOffset; - dev_priv->backOffset = init->backOffset; - dev_priv->depthOffset = init->depthOffset; - dev_priv->textureOffset = init->textureOffset; - dev_priv->textureSize = init->textureSize; - dev_priv->cpp = init->cpp; - dev_priv->sgram = init->sgram; - dev_priv->stride = init->stride; - - dev_priv->mAccess = init->mAccess; - init_waitqueue_head(&dev_priv->flush_queue); - init_waitqueue_head(&dev_priv->buf_queue); - dev_priv->WarpPipe = 0xff000000; - dev_priv->vertexsize = 0; - - DRM_DEBUG("chipset=%d ucode_size=%d backOffset=%x depthOffset=%x\n", - dev_priv->chipset, dev_priv->warp_ucode_size, - dev_priv->backOffset, dev_priv->depthOffset); - DRM_DEBUG("cpp: %d sgram: %d stride: %d maccess: %x\n", - dev_priv->cpp, dev_priv->sgram, dev_priv->stride, - dev_priv->mAccess); - - memcpy(&dev_priv->WarpIndex, &init->WarpIndex, - sizeof(drm_mga_warp_index_t) * MGA_MAX_WARP_PIPES); - - if(mga_init_primary_bufs(dev, init) != 0) { - DRM_ERROR("Can not initialize primary buffers\n"); - mga_dma_cleanup(dev); - return -ENOMEM; - } - dev_priv->real_status_page = mga_alloc_page(dev); - if(dev_priv->real_status_page == 0UL) { - mga_dma_cleanup(dev); - DRM_ERROR("Can not allocate status page\n"); - return -ENOMEM; - } - - dev_priv->status_page = - ioremap_nocache(virt_to_bus((void *)dev_priv->real_status_page), - PAGE_SIZE); - - if(dev_priv->status_page == NULL) { - mga_dma_cleanup(dev); - DRM_ERROR("Can not remap status page\n"); - return -ENOMEM; - } - - /* Write status page when secend or softrap occurs */ - MGA_WRITE(MGAREG_PRIMPTR, - virt_to_bus((void *)dev_priv->real_status_page) | 0x00000003); - - - /* Private is now filled in, initialize the hardware */ - { - PRIMLOCALS; - PRIMGETPTR( dev_priv ); - - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DWGSYNC, 0x0100); - PRIMOUTREG(MGAREG_SOFTRAP, 0); - /* Poll for the first buffer to insure that - * the status register will be correct - */ - - mga_flush_write_combine(); - MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL); - - MGA_WRITE(MGAREG_PRIMEND, ((phys_head + num_dwords * 4) | - PDEA_pagpxfer_enable)); - - while(MGA_READ(MGAREG_DWGSYNC) != 0x0100) ; - } - - if(mga_freelist_init(dev) != 0) { - DRM_ERROR("Could not initialize freelist\n"); - mga_dma_cleanup(dev); - return -ENOMEM; - } - return 0; -} - -int mga_dma_init(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_mga_init_t init; - - if (copy_from_user(&init, (drm_mga_init_t *)arg, sizeof(init))) - return -EFAULT; - - switch(init.func) { - case MGA_INIT_DMA: - return mga_dma_initialize(dev, &init); - case MGA_CLEANUP_DMA: - return mga_dma_cleanup(dev); - } - - return -EINVAL; -} - -static int mga_flush_queue(drm_device_t *dev) -{ - DECLARE_WAITQUEUE(entry, current); - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; - int ret = 0; - - if(!dev_priv) return 0; - - if(dev_priv->next_prim->num_dwords != 0) { - add_wait_queue(&dev_priv->flush_queue, &entry); - if (test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status)) - DRM_ERROR("Incorrect mga_flush_queue logic\n"); - set_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status); - mga_dma_schedule(dev, 0); - for (;;) { - current->state = TASK_INTERRUPTIBLE; - if (!test_bit(MGA_IN_FLUSH, - &dev_priv->dispatch_status)) - break; - atomic_inc(&dev->total_sleeps); - schedule(); - if (signal_pending(current)) { - ret = -EINTR; /* Can't restart */ - clear_bit(MGA_IN_FLUSH, - &dev_priv->dispatch_status); - break; - } - } - current->state = TASK_RUNNING; - remove_wait_queue(&dev_priv->flush_queue, &entry); - } - return ret; -} - -/* Must be called with the lock held */ -void mga_reclaim_buffers(drm_device_t *dev, pid_t pid) -{ - drm_device_dma_t *dma = dev->dma; - int i; - - if (!dma) return; - if(dev->dev_private == NULL) return; - if(dma->buflist == NULL) return; - - DRM_DEBUG("buf_count=%d\n", dma->buf_count); - - mga_flush_queue(dev); - - for (i = 0; i < dma->buf_count; i++) { - drm_buf_t *buf = dma->buflist[ i ]; - drm_mga_buf_priv_t *buf_priv = buf->dev_private; - - /* Only buffers that need to get reclaimed ever - * get set to free - */ - if (buf->pid == pid && buf_priv) { - if(buf_priv->my_freelist->age == MGA_BUF_USED) - buf_priv->my_freelist->age = MGA_BUF_FREE; - } - } -} - -int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - DECLARE_WAITQUEUE(entry, current); - int ret = 0; - drm_lock_t lock; - - if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock))) - return -EFAULT; - - if (lock.context == DRM_KERNEL_CONTEXT) { - DRM_ERROR("Process %d using kernel context %d\n", - current->pid, lock.context); - return -EINVAL; - } - - if (lock.context < 0) return -EINVAL; - - /* Only one queue: - */ - - if (!ret) { - add_wait_queue(&dev->lock.lock_queue, &entry); - for (;;) { - current->state = TASK_INTERRUPTIBLE; - if (!dev->lock.hw_lock) { - /* Device has been unregistered */ - ret = -EINTR; - break; - } - if (drm_lock_take(&dev->lock.hw_lock->lock, - lock.context)) { - dev->lock.pid = current->pid; - dev->lock.lock_time = jiffies; - atomic_inc(&dev->total_locks); - break; /* Got lock */ - } - - /* Contention */ - atomic_inc(&dev->total_sleeps); - schedule(); - if (signal_pending(current)) { - ret = -ERESTARTSYS; - break; - } - } - current->state = TASK_RUNNING; - remove_wait_queue(&dev->lock.lock_queue, &entry); - } - - if (!ret) { - sigemptyset(&dev->sigmask); - sigaddset(&dev->sigmask, SIGSTOP); - sigaddset(&dev->sigmask, SIGTSTP); - sigaddset(&dev->sigmask, SIGTTIN); - sigaddset(&dev->sigmask, SIGTTOU); - dev->sigdata.context = lock.context; - dev->sigdata.lock = dev->lock.hw_lock; - block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); - - if (lock.flags & _DRM_LOCK_QUIESCENT) { - DRM_DEBUG("_DRM_LOCK_QUIESCENT\n"); - mga_flush_queue(dev); - mga_dma_quiescent(dev); - } - } - - if (ret) DRM_DEBUG("%d %s\n", lock.context, - ret ? "interrupted" : "has lock"); - return ret; -} - -int mga_flush_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_lock_t lock; - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; - - if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock))) - return -EFAULT; - - if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("lock not held\n"); - return -EINVAL; - } - - if(lock.flags & _DRM_LOCK_FLUSH || lock.flags & _DRM_LOCK_FLUSH_ALL) { - drm_mga_prim_buf_t *temp_buf; - - temp_buf = dev_priv->current_prim; - - if(temp_buf && temp_buf->num_dwords) { - set_bit(MGA_BUF_FORCE_FIRE, &temp_buf->buffer_status); - mga_advance_primary(dev); - } - mga_dma_schedule(dev, 1); - } - if(lock.flags & _DRM_LOCK_QUIESCENT) { - mga_flush_queue(dev); - mga_dma_quiescent(dev); - } - - return 0; -} - - -#endif - - - - -/* - * **************************************************************** - * - * START NEW CODE HERE - * - * **************************************************************** - */ - static unsigned long mga_alloc_page( void ) { unsigned long address; @@ -1042,8 +93,6 @@ static void mga_free_page( unsigned long address ) } - - /* ================================================================ * Engine control */ @@ -1090,7 +139,7 @@ int mga_do_dma_reset( drm_mga_private_t *dev_priv ) /* The primary DMA stream should look like new right about now. */ primary->tail = 0; - primary->space = primary->size - MGA_DMA_SOFTRAP_SIZE; + primary->space = primary->size; primary->last_flush = 0; sarea_priv->last_wrap = 0; @@ -1150,15 +199,21 @@ void mga_do_dma_flush( drm_mga_private_t *dev_priv ) { drm_mga_primary_buffer_t *primary = &dev_priv->prim; u32 head, tail; + unsigned long flags; DMA_LOCALS; DRM_DEBUG( "%s:\n", __FUNCTION__ ); - if ( primary->tail == primary->last_flush ) { + if ( primary->tail == primary->last_flush + DMA_BLOCK_SIZE ) { DRM_DEBUG( " bailing out...\n" ); return; } + spin_lock_irqsave( &primary->flush_lock, flags ); + tail = primary->tail + dev_priv->primary->offset; + primary->last_flush = primary->tail; + + spin_unlock_irqrestore( &primary->flush_lock, flags ); BEGIN_DMA( 1 ); @@ -1169,24 +224,30 @@ void mga_do_dma_flush( drm_mga_private_t *dev_priv ) ADVANCE_DMA(); - mga_flush_write_combine(); - MGA_WRITE( MGA_PRIMEND, tail | MGA_PRIMNOSTART | MGA_PAGPXFER ); - head = *primary->head; - DRM_DEBUG( " head = 0x%06lx\n", head - dev_priv->primary->offset ); - DRM_DEBUG( " tail = 0x%06lx\n", tail - dev_priv->primary->offset ); - if ( head <= tail ) { primary->space = primary->size - primary->tail; } else { primary->space = head - tail; } - primary->space -= MGA_DMA_SOFTRAP_SIZE; - - DRM_DEBUG( " space = 0x%06x\n", primary->space ); - primary->last_flush = primary->tail; + if ( test_bit( 0, &primary->wrap_flag ) ) { + DRM_DEBUG( "%s: pending wrap...\n", __FUNCTION__ ); + spin_unlock_irqrestore( &primary->flush_lock, flags ); + return; + } + +#if 0 + DRM_INFO( " head = 0x%06lx\n", + head - dev_priv->primary->offset ); + DRM_INFO( " tail = 0x%06lx\n", + tail - dev_priv->primary->offset ); + DRM_INFO( " space = 0x%06x\n", primary->space ); +#endif + + mga_flush_write_combine(); + MGA_WRITE( MGA_PRIMEND, tail | MGA_PRIMNOSTART | MGA_PAGPXFER ); DRM_DEBUG( "%s: done.\n", __FUNCTION__ ); } @@ -1195,9 +256,12 @@ void mga_do_dma_wrap( drm_mga_private_t *dev_priv ) { drm_mga_primary_buffer_t *primary = &dev_priv->prim; u32 head, tail; + unsigned long flags; DMA_LOCALS; DRM_DEBUG( "%s:\n", __FUNCTION__ ); + spin_lock_irqsave( &primary->flush_lock, flags ); + BEGIN_DMA_WRAP(); DMA_BLOCK( MGA_DMAPAD, 0x00000000, @@ -1208,31 +272,38 @@ void mga_do_dma_wrap( drm_mga_private_t *dev_priv ) ADVANCE_DMA(); tail = primary->tail + dev_priv->primary->offset; - - mga_flush_write_combine(); - MGA_WRITE( MGA_PRIMEND, tail | MGA_PRIMNOSTART | MGA_PAGPXFER ); - - spin_lock_irqsave( &primary->tail_lock, flags ); primary->tail = 0; - spin_unlock_irqrestore( &primary->tail_lock, flags ); head = *primary->head; - DRM_DEBUG( " head = 0x%06lx\n", head - dev_priv->primary->offset ); - DRM_DEBUG( " tail = 0x%06x\n", 0 ); - - if ( head <= tail ) { - primary->space = primary->size - primary->tail; + if ( head == dev_priv->primary->offset ) { + primary->space = primary->size; } else { - primary->space = head - tail; + primary->space = head - dev_priv->primary->offset; } - primary->space -= MGA_DMA_SOFTRAP_SIZE; - - DRM_DEBUG( " space = 0x%06lx\n", (unsigned long)primary->space ); primary->last_flush = 0; + primary->last_wrap++; + + set_bit( 0, &primary->wrap_flag ); + + if ( 0 ) { + DRM_INFO( "%s:\n", __FUNCTION__ ); + DRM_INFO( " head = 0x%06lx\n", + head - dev_priv->primary->offset ); + DRM_INFO( " tail = 0x%06x\n", primary->tail ); + DRM_INFO( " wrap = %d\n", primary->last_wrap ); + DRM_INFO( " space = 0x%06x\n", primary->space ); + } + + mga_flush_write_combine(); + MGA_WRITE( MGA_PRIMEND, tail | MGA_PRIMNOSTART | MGA_PAGPXFER ); + + spin_unlock_irqrestore( &primary->flush_lock, flags ); DRM_DEBUG( "%s: done.\n", __FUNCTION__ ); + + mga_do_wait_for_idle( dev_priv ); } @@ -1247,7 +318,7 @@ static void mga_dma_service( int irq, void *device, struct pt_regs *regs ) drm_mga_primary_buffer_t *primary = &dev_priv->prim; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; u32 head = dev_priv->primary->offset; - u32 tail; + u32 flush; /* Verify the interrupt we're servicing is actually the one we * want to service. @@ -1256,29 +327,36 @@ static void mga_dma_service( int irq, void *device, struct pt_regs *regs ) return; atomic_inc( &dev->counts[_DRM_STAT_IRQ] ); - + + spin_lock( &primary->flush_lock ); + MGA_WRITE( MGA_ICLEAR, MGA_SOFTRAPICLR ); - spin_lock( &primary->tail_lock ); - tail = primary->tail + dev_priv->primary->offset; + flush = primary->last_flush + dev_priv->primary->offset; sarea_priv->last_wrap++; - spin_unlock( &primary->tail_lock ); - DRM_DEBUG( " *** wrap interrupt:\n" ); - DRM_DEBUG( " head = 0x%06lx\n", - head - dev_priv->primary->offset ); - DRM_DEBUG( " tail = 0x%06lx\n", - tail - dev_priv->primary->offset ); - DRM_DEBUG( " wrap = %d\n", sarea_priv->last_wrap ); + clear_bit( 0, &primary->wrap_flag ); + +#if 0 + DRM_INFO( " *** wrap interrupt:\n" ); + DRM_INFO( " head = 0x%06lx\n", + head - dev_priv->primary->offset ); + DRM_INFO( " flush = 0x%06lx\n", primary->last_flush ); + DRM_INFO( " tail = 0x%06lx %s\n", + primary->tail, + primary->tail != primary->last_flush + DMA_BLOCK_SIZE + ? "***" : "" ); + DRM_INFO( " wrap = %d\n", sarea_priv->last_wrap ); +#endif mga_flush_write_combine(); MGA_WRITE( MGA_PRIMADDRESS, head | MGA_DMA_GENERAL ); - MGA_WRITE( MGA_PRIMEND, tail | MGA_PRIMNOSTART | MGA_PAGPXFER ); -#if 0 - queue_task( &dev->tq, &tq_immediate ); - mark_bh( IMMEDIATE_BH ); -#endif + if ( primary->last_flush > 0 ) { + MGA_WRITE( MGA_PRIMEND, flush | MGA_PAGPXFER ); + } + + spin_unlock( &primary->flush_lock ); } static int mga_dma_task_queue( void *dev ) @@ -1545,6 +623,9 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) DO_FIND_MAP( dev_priv->mmio, init->mmio_offset ); DO_FIND_MAP( dev_priv->status, init->status_offset ); + DRM_INFO( "status handle = 0x%08lx\n", dev_priv->status->handle ); + DRM_INFO( "status offset = 0x%08lx\n", dev_priv->status->offset ); + DO_FIND_MAP( dev_priv->warp, init->warp_offset ); DO_FIND_MAP( dev_priv->primary, init->primary_offset ); DO_FIND_MAP( dev_priv->buffers, init->buffers_offset ); @@ -1571,24 +652,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) return ret; } -#if 0 - dev_priv->prim.status_page = mga_alloc_page(); - if ( !dev_priv->prim.status_page ) { - DRM_ERROR( "failed to allocate status page!\n" ); - mga_do_cleanup_dma( dev ); - return -ENOMEM; - } - dev_priv->prim.status = (u32 *)dev_priv->prim.status_page; - - if ( !dev_priv->prim.status ) { - DRM_ERROR( "failed to remap status page!\n" ); - mga_do_cleanup_dma( dev ); - return -ENOMEM; - } -#endif - dev_priv->sarea_priv->last_wrap = 0; - - dev_priv->prim.status = (u32 *)&dev_priv->status->handle; + dev_priv->prim.status = (u32 *)dev_priv->status->handle; mga_do_wait_for_idle( dev_priv ); @@ -1609,17 +673,24 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) dev_priv->prim.head = &dev_priv->prim.status[0]; dev_priv->prim.tail = 0; - dev_priv->prim.space = dev_priv->prim.size - MGA_DMA_SOFTRAP_SIZE; + dev_priv->prim.space = dev_priv->prim.size; dev_priv->prim.last_flush = 0; + dev_priv->prim.last_wrap = 0; + clear_bit( 0, &dev_priv->prim.wrap_flag ); + dev_priv->prim.high_mark = 0; - spin_lock_init( &dev_priv->prim.tail_lock ); + spin_lock_init( &dev_priv->prim.flush_lock ); spin_lock_init( &dev_priv->prim.list_lock ); dev_priv->prim.status[0] = dev_priv->primary->offset; dev_priv->prim.status[1] = 0; + dev_priv->sarea_priv->last_wrap = 0; + dev_priv->sarea_priv->last_frame.head = 0; + dev_priv->sarea_priv->last_frame.wrap = 0; + if ( mga_freelist_init( dev ) < 0 ) { DRM_ERROR( "could not initialize freelist\n" ); mga_do_cleanup_dma( dev ); @@ -1893,8 +964,7 @@ if ( 0 ) { DRM_INFO( "sync = 0x%08x\n", dev_priv->prim.status[1] ); DRM_INFO( "\n" ); DRM_INFO( "space = 0x%x / 0x%x\n", - dev_priv->prim.space, - dev_priv->prim.size - MGA_DMA_SOFTRAP_SIZE ); + dev_priv->prim.space, dev_priv->prim.size ); DRM_INFO( "\n" ); DRM_INFO( " irqs = %d\n", atomic_read( &dev->counts[_DRM_STAT_IRQ] ) ); diff --git a/linux/mga_drv.c b/linux/mga_drv.c index d458afb4..fdba9c5f 100644 --- a/linux/mga_drv.c +++ b/linux/mga_drv.c @@ -38,85 +38,23 @@ #define DRIVER_NAME "mga" #define DRIVER_DESC "Matrox G200/G400" -#define DRIVER_DATE "20010206" +#define DRIVER_DATE "20010212" #define DRIVER_MAJOR 3 #define DRIVER_MINOR 0 #define DRIVER_PATCHLEVEL 0 -/* Now that we do this, we can move the DRM(ioctls) array into a - * template file and have a DRIVER_IOCTLS block at the end. - */ -static drm_ioctl_desc_t mga_ioctls[] = { - [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { mga_version, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { mga_getunique, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { mga_getmagic, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { mga_irq_busid, 0, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { mga_getmap, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { mga_getclient, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { mga_getstats, 0, 0 }, - - [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { mga_setunique, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { mga_block, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { mga_unblock, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { mga_control, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { mga_authmagic, 1, 1 }, - - [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { mga_addmap, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { mga_addbufs, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { mga_markbufs, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { mga_infobufs, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { mga_mapbufs, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { mga_freebufs, 1, 0 }, - - [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { mga_addctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { mga_rmctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { mga_modctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { mga_getctx, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { mga_switchctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { mga_newctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { mga_resctx, 1, 0 }, - - [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { mga_adddraw, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { mga_rmdraw, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { mga_lock, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { mga_unlock, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { mga_finish, 1, 0 }, - -#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { mga_agp_acquire, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { mga_agp_release, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { mga_agp_enable, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { mga_agp_info, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { mga_agp_alloc, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { mga_agp_free, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { mga_agp_bind, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { mga_agp_unbind, 1, 1 }, -#endif - - [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_dma_flush, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)] = { mga_dma_reset, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_dma_swap, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_dma_clear, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 }, +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_dma_flush, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)] = { mga_dma_reset, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_dma_swap, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_dma_clear, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_dma_indices, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_dma_iload, 1, 0 }, -#if 0 - [DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_indices, 1, 0 }, -#endif -}; - -#define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( mga_ioctls ) - -#define __HAVE_AGP 1 -#define __MUST_HAVE_AGP 1 - -#define __HAVE_MTRR 1 - -#define __HAVE_CTX_BITMAP 1 -#define __HAVE_DMA 1 #define __HAVE_DMA_IRQ 1 #define __HAVE_COUNTERS 3 @@ -137,7 +75,7 @@ do { \ } while (0) #if 0 -#define __HAVE_DRIVER_RELEASE 1 +#define __HAVE_RELEASE 1 #define DRIVER_RELEASE() do { \ mga_reclaim_buffers( dev, priv->pid ); \ if ( dev->dev_private ) { \ diff --git a/linux/mga_drv.h b/linux/mga_drv.h index 510ee05b..5b575eb6 100644 --- a/linux/mga_drv.h +++ b/linux/mga_drv.h @@ -64,13 +64,15 @@ typedef struct drm_mga_primary_buffer { u32 tail; int space; - unsigned long status_page; volatile u32 *status; u32 last_flush; + u32 last_wrap; + __volatile__ long wrap_flag; + u32 high_mark; - spinlock_t tail_lock; + spinlock_t flush_lock; spinlock_t list_lock; } drm_mga_primary_buffer_t; @@ -173,20 +175,11 @@ extern int mga_dma_swap( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); extern int mga_dma_vertex( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); +extern int mga_dma_indices( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); extern int mga_dma_iload( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); -#if 0 -extern int mga_clear_bufs( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int mga_swap_bufs( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int mga_iload( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int mga_indices( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -#endif - /* mga_warp.c */ extern int mga_warp_install_microcode( drm_device_t *dev ); extern int mga_warp_init( drm_device_t *dev ); @@ -201,13 +194,6 @@ extern int mga_warp_init( drm_device_t *dev ); #define MGA_READ( reg ) MGA_DEREF( reg ) #define MGA_WRITE( reg, val ) do { MGA_DEREF( reg ) = val; } while (0) -typedef enum { - TT_GENERAL, - TT_BLIT, - TT_VECTOR, - TT_VERTEX -} transferType_t; - #define DWGREG0 0x1c00 #define DWGREG0_END 0x1dff @@ -219,104 +205,6 @@ typedef enum { #define DMAREG1(r) (u8)(((r - DWGREG1) >> 2) | 0x80) #define DMAREG(r) (ISREG0(r) ? DMAREG0(r) : DMAREG1(r)) -#define MGA_NUM_PRIM_BUFS 8 - -#define PRIMLOCALS u8 tempIndex[4]; u32 *dma_ptr; u32 phys_head; \ - int outcount, num_dwords - -#define PRIM_OVERFLOW(dev, dev_priv, length) do { \ - drm_mga_prim_buf_t *tmp_buf = \ - dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ - if( test_bit(MGA_BUF_NEEDS_OVERFLOW, &tmp_buf->buffer_status)) { \ - mga_advance_primary(dev); \ - mga_dma_schedule(dev, 1); \ - tmp_buf = dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ - } else if( tmp_buf->max_dwords - tmp_buf->num_dwords < length || \ - tmp_buf->sec_used > MGA_DMA_BUF_NR/2) { \ - set_bit(MGA_BUF_FORCE_FIRE, &tmp_buf->buffer_status); \ - mga_advance_primary(dev); \ - mga_dma_schedule(dev, 1); \ - tmp_buf = dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ - } \ - if(MGA_VERBOSE) \ - DRM_DEBUG("PRIMGETPTR in %s\n", __FUNCTION__); \ - dma_ptr = tmp_buf->current_dma_ptr; \ - num_dwords = tmp_buf->num_dwords; \ - phys_head = tmp_buf->phys_head; \ - outcount = 0; \ -} while(0) - -#define PRIMGETPTR(dev_priv) do { \ - drm_mga_prim_buf_t *tmp_buf = \ - dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ - if(MGA_VERBOSE) \ - DRM_DEBUG("PRIMGETPTR in %s\n", __FUNCTION__); \ - dma_ptr = tmp_buf->current_dma_ptr; \ - num_dwords = tmp_buf->num_dwords; \ - phys_head = tmp_buf->phys_head; \ - outcount = 0; \ -} while(0) - -#define PRIMPTR(prim_buf) do { \ - if(MGA_VERBOSE) \ - DRM_DEBUG("PRIMPTR in %s\n", __FUNCTION__); \ - dma_ptr = prim_buf->current_dma_ptr; \ - num_dwords = prim_buf->num_dwords; \ - phys_head = prim_buf->phys_head; \ - outcount = 0; \ -} while(0) - -#define PRIMFINISH(prim_buf) do { \ - if (MGA_VERBOSE) { \ - DRM_DEBUG( "PRIMFINISH in %s\n", __FUNCTION__); \ - if (outcount & 3) \ - DRM_DEBUG(" --- truncation\n"); \ - } \ - prim_buf->num_dwords = num_dwords; \ - prim_buf->current_dma_ptr = dma_ptr; \ -} while(0) - -#define PRIMADVANCE(dev_priv) do { \ -drm_mga_prim_buf_t *tmp_buf = \ - dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ - if (MGA_VERBOSE) { \ - DRM_DEBUG("PRIMADVANCE in %s\n", __FUNCTION__); \ - if (outcount & 3) \ - DRM_DEBUG(" --- truncation\n"); \ - } \ - tmp_buf->num_dwords = num_dwords; \ - tmp_buf->current_dma_ptr = dma_ptr; \ -} while (0) - -#define PRIMUPDATE(dev_priv) do { \ - drm_mga_prim_buf_t *tmp_buf = \ - dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ - tmp_buf->sec_used++; \ -} while (0) - -#define AGEBUF(dev_priv, buf_priv) do { \ - drm_mga_prim_buf_t *tmp_buf = \ - dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ - buf_priv->my_freelist->age = tmp_buf->prim_age; \ -} while (0) - - -#define PRIMOUTREG(reg, val) do { \ - tempIndex[outcount]=ADRINDEX(reg); \ - dma_ptr[1+outcount] = val; \ - if (MGA_VERBOSE) \ - DRM_DEBUG(" PRIMOUT %d: 0x%x -- 0x%x\n", \ - num_dwords + 1 + outcount, ADRINDEX(reg), val); \ - if( ++outcount == 4) { \ - outcount = 0; \ - dma_ptr[0] = *(unsigned long *)tempIndex; \ - dma_ptr+=5; \ - num_dwords += 5; \ - } \ -}while (0) - - - /* ================================================================ @@ -349,10 +237,10 @@ do { \ * Primary DMA command stream */ -#define MGA_VERBOSE 0 +#define MGA_VERBOSE ( 0 /*dev_priv->prim.space < 0x100*/ ) + +#define DMA_LOCALS unsigned int write; volatile u8 *prim; -#define DMA_LOCALS unsigned int write; volatile u8 *prim; \ - unsigned long flags; #define DMA_BLOCK_SIZE (5 * sizeof(u32)) #define BEGIN_DMA( n ) \ @@ -363,7 +251,8 @@ do { \ DRM_INFO( " space=0x%x req=0x%x\n", \ dev_priv->prim.space, (n) * DMA_BLOCK_SIZE ); \ } \ - if ( dev_priv->prim.space < (int)((n) * DMA_BLOCK_SIZE) ) { \ + if ( dev_priv->prim.space < (int)((n) * DMA_BLOCK_SIZE + \ + MGA_DMA_SOFTRAP_SIZE) ) { \ mga_do_dma_wrap( dev_priv ); \ } \ prim = dev_priv->prim.start; \ @@ -382,16 +271,27 @@ do { \ #define ADVANCE_DMA() \ do { \ - dev_priv->prim.space -= (write - dev_priv->prim.tail); \ - spin_lock_irqsave( &dev_priv->prim.tail_lock, flags ); \ dev_priv->prim.tail = write; \ - spin_unlock_irqrestore( &dev_priv->prim.tail_lock, flags ); \ if ( MGA_VERBOSE ) { \ DRM_INFO( "ADVANCE_DMA() tail=0x%05x sp=0x%x\n", \ write, dev_priv->prim.space ); \ } \ } while (0) +#if 0 +#define FLUSH_DMA() \ +do { \ + if ( dev_priv->prim.space < (int)(128 * DMA_BLOCK_SIZE + \ + MGA_DMA_SOFTRAP_SIZE) ) { \ + mga_do_dma_wrap( dev_priv ); \ + } else { \ + mga_do_dma_flush( dev_priv ); \ + } \ +} while (0) +#else +#define FLUSH_DMA() mga_do_dma_flush( dev_priv ); +#endif + /* Never use this, always use DMA_BLOCK(...) for primary DMA output. */ #define DMA_WRITE( offset, val ) \ diff --git a/linux/mga_state.c b/linux/mga_state.c index f1328d9e..a3c96aa1 100644 --- a/linux/mga_state.c +++ b/linux/mga_state.c @@ -598,7 +598,7 @@ static void mga_dma_dispatch_clear( drm_device_t *dev, ADVANCE_DMA(); #endif - mga_do_dma_flush( dev_priv ); + FLUSH_DMA(); } static void mga_dma_dispatch_swap( drm_device_t *dev ) @@ -611,7 +611,8 @@ static void mga_dma_dispatch_swap( drm_device_t *dev ) u32 pitch = dev_priv->front_pitch / dev_priv->fb_cpp; int i; DMA_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "%s:\n", __FUNCTION__ ); + DRM_DEBUG( " head = 0x%06x\n", *dev_priv->prim.head ); BEGIN_DMA( 2 + nbox ); @@ -645,7 +646,13 @@ static void mga_dma_dispatch_swap( drm_device_t *dev ) ADVANCE_DMA(); - mga_do_dma_flush( dev_priv ); + sarea_priv->last_frame.head = dev_priv->prim.tail; + sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap; + + DRM_DEBUG( " tail = 0x%06x\n", dev_priv->prim.tail ); + DRM_DEBUG( " wrap = 0x%06x\n", dev_priv->prim.last_wrap ); + + FLUSH_DMA(); } static void mga_dma_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf ) @@ -695,65 +702,56 @@ static void mga_dma_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf ) mga_freelist_put( dev, buf ); } - mga_do_dma_flush( dev_priv ); + FLUSH_DMA(); } - - -#if 0 - - -static void mga_dma_dispatch_indices(drm_device_t * dev, - drm_buf_t * buf, - unsigned int start, unsigned int end) +static void mga_dma_dispatch_indices( drm_device_t *dev, drm_buf_t *buf, + unsigned int start, unsigned int end ) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_buf_priv_t *buf_priv = buf->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int address = (unsigned int) buf->bus_address; - int use_agp = PDEA_pagpxfer_enable; + u32 address = (u32) buf->bus_address; int i = 0; - PRIMLOCALS; + DMA_LOCALS; + DRM_INFO( __FUNCTION__ ": buf=%d start=%d end=%d\n", + buf->idx, start, end ); - if (start != end) { - /* WARNING: if you change any of the state functions verify - * these numbers (Overestimating this doesn't hurt). - */ + if ( start != end ) { buf_priv->dispatched = 1; - PRIM_OVERFLOW(dev, dev_priv, - (MAX_STATE_SIZE + (5 * MGA_NR_SAREA_CLIPRECTS))); - mgaEmitState(dev_priv); + + MGA_EMIT_STATE( dev_priv, sarea_priv->dirty ); do { - if (i < sarea_priv->nbox) { - mgaEmitClipRect(dev_priv, - &sarea_priv->boxes[i]); + if ( i < sarea_priv->nbox ) { + mga_emit_clip_rect( dev_priv, + &sarea_priv->boxes[i] ); } - PRIMGETPTR(dev_priv); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_SETUPADDRESS, - ((address + start) | - SETADD_mode_vertlist)); - PRIMOUTREG(MGAREG_SETUPEND, - ((address + end) | use_agp)); -/* ((address + start + 12) | use_agp)); */ - PRIMADVANCE(dev_priv); - } while (++i < sarea_priv->nbox); - } - if (buf_priv->discard) { - if (buf_priv->dispatched == 1) - AGEBUF(dev_priv, buf_priv); - buf_priv->dispatched = 0; - mga_freelist_put(dev, buf); - } -} + BEGIN_DMA( 1 ); + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_SETUPADDRESS, address + start, + MGA_SETUPEND, ((address + end) | + MGA_PAGPXFER) ); + ADVANCE_DMA(); + } while ( ++i < sarea_priv->nbox ); + } -#endif + if ( buf_priv->discard ) { + if ( buf_priv->dispatched == 1 ) + AGE_BUFFER( buf_priv ); + buf->pending = 0; + buf->used = 0; + buf_priv->dispatched = 0; + + mga_freelist_put( dev, buf ); + } + FLUSH_DMA(); +} /* This copies a 64 byte aligned agp region to the frambuffer with a * standard blit, the ioctl needs to do checking. @@ -767,6 +765,9 @@ static void mga_dma_dispatch_iload( drm_device_t *dev, drm_buf_t *buf, u32 y2; DMA_LOCALS; + DRM_DEBUG( "%s: buf=%d used=%d\n", + __FUNCTION__, buf->idx, buf->used ); + y2 = length / 64; BEGIN_DMA( 4 ); @@ -793,11 +794,12 @@ static void mga_dma_dispatch_iload( drm_device_t *dev, drm_buf_t *buf, ADVANCE_DMA(); -#if 0 AGE_BUFFER( buf_priv ); -#endif + buf_priv->discard = 1; mga_freelist_put( dev, buf ); + + FLUSH_DMA(); } @@ -871,12 +873,6 @@ int mga_dma_vertex( struct inode *inode, struct file *filp, (drm_mga_vertex_t *)arg, sizeof(vertex) ) ) return -EFAULT; -#if 0 - /* HACK: oh well... - */ - if ( mga_do_wait_for_idle( dev_priv ) < 0 ) - return -EBUSY; -#endif buf = dma->buflist[vertex.idx]; buf_priv = buf->dev_private; @@ -886,10 +882,8 @@ int mga_dma_vertex( struct inode *inode, struct file *filp, if ( !mga_verify_state( dev_priv ) ) { if ( vertex.discard ) { -#if 0 if ( buf_priv->dispatched == 1 ) - AGEBUF(dev_priv, buf_priv); -#endif + AGE_BUFFER( buf_priv ); buf_priv->dispatched = 0; mga_freelist_put( dev, buf ); } @@ -901,59 +895,45 @@ int mga_dma_vertex( struct inode *inode, struct file *filp, return 0; } - - -#if 0 - - -int mga_indices(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +int mga_dma_indices( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - drm_mga_private_t *dev_priv = - (drm_mga_private_t *) dev->dev_private; + drm_mga_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; drm_mga_buf_priv_t *buf_priv; drm_mga_indices_t indices; + DRM_INFO( __FUNCTION__ "\n" ); - if (copy_from_user(&indices, - (drm_mga_indices_t *)arg, sizeof(indices))) - return -EFAULT; + LOCK_TEST_WITH_RETURN( dev ); - if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("mga_indices called without lock held\n"); - return -EINVAL; - } + if ( copy_from_user( &indices, + (drm_mga_indices_t *)arg, + sizeof(indices) ) ) + return -EFAULT; buf = dma->buflist[indices.idx]; buf_priv = buf->dev_private; buf_priv->discard = indices.discard; - if (!mgaVerifyState(dev_priv)) { - if (indices.discard) { - if (buf_priv->dispatched == 1) - AGEBUF(dev_priv, buf_priv); + if ( !mga_verify_state( dev_priv ) ) { + if ( indices.discard ) { + if ( buf_priv->dispatched == 1 ) + AGE_BUFFER( buf_priv ); buf_priv->dispatched = 0; - mga_freelist_put(dev, buf); + mga_freelist_put( dev, buf ); } return -EINVAL; } - mga_dma_dispatch_indices(dev, buf, indices.start, indices.end); + mga_dma_dispatch_indices( dev, buf, indices.start, indices.end ); - PRIMUPDATE(dev_priv); - mga_flush_write_combine(); - mga_dma_schedule(dev, 1); return 0; } - -#endif - - int mga_dma_iload( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ) { @@ -970,12 +950,9 @@ int mga_dma_iload( struct inode *inode, struct file *filp, if ( copy_from_user( &iload, (drm_mga_iload_t *)arg, sizeof(iload) ) ) return -EFAULT; -#if 1 - /* HACK: oh well... - */ + if ( mga_do_wait_for_idle( dev_priv ) < 0 ) return -EBUSY; -#endif buf = dma->buflist[iload.idx]; buf_priv = buf->dev_private; |