From c14006ba9f0522875327998215150067d8ca6ea7 Mon Sep 17 00:00:00 2001
From: Alan Hourihane <alanh@fairlite.demon.co.uk>
Date: Tue, 25 Mar 2003 00:29:14 +0000
Subject: XFree86 4.3.0 merge

---
 bsd-core/drm_os_netbsd.h  | 129 +++++++++++++--------------------
 bsd-core/mga_drv.c        |   8 +--
 bsd-core/r128_drv.c       |   9 +--
 bsd-core/radeon_drv.c     |  61 +++++++---------
 bsd-core/tdfx_drv.c       |   7 +-
 bsd/drm_os_netbsd.h       | 129 +++++++++++++--------------------
 bsd/mga_drv.c             |   8 +--
 bsd/r128_drv.c            |   9 +--
 bsd/radeon_drv.c          |  61 +++++++---------
 bsd/tdfx_drv.c            |   7 +-
 libdrm/xf86drmCompat.c    |   2 +-
 linux-core/drm_os_linux.h |  14 ++--
 linux-core/i830_irq.c     | 178 ++++++++++++++++++++++++++++++++++++++++++++++
 linux/drm_os_linux.h      |  14 ++--
 linux/gamma_drm.h         |  10 +++
 linux/i830_irq.c          | 178 ++++++++++++++++++++++++++++++++++++++++++++++
 shared-core/mga_drv.h     |  36 +++++-----
 shared-core/r128_cce.c    |   1 -
 shared-core/r128_drv.h    |  34 +++++----
 shared-core/r128_state.c  | 118 +++++++++++++++---------------
 shared-core/radeon_cp.c   |  63 ++--------------
 shared-core/radeon_drv.h  |  79 ++++++++++++++------
 shared-core/radeon_mem.c  |  22 ++++--
 shared/mga_drv.h          |  36 +++++-----
 shared/r128_cce.c         |   1 -
 shared/r128_drv.h         |  34 +++++----
 shared/r128_state.c       | 118 +++++++++++++++---------------
 shared/radeon.h           |  35 ++++-----
 shared/radeon_cp.c        |  63 ++--------------
 shared/radeon_drv.h       |  79 ++++++++++++++------
 shared/radeon_mem.c       |  22 ++++--
 31 files changed, 920 insertions(+), 645 deletions(-)
 create mode 100644 linux-core/i830_irq.c
 create mode 100644 linux/i830_irq.c

diff --git a/bsd-core/drm_os_netbsd.h b/bsd-core/drm_os_netbsd.h
index 5551f172..605b6a2c 100644
--- a/bsd-core/drm_os_netbsd.h
+++ b/bsd-core/drm_os_netbsd.h
@@ -17,7 +17,6 @@
 #include <uvm/uvm.h>
 #include <sys/vnode.h>
 #include <sys/poll.h>
-#include <sys/lkm.h>
 /* For TIOCSPGRP/TIOCGPGRP */
 #include <sys/ttycom.h>
 
@@ -32,9 +31,11 @@
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
  
+#include "drmvar.h"
+
 #define __REALLY_HAVE_AGP	__HAVE_AGP
 
-#define __REALLY_HAVE_MTRR	1
+#define __REALLY_HAVE_MTRR	0
 #define __REALLY_HAVE_SG	0
 
 #if __REALLY_HAVE_AGP
@@ -42,7 +43,8 @@
 #include <sys/agpio.h>
 #endif
 
-#include <opt_drm.h>
+#define device_t struct device *
+extern struct cfdriver DRM(_cd);
 
 #if DRM_DEBUG
 #undef  DRM_DEBUG_CODE
@@ -50,20 +52,12 @@
 #endif
 #undef DRM_DEBUG
 
-#if DRM_LINUX
-#undef DRM_LINUX	/* FIXME: Linux compat has not been ported yet */
-#endif
-
-typedef drm_device_t *device_t;
-
-extern struct cfdriver DRM(cd);
-
 #define DRM_TIME_SLICE	      (hz/20)  /* Time slice for GLXContexts	  */
 
 #define DRM_DEV_MODE	(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
 #define DRM_DEV_UID	0
 #define DRM_DEV_GID	0
-#define CDEV_MAJOR	34
+#define CDEV_MAJOR	90
 
 #define DRM_CURPROC		curproc
 #define DRM_STRUCTPROC		struct proc
@@ -79,25 +73,16 @@ extern struct cfdriver DRM(cd);
 #define DRM_UNLOCK 		lockmgr(&dev->dev_lock, LK_RELEASE, NULL)
 #define DRM_SUSER(p)		suser(p->p_ucred, &p->p_acflag)
 #define DRM_TASKQUEUE_ARGS	void *dev, int pending
-#define DRM_IRQ_ARGS		void *arg
-#define DRM_DEVICE		drm_device_t *dev = device_lookup(&DRM(cd), minor(kdev))
-/* XXX Not sure if this is the 'right' version.. */
-#if __NetBSD_Version__ >= 106140000
-MALLOC_DECLARE(DRM(M_DRM));
-#else
-/* XXX Make sure this works */
-extern const int DRM(M_DRM) = M_DEVBUF;
-#endif /* __NetBSD_Version__ */
+#define DRM_IRQ_ARGS		void *device
+#define DRM_DEVICE		drm_device_t *dev = device_lookup(&DRM(_cd), minor(kdev))
 #define DRM_MALLOC(size)	malloc( size, DRM(M_DRM), M_NOWAIT )
-#define DRM_FREE(pt,size)		free( pt, DRM(M_DRM) )
+#define DRM_FREE(pt)		free( pt, DRM(M_DRM) )
 #define DRM_VTOPHYS(addr)	vtophys(addr)
-
-#define DRM_READ8(map, offset)		bus_space_read_1(  (map)->iot, (map)->ioh, (offset) )
-#define DRM_READ32(map, offset)		bus_space_read_4(  (map)->iot, (map)->ioh, (offset) )
-#define DRM_WRITE8(map, offset, val)	bus_space_write_1( (map)->iot, (map)->ioh, (offset), (val) )
-#define DRM_WRITE32(map, offset, val)	bus_space_write_4( (map)->iot, (map)->ioh, (offset), (val) )
-
-#define DRM_AGP_FIND_DEVICE()	agp_find_device(0)
+#define DRM_READ8(addr)	*((volatile char *)(addr))
+#define DRM_READ32(addr)	*((volatile long *)(addr))
+#define DRM_WRITE8(addr, val)	*((volatile char *)(addr)) = (val)
+#define DRM_WRITE32(addr, val)	*((volatile long *)(addr)) = (val)
+#define DRM_AGP_FIND_DEVICE()
 
 #define DRM_PRIV					\
 	drm_file_t	*priv	= (drm_file_t *) DRM(find_file_by_proc)(dev, p); \
@@ -120,7 +105,7 @@ do {								\
 do {								\
 	drm_map_list_entry_t *listentry;			\
 	TAILQ_FOREACH(listentry, dev->maplist, link) {		\
-		drm_local_map_t *map = listentry->map;		\
+		drm_map_t *map = listentry->map;		\
 		if (map->type == _DRM_SHM &&			\
 			map->flags & _DRM_CONTAINS_LOCK) {	\
 			dev_priv->sarea = map;			\
@@ -129,15 +114,7 @@ do {								\
 	}							\
 } while (0)
 
-#define DRM_HZ hz
-
-#define DRM_WAIT_ON( ret, queue, timeout, condition )		\
-while (!condition) {						\
-	ret = tsleep( (void *)&(queue), PZERO | PCATCH, "drmwtq", (timeout) ); \
-	if ( ret )						\
-		return ret;					\
-}
-
+#define return DRM_ERR(v)	return v;
 #define DRM_ERR(v)		v
 
 #define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \
@@ -148,25 +125,21 @@ while (!condition) {						\
 	copyout(arg2, arg1, arg3)
 #define DRM_COPY_FROM_USER(arg1, arg2, arg3) \
 	copyin(arg2, arg1, arg3)
-/* Macros for userspace access with checking readability once */
-/* FIXME: can't find equivalent functionality for nocheck yet.
- * It'll be slower than linux, but should be correct.
- */
-#define DRM_VERIFYAREA_READ( uaddr, size )		\
-	(!uvm_useracc((caddr_t)uaddr, size, VM_PROT_READ))
-#define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) 	\
-	copyin(arg2, arg1, arg3)
-#define DRM_GET_USER_UNCHECKED(val, uaddr)			\
-	((val) = fuword(uaddr), 0)
 
-#define DRM_WRITEMEMORYBARRIER( map )					\
-	bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, 0);
-#define DRM_READMEMORYBARRIER( map )					\
-	bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, BUS_SPACE_BARRIER_READ);
+#define DRM_READMEMORYBARRIER \
+{												\
+   	int xchangeDummy;									\
+	DRM_DEBUG("%s\n", __FUNCTION__);							\
+   	__asm__ volatile(" push %%eax ; xchg %%eax, %0 ; pop %%eax" : : "m" (xchangeDummy));	\
+   	__asm__ volatile(" push %%eax ; push %%ebx ; push %%ecx ; push %%edx ;"			\
+			 " movl $0,%%eax ; cpuid ; pop %%edx ; pop %%ecx ; pop %%ebx ;"		\
+			 " pop %%eax" : /* no outputs */ :  /* no inputs */ );			\
+} while (0);
 
-#define DRM_WAKEUP(w) wakeup((void *)w)
+#define DRM_WRITEMEMORYBARRIER DRM_READMEMORYBARRIER
+
+#define DRM_WAKEUP(w) wakeup(w)
 #define DRM_WAKEUP_INT(w) wakeup(w)
-#define DRM_INIT_WAITQUEUE( queue )  do {} while (0)
 
 #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
 
@@ -178,46 +151,30 @@ typedef struct drm_chipinfo
 	char *name;
 } drm_chipinfo_t;
 
-#define cpu_to_le32(x) (x)	/* FIXME */
-
 typedef u_int32_t dma_addr_t;
-typedef volatile long atomic_t;
+typedef volatile u_int32_t atomic_t;
 typedef u_int32_t cycles_t;
+typedef u_int32_t spinlock_t;
 typedef u_int32_t u32;
 typedef u_int16_t u16;
 typedef u_int8_t u8;
 typedef dev_type_ioctl(d_ioctl_t);
 typedef vaddr_t vm_offset_t;
 
-/* FIXME */
 #define atomic_set(p, v)	(*(p) = (v))
 #define atomic_read(p)		(*(p))
-#define atomic_inc(p)		(*(p) += 1)
-#define atomic_dec(p)		(*(p) -= 1)
-#define atomic_add(n, p)	(*(p) += (n))
-#define atomic_sub(n, p)	(*(p) -= (n))
+#define atomic_inc(p)		atomic_add_int(p, 1)
+#define atomic_dec(p)		atomic_subtract_int(p, 1)
+#define atomic_add(n, p)	atomic_add_int(p, n)
+#define atomic_sub(n, p)	atomic_subtract_int(p, n)
 
-/* FIXME */
+/* FIXME: Is NetBSD's kernel non-reentrant? */
 #define atomic_add_int(p, v)      *(p) += v
 #define atomic_subtract_int(p, v) *(p) -= v
 #define atomic_set_int(p, bits)   *(p) |= (bits)
 #define atomic_clear_int(p, bits) *(p) &= ~(bits)
 
 /* Fake this */
-
-static __inline int
-atomic_cmpset_int(__volatile__ int *dst, int old, int new)
-{
-	int s = splhigh();
-	if (*dst==old) {
-		*dst = new;
-		splx(s);
-		return 1;
-	}
-	splx(s);
-	return 0;
-}
-
 static __inline atomic_t
 test_and_set_bit(int b, atomic_t *p)
 {
@@ -267,6 +224,20 @@ find_first_zero_bit(atomic_t *p, int max)
 #define spldrm()		spltty()
 #define jiffies			hardclock_ticks
 
+#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock)
+#define _DRM_CAS(lock,old,new,__ret)				       \
+	do {							       \
+		int __dummy;	/* Can't mark eax as clobbered */      \
+		__asm__ __volatile__(				       \
+			"lock ; cmpxchg %4,%1\n\t"		       \
+			"setnz %0"				       \
+			: "=d" (__ret),				       \
+			  "=m" (__drm_dummy_lock(lock)),	       \
+			  "=a" (__dummy)			       \
+			: "2" (old),				       \
+			  "r" (new));				       \
+	} while (0)
+
 /* Redefinitions to make templating easy */
 #define wait_queue_head_t	atomic_t
 #define agp_memory		void
@@ -287,7 +258,7 @@ do { \
 #define DRM_DEBUG(fmt, arg...)						  \
 	do {								  \
 		if (DRM(flags) & DRM_FLAG_DEBUG)			  \
-			printf("[" DRM_NAME ":%s] " fmt , __FUNCTION__ ,## arg); \
+			printf("[" DRM_NAME ":%s] " fmt , __FUNCTION__,## arg); \
 	} while (0)
 #else
 #define DRM_DEBUG(fmt, arg...)		 do { } while (0)
diff --git a/bsd-core/mga_drv.c b/bsd-core/mga_drv.c
index de0387f7..8b69b41b 100644
--- a/bsd-core/mga_drv.c
+++ b/bsd-core/mga_drv.c
@@ -27,10 +27,10 @@
  * Authors:
  *    Rickard E. (Rik) Faith <faith@valinux.com>
  *    Gareth Hughes <gareth@valinux.com>
- *
- * $FreeBSD: src/sys/dev/drm/mga_drv.c,v 1.4 2003/03/09 02:08:28 anholt Exp $
  */
 
+#include <sys/types.h>
+
 #include "mga.h"
 #include "drmP.h"
 #include "drm.h"
@@ -63,8 +63,4 @@ drm_chipinfo_t DRM(devicelist)[] = {
 #include "drm_vm.h"
 #include "drm_sysctl.h"
 
-#ifdef __FreeBSD__
 DRIVER_MODULE(mga, pci, mga_driver, mga_devclass, 0, 0);
-#elif defined(__NetBSD__)
-CFDRIVER_DECL(mga, DV_TTY, NULL);
-#endif
diff --git a/bsd-core/r128_drv.c b/bsd-core/r128_drv.c
index 28a2c85e..1a8046fb 100644
--- a/bsd-core/r128_drv.c
+++ b/bsd-core/r128_drv.c
@@ -27,10 +27,11 @@
  * Authors:
  *    Rickard E. (Rik) Faith <faith@valinux.com>
  *    Gareth Hughes <gareth@valinux.com>
- *
- * $FreeBSD: src/sys/dev/drm/r128_drv.c,v 1.4 2003/03/09 02:08:28 anholt Exp $
  */
 
+
+#include <sys/types.h>
+
 #include "r128.h"
 #include "drmP.h"
 #include "drm.h"
@@ -82,8 +83,4 @@ drm_chipinfo_t DRM(devicelist)[] = {
 #include "drm_scatter.h"
 #endif
 
-#ifdef __FreeBSD__
 DRIVER_MODULE(r128, pci, r128_driver, r128_devclass, 0, 0);
-#elif defined(__NetBSD__)
-CFDRIVER_DECL(r128, DV_TTY, NULL);
-#endif /* __FreeBSD__ */
diff --git a/bsd-core/radeon_drv.c b/bsd-core/radeon_drv.c
index 2e7c5d66..a253b9cb 100644
--- a/bsd-core/radeon_drv.c
+++ b/bsd-core/radeon_drv.c
@@ -25,10 +25,10 @@
  *
  * Authors:
  *    Gareth Hughes <gareth@valinux.com>
- *
- * $FreeBSD: src/sys/dev/drm/radeon_drv.c,v 1.5 2003/03/11 01:38:17 anholt Exp $
  */
 
+#include <sys/types.h>
+
 #include "radeon.h"
 #include "drmP.h"
 #include "drm.h"
@@ -39,41 +39,38 @@
 #endif
 
 drm_chipinfo_t DRM(devicelist)[] = {
-	{0x1002, 0x4242, 1, "ATI Radeon BB R200 AIW 8500DV"},
-	{0x1002, 0x4336, 1, "ATI Radeon Mobility U1"},
-	{0x1002, 0x4964, 1, "ATI Radeon Id R250 9000"},
-	{0x1002, 0x4965, 1, "ATI Radeon Ie R250 9000"},
-	{0x1002, 0x4966, 1, "ATI Radeon If R250 9000"},
-	{0x1002, 0x4967, 1, "ATI Radeon Ig R250 9000"},
-	{0x1002, 0x4C57, 1, "ATI Radeon LW Mobility 7500 M7"},
-	{0x1002, 0x4C58, 1, "ATI Radeon LX RV200 Mobility FireGL 7800 M7"},
-	{0x1002, 0x4C59, 1, "ATI Radeon LY Mobility M6"},
-	{0x1002, 0x4C5A, 1, "ATI Radeon LZ Mobility M6"},
-	{0x1002, 0x4C64, 1, "ATI Radeon Ld R250 Mobility 9000 M9"},
-	{0x1002, 0x4C65, 1, "ATI Radeon Le R250 Mobility 9000 M9"},
-	{0x1002, 0x4C66, 1, "ATI Radeon Lf R250 Mobility 9000 M9"},
-	{0x1002, 0x4C67, 1, "ATI Radeon Lg R250 Mobility 9000 M9"},
-	{0x1002, 0x5144, 1, "ATI Radeon QD R100"},
-	{0x1002, 0x5145, 1, "ATI Radeon QE R100"},
-	{0x1002, 0x5146, 1, "ATI Radeon QF R100"},
-	{0x1002, 0x5147, 1, "ATI Radeon QG R100"},
-	{0x1002, 0x5148, 1, "ATI Radeon QH FireGL 8x00"},
+	{0x1002, 0x4242, 1, "ATI Radeon BB AIW 8500DV (AGP)"},
+	{0x1002, 0x4336, 1, "ATI Radeon Mobility"},
+	{0x1002, 0x4964, 1, "ATI Radeon Id 9000"},
+	{0x1002, 0x4965, 1, "ATI Radeon Ie 9000"},
+	{0x1002, 0x4966, 1, "ATI Radeon If 9000"},
+	{0x1002, 0x4967, 1, "ATI Radeon Ig 9000"},
+	{0x1002, 0x496e, 1, "ATI Radeon Ig 9000"},
+	{0x1002, 0x4C57, 1, "ATI Radeon LW Mobility 7 (AGP)"},
+	{0x1002, 0x4C58, 1, "ATI Radeon LX Mobility 7 (AGP)"},
+	{0x1002, 0x4C59, 1, "ATI Radeon LY Mobility 6 (AGP)"},
+	{0x1002, 0x4C5A, 1, "ATI Radeon LZ Mobility 6 (AGP)"},
+	{0x1002, 0x4C64, 1, "ATI Radeon Ld Mobility 9000 (AGP)"},
+	{0x1002, 0x4C65, 1, "ATI Radeon Le Mobility 9000 (AGP)"},
+	{0x1002, 0x4C66, 1, "ATI Radeon Lf Mobility 9000 (AGP)"},
+	{0x1002, 0x4C67, 1, "ATI Radeon Lg Mobility 9000 (AGP)"},
+	{0x1002, 0x5144, 1, "ATI Radeon QD R100 (AGP)"},
+	{0x1002, 0x5145, 1, "ATI Radeon QE R100 (AGP)"},
+	{0x1002, 0x5146, 1, "ATI Radeon QF R100 (AGP)"},
+	{0x1002, 0x5147, 1, "ATI Radeon QG R100 (AGP)"},
+	{0x1002, 0x5148, 1, "ATI Radeon QH FireGL 8x00 (AGP)"},
 	{0x1002, 0x5149, 1, "ATI Radeon QI R200"},
 	{0x1002, 0x514A, 1, "ATI Radeon QJ R200"},
 	{0x1002, 0x514B, 1, "ATI Radeon QK R200"},
-	{0x1002, 0x514C, 1, "ATI Radeon QL R200 8500 LE"},
-	{0x1002, 0x514D, 1, "ATI Radeon QM R200 9100"},
-	{0x1002, 0x514E, 1, "ATI Radeon QN R200 8500 LE"},
-	{0x1002, 0x514F, 1, "ATI Radeon QO R200 8500 LE"},
-	{0x1002, 0x5157, 1, "ATI Radeon QW RV200 7500"},
-	{0x1002, 0x5158, 1, "ATI Radeon QX RV200 7500"},
-	{0x1002, 0x5159, 1, "ATI Radeon QY RV100 VE"},
-	{0x1002, 0x515A, 1, "ATI Radeon QZ RV100 VE"},
+	{0x1002, 0x514C, 1, "ATI Radeon QL 8500 (AGP)"},
+	{0x1002, 0x5157, 1, "ATI Radeon QW 7500 (AGP)"},
+	{0x1002, 0x5158, 1, "ATI Radeon QX 7500 (AGP)"},
+	{0x1002, 0x5159, 1, "ATI Radeon QY VE (AGP)"},
+	{0x1002, 0x515A, 1, "ATI Radeon QZ VE (AGP)"},
 	{0x1002, 0x5168, 1, "ATI Radeon Qh R200"},
 	{0x1002, 0x5169, 1, "ATI Radeon Qi R200"},
 	{0x1002, 0x516A, 1, "ATI Radeon Qj R200"},
 	{0x1002, 0x516B, 1, "ATI Radeon Qk R200"},
-	{0x1002, 0x516C, 1, "ATI Radeon Ql R200"},
 	{0, 0, 0, NULL}
 };
 
@@ -95,8 +92,4 @@ drm_chipinfo_t DRM(devicelist)[] = {
 #include "drm_scatter.h"
 #endif
 
-#ifdef __FreeBSD__
 DRIVER_MODULE(DRIVER_NAME, pci, DRM(driver), DRM(devclass), 0, 0);
-#elif defined(__NetBSD__)
-CFDRIVER_DECL(radeon, DV_TTY, NULL);
-#endif /* __FreeBSD__ */
diff --git a/bsd-core/tdfx_drv.c b/bsd-core/tdfx_drv.c
index e10542f1..8bc8c57d 100644
--- a/bsd-core/tdfx_drv.c
+++ b/bsd-core/tdfx_drv.c
@@ -28,10 +28,11 @@
  *    Rickard E. (Rik) Faith <faith@valinux.com>
  *    Daryll Strauss <daryll@valinux.com>
  *    Gareth Hughes <gareth@valinux.com>
- *
- * $FreeBSD: src/sys/dev/drm/tdfx_drv.c,v 1.3 2003/03/09 02:08:28 anholt Exp $
  */
 
+
+#include <sys/types.h>
+
 #include "tdfx.h"
 #include "drmP.h"
 
@@ -95,6 +96,4 @@ drm_chipinfo_t DRM(devicelist)[] = {
 
 #ifdef __FreeBSD__
 DRIVER_MODULE(tdfx, pci, tdfx_driver, tdfx_devclass, 0, 0);
-#elif defined(__NetBSD__)
-CFDRIVER_DECL(tdfx, DV_TTY, NULL);
 #endif /* __FreeBSD__ */
diff --git a/bsd/drm_os_netbsd.h b/bsd/drm_os_netbsd.h
index 5551f172..605b6a2c 100644
--- a/bsd/drm_os_netbsd.h
+++ b/bsd/drm_os_netbsd.h
@@ -17,7 +17,6 @@
 #include <uvm/uvm.h>
 #include <sys/vnode.h>
 #include <sys/poll.h>
-#include <sys/lkm.h>
 /* For TIOCSPGRP/TIOCGPGRP */
 #include <sys/ttycom.h>
 
@@ -32,9 +31,11 @@
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
  
+#include "drmvar.h"
+
 #define __REALLY_HAVE_AGP	__HAVE_AGP
 
-#define __REALLY_HAVE_MTRR	1
+#define __REALLY_HAVE_MTRR	0
 #define __REALLY_HAVE_SG	0
 
 #if __REALLY_HAVE_AGP
@@ -42,7 +43,8 @@
 #include <sys/agpio.h>
 #endif
 
-#include <opt_drm.h>
+#define device_t struct device *
+extern struct cfdriver DRM(_cd);
 
 #if DRM_DEBUG
 #undef  DRM_DEBUG_CODE
@@ -50,20 +52,12 @@
 #endif
 #undef DRM_DEBUG
 
-#if DRM_LINUX
-#undef DRM_LINUX	/* FIXME: Linux compat has not been ported yet */
-#endif
-
-typedef drm_device_t *device_t;
-
-extern struct cfdriver DRM(cd);
-
 #define DRM_TIME_SLICE	      (hz/20)  /* Time slice for GLXContexts	  */
 
 #define DRM_DEV_MODE	(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
 #define DRM_DEV_UID	0
 #define DRM_DEV_GID	0
-#define CDEV_MAJOR	34
+#define CDEV_MAJOR	90
 
 #define DRM_CURPROC		curproc
 #define DRM_STRUCTPROC		struct proc
@@ -79,25 +73,16 @@ extern struct cfdriver DRM(cd);
 #define DRM_UNLOCK 		lockmgr(&dev->dev_lock, LK_RELEASE, NULL)
 #define DRM_SUSER(p)		suser(p->p_ucred, &p->p_acflag)
 #define DRM_TASKQUEUE_ARGS	void *dev, int pending
-#define DRM_IRQ_ARGS		void *arg
-#define DRM_DEVICE		drm_device_t *dev = device_lookup(&DRM(cd), minor(kdev))
-/* XXX Not sure if this is the 'right' version.. */
-#if __NetBSD_Version__ >= 106140000
-MALLOC_DECLARE(DRM(M_DRM));
-#else
-/* XXX Make sure this works */
-extern const int DRM(M_DRM) = M_DEVBUF;
-#endif /* __NetBSD_Version__ */
+#define DRM_IRQ_ARGS		void *device
+#define DRM_DEVICE		drm_device_t *dev = device_lookup(&DRM(_cd), minor(kdev))
 #define DRM_MALLOC(size)	malloc( size, DRM(M_DRM), M_NOWAIT )
-#define DRM_FREE(pt,size)		free( pt, DRM(M_DRM) )
+#define DRM_FREE(pt)		free( pt, DRM(M_DRM) )
 #define DRM_VTOPHYS(addr)	vtophys(addr)
-
-#define DRM_READ8(map, offset)		bus_space_read_1(  (map)->iot, (map)->ioh, (offset) )
-#define DRM_READ32(map, offset)		bus_space_read_4(  (map)->iot, (map)->ioh, (offset) )
-#define DRM_WRITE8(map, offset, val)	bus_space_write_1( (map)->iot, (map)->ioh, (offset), (val) )
-#define DRM_WRITE32(map, offset, val)	bus_space_write_4( (map)->iot, (map)->ioh, (offset), (val) )
-
-#define DRM_AGP_FIND_DEVICE()	agp_find_device(0)
+#define DRM_READ8(addr)	*((volatile char *)(addr))
+#define DRM_READ32(addr)	*((volatile long *)(addr))
+#define DRM_WRITE8(addr, val)	*((volatile char *)(addr)) = (val)
+#define DRM_WRITE32(addr, val)	*((volatile long *)(addr)) = (val)
+#define DRM_AGP_FIND_DEVICE()
 
 #define DRM_PRIV					\
 	drm_file_t	*priv	= (drm_file_t *) DRM(find_file_by_proc)(dev, p); \
@@ -120,7 +105,7 @@ do {								\
 do {								\
 	drm_map_list_entry_t *listentry;			\
 	TAILQ_FOREACH(listentry, dev->maplist, link) {		\
-		drm_local_map_t *map = listentry->map;		\
+		drm_map_t *map = listentry->map;		\
 		if (map->type == _DRM_SHM &&			\
 			map->flags & _DRM_CONTAINS_LOCK) {	\
 			dev_priv->sarea = map;			\
@@ -129,15 +114,7 @@ do {								\
 	}							\
 } while (0)
 
-#define DRM_HZ hz
-
-#define DRM_WAIT_ON( ret, queue, timeout, condition )		\
-while (!condition) {						\
-	ret = tsleep( (void *)&(queue), PZERO | PCATCH, "drmwtq", (timeout) ); \
-	if ( ret )						\
-		return ret;					\
-}
-
+#define return DRM_ERR(v)	return v;
 #define DRM_ERR(v)		v
 
 #define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \
@@ -148,25 +125,21 @@ while (!condition) {						\
 	copyout(arg2, arg1, arg3)
 #define DRM_COPY_FROM_USER(arg1, arg2, arg3) \
 	copyin(arg2, arg1, arg3)
-/* Macros for userspace access with checking readability once */
-/* FIXME: can't find equivalent functionality for nocheck yet.
- * It'll be slower than linux, but should be correct.
- */
-#define DRM_VERIFYAREA_READ( uaddr, size )		\
-	(!uvm_useracc((caddr_t)uaddr, size, VM_PROT_READ))
-#define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) 	\
-	copyin(arg2, arg1, arg3)
-#define DRM_GET_USER_UNCHECKED(val, uaddr)			\
-	((val) = fuword(uaddr), 0)
 
-#define DRM_WRITEMEMORYBARRIER( map )					\
-	bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, 0);
-#define DRM_READMEMORYBARRIER( map )					\
-	bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, BUS_SPACE_BARRIER_READ);
+#define DRM_READMEMORYBARRIER \
+{												\
+   	int xchangeDummy;									\
+	DRM_DEBUG("%s\n", __FUNCTION__);							\
+   	__asm__ volatile(" push %%eax ; xchg %%eax, %0 ; pop %%eax" : : "m" (xchangeDummy));	\
+   	__asm__ volatile(" push %%eax ; push %%ebx ; push %%ecx ; push %%edx ;"			\
+			 " movl $0,%%eax ; cpuid ; pop %%edx ; pop %%ecx ; pop %%ebx ;"		\
+			 " pop %%eax" : /* no outputs */ :  /* no inputs */ );			\
+} while (0);
 
-#define DRM_WAKEUP(w) wakeup((void *)w)
+#define DRM_WRITEMEMORYBARRIER DRM_READMEMORYBARRIER
+
+#define DRM_WAKEUP(w) wakeup(w)
 #define DRM_WAKEUP_INT(w) wakeup(w)
-#define DRM_INIT_WAITQUEUE( queue )  do {} while (0)
 
 #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
 
@@ -178,46 +151,30 @@ typedef struct drm_chipinfo
 	char *name;
 } drm_chipinfo_t;
 
-#define cpu_to_le32(x) (x)	/* FIXME */
-
 typedef u_int32_t dma_addr_t;
-typedef volatile long atomic_t;
+typedef volatile u_int32_t atomic_t;
 typedef u_int32_t cycles_t;
+typedef u_int32_t spinlock_t;
 typedef u_int32_t u32;
 typedef u_int16_t u16;
 typedef u_int8_t u8;
 typedef dev_type_ioctl(d_ioctl_t);
 typedef vaddr_t vm_offset_t;
 
-/* FIXME */
 #define atomic_set(p, v)	(*(p) = (v))
 #define atomic_read(p)		(*(p))
-#define atomic_inc(p)		(*(p) += 1)
-#define atomic_dec(p)		(*(p) -= 1)
-#define atomic_add(n, p)	(*(p) += (n))
-#define atomic_sub(n, p)	(*(p) -= (n))
+#define atomic_inc(p)		atomic_add_int(p, 1)
+#define atomic_dec(p)		atomic_subtract_int(p, 1)
+#define atomic_add(n, p)	atomic_add_int(p, n)
+#define atomic_sub(n, p)	atomic_subtract_int(p, n)
 
-/* FIXME */
+/* FIXME: Is NetBSD's kernel non-reentrant? */
 #define atomic_add_int(p, v)      *(p) += v
 #define atomic_subtract_int(p, v) *(p) -= v
 #define atomic_set_int(p, bits)   *(p) |= (bits)
 #define atomic_clear_int(p, bits) *(p) &= ~(bits)
 
 /* Fake this */
-
-static __inline int
-atomic_cmpset_int(__volatile__ int *dst, int old, int new)
-{
-	int s = splhigh();
-	if (*dst==old) {
-		*dst = new;
-		splx(s);
-		return 1;
-	}
-	splx(s);
-	return 0;
-}
-
 static __inline atomic_t
 test_and_set_bit(int b, atomic_t *p)
 {
@@ -267,6 +224,20 @@ find_first_zero_bit(atomic_t *p, int max)
 #define spldrm()		spltty()
 #define jiffies			hardclock_ticks
 
+#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock)
+#define _DRM_CAS(lock,old,new,__ret)				       \
+	do {							       \
+		int __dummy;	/* Can't mark eax as clobbered */      \
+		__asm__ __volatile__(				       \
+			"lock ; cmpxchg %4,%1\n\t"		       \
+			"setnz %0"				       \
+			: "=d" (__ret),				       \
+			  "=m" (__drm_dummy_lock(lock)),	       \
+			  "=a" (__dummy)			       \
+			: "2" (old),				       \
+			  "r" (new));				       \
+	} while (0)
+
 /* Redefinitions to make templating easy */
 #define wait_queue_head_t	atomic_t
 #define agp_memory		void
@@ -287,7 +258,7 @@ do { \
 #define DRM_DEBUG(fmt, arg...)						  \
 	do {								  \
 		if (DRM(flags) & DRM_FLAG_DEBUG)			  \
-			printf("[" DRM_NAME ":%s] " fmt , __FUNCTION__ ,## arg); \
+			printf("[" DRM_NAME ":%s] " fmt , __FUNCTION__,## arg); \
 	} while (0)
 #else
 #define DRM_DEBUG(fmt, arg...)		 do { } while (0)
diff --git a/bsd/mga_drv.c b/bsd/mga_drv.c
index de0387f7..8b69b41b 100644
--- a/bsd/mga_drv.c
+++ b/bsd/mga_drv.c
@@ -27,10 +27,10 @@
  * Authors:
  *    Rickard E. (Rik) Faith <faith@valinux.com>
  *    Gareth Hughes <gareth@valinux.com>
- *
- * $FreeBSD: src/sys/dev/drm/mga_drv.c,v 1.4 2003/03/09 02:08:28 anholt Exp $
  */
 
+#include <sys/types.h>
+
 #include "mga.h"
 #include "drmP.h"
 #include "drm.h"
@@ -63,8 +63,4 @@ drm_chipinfo_t DRM(devicelist)[] = {
 #include "drm_vm.h"
 #include "drm_sysctl.h"
 
-#ifdef __FreeBSD__
 DRIVER_MODULE(mga, pci, mga_driver, mga_devclass, 0, 0);
-#elif defined(__NetBSD__)
-CFDRIVER_DECL(mga, DV_TTY, NULL);
-#endif
diff --git a/bsd/r128_drv.c b/bsd/r128_drv.c
index 28a2c85e..1a8046fb 100644
--- a/bsd/r128_drv.c
+++ b/bsd/r128_drv.c
@@ -27,10 +27,11 @@
  * Authors:
  *    Rickard E. (Rik) Faith <faith@valinux.com>
  *    Gareth Hughes <gareth@valinux.com>
- *
- * $FreeBSD: src/sys/dev/drm/r128_drv.c,v 1.4 2003/03/09 02:08:28 anholt Exp $
  */
 
+
+#include <sys/types.h>
+
 #include "r128.h"
 #include "drmP.h"
 #include "drm.h"
@@ -82,8 +83,4 @@ drm_chipinfo_t DRM(devicelist)[] = {
 #include "drm_scatter.h"
 #endif
 
-#ifdef __FreeBSD__
 DRIVER_MODULE(r128, pci, r128_driver, r128_devclass, 0, 0);
-#elif defined(__NetBSD__)
-CFDRIVER_DECL(r128, DV_TTY, NULL);
-#endif /* __FreeBSD__ */
diff --git a/bsd/radeon_drv.c b/bsd/radeon_drv.c
index 2e7c5d66..a253b9cb 100644
--- a/bsd/radeon_drv.c
+++ b/bsd/radeon_drv.c
@@ -25,10 +25,10 @@
  *
  * Authors:
  *    Gareth Hughes <gareth@valinux.com>
- *
- * $FreeBSD: src/sys/dev/drm/radeon_drv.c,v 1.5 2003/03/11 01:38:17 anholt Exp $
  */
 
+#include <sys/types.h>
+
 #include "radeon.h"
 #include "drmP.h"
 #include "drm.h"
@@ -39,41 +39,38 @@
 #endif
 
 drm_chipinfo_t DRM(devicelist)[] = {
-	{0x1002, 0x4242, 1, "ATI Radeon BB R200 AIW 8500DV"},
-	{0x1002, 0x4336, 1, "ATI Radeon Mobility U1"},
-	{0x1002, 0x4964, 1, "ATI Radeon Id R250 9000"},
-	{0x1002, 0x4965, 1, "ATI Radeon Ie R250 9000"},
-	{0x1002, 0x4966, 1, "ATI Radeon If R250 9000"},
-	{0x1002, 0x4967, 1, "ATI Radeon Ig R250 9000"},
-	{0x1002, 0x4C57, 1, "ATI Radeon LW Mobility 7500 M7"},
-	{0x1002, 0x4C58, 1, "ATI Radeon LX RV200 Mobility FireGL 7800 M7"},
-	{0x1002, 0x4C59, 1, "ATI Radeon LY Mobility M6"},
-	{0x1002, 0x4C5A, 1, "ATI Radeon LZ Mobility M6"},
-	{0x1002, 0x4C64, 1, "ATI Radeon Ld R250 Mobility 9000 M9"},
-	{0x1002, 0x4C65, 1, "ATI Radeon Le R250 Mobility 9000 M9"},
-	{0x1002, 0x4C66, 1, "ATI Radeon Lf R250 Mobility 9000 M9"},
-	{0x1002, 0x4C67, 1, "ATI Radeon Lg R250 Mobility 9000 M9"},
-	{0x1002, 0x5144, 1, "ATI Radeon QD R100"},
-	{0x1002, 0x5145, 1, "ATI Radeon QE R100"},
-	{0x1002, 0x5146, 1, "ATI Radeon QF R100"},
-	{0x1002, 0x5147, 1, "ATI Radeon QG R100"},
-	{0x1002, 0x5148, 1, "ATI Radeon QH FireGL 8x00"},
+	{0x1002, 0x4242, 1, "ATI Radeon BB AIW 8500DV (AGP)"},
+	{0x1002, 0x4336, 1, "ATI Radeon Mobility"},
+	{0x1002, 0x4964, 1, "ATI Radeon Id 9000"},
+	{0x1002, 0x4965, 1, "ATI Radeon Ie 9000"},
+	{0x1002, 0x4966, 1, "ATI Radeon If 9000"},
+	{0x1002, 0x4967, 1, "ATI Radeon Ig 9000"},
+	{0x1002, 0x496e, 1, "ATI Radeon Ig 9000"},
+	{0x1002, 0x4C57, 1, "ATI Radeon LW Mobility 7 (AGP)"},
+	{0x1002, 0x4C58, 1, "ATI Radeon LX Mobility 7 (AGP)"},
+	{0x1002, 0x4C59, 1, "ATI Radeon LY Mobility 6 (AGP)"},
+	{0x1002, 0x4C5A, 1, "ATI Radeon LZ Mobility 6 (AGP)"},
+	{0x1002, 0x4C64, 1, "ATI Radeon Ld Mobility 9000 (AGP)"},
+	{0x1002, 0x4C65, 1, "ATI Radeon Le Mobility 9000 (AGP)"},
+	{0x1002, 0x4C66, 1, "ATI Radeon Lf Mobility 9000 (AGP)"},
+	{0x1002, 0x4C67, 1, "ATI Radeon Lg Mobility 9000 (AGP)"},
+	{0x1002, 0x5144, 1, "ATI Radeon QD R100 (AGP)"},
+	{0x1002, 0x5145, 1, "ATI Radeon QE R100 (AGP)"},
+	{0x1002, 0x5146, 1, "ATI Radeon QF R100 (AGP)"},
+	{0x1002, 0x5147, 1, "ATI Radeon QG R100 (AGP)"},
+	{0x1002, 0x5148, 1, "ATI Radeon QH FireGL 8x00 (AGP)"},
 	{0x1002, 0x5149, 1, "ATI Radeon QI R200"},
 	{0x1002, 0x514A, 1, "ATI Radeon QJ R200"},
 	{0x1002, 0x514B, 1, "ATI Radeon QK R200"},
-	{0x1002, 0x514C, 1, "ATI Radeon QL R200 8500 LE"},
-	{0x1002, 0x514D, 1, "ATI Radeon QM R200 9100"},
-	{0x1002, 0x514E, 1, "ATI Radeon QN R200 8500 LE"},
-	{0x1002, 0x514F, 1, "ATI Radeon QO R200 8500 LE"},
-	{0x1002, 0x5157, 1, "ATI Radeon QW RV200 7500"},
-	{0x1002, 0x5158, 1, "ATI Radeon QX RV200 7500"},
-	{0x1002, 0x5159, 1, "ATI Radeon QY RV100 VE"},
-	{0x1002, 0x515A, 1, "ATI Radeon QZ RV100 VE"},
+	{0x1002, 0x514C, 1, "ATI Radeon QL 8500 (AGP)"},
+	{0x1002, 0x5157, 1, "ATI Radeon QW 7500 (AGP)"},
+	{0x1002, 0x5158, 1, "ATI Radeon QX 7500 (AGP)"},
+	{0x1002, 0x5159, 1, "ATI Radeon QY VE (AGP)"},
+	{0x1002, 0x515A, 1, "ATI Radeon QZ VE (AGP)"},
 	{0x1002, 0x5168, 1, "ATI Radeon Qh R200"},
 	{0x1002, 0x5169, 1, "ATI Radeon Qi R200"},
 	{0x1002, 0x516A, 1, "ATI Radeon Qj R200"},
 	{0x1002, 0x516B, 1, "ATI Radeon Qk R200"},
-	{0x1002, 0x516C, 1, "ATI Radeon Ql R200"},
 	{0, 0, 0, NULL}
 };
 
@@ -95,8 +92,4 @@ drm_chipinfo_t DRM(devicelist)[] = {
 #include "drm_scatter.h"
 #endif
 
-#ifdef __FreeBSD__
 DRIVER_MODULE(DRIVER_NAME, pci, DRM(driver), DRM(devclass), 0, 0);
-#elif defined(__NetBSD__)
-CFDRIVER_DECL(radeon, DV_TTY, NULL);
-#endif /* __FreeBSD__ */
diff --git a/bsd/tdfx_drv.c b/bsd/tdfx_drv.c
index e10542f1..8bc8c57d 100644
--- a/bsd/tdfx_drv.c
+++ b/bsd/tdfx_drv.c
@@ -28,10 +28,11 @@
  *    Rickard E. (Rik) Faith <faith@valinux.com>
  *    Daryll Strauss <daryll@valinux.com>
  *    Gareth Hughes <gareth@valinux.com>
- *
- * $FreeBSD: src/sys/dev/drm/tdfx_drv.c,v 1.3 2003/03/09 02:08:28 anholt Exp $
  */
 
+
+#include <sys/types.h>
+
 #include "tdfx.h"
 #include "drmP.h"
 
@@ -95,6 +96,4 @@ drm_chipinfo_t DRM(devicelist)[] = {
 
 #ifdef __FreeBSD__
 DRIVER_MODULE(tdfx, pci, tdfx_driver, tdfx_devclass, 0, 0);
-#elif defined(__NetBSD__)
-CFDRIVER_DECL(tdfx, DV_TTY, NULL);
 #endif /* __FreeBSD__ */
diff --git a/libdrm/xf86drmCompat.c b/libdrm/xf86drmCompat.c
index a30eacfc..6f938474 100644
--- a/libdrm/xf86drmCompat.c
+++ b/libdrm/xf86drmCompat.c
@@ -26,7 +26,7 @@
  *   Jens Owen <jens@tungstengraphics.com>
  *
  */
-/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.4 2001/08/27 17:40:59 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmCompat.c,v 1.1 2002/10/30 12:52:33 alanh Exp $ */
 
 #ifdef XFree86Server
 # include "xf86.h"
diff --git a/linux-core/drm_os_linux.h b/linux-core/drm_os_linux.h
index b99b4899..e9b24356 100644
--- a/linux-core/drm_os_linux.h
+++ b/linux-core/drm_os_linux.h
@@ -7,12 +7,12 @@
 #define DRM_ERR(d)			-(d)
 #define DRM_CURRENTPID			current->pid
 #define DRM_UDELAY(d)			udelay(d)
-#define DRM_READ8(map, offset)		readb(((unsigned long)(map)->handle) + (offset))
-#define DRM_READ32(map, offset)		readl(((unsigned long)(map)->handle) + (offset))
-#define DRM_WRITE8(map, offset, val)	writeb(val, ((unsigned long)(map)->handle) + (offset))
-#define DRM_WRITE32(map, offset, val)	writel(val, ((unsigned long)(map)->handle) + (offset))
-#define DRM_READMEMORYBARRIER(map)	mb()
-#define DRM_WRITEMEMORYBARRIER(map)	wmb()
+#define DRM_READ8(addr)			readb(addr)
+#define DRM_READ32(addr)		readl(addr)
+#define DRM_WRITE8(addr, val)		writeb(val, addr)
+#define DRM_WRITE32(addr, val)		writel(val, addr)
+#define DRM_READMEMORYBARRIER()		mb()
+#define DRM_WRITEMEMORYBARRIER()	wmb()
 #define DRM_DEVICE	drm_file_t	*priv	= filp->private_data; \
 			drm_device_t	*dev	= priv->dev
 
@@ -42,7 +42,7 @@
 
 /* malloc/free without the overhead of DRM(alloc) */
 #define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL)
-#define DRM_FREE(x,size) kfree(x)
+#define DRM_FREE(x) kfree(x)
 
 #define DRM_GETSAREA()							 \
 do { 									 \
diff --git a/linux-core/i830_irq.c b/linux-core/i830_irq.c
new file mode 100644
index 00000000..cedafc0d
--- /dev/null
+++ b/linux-core/i830_irq.c
@@ -0,0 +1,178 @@
+/* i830_dma.c -- DMA support for the I830 -*- linux-c -*-
+ *
+ * Copyright 2002 Tungsten Graphics, 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
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Keith Whitwell <keith@tungstengraphics.com>
+ *
+ */
+
+#define __NO_VERSION__
+#include "i830.h"
+#include "drmP.h"
+#include "drm.h"
+#include "i830_drm.h"
+#include "i830_drv.h"
+#include <linux/interrupt.h>	/* For task queue support */
+#include <linux/delay.h>
+
+
+void DRM(dma_service)(int irq, void *device, struct pt_regs *regs)
+{
+	drm_device_t	 *dev = (drm_device_t *)device;
+      	drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
+   	u16 temp;
+   
+      	temp = I830_READ16(I830REG_INT_IDENTITY_R);
+	printk("%s: %x\n", __FUNCTION__, temp);
+	
+   	if(temp == 0) 
+	   return;
+
+	I830_WRITE16(I830REG_INT_IDENTITY_R, temp); 
+
+	if (temp & 2) {
+		atomic_inc(&dev_priv->irq_received);
+		wake_up_interruptible(&dev_priv->irq_queue); 
+	}
+}
+
+
+int i830_emit_irq(drm_device_t *dev)
+{
+	drm_i830_private_t *dev_priv = dev->dev_private;
+	RING_LOCALS;
+
+	DRM_DEBUG("%s\n", __FUNCTION__);
+
+	atomic_inc(&dev_priv->irq_emitted);
+
+   	BEGIN_LP_RING(2);
+      	OUT_RING( 0 );
+      	OUT_RING( GFX_OP_USER_INTERRUPT );
+      	ADVANCE_LP_RING();
+
+	return atomic_read(&dev_priv->irq_emitted);
+}
+
+
+int i830_wait_irq(drm_device_t *dev, int irq_nr)
+{
+  	drm_i830_private_t *dev_priv = 
+	   (drm_i830_private_t *)dev->dev_private;
+	DECLARE_WAITQUEUE(entry, current);
+	unsigned long end = jiffies + HZ*3;
+	int ret = 0;
+
+	DRM_DEBUG("%s\n", __FUNCTION__);
+
+ 	if (atomic_read(&dev_priv->irq_received) >= irq_nr)  
+ 		return 0; 
+
+	dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT;
+
+	add_wait_queue(&dev_priv->irq_queue, &entry);
+
+	for (;;) {
+		current->state = TASK_INTERRUPTIBLE;
+	   	if (atomic_read(&dev_priv->irq_received) >= irq_nr) 
+		   break;
+		if((signed)(end - jiffies) <= 0) {
+			DRM_ERROR("timeout iir %x imr %x ier %x hwstam %x\n",
+				  I830_READ16( I830REG_INT_IDENTITY_R ),
+				  I830_READ16( I830REG_INT_MASK_R ),
+				  I830_READ16( I830REG_INT_ENABLE_R ),
+				  I830_READ16( I830REG_HWSTAM ));
+
+		   	ret = -EBUSY;	/* Lockup?  Missed irq? */
+			break;
+		}
+	      	schedule_timeout(HZ*3);
+	      	if (signal_pending(current)) {
+		   	ret = -EINTR;
+			break;
+		}
+	}
+
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&dev_priv->irq_queue, &entry);
+	return ret;
+}
+
+
+/* Needs the lock as it touches the ring.
+ */
+int i830_irq_emit( 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_i830_private_t *dev_priv = dev->dev_private;
+	drm_i830_irq_emit_t emit;
+	int result;
+
+   	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+		DRM_ERROR("i830_irq_emit called without lock held\n");
+		return -EINVAL;
+	}
+
+	if ( !dev_priv ) {
+		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+		return -EINVAL;
+	}
+
+	if (copy_from_user( &emit, (drm_i830_irq_emit_t *)arg, sizeof(emit) ))
+		return -EFAULT;
+
+	result = i830_emit_irq( dev );
+
+	if ( copy_to_user( emit.irq_seq, &result, sizeof(int) ) ) {
+		DRM_ERROR( "copy_to_user\n" );
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+
+/* Doesn't need the hardware lock.
+ */
+int i830_irq_wait( 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_i830_private_t *dev_priv = dev->dev_private;
+	drm_i830_irq_wait_t irqwait;
+
+	if ( !dev_priv ) {
+		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+		return -EINVAL;
+	}
+
+	if (copy_from_user( &irqwait, (drm_i830_irq_wait_t *)arg, 
+			    sizeof(irqwait) ))
+		return -EFAULT;
+
+	return i830_wait_irq( dev, irqwait.irq_seq );
+}
+
diff --git a/linux/drm_os_linux.h b/linux/drm_os_linux.h
index b99b4899..e9b24356 100644
--- a/linux/drm_os_linux.h
+++ b/linux/drm_os_linux.h
@@ -7,12 +7,12 @@
 #define DRM_ERR(d)			-(d)
 #define DRM_CURRENTPID			current->pid
 #define DRM_UDELAY(d)			udelay(d)
-#define DRM_READ8(map, offset)		readb(((unsigned long)(map)->handle) + (offset))
-#define DRM_READ32(map, offset)		readl(((unsigned long)(map)->handle) + (offset))
-#define DRM_WRITE8(map, offset, val)	writeb(val, ((unsigned long)(map)->handle) + (offset))
-#define DRM_WRITE32(map, offset, val)	writel(val, ((unsigned long)(map)->handle) + (offset))
-#define DRM_READMEMORYBARRIER(map)	mb()
-#define DRM_WRITEMEMORYBARRIER(map)	wmb()
+#define DRM_READ8(addr)			readb(addr)
+#define DRM_READ32(addr)		readl(addr)
+#define DRM_WRITE8(addr, val)		writeb(val, addr)
+#define DRM_WRITE32(addr, val)		writel(val, addr)
+#define DRM_READMEMORYBARRIER()		mb()
+#define DRM_WRITEMEMORYBARRIER()	wmb()
 #define DRM_DEVICE	drm_file_t	*priv	= filp->private_data; \
 			drm_device_t	*dev	= priv->dev
 
@@ -42,7 +42,7 @@
 
 /* malloc/free without the overhead of DRM(alloc) */
 #define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL)
-#define DRM_FREE(x,size) kfree(x)
+#define DRM_FREE(x) kfree(x)
 
 #define DRM_GETSAREA()							 \
 do { 									 \
diff --git a/linux/gamma_drm.h b/linux/gamma_drm.h
index d06763ae..0d58b07b 100644
--- a/linux/gamma_drm.h
+++ b/linux/gamma_drm.h
@@ -48,6 +48,16 @@ typedef struct _drm_gamma_sarea {
 	int vertex_prim;
 } drm_gamma_sarea_t;
 
+/* WARNING: If you change any of these defines, make sure to change the
+ * defines in the Xserver file (xf86drmGamma.h)
+ */
+
+/* Gamma specific ioctls
+ * The device specific ioctl range is 0x40 to 0x79.
+ */
+#define DRM_IOCTL_GAMMA_INIT		DRM_IOW( 0x40, drm_gamma_init_t)
+#define DRM_IOCTL_GAMMA_COPY		DRM_IOW( 0x41, drm_gamma_copy_t)
+
 typedef struct drm_gamma_copy {
 	unsigned int	DMAOutputAddress;
 	unsigned int	DMAOutputCount;
diff --git a/linux/i830_irq.c b/linux/i830_irq.c
new file mode 100644
index 00000000..cedafc0d
--- /dev/null
+++ b/linux/i830_irq.c
@@ -0,0 +1,178 @@
+/* i830_dma.c -- DMA support for the I830 -*- linux-c -*-
+ *
+ * Copyright 2002 Tungsten Graphics, 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
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Keith Whitwell <keith@tungstengraphics.com>
+ *
+ */
+
+#define __NO_VERSION__
+#include "i830.h"
+#include "drmP.h"
+#include "drm.h"
+#include "i830_drm.h"
+#include "i830_drv.h"
+#include <linux/interrupt.h>	/* For task queue support */
+#include <linux/delay.h>
+
+
+void DRM(dma_service)(int irq, void *device, struct pt_regs *regs)
+{
+	drm_device_t	 *dev = (drm_device_t *)device;
+      	drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
+   	u16 temp;
+   
+      	temp = I830_READ16(I830REG_INT_IDENTITY_R);
+	printk("%s: %x\n", __FUNCTION__, temp);
+	
+   	if(temp == 0) 
+	   return;
+
+	I830_WRITE16(I830REG_INT_IDENTITY_R, temp); 
+
+	if (temp & 2) {
+		atomic_inc(&dev_priv->irq_received);
+		wake_up_interruptible(&dev_priv->irq_queue); 
+	}
+}
+
+
+int i830_emit_irq(drm_device_t *dev)
+{
+	drm_i830_private_t *dev_priv = dev->dev_private;
+	RING_LOCALS;
+
+	DRM_DEBUG("%s\n", __FUNCTION__);
+
+	atomic_inc(&dev_priv->irq_emitted);
+
+   	BEGIN_LP_RING(2);
+      	OUT_RING( 0 );
+      	OUT_RING( GFX_OP_USER_INTERRUPT );
+      	ADVANCE_LP_RING();
+
+	return atomic_read(&dev_priv->irq_emitted);
+}
+
+
+int i830_wait_irq(drm_device_t *dev, int irq_nr)
+{
+  	drm_i830_private_t *dev_priv = 
+	   (drm_i830_private_t *)dev->dev_private;
+	DECLARE_WAITQUEUE(entry, current);
+	unsigned long end = jiffies + HZ*3;
+	int ret = 0;
+
+	DRM_DEBUG("%s\n", __FUNCTION__);
+
+ 	if (atomic_read(&dev_priv->irq_received) >= irq_nr)  
+ 		return 0; 
+
+	dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT;
+
+	add_wait_queue(&dev_priv->irq_queue, &entry);
+
+	for (;;) {
+		current->state = TASK_INTERRUPTIBLE;
+	   	if (atomic_read(&dev_priv->irq_received) >= irq_nr) 
+		   break;
+		if((signed)(end - jiffies) <= 0) {
+			DRM_ERROR("timeout iir %x imr %x ier %x hwstam %x\n",
+				  I830_READ16( I830REG_INT_IDENTITY_R ),
+				  I830_READ16( I830REG_INT_MASK_R ),
+				  I830_READ16( I830REG_INT_ENABLE_R ),
+				  I830_READ16( I830REG_HWSTAM ));
+
+		   	ret = -EBUSY;	/* Lockup?  Missed irq? */
+			break;
+		}
+	      	schedule_timeout(HZ*3);
+	      	if (signal_pending(current)) {
+		   	ret = -EINTR;
+			break;
+		}
+	}
+
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&dev_priv->irq_queue, &entry);
+	return ret;
+}
+
+
+/* Needs the lock as it touches the ring.
+ */
+int i830_irq_emit( 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_i830_private_t *dev_priv = dev->dev_private;
+	drm_i830_irq_emit_t emit;
+	int result;
+
+   	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+		DRM_ERROR("i830_irq_emit called without lock held\n");
+		return -EINVAL;
+	}
+
+	if ( !dev_priv ) {
+		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+		return -EINVAL;
+	}
+
+	if (copy_from_user( &emit, (drm_i830_irq_emit_t *)arg, sizeof(emit) ))
+		return -EFAULT;
+
+	result = i830_emit_irq( dev );
+
+	if ( copy_to_user( emit.irq_seq, &result, sizeof(int) ) ) {
+		DRM_ERROR( "copy_to_user\n" );
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+
+/* Doesn't need the hardware lock.
+ */
+int i830_irq_wait( 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_i830_private_t *dev_priv = dev->dev_private;
+	drm_i830_irq_wait_t irqwait;
+
+	if ( !dev_priv ) {
+		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+		return -EINVAL;
+	}
+
+	if (copy_from_user( &irqwait, (drm_i830_irq_wait_t *)arg, 
+			    sizeof(irqwait) ))
+		return -EFAULT;
+
+	return i830_wait_irq( dev, irqwait.irq_seq );
+}
+
diff --git a/shared-core/mga_drv.h b/shared-core/mga_drv.h
index 0e650b42..a5085b06 100644
--- a/shared-core/mga_drv.h
+++ b/shared-core/mga_drv.h
@@ -90,14 +90,14 @@ typedef struct drm_mga_private {
 	unsigned int texture_offset;
 	unsigned int texture_size;
 
-	drm_local_map_t *sarea;
-	drm_local_map_t *fb;
-	drm_local_map_t *mmio;
-	drm_local_map_t *status;
-	drm_local_map_t *warp;
-	drm_local_map_t *primary;
-	drm_local_map_t *buffers;
-	drm_local_map_t *agp_textures;
+	drm_map_t *sarea;
+	drm_map_t *fb;
+	drm_map_t *mmio;
+	drm_map_t *status;
+	drm_map_t *warp;
+	drm_map_t *primary;
+	drm_map_t *buffers;
+	drm_map_t *agp_textures;
 } drm_mga_private_t;
 
 				/* mga_dma.c */
@@ -131,30 +131,32 @@ extern int  mga_getparam( DRM_IOCTL_ARGS );
 extern int mga_warp_install_microcode( drm_mga_private_t *dev_priv );
 extern int mga_warp_init( drm_mga_private_t *dev_priv );
 
-#define mga_flush_write_combine()	DRM_WRITEMEMORYBARRIER(dev_priv->primary)
+#define mga_flush_write_combine()	DRM_WRITEMEMORYBARRIER()
+
 
-#if defined(__linux__) && defined(__alpha__)
 #define MGA_BASE( reg )		((unsigned long)(dev_priv->mmio->handle))
 #define MGA_ADDR( reg )		(MGA_BASE(reg) + reg)
 
 #define MGA_DEREF( reg )	*(volatile u32 *)MGA_ADDR( reg )
 #define MGA_DEREF8( reg )	*(volatile u8 *)MGA_ADDR( reg )
 
+#ifdef __alpha__
 #define MGA_READ( reg )		(_MGA_READ((u32 *)MGA_ADDR(reg)))
 #define MGA_READ8( reg )	(_MGA_READ((u8 *)MGA_ADDR(reg)))
-#define MGA_WRITE( reg, val )	do { DRM_WRITEMEMORYBARRIER(dev_priv->mmio); MGA_DEREF( reg ) = val; } while (0)
-#define MGA_WRITE8( reg, val )  do { DRM_WRITEMEMORYBARRIER(dev_priv->mmio); MGA_DEREF8( reg ) = val; } while (0)
+#define MGA_WRITE( reg, val )	do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF( reg ) = val; } while (0)
+#define MGA_WRITE8( reg, val )  do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8( reg ) = val; } while (0)
 
 static inline u32 _MGA_READ(u32 *addr)
 {
-	DRM_READMEMORYBARRIER(dev_priv->mmio);
+	DRM_READMEMORYBARRIER();
 	return *(volatile u32 *)addr;
 }
+
 #else
-#define MGA_READ8( reg )	DRM_READ8(dev_priv->mmio, (reg))
-#define MGA_READ( reg )		DRM_READ32(dev_priv->mmio, (reg))
-#define MGA_WRITE8( reg, val )  DRM_WRITE8(dev_priv->mmio, (reg), (val))
-#define MGA_WRITE( reg, val )	DRM_WRITE32(dev_priv->mmio, (reg), (val))
+#define MGA_READ( reg )		MGA_DEREF( reg )
+#define MGA_READ8( reg )	MGA_DEREF8( reg )
+#define MGA_WRITE( reg, val )	do { MGA_DEREF( reg ) = val; } while (0)
+#define MGA_WRITE8( reg, val )  do { MGA_DEREF8( reg ) = val; } while (0)
 #endif
 
 #define DWGREG0 	0x1c00
diff --git a/shared-core/r128_cce.c b/shared-core/r128_cce.c
index 8d305b75..5175885e 100644
--- a/shared-core/r128_cce.c
+++ b/shared-core/r128_cce.c
@@ -579,7 +579,6 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
 		(dev_priv->ring.size / sizeof(u32)) - 1;
 
 	dev_priv->ring.high_mark = 128;
-	dev_priv->ring.ring_rptr = dev_priv->ring_rptr;
 
 	dev_priv->sarea_priv->last_frame = 0;
 	R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame );
diff --git a/shared-core/r128_drv.h b/shared-core/r128_drv.h
index 5e6f1215..763fcb3a 100644
--- a/shared-core/r128_drv.h
+++ b/shared-core/r128_drv.h
@@ -34,8 +34,8 @@
 #ifndef __R128_DRV_H__
 #define __R128_DRV_H__
 
-#define GET_RING_HEAD(ring)		DRM_READ32(  (ring)->ring_rptr, 0 ) /* (ring)->head */
-#define SET_RING_HEAD(ring,val)		DRM_WRITE32( (ring)->ring_rptr, 0, (val) ) /* (ring)->head */
+#define GET_RING_HEAD(ring)		DRM_READ32(  (volatile u32 *) (ring)->head )
+#define SET_RING_HEAD(ring,val)		DRM_WRITE32( (volatile u32 *) (ring)->head, (val) )
 
 typedef struct drm_r128_freelist {
    	unsigned int age;
@@ -56,7 +56,6 @@ typedef struct drm_r128_ring_buffer {
 	int space;
 
 	int high_mark;
-	drm_local_map_t *ring_rptr;
 } drm_r128_ring_buffer_t;
 
 typedef struct drm_r128_private {
@@ -99,13 +98,13 @@ typedef struct drm_r128_private {
 	u32 depth_pitch_offset_c;
 	u32 span_pitch_offset_c;
 
-	drm_local_map_t *sarea;
-	drm_local_map_t *fb;
-	drm_local_map_t *mmio;
-	drm_local_map_t *cce_ring;
-	drm_local_map_t *ring_rptr;
-	drm_local_map_t *buffers;
-	drm_local_map_t *agp_textures;
+	drm_map_t *sarea;
+	drm_map_t *fb;
+	drm_map_t *mmio;
+	drm_map_t *cce_ring;
+	drm_map_t *ring_rptr;
+	drm_map_t *buffers;
+	drm_map_t *agp_textures;
 } drm_r128_private_t;
 
 typedef struct drm_r128_buf_priv {
@@ -371,10 +370,15 @@ extern int r128_cce_indirect( DRM_IOCTL_ARGS );
 
 #define R128_PERFORMANCE_BOXES		0
 
-#define R128_READ(reg)		DRM_READ32(  dev_priv->mmio, (reg) )
-#define R128_WRITE(reg,val)	DRM_WRITE32( dev_priv->mmio, (reg), (val) )
-#define R128_READ8(reg)		DRM_READ8(   dev_priv->mmio, (reg) )
-#define R128_WRITE8(reg,val)	DRM_WRITE8(  dev_priv->mmio, (reg), (val) )
+
+#define R128_BASE(reg)		((unsigned long)(dev_priv->mmio->handle))
+#define R128_ADDR(reg)		(R128_BASE( reg ) + reg)
+
+#define R128_READ(reg)		DRM_READ32(  (volatile u32 *) R128_ADDR(reg) )
+#define R128_WRITE(reg,val)	DRM_WRITE32( (volatile u32 *) R128_ADDR(reg), (val) )
+
+#define R128_READ8(reg)		DRM_READ8(  (volatile u8 *) R128_ADDR(reg) )
+#define R128_WRITE8(reg,val)	DRM_WRITE8( (volatile u8 *) R128_ADDR(reg), (val) )
 
 #define R128_WRITE_PLL(addr,val)					\
 do {									\
@@ -449,7 +453,7 @@ do {									\
 #if defined(__powerpc__)
 #define r128_flush_write_combine()	(void) GET_RING_HEAD( &dev_priv->ring )
 #else
-#define r128_flush_write_combine()	DRM_WRITEMEMORYBARRIER(dev_priv->ring_rptr)
+#define r128_flush_write_combine()	DRM_WRITEMEMORYBARRIER()
 #endif
 
 
diff --git a/shared-core/r128_state.c b/shared-core/r128_state.c
index 20307c04..68f73061 100644
--- a/shared-core/r128_state.c
+++ b/shared-core/r128_state.c
@@ -896,7 +896,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
 	int count, x, y;
 	u32 *buffer;
 	u8 *mask;
-	int i, buffer_size, mask_size;
+	int i;
 	RING_LOCALS;
 	DRM_DEBUG( "\n" );
 
@@ -908,25 +908,25 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
 		return DRM_ERR(EFAULT);
 	}
 
-	buffer_size = depth->n * sizeof(u32);
-	buffer = DRM_MALLOC( buffer_size );
+	buffer = DRM_MALLOC( depth->n * sizeof(u32) );
 	if ( buffer == NULL )
 		return DRM_ERR(ENOMEM);
-	if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) {
-		DRM_FREE( buffer, buffer_size);
+	if ( DRM_COPY_FROM_USER( buffer, depth->buffer,
+			     depth->n * sizeof(u32) ) ) {
+		DRM_FREE( buffer );
 		return DRM_ERR(EFAULT);
 	}
 
-	mask_size = depth->n * sizeof(u8);
 	if ( depth->mask ) {
-		mask = DRM_MALLOC( mask_size );
+		mask = DRM_MALLOC( depth->n * sizeof(u8) );
 		if ( mask == NULL ) {
-			DRM_FREE( buffer, buffer_size );
+			DRM_FREE( buffer );
 			return DRM_ERR(ENOMEM);
 		}
-		if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) {
-			DRM_FREE( buffer, buffer_size );
-			DRM_FREE( mask, mask_size );
+		if ( DRM_COPY_FROM_USER( mask, depth->mask,
+				     depth->n * sizeof(u8) ) ) {
+			DRM_FREE( buffer );
+			DRM_FREE( mask );
 			return DRM_ERR(EFAULT);
 		}
 
@@ -953,7 +953,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
 			}
 		}
 
-		DRM_FREE( mask, mask_size );
+		DRM_FREE( mask );
 	} else {
 		for ( i = 0 ; i < count ; i++, x++ ) {
 			BEGIN_RING( 6 );
@@ -977,7 +977,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
 		}
 	}
 
-	DRM_FREE( buffer, buffer_size );
+	DRM_FREE( buffer );
 
 	return 0;
 }
@@ -989,62 +989,60 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
 	int count, *x, *y;
 	u32 *buffer;
 	u8 *mask;
-	int i, xbuf_size, ybuf_size, buffer_size, mask_size;
+	int i;
 	RING_LOCALS;
 	DRM_DEBUG( "\n" );
 
 	count = depth->n;
 
-	xbuf_size = count * sizeof(*x);
-	ybuf_size = count * sizeof(*y);
-	x = DRM_MALLOC( xbuf_size );
+	x = DRM_MALLOC( count * sizeof(*x) );
 	if ( x == NULL ) {
 		return DRM_ERR(ENOMEM);
 	}
-	y = DRM_MALLOC( ybuf_size );
+	y = DRM_MALLOC( count * sizeof(*y) );
 	if ( y == NULL ) {
-		DRM_FREE( x, xbuf_size );
+		DRM_FREE( x );
 		return DRM_ERR(ENOMEM);
 	}
-	if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
+	if ( DRM_COPY_FROM_USER( x, depth->x, count * sizeof(int) ) ) {
+		DRM_FREE( x );
+		DRM_FREE( y );
 		return DRM_ERR(EFAULT);
 	}
-	if ( DRM_COPY_FROM_USER( y, depth->y, xbuf_size ) ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
+	if ( DRM_COPY_FROM_USER( y, depth->y, count * sizeof(int) ) ) {
+		DRM_FREE( x );
+		DRM_FREE( y );
 		return DRM_ERR(EFAULT);
 	}
 
-	buffer_size = depth->n * sizeof(u32);
-	buffer = DRM_MALLOC( buffer_size );
+	buffer = DRM_MALLOC( depth->n * sizeof(u32) );
 	if ( buffer == NULL ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
+		DRM_FREE( x );
+		DRM_FREE( y );
 		return DRM_ERR(ENOMEM);
 	}
-	if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
-		DRM_FREE( buffer, buffer_size );
+	if ( DRM_COPY_FROM_USER( buffer, depth->buffer,
+			     depth->n * sizeof(u32) ) ) {
+		DRM_FREE( x );
+		DRM_FREE( y );
+		DRM_FREE( buffer );
 		return DRM_ERR(EFAULT);
 	}
 
 	if ( depth->mask ) {
-		mask_size = depth->n * sizeof(u8);
-		mask = DRM_MALLOC( mask_size );
+		mask = DRM_MALLOC( depth->n * sizeof(u8) );
 		if ( mask == NULL ) {
-			DRM_FREE( x, xbuf_size );
-			DRM_FREE( y, ybuf_size );
-			DRM_FREE( buffer, buffer_size );
+			DRM_FREE( x );
+			DRM_FREE( y );
+			DRM_FREE( buffer );
 			return DRM_ERR(ENOMEM);
 		}
-		if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) {
-			DRM_FREE( x, xbuf_size );
-			DRM_FREE( y, ybuf_size );
-			DRM_FREE( buffer, buffer_size );
-			DRM_FREE( mask, mask_size );
+		if ( DRM_COPY_FROM_USER( mask, depth->mask,
+				     depth->n * sizeof(u8) ) ) {
+			DRM_FREE( x );
+			DRM_FREE( y );
+			DRM_FREE( buffer );
+			DRM_FREE( mask );
 			return DRM_ERR(EFAULT);
 		}
 
@@ -1071,7 +1069,7 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
 			}
 		}
 
-		DRM_FREE( mask, mask_size );
+		DRM_FREE( mask );
 	} else {
 		for ( i = 0 ; i < count ; i++ ) {
 			BEGIN_RING( 6 );
@@ -1095,9 +1093,9 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
 		}
 	}
 
-	DRM_FREE( x, xbuf_size );
-	DRM_FREE( y, ybuf_size );
-	DRM_FREE( buffer, buffer_size );
+	DRM_FREE( x );
+	DRM_FREE( y );
+	DRM_FREE( buffer );
 
 	return 0;
 }
@@ -1148,7 +1146,7 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
 {
 	drm_r128_private_t *dev_priv = dev->dev_private;
 	int count, *x, *y;
-	int i, xbuf_size, ybuf_size;
+	int i;
 	RING_LOCALS;
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
@@ -1157,25 +1155,23 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
 		count = dev_priv->depth_pitch;
 	}
 
-	xbuf_size = count * sizeof(*x);
-	ybuf_size = count * sizeof(*y);
-	x = DRM_MALLOC( xbuf_size );
+	x = DRM_MALLOC( count * sizeof(*x) );
 	if ( x == NULL ) {
 		return DRM_ERR(ENOMEM);
 	}
-	y = DRM_MALLOC( ybuf_size );
+	y = DRM_MALLOC( count * sizeof(*y) );
 	if ( y == NULL ) {
-		DRM_FREE( x, xbuf_size );
+		DRM_FREE( x );
 		return DRM_ERR(ENOMEM);
 	}
-	if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
+	if ( DRM_COPY_FROM_USER( x, depth->x, count * sizeof(int) ) ) {
+		DRM_FREE( x );
+		DRM_FREE( y );
 		return DRM_ERR(EFAULT);
 	}
-	if ( DRM_COPY_FROM_USER( y, depth->y, ybuf_size ) ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
+	if ( DRM_COPY_FROM_USER( y, depth->y, count * sizeof(int) ) ) {
+		DRM_FREE( x );
+		DRM_FREE( y );
 		return DRM_ERR(EFAULT);
 	}
 
@@ -1203,8 +1199,8 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
 		ADVANCE_RING();
 	}
 
-	DRM_FREE( x, xbuf_size );
-	DRM_FREE( y, ybuf_size );
+	DRM_FREE( x );
+	DRM_FREE( y );
 
 	return 0;
 }
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c
index 89c9eab1..b4d0e4b6 100644
--- a/shared-core/radeon_cp.c
+++ b/shared-core/radeon_cp.c
@@ -36,11 +36,6 @@
 
 #define RADEON_FIFO_DEBUG	0
 
-#if defined(__alpha__) || defined(__powerpc__)
-# define PCIGART_ENABLED
-#else
-# undef PCIGART_ENABLED
-#endif
 
 
 /* CP microcode (from ATI) */
@@ -885,6 +880,7 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
 
 	/* Set the write pointer delay */
 	RADEON_WRITE( RADEON_CP_RB_WPTR_DELAY, 0 );
+	RADEON_READ( RADEON_CP_RB_WPTR_DELAY ); /* read back to propagate */
 
 	/* Initialize the ring buffer's read and write pointers */
 	cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR );
@@ -926,11 +922,11 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
 	RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 );
 
 	/* Writeback doesn't seem to work everywhere, test it first */
-	DRM_WRITE32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0 );
+	DRM_WRITE32( &dev_priv->scratch[1], 0 );
 	RADEON_WRITE( RADEON_SCRATCH_REG1, 0xdeadbeef );
 
 	for ( tmp = 0 ; tmp < dev_priv->usec_timeout ; tmp++ ) {
-		if ( DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1) ) == 0xdeadbeef )
+		if ( DRM_READ32( &dev_priv->scratch[1] ) == 0xdeadbeef )
 			break;
 		DRM_UDELAY( 1 );
 	}
@@ -990,17 +986,6 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
 
 	dev_priv->is_pci = init->is_pci;
 
-#if !defined(PCIGART_ENABLED)
-	/* PCI support is not 100% working, so we disable it here.
-	 */
-	if ( dev_priv->is_pci ) {
-		DRM_ERROR( "PCI GART not yet supported for Radeon!\n" );
-		dev->dev_private = (void *)dev_priv;
-		radeon_do_cleanup_cp(dev);
-		return DRM_ERR(EINVAL);
-	}
-#endif
-
 	if ( dev_priv->is_pci && !dev->sg ) {
 		DRM_ERROR( "PCI GART memory not allocated!\n" );
 		dev->dev_private = (void *)dev_priv;
@@ -1217,7 +1202,6 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
 		(dev_priv->ring.size / sizeof(u32)) - 1;
 
 	dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
-	dev_priv->ring.ring_rptr = dev_priv->ring_rptr;
 
 #if __REALLY_HAVE_SG
 	if ( dev_priv->is_pci ) {
@@ -1355,9 +1339,6 @@ int radeon_cp_stop( DRM_IOCTL_ARGS )
 
 	DRM_COPY_FROM_USER_IOCTL( stop, (drm_radeon_cp_stop_t *)data, sizeof(stop) );
 
-	if (!dev_priv->cp_running)
-		return 0;
-
 	/* Flush any pending CP commands.  This ensures any outstanding
 	 * commands are exectuted by the engine before we turn it off.
 	 */
@@ -1385,39 +1366,6 @@ int radeon_cp_stop( DRM_IOCTL_ARGS )
 	return 0;
 }
 
-
-void radeon_do_release( drm_device_t *dev )
-{
-	drm_radeon_private_t *dev_priv = dev->dev_private;
-	int ret;
-
-	if (dev_priv) {
-		if (dev_priv->cp_running) {
-			/* Stop the cp */
-			while ((ret = radeon_do_cp_idle( dev_priv )) != 0) {
-				DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
-#ifdef __linux__
-				schedule();
-#else
-				tsleep(&ret, PZERO, "rdnrel", 1);
-#endif
-			}
-			radeon_do_cp_stop( dev_priv );
-			radeon_do_engine_reset( dev );
-		}
-
-		/* Disable *all* interrupts */
-		RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
-
-		/* Free memory heap structures */
-		radeon_mem_takedown( &(dev_priv->agp_heap) );
-		radeon_mem_takedown( &(dev_priv->fb_heap) );
-
-		/* deallocate kernel resources */
-		radeon_do_cleanup_cp( dev );
-	}
-}
-
 /* Just reset the CP ring.  Called as part of an X Server engine reset.
  */
 int radeon_cp_reset( DRM_IOCTL_ARGS )
@@ -1449,6 +1397,9 @@ int radeon_cp_idle( DRM_IOCTL_ARGS )
 
 	LOCK_TEST_WITH_RETURN( dev );
 
+/* 	if (dev->irq)  */
+/* 		radeon_emit_and_wait_irq( dev ); */
+
 	return radeon_do_cp_idle( dev_priv );
 }
 
@@ -1543,7 +1494,7 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev )
 	drm_buf_t *buf;
 	int i, t;
 	int start;
-	u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1));
+	u32 done_age = DRM_READ32(&dev_priv->scratch[1]);
 
 	if ( ++dev_priv->last_buf >= dma->buf_count )
 		dev_priv->last_buf = 0;
diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h
index 502ba89b..635ad14b 100644
--- a/shared-core/radeon_drv.h
+++ b/shared-core/radeon_drv.h
@@ -31,8 +31,8 @@
 #ifndef __RADEON_DRV_H__
 #define __RADEON_DRV_H__
 
-#define GET_RING_HEAD(ring)		DRM_READ32(  (ring)->ring_rptr, 0 ) /* (ring)->head */
-#define SET_RING_HEAD(ring,val)		DRM_WRITE32( (ring)->ring_rptr, 0, (val) ) /* (ring)->head */
+#define GET_RING_HEAD(ring)		DRM_READ32(  (volatile u32 *) (ring)->head )
+#define SET_RING_HEAD(ring,val)		DRM_WRITE32( (volatile u32 *) (ring)->head , (val))
 
 typedef struct drm_radeon_freelist {
    	unsigned int age;
@@ -53,7 +53,6 @@ typedef struct drm_radeon_ring_buffer {
 	int space;
 
 	int high_mark;
-	drm_local_map_t *ring_rptr;
 } drm_radeon_ring_buffer_t;
 
 typedef struct drm_radeon_depth_clear_t {
@@ -127,13 +126,13 @@ typedef struct drm_radeon_private {
 
 	drm_radeon_depth_clear_t depth_clear;
 
-	drm_local_map_t *sarea;
-	drm_local_map_t *fb;
-	drm_local_map_t *mmio;
-	drm_local_map_t *cp_ring;
-	drm_local_map_t *ring_rptr;
-	drm_local_map_t *buffers;
-	drm_local_map_t *agp_textures;
+	drm_map_t *sarea;
+	drm_map_t *fb;
+	drm_map_t *mmio;
+	drm_map_t *cp_ring;
+	drm_map_t *ring_rptr;
+	drm_map_t *buffers;
+	drm_map_t *agp_textures;
 
 	struct mem_block *agp_heap;
 	struct mem_block *fb_heap;
@@ -194,7 +193,6 @@ extern int radeon_emit_and_wait_irq(drm_device_t *dev);
 extern int radeon_wait_irq(drm_device_t *dev, int swi_nr);
 extern int radeon_emit_irq(drm_device_t *dev);
 
-extern void radeon_do_release(drm_device_t *dev);
 
 /* Flags for stats.boxes
  */
@@ -268,10 +266,8 @@ extern void radeon_do_release(drm_device_t *dev);
 #define RADEON_SCRATCH_UMSK		0x0770
 #define RADEON_SCRATCH_ADDR		0x0774
 
-#define RADEON_SCRATCHOFF( x )		(RADEON_SCRATCH_REG_OFFSET + 4*(x))
-
 #define GET_SCRATCH( x )	(dev_priv->writeback_works			\
-				? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \
+				? DRM_READ32( &dev_priv->scratch[(x)] )		\
 				: RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
 
 
@@ -690,10 +686,15 @@ extern void radeon_do_release(drm_device_t *dev);
 
 #define RADEON_RING_HIGH_MARK		128
 
-#define RADEON_READ(reg)	DRM_READ32(  dev_priv->mmio, (reg) )
-#define RADEON_WRITE(reg,val)	DRM_WRITE32( dev_priv->mmio, (reg), (val) )
-#define RADEON_READ8(reg)	DRM_READ8(  dev_priv->mmio, (reg) )
-#define RADEON_WRITE8(reg,val)	DRM_WRITE8( dev_priv->mmio, (reg), (val) )
+
+#define RADEON_BASE(reg)	((unsigned long)(dev_priv->mmio->handle))
+#define RADEON_ADDR(reg)	(RADEON_BASE( reg ) + reg)
+
+#define RADEON_READ(reg)	DRM_READ32(  (volatile u32 *) RADEON_ADDR(reg) )
+#define RADEON_WRITE(reg,val)	DRM_WRITE32( (volatile u32 *) RADEON_ADDR(reg), (val) )
+
+#define RADEON_READ8(reg)	DRM_READ8(  (volatile u8 *) RADEON_ADDR(reg) )
+#define RADEON_WRITE8(reg,val)	DRM_WRITE8( (volatile u8 *) RADEON_ADDR(reg), (val) )
 
 #define RADEON_WRITE_PLL( addr, val )					\
 do {									\
@@ -826,10 +827,43 @@ do {									\
 
 #define RING_LOCALS	int write, _nr; unsigned int mask; u32 *ring;
 
-#define BEGIN_RING( n ) do {						\
+#if defined(__alpha__)
+#  define RADEON_PAD_RING 16 /* pad ring requests to 16 lw boundaries */
+#else
+#  define RADEON_PAD_RING 0
+#endif
+
+#if RADEON_PAD_RING
+# define radeon_pad_size(n) 	\
+	(((RADEON_PAD_RING) - ((n) % (RADEON_PAD_RING))) % (RADEON_PAD_RING))
+# define radeon_pad_ring() do {						\
+	if (RADEON_VERBOSE) {						\
+		DRM_INFO("Padding ring from %d (%x) with %d words\n", 	\
+			 write, write, radeon_pad_size(write));		\
+	}								\
+	switch (radeon_pad_size(write)) {			      	\
+	case 0:  /* aligned */					      	\
+		break;						      	\
+	case 1:  /* 1 word */					      	\
+		OUT_RING(CP_PACKET2());				      	\
+		break;						      	\
+	default: /* >= 2 words */				      	\
+		OUT_RING(CP_PACKET3(0x1000, radeon_pad_size(write) - 1));\
+		write = (write + radeon_pad_size(write)) & mask;	\
+		write &= mask;						\
+		break;						      	\
+	}							      	\
+} while(0)
+#else
+# define radeon_pad_size(n) 0
+# define radeon_pad_ring()
+#endif
+
+#define BEGIN_RING( req_n ) do {					\
+	int n = req_n + radeon_pad_size(req_n);				\
 	if ( RADEON_VERBOSE ) {						\
-		DRM_INFO( "BEGIN_RING( %d ) in %s\n",			\
-			   n, __FUNCTION__ );				\
+		DRM_INFO( "BEGIN_RING( %d (%d) ) in %s\n",		\
+			   n, req_n, __FUNCTION__ );			\
 	}								\
 	if ( dev_priv->ring.space <= (n) * sizeof(u32) ) {		\
                 COMMIT_RING();						\
@@ -846,6 +880,7 @@ do {									\
 		DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n",	\
 			  write, dev_priv->ring.tail );			\
 	}								\
+	radeon_pad_ring();						\
 	if (((dev_priv->ring.tail + _nr) & mask) != write) {		\
 		DRM_ERROR( 						\
 			"ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n",	\
@@ -857,7 +892,7 @@ do {									\
 
 #define COMMIT_RING() do {						\
 	/* Flush writes to ring */					\
-	DRM_READMEMORYBARRIER(dev_priv->mmio);					\
+	DRM_READMEMORYBARRIER();					\
 	GET_RING_HEAD( &dev_priv->ring );				\
 	RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail );		\
 	/* read from PCI bus to ensure correct posting */		\
diff --git a/shared-core/radeon_mem.c b/shared-core/radeon_mem.c
index 3a2c8969..5c07c1af 100644
--- a/shared-core/radeon_mem.c
+++ b/shared-core/radeon_mem.c
@@ -118,7 +118,7 @@ static void free_block( struct mem_block *p )
 		p->size += q->size;
 		p->next = q->next;
 		p->next->prev = p;
-		DRM_FREE(q, sizeof(*q));
+		DRM_FREE(q);
 	}
 
 	if (p->prev->pid == 0) {
@@ -126,10 +126,20 @@ static void free_block( struct mem_block *p )
 		q->size += p->size;
 		q->next = p->next;
 		q->next->prev = q;
-		DRM_FREE(p, sizeof(*q));
+		DRM_FREE(p);
 	}
 }
 
+static void print_heap( struct mem_block *heap )
+{
+	struct mem_block *p;
+
+	for (p = heap->next ; p != heap ; p = p->next) 
+		DRM_DEBUG("0x%x..0x%x (0x%x) -- owner %d\n",
+			  p->start, p->start + p->size,
+			  p->size, p->pid);
+}
+
 /* Initialize.  How to check for an uninitialized heap?
  */
 static int init_heap(struct mem_block **heap, int start, int size)
@@ -141,7 +151,7 @@ static int init_heap(struct mem_block **heap, int start, int size)
 	
 	*heap = DRM_MALLOC(sizeof(**heap));
 	if (!*heap) {
-		DRM_FREE( blocks, sizeof(*blocks) );
+		DRM_FREE( blocks );
 		return -ENOMEM;
 	}
 
@@ -181,7 +191,7 @@ void radeon_mem_release( struct mem_block *heap )
 			p->size += q->size;
 			p->next = q->next;
 			p->next->prev = p;
-			DRM_FREE(q, sizeof(*q));
+			DRM_FREE(q);
 		}
 	}
 }
@@ -198,10 +208,10 @@ void radeon_mem_takedown( struct mem_block **heap )
 	for (p = (*heap)->next ; p != *heap ; ) {
 		struct mem_block *q = p;
 		p = p->next;
-		DRM_FREE(q, sizeof(*q));
+		DRM_FREE(q);
 	}
 
-	DRM_FREE( *heap, sizeof(**heap) );
+	DRM_FREE( *heap );
 	*heap = 0;
 }
 
diff --git a/shared/mga_drv.h b/shared/mga_drv.h
index 0e650b42..a5085b06 100644
--- a/shared/mga_drv.h
+++ b/shared/mga_drv.h
@@ -90,14 +90,14 @@ typedef struct drm_mga_private {
 	unsigned int texture_offset;
 	unsigned int texture_size;
 
-	drm_local_map_t *sarea;
-	drm_local_map_t *fb;
-	drm_local_map_t *mmio;
-	drm_local_map_t *status;
-	drm_local_map_t *warp;
-	drm_local_map_t *primary;
-	drm_local_map_t *buffers;
-	drm_local_map_t *agp_textures;
+	drm_map_t *sarea;
+	drm_map_t *fb;
+	drm_map_t *mmio;
+	drm_map_t *status;
+	drm_map_t *warp;
+	drm_map_t *primary;
+	drm_map_t *buffers;
+	drm_map_t *agp_textures;
 } drm_mga_private_t;
 
 				/* mga_dma.c */
@@ -131,30 +131,32 @@ extern int  mga_getparam( DRM_IOCTL_ARGS );
 extern int mga_warp_install_microcode( drm_mga_private_t *dev_priv );
 extern int mga_warp_init( drm_mga_private_t *dev_priv );
 
-#define mga_flush_write_combine()	DRM_WRITEMEMORYBARRIER(dev_priv->primary)
+#define mga_flush_write_combine()	DRM_WRITEMEMORYBARRIER()
+
 
-#if defined(__linux__) && defined(__alpha__)
 #define MGA_BASE( reg )		((unsigned long)(dev_priv->mmio->handle))
 #define MGA_ADDR( reg )		(MGA_BASE(reg) + reg)
 
 #define MGA_DEREF( reg )	*(volatile u32 *)MGA_ADDR( reg )
 #define MGA_DEREF8( reg )	*(volatile u8 *)MGA_ADDR( reg )
 
+#ifdef __alpha__
 #define MGA_READ( reg )		(_MGA_READ((u32 *)MGA_ADDR(reg)))
 #define MGA_READ8( reg )	(_MGA_READ((u8 *)MGA_ADDR(reg)))
-#define MGA_WRITE( reg, val )	do { DRM_WRITEMEMORYBARRIER(dev_priv->mmio); MGA_DEREF( reg ) = val; } while (0)
-#define MGA_WRITE8( reg, val )  do { DRM_WRITEMEMORYBARRIER(dev_priv->mmio); MGA_DEREF8( reg ) = val; } while (0)
+#define MGA_WRITE( reg, val )	do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF( reg ) = val; } while (0)
+#define MGA_WRITE8( reg, val )  do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8( reg ) = val; } while (0)
 
 static inline u32 _MGA_READ(u32 *addr)
 {
-	DRM_READMEMORYBARRIER(dev_priv->mmio);
+	DRM_READMEMORYBARRIER();
 	return *(volatile u32 *)addr;
 }
+
 #else
-#define MGA_READ8( reg )	DRM_READ8(dev_priv->mmio, (reg))
-#define MGA_READ( reg )		DRM_READ32(dev_priv->mmio, (reg))
-#define MGA_WRITE8( reg, val )  DRM_WRITE8(dev_priv->mmio, (reg), (val))
-#define MGA_WRITE( reg, val )	DRM_WRITE32(dev_priv->mmio, (reg), (val))
+#define MGA_READ( reg )		MGA_DEREF( reg )
+#define MGA_READ8( reg )	MGA_DEREF8( reg )
+#define MGA_WRITE( reg, val )	do { MGA_DEREF( reg ) = val; } while (0)
+#define MGA_WRITE8( reg, val )  do { MGA_DEREF8( reg ) = val; } while (0)
 #endif
 
 #define DWGREG0 	0x1c00
diff --git a/shared/r128_cce.c b/shared/r128_cce.c
index 8d305b75..5175885e 100644
--- a/shared/r128_cce.c
+++ b/shared/r128_cce.c
@@ -579,7 +579,6 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
 		(dev_priv->ring.size / sizeof(u32)) - 1;
 
 	dev_priv->ring.high_mark = 128;
-	dev_priv->ring.ring_rptr = dev_priv->ring_rptr;
 
 	dev_priv->sarea_priv->last_frame = 0;
 	R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame );
diff --git a/shared/r128_drv.h b/shared/r128_drv.h
index 5e6f1215..763fcb3a 100644
--- a/shared/r128_drv.h
+++ b/shared/r128_drv.h
@@ -34,8 +34,8 @@
 #ifndef __R128_DRV_H__
 #define __R128_DRV_H__
 
-#define GET_RING_HEAD(ring)		DRM_READ32(  (ring)->ring_rptr, 0 ) /* (ring)->head */
-#define SET_RING_HEAD(ring,val)		DRM_WRITE32( (ring)->ring_rptr, 0, (val) ) /* (ring)->head */
+#define GET_RING_HEAD(ring)		DRM_READ32(  (volatile u32 *) (ring)->head )
+#define SET_RING_HEAD(ring,val)		DRM_WRITE32( (volatile u32 *) (ring)->head, (val) )
 
 typedef struct drm_r128_freelist {
    	unsigned int age;
@@ -56,7 +56,6 @@ typedef struct drm_r128_ring_buffer {
 	int space;
 
 	int high_mark;
-	drm_local_map_t *ring_rptr;
 } drm_r128_ring_buffer_t;
 
 typedef struct drm_r128_private {
@@ -99,13 +98,13 @@ typedef struct drm_r128_private {
 	u32 depth_pitch_offset_c;
 	u32 span_pitch_offset_c;
 
-	drm_local_map_t *sarea;
-	drm_local_map_t *fb;
-	drm_local_map_t *mmio;
-	drm_local_map_t *cce_ring;
-	drm_local_map_t *ring_rptr;
-	drm_local_map_t *buffers;
-	drm_local_map_t *agp_textures;
+	drm_map_t *sarea;
+	drm_map_t *fb;
+	drm_map_t *mmio;
+	drm_map_t *cce_ring;
+	drm_map_t *ring_rptr;
+	drm_map_t *buffers;
+	drm_map_t *agp_textures;
 } drm_r128_private_t;
 
 typedef struct drm_r128_buf_priv {
@@ -371,10 +370,15 @@ extern int r128_cce_indirect( DRM_IOCTL_ARGS );
 
 #define R128_PERFORMANCE_BOXES		0
 
-#define R128_READ(reg)		DRM_READ32(  dev_priv->mmio, (reg) )
-#define R128_WRITE(reg,val)	DRM_WRITE32( dev_priv->mmio, (reg), (val) )
-#define R128_READ8(reg)		DRM_READ8(   dev_priv->mmio, (reg) )
-#define R128_WRITE8(reg,val)	DRM_WRITE8(  dev_priv->mmio, (reg), (val) )
+
+#define R128_BASE(reg)		((unsigned long)(dev_priv->mmio->handle))
+#define R128_ADDR(reg)		(R128_BASE( reg ) + reg)
+
+#define R128_READ(reg)		DRM_READ32(  (volatile u32 *) R128_ADDR(reg) )
+#define R128_WRITE(reg,val)	DRM_WRITE32( (volatile u32 *) R128_ADDR(reg), (val) )
+
+#define R128_READ8(reg)		DRM_READ8(  (volatile u8 *) R128_ADDR(reg) )
+#define R128_WRITE8(reg,val)	DRM_WRITE8( (volatile u8 *) R128_ADDR(reg), (val) )
 
 #define R128_WRITE_PLL(addr,val)					\
 do {									\
@@ -449,7 +453,7 @@ do {									\
 #if defined(__powerpc__)
 #define r128_flush_write_combine()	(void) GET_RING_HEAD( &dev_priv->ring )
 #else
-#define r128_flush_write_combine()	DRM_WRITEMEMORYBARRIER(dev_priv->ring_rptr)
+#define r128_flush_write_combine()	DRM_WRITEMEMORYBARRIER()
 #endif
 
 
diff --git a/shared/r128_state.c b/shared/r128_state.c
index 20307c04..68f73061 100644
--- a/shared/r128_state.c
+++ b/shared/r128_state.c
@@ -896,7 +896,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
 	int count, x, y;
 	u32 *buffer;
 	u8 *mask;
-	int i, buffer_size, mask_size;
+	int i;
 	RING_LOCALS;
 	DRM_DEBUG( "\n" );
 
@@ -908,25 +908,25 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
 		return DRM_ERR(EFAULT);
 	}
 
-	buffer_size = depth->n * sizeof(u32);
-	buffer = DRM_MALLOC( buffer_size );
+	buffer = DRM_MALLOC( depth->n * sizeof(u32) );
 	if ( buffer == NULL )
 		return DRM_ERR(ENOMEM);
-	if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) {
-		DRM_FREE( buffer, buffer_size);
+	if ( DRM_COPY_FROM_USER( buffer, depth->buffer,
+			     depth->n * sizeof(u32) ) ) {
+		DRM_FREE( buffer );
 		return DRM_ERR(EFAULT);
 	}
 
-	mask_size = depth->n * sizeof(u8);
 	if ( depth->mask ) {
-		mask = DRM_MALLOC( mask_size );
+		mask = DRM_MALLOC( depth->n * sizeof(u8) );
 		if ( mask == NULL ) {
-			DRM_FREE( buffer, buffer_size );
+			DRM_FREE( buffer );
 			return DRM_ERR(ENOMEM);
 		}
-		if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) {
-			DRM_FREE( buffer, buffer_size );
-			DRM_FREE( mask, mask_size );
+		if ( DRM_COPY_FROM_USER( mask, depth->mask,
+				     depth->n * sizeof(u8) ) ) {
+			DRM_FREE( buffer );
+			DRM_FREE( mask );
 			return DRM_ERR(EFAULT);
 		}
 
@@ -953,7 +953,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
 			}
 		}
 
-		DRM_FREE( mask, mask_size );
+		DRM_FREE( mask );
 	} else {
 		for ( i = 0 ; i < count ; i++, x++ ) {
 			BEGIN_RING( 6 );
@@ -977,7 +977,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
 		}
 	}
 
-	DRM_FREE( buffer, buffer_size );
+	DRM_FREE( buffer );
 
 	return 0;
 }
@@ -989,62 +989,60 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
 	int count, *x, *y;
 	u32 *buffer;
 	u8 *mask;
-	int i, xbuf_size, ybuf_size, buffer_size, mask_size;
+	int i;
 	RING_LOCALS;
 	DRM_DEBUG( "\n" );
 
 	count = depth->n;
 
-	xbuf_size = count * sizeof(*x);
-	ybuf_size = count * sizeof(*y);
-	x = DRM_MALLOC( xbuf_size );
+	x = DRM_MALLOC( count * sizeof(*x) );
 	if ( x == NULL ) {
 		return DRM_ERR(ENOMEM);
 	}
-	y = DRM_MALLOC( ybuf_size );
+	y = DRM_MALLOC( count * sizeof(*y) );
 	if ( y == NULL ) {
-		DRM_FREE( x, xbuf_size );
+		DRM_FREE( x );
 		return DRM_ERR(ENOMEM);
 	}
-	if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
+	if ( DRM_COPY_FROM_USER( x, depth->x, count * sizeof(int) ) ) {
+		DRM_FREE( x );
+		DRM_FREE( y );
 		return DRM_ERR(EFAULT);
 	}
-	if ( DRM_COPY_FROM_USER( y, depth->y, xbuf_size ) ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
+	if ( DRM_COPY_FROM_USER( y, depth->y, count * sizeof(int) ) ) {
+		DRM_FREE( x );
+		DRM_FREE( y );
 		return DRM_ERR(EFAULT);
 	}
 
-	buffer_size = depth->n * sizeof(u32);
-	buffer = DRM_MALLOC( buffer_size );
+	buffer = DRM_MALLOC( depth->n * sizeof(u32) );
 	if ( buffer == NULL ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
+		DRM_FREE( x );
+		DRM_FREE( y );
 		return DRM_ERR(ENOMEM);
 	}
-	if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
-		DRM_FREE( buffer, buffer_size );
+	if ( DRM_COPY_FROM_USER( buffer, depth->buffer,
+			     depth->n * sizeof(u32) ) ) {
+		DRM_FREE( x );
+		DRM_FREE( y );
+		DRM_FREE( buffer );
 		return DRM_ERR(EFAULT);
 	}
 
 	if ( depth->mask ) {
-		mask_size = depth->n * sizeof(u8);
-		mask = DRM_MALLOC( mask_size );
+		mask = DRM_MALLOC( depth->n * sizeof(u8) );
 		if ( mask == NULL ) {
-			DRM_FREE( x, xbuf_size );
-			DRM_FREE( y, ybuf_size );
-			DRM_FREE( buffer, buffer_size );
+			DRM_FREE( x );
+			DRM_FREE( y );
+			DRM_FREE( buffer );
 			return DRM_ERR(ENOMEM);
 		}
-		if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) {
-			DRM_FREE( x, xbuf_size );
-			DRM_FREE( y, ybuf_size );
-			DRM_FREE( buffer, buffer_size );
-			DRM_FREE( mask, mask_size );
+		if ( DRM_COPY_FROM_USER( mask, depth->mask,
+				     depth->n * sizeof(u8) ) ) {
+			DRM_FREE( x );
+			DRM_FREE( y );
+			DRM_FREE( buffer );
+			DRM_FREE( mask );
 			return DRM_ERR(EFAULT);
 		}
 
@@ -1071,7 +1069,7 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
 			}
 		}
 
-		DRM_FREE( mask, mask_size );
+		DRM_FREE( mask );
 	} else {
 		for ( i = 0 ; i < count ; i++ ) {
 			BEGIN_RING( 6 );
@@ -1095,9 +1093,9 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
 		}
 	}
 
-	DRM_FREE( x, xbuf_size );
-	DRM_FREE( y, ybuf_size );
-	DRM_FREE( buffer, buffer_size );
+	DRM_FREE( x );
+	DRM_FREE( y );
+	DRM_FREE( buffer );
 
 	return 0;
 }
@@ -1148,7 +1146,7 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
 {
 	drm_r128_private_t *dev_priv = dev->dev_private;
 	int count, *x, *y;
-	int i, xbuf_size, ybuf_size;
+	int i;
 	RING_LOCALS;
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
@@ -1157,25 +1155,23 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
 		count = dev_priv->depth_pitch;
 	}
 
-	xbuf_size = count * sizeof(*x);
-	ybuf_size = count * sizeof(*y);
-	x = DRM_MALLOC( xbuf_size );
+	x = DRM_MALLOC( count * sizeof(*x) );
 	if ( x == NULL ) {
 		return DRM_ERR(ENOMEM);
 	}
-	y = DRM_MALLOC( ybuf_size );
+	y = DRM_MALLOC( count * sizeof(*y) );
 	if ( y == NULL ) {
-		DRM_FREE( x, xbuf_size );
+		DRM_FREE( x );
 		return DRM_ERR(ENOMEM);
 	}
-	if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
+	if ( DRM_COPY_FROM_USER( x, depth->x, count * sizeof(int) ) ) {
+		DRM_FREE( x );
+		DRM_FREE( y );
 		return DRM_ERR(EFAULT);
 	}
-	if ( DRM_COPY_FROM_USER( y, depth->y, ybuf_size ) ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
+	if ( DRM_COPY_FROM_USER( y, depth->y, count * sizeof(int) ) ) {
+		DRM_FREE( x );
+		DRM_FREE( y );
 		return DRM_ERR(EFAULT);
 	}
 
@@ -1203,8 +1199,8 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
 		ADVANCE_RING();
 	}
 
-	DRM_FREE( x, xbuf_size );
-	DRM_FREE( y, ybuf_size );
+	DRM_FREE( x );
+	DRM_FREE( y );
 
 	return 0;
 }
diff --git a/shared/radeon.h b/shared/radeon.h
index c36accb4..fe71687a 100644
--- a/shared/radeon.h
+++ b/shared/radeon.h
@@ -51,7 +51,7 @@
 #define DRIVER_DATE		"20020828"
 
 #define DRIVER_MAJOR		1
-#define DRIVER_MINOR		8
+#define DRIVER_MINOR		7
 #define DRIVER_PATCHLEVEL	0
 
 /* Interface history:
@@ -77,7 +77,6 @@
  *       and R200_PP_CUBIC_OFFSET_F1_[0..5].
  *       Added packets R200_EMIT_PP_CUBIC_FACES_[0..5] and
  *       R200_EMIT_PP_CUBIC_OFFSETS_[0..5].  (brian)
- * 1.8 - Remove need to call cleanup ioctls on last client exit (keith)
  */
 #define DRIVER_IOCTLS							     \
  [DRM_IOCTL_NR(DRM_IOCTL_DMA)]               = { radeon_cp_buffers,  1, 0 }, \
@@ -106,6 +105,11 @@
  [DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_WAIT)]   = { radeon_irq_wait, 1, 0 },
 
 
+#define USE_IRQS 1
+#if USE_IRQS
+#define __HAVE_DMA_IRQ		1
+#define __HAVE_VBL_IRQ		1
+#define __HAVE_SHARED_IRQ       1
 
 /* When a client dies:
  *    - Check for and clean up flipped page state
@@ -113,36 +117,35 @@
  *
  * DRM infrastructure takes care of reclaiming dma buffers.
  */
-#define DRIVER_PRERELEASE() 						\
-do {									\
+#define DRIVER_PRERELEASE() do {					\
 	if ( dev->dev_private ) {					\
 		drm_radeon_private_t *dev_priv = dev->dev_private;	\
 		if ( dev_priv->page_flipping ) {			\
 			radeon_do_cleanup_pageflip( dev );		\
 		}							\
                 radeon_mem_release( dev_priv->agp_heap );		\
-                radeon_mem_release( dev_priv->fb_heap );		\
 	}								\
 } while (0)
 
-/* When the last client dies, shut down the CP and free dev->dev_priv.
+/* On unloading the module:
+ *    - Free memory heap structure
+ *    - Remove mappings made at startup and free dev_private.
  */
-#define __HAVE_RELEASE 1
-#define DRIVER_RELEASE() 			\
-do {						\
-        DRM(reclaim_buffers)( dev, priv->pid ); \
-	if ( dev->open_count == 1)		\
-                 radeon_do_release( dev );	\
+#define DRIVER_PRETAKEDOWN() do {					\
+	if ( dev->dev_private ) {					\
+		drm_radeon_private_t *dev_priv = dev->dev_private;	\
+		radeon_mem_takedown( &(dev_priv->agp_heap) );		\
+		radeon_do_cleanup_cp( dev );				\
+	}								\
 } while (0)
 
-
+#else
+#define __HAVE_DMA_IRQ 0
+#endif
 
 /* DMA customization:
  */
 #define __HAVE_DMA		1
-#define __HAVE_DMA_IRQ		1
-#define __HAVE_VBL_IRQ		1
-#define __HAVE_SHARED_IRQ       1
 
 
 /* Buffer customization:
diff --git a/shared/radeon_cp.c b/shared/radeon_cp.c
index 89c9eab1..b4d0e4b6 100644
--- a/shared/radeon_cp.c
+++ b/shared/radeon_cp.c
@@ -36,11 +36,6 @@
 
 #define RADEON_FIFO_DEBUG	0
 
-#if defined(__alpha__) || defined(__powerpc__)
-# define PCIGART_ENABLED
-#else
-# undef PCIGART_ENABLED
-#endif
 
 
 /* CP microcode (from ATI) */
@@ -885,6 +880,7 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
 
 	/* Set the write pointer delay */
 	RADEON_WRITE( RADEON_CP_RB_WPTR_DELAY, 0 );
+	RADEON_READ( RADEON_CP_RB_WPTR_DELAY ); /* read back to propagate */
 
 	/* Initialize the ring buffer's read and write pointers */
 	cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR );
@@ -926,11 +922,11 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
 	RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 );
 
 	/* Writeback doesn't seem to work everywhere, test it first */
-	DRM_WRITE32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0 );
+	DRM_WRITE32( &dev_priv->scratch[1], 0 );
 	RADEON_WRITE( RADEON_SCRATCH_REG1, 0xdeadbeef );
 
 	for ( tmp = 0 ; tmp < dev_priv->usec_timeout ; tmp++ ) {
-		if ( DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1) ) == 0xdeadbeef )
+		if ( DRM_READ32( &dev_priv->scratch[1] ) == 0xdeadbeef )
 			break;
 		DRM_UDELAY( 1 );
 	}
@@ -990,17 +986,6 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
 
 	dev_priv->is_pci = init->is_pci;
 
-#if !defined(PCIGART_ENABLED)
-	/* PCI support is not 100% working, so we disable it here.
-	 */
-	if ( dev_priv->is_pci ) {
-		DRM_ERROR( "PCI GART not yet supported for Radeon!\n" );
-		dev->dev_private = (void *)dev_priv;
-		radeon_do_cleanup_cp(dev);
-		return DRM_ERR(EINVAL);
-	}
-#endif
-
 	if ( dev_priv->is_pci && !dev->sg ) {
 		DRM_ERROR( "PCI GART memory not allocated!\n" );
 		dev->dev_private = (void *)dev_priv;
@@ -1217,7 +1202,6 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
 		(dev_priv->ring.size / sizeof(u32)) - 1;
 
 	dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
-	dev_priv->ring.ring_rptr = dev_priv->ring_rptr;
 
 #if __REALLY_HAVE_SG
 	if ( dev_priv->is_pci ) {
@@ -1355,9 +1339,6 @@ int radeon_cp_stop( DRM_IOCTL_ARGS )
 
 	DRM_COPY_FROM_USER_IOCTL( stop, (drm_radeon_cp_stop_t *)data, sizeof(stop) );
 
-	if (!dev_priv->cp_running)
-		return 0;
-
 	/* Flush any pending CP commands.  This ensures any outstanding
 	 * commands are exectuted by the engine before we turn it off.
 	 */
@@ -1385,39 +1366,6 @@ int radeon_cp_stop( DRM_IOCTL_ARGS )
 	return 0;
 }
 
-
-void radeon_do_release( drm_device_t *dev )
-{
-	drm_radeon_private_t *dev_priv = dev->dev_private;
-	int ret;
-
-	if (dev_priv) {
-		if (dev_priv->cp_running) {
-			/* Stop the cp */
-			while ((ret = radeon_do_cp_idle( dev_priv )) != 0) {
-				DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
-#ifdef __linux__
-				schedule();
-#else
-				tsleep(&ret, PZERO, "rdnrel", 1);
-#endif
-			}
-			radeon_do_cp_stop( dev_priv );
-			radeon_do_engine_reset( dev );
-		}
-
-		/* Disable *all* interrupts */
-		RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
-
-		/* Free memory heap structures */
-		radeon_mem_takedown( &(dev_priv->agp_heap) );
-		radeon_mem_takedown( &(dev_priv->fb_heap) );
-
-		/* deallocate kernel resources */
-		radeon_do_cleanup_cp( dev );
-	}
-}
-
 /* Just reset the CP ring.  Called as part of an X Server engine reset.
  */
 int radeon_cp_reset( DRM_IOCTL_ARGS )
@@ -1449,6 +1397,9 @@ int radeon_cp_idle( DRM_IOCTL_ARGS )
 
 	LOCK_TEST_WITH_RETURN( dev );
 
+/* 	if (dev->irq)  */
+/* 		radeon_emit_and_wait_irq( dev ); */
+
 	return radeon_do_cp_idle( dev_priv );
 }
 
@@ -1543,7 +1494,7 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev )
 	drm_buf_t *buf;
 	int i, t;
 	int start;
-	u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1));
+	u32 done_age = DRM_READ32(&dev_priv->scratch[1]);
 
 	if ( ++dev_priv->last_buf >= dma->buf_count )
 		dev_priv->last_buf = 0;
diff --git a/shared/radeon_drv.h b/shared/radeon_drv.h
index 502ba89b..635ad14b 100644
--- a/shared/radeon_drv.h
+++ b/shared/radeon_drv.h
@@ -31,8 +31,8 @@
 #ifndef __RADEON_DRV_H__
 #define __RADEON_DRV_H__
 
-#define GET_RING_HEAD(ring)		DRM_READ32(  (ring)->ring_rptr, 0 ) /* (ring)->head */
-#define SET_RING_HEAD(ring,val)		DRM_WRITE32( (ring)->ring_rptr, 0, (val) ) /* (ring)->head */
+#define GET_RING_HEAD(ring)		DRM_READ32(  (volatile u32 *) (ring)->head )
+#define SET_RING_HEAD(ring,val)		DRM_WRITE32( (volatile u32 *) (ring)->head , (val))
 
 typedef struct drm_radeon_freelist {
    	unsigned int age;
@@ -53,7 +53,6 @@ typedef struct drm_radeon_ring_buffer {
 	int space;
 
 	int high_mark;
-	drm_local_map_t *ring_rptr;
 } drm_radeon_ring_buffer_t;
 
 typedef struct drm_radeon_depth_clear_t {
@@ -127,13 +126,13 @@ typedef struct drm_radeon_private {
 
 	drm_radeon_depth_clear_t depth_clear;
 
-	drm_local_map_t *sarea;
-	drm_local_map_t *fb;
-	drm_local_map_t *mmio;
-	drm_local_map_t *cp_ring;
-	drm_local_map_t *ring_rptr;
-	drm_local_map_t *buffers;
-	drm_local_map_t *agp_textures;
+	drm_map_t *sarea;
+	drm_map_t *fb;
+	drm_map_t *mmio;
+	drm_map_t *cp_ring;
+	drm_map_t *ring_rptr;
+	drm_map_t *buffers;
+	drm_map_t *agp_textures;
 
 	struct mem_block *agp_heap;
 	struct mem_block *fb_heap;
@@ -194,7 +193,6 @@ extern int radeon_emit_and_wait_irq(drm_device_t *dev);
 extern int radeon_wait_irq(drm_device_t *dev, int swi_nr);
 extern int radeon_emit_irq(drm_device_t *dev);
 
-extern void radeon_do_release(drm_device_t *dev);
 
 /* Flags for stats.boxes
  */
@@ -268,10 +266,8 @@ extern void radeon_do_release(drm_device_t *dev);
 #define RADEON_SCRATCH_UMSK		0x0770
 #define RADEON_SCRATCH_ADDR		0x0774
 
-#define RADEON_SCRATCHOFF( x )		(RADEON_SCRATCH_REG_OFFSET + 4*(x))
-
 #define GET_SCRATCH( x )	(dev_priv->writeback_works			\
-				? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \
+				? DRM_READ32( &dev_priv->scratch[(x)] )		\
 				: RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
 
 
@@ -690,10 +686,15 @@ extern void radeon_do_release(drm_device_t *dev);
 
 #define RADEON_RING_HIGH_MARK		128
 
-#define RADEON_READ(reg)	DRM_READ32(  dev_priv->mmio, (reg) )
-#define RADEON_WRITE(reg,val)	DRM_WRITE32( dev_priv->mmio, (reg), (val) )
-#define RADEON_READ8(reg)	DRM_READ8(  dev_priv->mmio, (reg) )
-#define RADEON_WRITE8(reg,val)	DRM_WRITE8( dev_priv->mmio, (reg), (val) )
+
+#define RADEON_BASE(reg)	((unsigned long)(dev_priv->mmio->handle))
+#define RADEON_ADDR(reg)	(RADEON_BASE( reg ) + reg)
+
+#define RADEON_READ(reg)	DRM_READ32(  (volatile u32 *) RADEON_ADDR(reg) )
+#define RADEON_WRITE(reg,val)	DRM_WRITE32( (volatile u32 *) RADEON_ADDR(reg), (val) )
+
+#define RADEON_READ8(reg)	DRM_READ8(  (volatile u8 *) RADEON_ADDR(reg) )
+#define RADEON_WRITE8(reg,val)	DRM_WRITE8( (volatile u8 *) RADEON_ADDR(reg), (val) )
 
 #define RADEON_WRITE_PLL( addr, val )					\
 do {									\
@@ -826,10 +827,43 @@ do {									\
 
 #define RING_LOCALS	int write, _nr; unsigned int mask; u32 *ring;
 
-#define BEGIN_RING( n ) do {						\
+#if defined(__alpha__)
+#  define RADEON_PAD_RING 16 /* pad ring requests to 16 lw boundaries */
+#else
+#  define RADEON_PAD_RING 0
+#endif
+
+#if RADEON_PAD_RING
+# define radeon_pad_size(n) 	\
+	(((RADEON_PAD_RING) - ((n) % (RADEON_PAD_RING))) % (RADEON_PAD_RING))
+# define radeon_pad_ring() do {						\
+	if (RADEON_VERBOSE) {						\
+		DRM_INFO("Padding ring from %d (%x) with %d words\n", 	\
+			 write, write, radeon_pad_size(write));		\
+	}								\
+	switch (radeon_pad_size(write)) {			      	\
+	case 0:  /* aligned */					      	\
+		break;						      	\
+	case 1:  /* 1 word */					      	\
+		OUT_RING(CP_PACKET2());				      	\
+		break;						      	\
+	default: /* >= 2 words */				      	\
+		OUT_RING(CP_PACKET3(0x1000, radeon_pad_size(write) - 1));\
+		write = (write + radeon_pad_size(write)) & mask;	\
+		write &= mask;						\
+		break;						      	\
+	}							      	\
+} while(0)
+#else
+# define radeon_pad_size(n) 0
+# define radeon_pad_ring()
+#endif
+
+#define BEGIN_RING( req_n ) do {					\
+	int n = req_n + radeon_pad_size(req_n);				\
 	if ( RADEON_VERBOSE ) {						\
-		DRM_INFO( "BEGIN_RING( %d ) in %s\n",			\
-			   n, __FUNCTION__ );				\
+		DRM_INFO( "BEGIN_RING( %d (%d) ) in %s\n",		\
+			   n, req_n, __FUNCTION__ );			\
 	}								\
 	if ( dev_priv->ring.space <= (n) * sizeof(u32) ) {		\
                 COMMIT_RING();						\
@@ -846,6 +880,7 @@ do {									\
 		DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n",	\
 			  write, dev_priv->ring.tail );			\
 	}								\
+	radeon_pad_ring();						\
 	if (((dev_priv->ring.tail + _nr) & mask) != write) {		\
 		DRM_ERROR( 						\
 			"ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n",	\
@@ -857,7 +892,7 @@ do {									\
 
 #define COMMIT_RING() do {						\
 	/* Flush writes to ring */					\
-	DRM_READMEMORYBARRIER(dev_priv->mmio);					\
+	DRM_READMEMORYBARRIER();					\
 	GET_RING_HEAD( &dev_priv->ring );				\
 	RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail );		\
 	/* read from PCI bus to ensure correct posting */		\
diff --git a/shared/radeon_mem.c b/shared/radeon_mem.c
index 3a2c8969..5c07c1af 100644
--- a/shared/radeon_mem.c
+++ b/shared/radeon_mem.c
@@ -118,7 +118,7 @@ static void free_block( struct mem_block *p )
 		p->size += q->size;
 		p->next = q->next;
 		p->next->prev = p;
-		DRM_FREE(q, sizeof(*q));
+		DRM_FREE(q);
 	}
 
 	if (p->prev->pid == 0) {
@@ -126,10 +126,20 @@ static void free_block( struct mem_block *p )
 		q->size += p->size;
 		q->next = p->next;
 		q->next->prev = q;
-		DRM_FREE(p, sizeof(*q));
+		DRM_FREE(p);
 	}
 }
 
+static void print_heap( struct mem_block *heap )
+{
+	struct mem_block *p;
+
+	for (p = heap->next ; p != heap ; p = p->next) 
+		DRM_DEBUG("0x%x..0x%x (0x%x) -- owner %d\n",
+			  p->start, p->start + p->size,
+			  p->size, p->pid);
+}
+
 /* Initialize.  How to check for an uninitialized heap?
  */
 static int init_heap(struct mem_block **heap, int start, int size)
@@ -141,7 +151,7 @@ static int init_heap(struct mem_block **heap, int start, int size)
 	
 	*heap = DRM_MALLOC(sizeof(**heap));
 	if (!*heap) {
-		DRM_FREE( blocks, sizeof(*blocks) );
+		DRM_FREE( blocks );
 		return -ENOMEM;
 	}
 
@@ -181,7 +191,7 @@ void radeon_mem_release( struct mem_block *heap )
 			p->size += q->size;
 			p->next = q->next;
 			p->next->prev = p;
-			DRM_FREE(q, sizeof(*q));
+			DRM_FREE(q);
 		}
 	}
 }
@@ -198,10 +208,10 @@ void radeon_mem_takedown( struct mem_block **heap )
 	for (p = (*heap)->next ; p != *heap ; ) {
 		struct mem_block *q = p;
 		p = p->next;
-		DRM_FREE(q, sizeof(*q));
+		DRM_FREE(q);
 	}
 
-	DRM_FREE( *heap, sizeof(**heap) );
+	DRM_FREE( *heap );
 	*heap = 0;
 }
 
-- 
cgit v1.2.3