## Automatically generated incremental diff
## From:   linux-2.2.18-pre23
## To:     linux-2.2.18-pre24
## Robot:  $Id: make-incremental-diff,v 1.6 2001/12/04 04:41:15 hpa Exp $

diff -urN linux-2.2.18-pre23/Makefile linux/Makefile
--- linux-2.2.18-pre23/Makefile	Mon Dec  3 20:44:34 2001
+++ linux/Makefile	Mon Dec  3 20:45:21 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 2
 SUBLEVEL = 18
-EXTRAVERSION = pre23
+EXTRAVERSION = pre24
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
diff -urN linux-2.2.18-pre23/arch/alpha/boot/Makefile linux/arch/alpha/boot/Makefile
--- linux-2.2.18-pre23/arch/alpha/boot/Makefile	Mon Oct 12 11:40:12 1998
+++ linux/arch/alpha/boot/Makefile	Mon Dec  3 20:45:21 2001
@@ -80,7 +80,7 @@
 	$(OBJSTRIP) -vb bootpheader tools/bootph
 
 $(OBJSTRIP): $(OBJSTRIP).c
-	$(HOSTCC) $(OBJSTRIP).c -o $(OBJSTRIP)
+	$(HOSTCC) -I$(HPATH) $(OBJSTRIP).c -o $(OBJSTRIP)
 
 tools/mkbb: tools/mkbb.c
 	$(HOSTCC) tools/mkbb.c -o tools/mkbb
diff -urN linux-2.2.18-pre23/arch/alpha/kernel/alpha_ksyms.c linux/arch/alpha/kernel/alpha_ksyms.c
--- linux-2.2.18-pre23/arch/alpha/kernel/alpha_ksyms.c	Mon Dec  3 20:44:34 2001
+++ linux/arch/alpha/kernel/alpha_ksyms.c	Mon Dec  3 20:45:21 2001
@@ -210,5 +210,6 @@
 EXPORT_SYMBOL_NOVERS(__remqu);
 EXPORT_SYMBOL_NOVERS(memcpy);
 EXPORT_SYMBOL_NOVERS(memset);
+EXPORT_SYMBOL_NOVERS(memscan);
 
 
diff -urN linux-2.2.18-pre23/arch/i386/kernel/dmi_scan.c linux/arch/i386/kernel/dmi_scan.c
--- linux-2.2.18-pre23/arch/i386/kernel/dmi_scan.c	Mon Dec  3 20:44:34 2001
+++ linux/arch/i386/kernel/dmi_scan.c	Mon Dec  3 20:45:21 2001
@@ -31,7 +31,7 @@
 	char *buf;
 	struct dmi_header *dm;
 	u8 *data;
-	int i=0;
+	int i=1;
 		
 		
 	buf = ioremap(base, len);
@@ -124,8 +124,8 @@
 			 */
 			 
 			if(strcmp(dmi_string(dm, data[4]), "Phoenix Technologies LTD")==0 &&
-			   strcmp(dmi_string(dm, data[5]), "A04")==0)
-//			   &&strcmp(dmi_string(dm, data[8]), "???")==0)
+			   strcmp(dmi_string(dm, data[5]), "A04")==0 &&
+			   strcmp(dmi_string(dm, data[8]), "08/24/2000")==0)
 			{
 #ifdef CONFIG_APM
 				extern void apm_battery_horked(void);
diff -urN linux-2.2.18-pre23/drivers/char/Makefile linux/drivers/char/Makefile
--- linux-2.2.18-pre23/drivers/char/Makefile	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/Makefile	Mon Dec  3 20:45:22 2001
@@ -11,7 +11,7 @@
 
 SUB_DIRS     := 
 MOD_SUB_DIRS := $(SUB_DIRS)
-ALL_SUB_DIRS := $(SUB_DIRS) rio ftape joystick drm agp
+ALL_SUB_DIRS := $(SUB_DIRS) rio ftape joystick
 
 #
 # This file contains the font map for the default (hardware) font
@@ -386,6 +386,18 @@
   endif
 endif
 
+ifeq ($(CONFIG_DRM),y)
+O_OBJS += drm/drm.o
+ALL_SUB_DIRS += drm
+MOD_SUB_DIRS += drm
+SUB_DIRS += drm
+else
+  ifeq ($(CONFIG_DRM),m)
+  ALL_SUB_DIRS += drm
+  MOD_SUB_DIRS += drm
+  endif
+endif
+
 ifeq ($(CONFIG_INTEL_RNG),y)
 O_OBJS += i810_rng.o
 else
@@ -641,18 +653,6 @@
 ifdef CONFIG_H8
 OX_OBJS += h8.o
 endif
-
-
-ifeq ($(CONFIG_DRM),y)
-SUB_DIRS += drm
-O_OBJS += drm/drm.o
-MOD_SUB_DIRS += drm
-else
-  ifeq ($(CONFIG_DRM),m)
-  MOD_SUB_DIRS += drm
-  endif
-endif
-
 
 ifeq ($(L_I2C),y)
 OX_OBJS += i2c.o
diff -urN linux-2.2.18-pre23/drivers/char/drm/agpsupport.c linux/drivers/char/drm/agpsupport.c
--- linux-2.2.18-pre23/drivers/char/drm/agpsupport.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/agpsupport.c	Mon Dec  3 20:45:22 2001
@@ -287,6 +287,10 @@
 			return NULL;
 		memset((void *)head, 0, sizeof(*head));
 		(*drm_agp.copy_info)(&head->agp_info);
+		if (head->agp_info.chipset == NOT_SUPPORTED) {
+			drm_free(head, sizeof(*head), DRM_MEM_AGPLISTS);
+			return NULL;
+		}
 		head->memory = NULL;
 		switch (head->agp_info.chipset) {
 		case INTEL_GENERIC:    head->chipset = "Intel";            break;
@@ -294,20 +298,31 @@
 		case INTEL_BX:         head->chipset = "Intel 440BX";      break;
 		case INTEL_GX:         head->chipset = "Intel 440GX";      break;
 		case INTEL_I810:       head->chipset = "Intel i810";       break;
+#if LINUX_VERSION_CODE >= 0x020400
+		case INTEL_I840:       head->chipset = "Intel i840";       break;
+#endif
+
 		case VIA_GENERIC:      head->chipset = "VIA";              break;
 		case VIA_VP3:          head->chipset = "VIA VP3";          break;
 		case VIA_MVP3:         head->chipset = "VIA MVP3";         break;
+#if LINUX_VERSION_CODE >= 0x020400
+		case VIA_MVP4:         head->chipset = "VIA MVP4";         break;
+#endif
 		case VIA_APOLLO_PRO:   head->chipset = "VIA Apollo Pro";   break;
 		case VIA_APOLLO_KX133: head->chipset = "VIA Apollo KX133"; break;
 		case VIA_APOLLO_KT133: head->chipset = "VIA Apollo KT133"; break;
+
 		case SIS_GENERIC:      head->chipset = "SiS";              break;
+
 		case AMD_GENERIC:      head->chipset = "AMD";              break;
 		case AMD_IRONGATE:     head->chipset = "AMD Irongate";     break;
+
 		case ALI_GENERIC:      head->chipset = "ALi";              break;
 		case ALI_M1541:        head->chipset = "ALi M1541";        break;
-		default:
+
+		default:               head->chipset = "Unknown";          break;
 		}
-		DRM_INFO("AGP %d.%d on %s @ 0x%08lx %dMB\n",
+		DRM_INFO("AGP %d.%d on %s @ 0x%08lx %uMB\n",
 			 head->agp_info.version.major,
 			 head->agp_info.version.minor,
 			 head->chipset,
diff -urN linux-2.2.18-pre23/drivers/char/drm/auth.c linux/drivers/char/drm/auth.c
--- linux-2.2.18-pre23/drivers/char/drm/auth.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/auth.c	Mon Dec  3 20:45:22 2001
@@ -126,12 +126,12 @@
 	if (priv->magic) {
 		auth.magic = priv->magic;
 	} else {
-		spin_lock(&lock);
 		do {
+			spin_lock(&lock);
 			if (!sequence) ++sequence; /* reserve 0 */
 			auth.magic = sequence++;
+			spin_unlock(&lock);
 		} while (drm_find_file(dev, auth.magic));
-		spin_unlock(&lock);
 		priv->magic = auth.magic;
 		drm_add_magic(dev, priv, auth.magic);
 	}
diff -urN linux-2.2.18-pre23/drivers/char/drm/bufs.c linux/drivers/char/drm/bufs.c
--- linux-2.2.18-pre23/drivers/char/drm/bufs.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/bufs.c	Mon Dec  3 20:45:22 2001
@@ -73,7 +73,7 @@
 	switch (map->type) {
 	case _DRM_REGISTERS:
 	case _DRM_FRAME_BUFFER:
-#ifndef __sparc__
+#if !defined(__sparc__) && !defined(__alpha__)
 		if (map->offset + map->size < map->offset
 		    || map->offset < virt_to_phys(high_memory)) {
 			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
diff -urN linux-2.2.18-pre23/drivers/char/drm/dma.c linux/drivers/char/drm/dma.c
--- linux-2.2.18-pre23/drivers/char/drm/dma.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/dma.c	Mon Dec  3 20:45:22 2001
@@ -397,10 +397,10 @@
 
 	atomic_inc(&q->use_count);
 	if (atomic_read(&q->block_write)) {
-		current->state = TASK_INTERRUPTIBLE;
 		add_wait_queue(&q->write_queue, &entry);
 		atomic_inc(&q->block_count);
 		for (;;) {
+			current->state = TASK_INTERRUPTIBLE;
 			if (!atomic_read(&q->block_write)) break;
 			schedule();
 			if (signal_pending(current)) {
diff -urN linux-2.2.18-pre23/drivers/char/drm/drmP.h linux/drivers/char/drm/drmP.h
--- linux-2.2.18-pre23/drivers/char/drm/drmP.h	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/drmP.h	Mon Dec  3 20:45:22 2001
@@ -33,6 +33,11 @@
 #define _DRM_P_H_
 
 #ifdef __KERNEL__
+#ifdef __alpha__
+/* add include of current.h so that "current" is defined
+ * before static inline funcs in wait.h. 4/21/2000 S + B */
+#include <asm/current.h>
+#endif /* __alpha__ */
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -46,10 +51,13 @@
 #include <linux/version.h>
 #include <linux/sched.h>
 #include <linux/smp_lock.h>	/* For (un)lock_kernel */
+#include <linux/mm.h>
+#ifdef __alpha__
+#include <asm/pgtable.h> /* For pte_wrprotect */
+#endif
 #include <asm/io.h>
 #include <asm/mman.h>
 #include <asm/uaccess.h>
-#include <asm/pgtable.h>
 #ifdef CONFIG_MTRR
 #include <asm/mtrr.h>
 #endif
@@ -132,10 +140,25 @@
 #define NOPAGE_OOM 0
 #endif
 
+				/* module_init/module_exit added in 2.3.13 */
+#ifndef module_init
+#define module_init(x)  int init_module(void) { return x(); }
+#endif
+#ifndef module_exit
+#define module_exit(x)  void cleanup_module(void) { x(); }
+#endif
+
+				/* virt_to_page added in 2.4.0-test6 */
+#if LINUX_VERSION_CODE < 0x020400
+#define virt_to_page(kaddr) (mem_map + MAP_NR(kaddr))
+#endif
+
 				/* Generic cmpxchg added in 2.3.x */
 #ifndef __HAVE_ARCH_CMPXCHG
 				/* Include this here so that driver can be
                                    used with older kernels. */
+
+#if __i386__
 static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
 				      unsigned long new, int size)
 {
@@ -166,6 +189,7 @@
 #define cmpxchg(ptr,o,n)						\
   ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),		\
 				 (unsigned long)(n),sizeof(*(ptr))))
+#endif /* i386 */
 #endif
 
 				/* Macros to make printk easier */
@@ -315,6 +339,7 @@
 	int		  low_mark;    /* Low water mark		   */
 	int		  high_mark;   /* High water mark		   */
 	atomic_t	  wfh;	       /* If waiting for high mark	   */
+	spinlock_t        lock;
 } drm_freelist_t;
 
 typedef struct drm_buf_entry {
@@ -343,6 +368,7 @@
 	struct drm_file	  *next;
 	struct drm_file	  *prev;
 	struct drm_device *dev;
+	int 		  remove_auth_on_close;
 } drm_file_t;
 
 
@@ -551,6 +577,9 @@
 extern unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma,
 				       unsigned long address,
 				       int write_access);
+extern unsigned long drm_vm_shm_nopage_lock(struct vm_area_struct *vma,
+					    unsigned long address,
+					    int write_access);
 extern unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma,
 				       unsigned long address,
 				       int write_access);
@@ -562,6 +591,9 @@
 extern struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
 				      unsigned long address,
 				      int write_access);
+extern struct page *drm_vm_shm_nopage_lock(struct vm_area_struct *vma,
+					   unsigned long address,
+					   int write_access);
 extern struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
 				      unsigned long address,
 				      int write_access);
@@ -571,9 +603,7 @@
 extern int	     drm_mmap_dma(struct file *filp,
 				  struct vm_area_struct *vma);
 extern int	     drm_mmap(struct file *filp, struct vm_area_struct *vma);
-extern struct vm_operations_struct drm_vm_ops;
-extern struct vm_operations_struct drm_vm_shm_ops;
-extern struct vm_operations_struct drm_vm_dma_ops;
+
 
 				/* Proc support (proc.c) */
 extern int	     drm_proc_init(drm_device_t *dev);
diff -urN linux-2.2.18-pre23/drivers/char/drm/ffb_drv.c linux/drivers/char/drm/ffb_drv.c
--- linux-2.2.18-pre23/drivers/char/drm/ffb_drv.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/ffb_drv.c	Mon Dec  3 20:45:22 2001
@@ -648,6 +648,7 @@
 
 	add_wait_queue(&dev->lock.lock_queue, &entry);
 	for (;;) {
+		current->state = TASK_INTERRUPTIBLE;
 		if (!dev->lock.hw_lock) {
 			/* Device has been unregistered */
 			ret = -EINTR;
@@ -663,7 +664,6 @@
                         
 		/* Contention */
 		atomic_inc(&dev->total_sleeps);
-		current->state = TASK_INTERRUPTIBLE;
 		current->policy |= SCHED_YIELD;
 		schedule();
 		if (signal_pending(current)) {
diff -urN linux-2.2.18-pre23/drivers/char/drm/gamma_dma.c linux/drivers/char/drm/gamma_dma.c
--- linux-2.2.18-pre23/drivers/char/drm/gamma_dma.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/gamma_dma.c	Mon Dec  3 20:45:22 2001
@@ -542,8 +542,8 @@
 	
 	if (d->flags & _DRM_DMA_BLOCK) {
 		DRM_DEBUG("%d waiting\n", current->pid);
-		current->state = TASK_INTERRUPTIBLE;
 		for (;;) {
+			current->state = TASK_INTERRUPTIBLE;
 			if (!last_buf->waiting
 			    && !last_buf->pending)
 				break; /* finished */
@@ -774,6 +774,7 @@
 		}
 		add_wait_queue(&dev->lock.lock_queue, &entry);
 		for (;;) {
+			current->state = TASK_INTERRUPTIBLE;
 			if (!dev->lock.hw_lock) {
 				/* Device has been unregistered */
 				ret = -EINTR;
@@ -790,7 +791,6 @@
 			
 				/* Contention */
 			atomic_inc(&dev->total_sleeps);
-			current->state = TASK_INTERRUPTIBLE;
 			schedule();
 			if (signal_pending(current)) {
 				ret = -ERESTARTSYS;
diff -urN linux-2.2.18-pre23/drivers/char/drm/gamma_drv.c linux/drivers/char/drm/gamma_drv.c
--- linux-2.2.18-pre23/drivers/char/drm/gamma_drv.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/gamma_drv.c	Mon Dec  3 20:45:22 2001
@@ -57,8 +57,8 @@
 static drm_device_t	      gamma_device;
 
 static struct file_operations gamma_fops = {
-#if LINUX_VERSION_CODE >= 0x020322
-				/* This started being used approx. 2.3.34 */
+#if LINUX_VERSION_CODE >= 0x020400
+				/* This started being used during 2.4.0-test */
 	owner:   THIS_MODULE,
 #endif
 	open:	 gamma_open,
diff -urN linux-2.2.18-pre23/drivers/char/drm/i810_dma.c linux/drivers/char/drm/i810_dma.c
--- linux-2.2.18-pre23/drivers/char/drm/i810_dma.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/i810_dma.c	Mon Dec  3 20:45:22 2001
@@ -282,8 +282,8 @@
 	if(address == 0UL) 
 		return 0;
 	
-	atomic_inc(&mem_map[MAP_NR((void *) address)].count);
-	set_bit(PG_locked, &mem_map[MAP_NR((void *) address)].flags);
+	atomic_inc(&virt_to_page(address)->count);
+	set_bit(PG_locked, &virt_to_page(address)->flags);
    
 	return address;
 }
@@ -293,9 +293,9 @@
 	if(page == 0UL) 
 		return;
 	
-	atomic_dec(&mem_map[MAP_NR((void *) page)].count);
-	clear_bit(PG_locked, &mem_map[MAP_NR((void *) page)].flags);
-	wake_up(&mem_map[MAP_NR((void *) page)].wait);
+	atomic_dec(&virt_to_page(page)->count);
+	clear_bit(PG_locked, &virt_to_page(page)->flags);
+	wake_up(&virt_to_page(page)->wait);
 	free_page(page);
 	return;
 }
@@ -1068,11 +1068,11 @@
 	   	return;
 	}
       	atomic_set(&dev_priv->flush_done, 0);
-   	current->state = TASK_INTERRUPTIBLE;
    	add_wait_queue(&dev_priv->flush_queue, &entry);
    	end = jiffies + (HZ*3);
    
    	for (;;) {
+		current->state = TASK_INTERRUPTIBLE;
 	      	i810_dma_quiescent_emit(dev);
 	   	if (atomic_read(&dev_priv->flush_done) == 1) break;
 		if((signed)(end - jiffies) <= 0) {
@@ -1103,10 +1103,10 @@
 	   	return 0;
 	}
       	atomic_set(&dev_priv->flush_done, 0);
-   	current->state = TASK_INTERRUPTIBLE;
    	add_wait_queue(&dev_priv->flush_queue, &entry);
    	end = jiffies + (HZ*3);
    	for (;;) {
+		current->state = TASK_INTERRUPTIBLE;
 	      	i810_dma_emit_flush(dev);
 	   	if (atomic_read(&dev_priv->flush_done) == 1) break;
 		if((signed)(end - jiffies) <= 0) {
@@ -1199,6 +1199,7 @@
 	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;
@@ -1214,7 +1215,6 @@
 			
 				/* Contention */
 			atomic_inc(&dev->total_sleeps);
-			current->state = TASK_INTERRUPTIBLE;
 		   	DRM_DEBUG("Calling lock schedule\n");
 			schedule();
 			if (signal_pending(current)) {
diff -urN linux-2.2.18-pre23/drivers/char/drm/i810_drv.c linux/drivers/char/drm/i810_drv.c
--- linux-2.2.18-pre23/drivers/char/drm/i810_drv.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/i810_drv.c	Mon Dec  3 20:45:22 2001
@@ -514,6 +514,7 @@
 	   	DECLARE_WAITQUEUE(entry, current);
 	   	add_wait_queue(&dev->lock.lock_queue, &entry);
 		for (;;) {
+			current->state = TASK_INTERRUPTIBLE;
 			if (!dev->lock.hw_lock) {
 				/* Device has been unregistered */
 				retcode = -EINTR;
@@ -528,7 +529,6 @@
 			}			
 				/* Contention */
 			atomic_inc(&dev->total_sleeps);
-			current->state = TASK_INTERRUPTIBLE;
 			schedule();
 			if (signal_pending(current)) {
 				retcode = -ERESTARTSYS;
diff -urN linux-2.2.18-pre23/drivers/char/drm/lists.c linux/drivers/char/drm/lists.c
--- linux-2.2.18-pre23/drivers/char/drm/lists.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/lists.c	Mon Dec  3 20:45:22 2001
@@ -116,6 +116,7 @@
 	bl->low_mark  = 0;
 	bl->high_mark = 0;
 	atomic_set(&bl->wfh,   0);
+	bl->lock      = SPIN_LOCK_UNLOCKED;
 	++bl->initialized;
 	return 0;
 }
@@ -130,8 +131,6 @@
 
 int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
 {
-	drm_buf_t        *old, *prev;
-	int		 count = 0;
 	drm_device_dma_t *dma  = dev->dma;
 
 	if (!dma) {
@@ -152,15 +151,12 @@
 	drm_histogram_compute(dev, buf);
 #endif
 	buf->list	= DRM_LIST_FREE;
-	do {
-		old       = bl->next;
-		buf->next = old;
-		prev      = cmpxchg(&bl->next, old, buf);
-		if (++count > DRM_LOOPING_LIMIT) {
-			DRM_ERROR("Looping\n");
-			return 1;
-		}
-	} while (prev != old);
+	
+	spin_lock(&bl->lock);
+	buf->next	= bl->next;
+	bl->next	= buf;
+	spin_unlock(&bl->lock);
+	
 	atomic_inc(&bl->count);
 	if (atomic_read(&bl->count) > dma->buf_count) {
 		DRM_ERROR("%d of %d buffers free after addition of %d\n",
@@ -177,31 +173,23 @@
 
 static drm_buf_t *drm_freelist_try(drm_freelist_t *bl)
 {
-	drm_buf_t         *old, *new, *prev;
 	drm_buf_t	  *buf;
-	int		  count = 0;
 
 	if (!bl) return NULL;
 	
 				/* Get buffer */
-	do {
-		old = bl->next;
-		if (!old) return NULL;
-		new  = bl->next->next;
-		prev = cmpxchg(&bl->next, old, new);
-		if (++count > DRM_LOOPING_LIMIT) {
-			DRM_ERROR("Looping\n");
-			return NULL;
-		}
-	} while (prev != old);
-	atomic_dec(&bl->count);
+	spin_lock(&bl->lock);
+	if (!bl->next) {
+		spin_unlock(&bl->lock);
+		return NULL;
+	}
+	buf	  = bl->next;
+	bl->next  = bl->next->next;
+	spin_unlock(&bl->lock);
 	
-	buf	  = old;
+	atomic_dec(&bl->count);
 	buf->next = NULL;
 	buf->list = DRM_LIST_NONE;
-	DRM_DEBUG("%d, count = %d, wfh = %d, w%d, p%d\n",
-		  buf->idx, atomic_read(&bl->count), atomic_read(&bl->wfh),
-		  buf->waiting, buf->pending);
 	if (buf->waiting || buf->pending) {
 		DRM_ERROR("Free buffer %d: w%d, p%d, l%d\n",
 			  buf->idx, buf->waiting, buf->pending, buf->list);
@@ -221,13 +209,10 @@
 	if (atomic_read(&bl->count) <= bl->low_mark) /* Became low */
 		atomic_set(&bl->wfh, 1);
 	if (atomic_read(&bl->wfh)) {
-		DRM_DEBUG("Block = %d, count = %d, wfh = %d\n",
-			  block, atomic_read(&bl->count),
-			  atomic_read(&bl->wfh));
 		if (block) {
 			add_wait_queue(&bl->waiting, &entry);
-			current->state = TASK_INTERRUPTIBLE;
 			for (;;) {
+				current->state = TASK_INTERRUPTIBLE;
 				if (!atomic_read(&bl->wfh)
 				    && (buf = drm_freelist_try(bl))) break;
 				schedule();
diff -urN linux-2.2.18-pre23/drivers/char/drm/lock.c linux/drivers/char/drm/lock.c
--- linux-2.2.18-pre23/drivers/char/drm/lock.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/lock.c	Mon Dec  3 20:45:22 2001
@@ -128,10 +128,10 @@
 	atomic_inc(&q->use_count);
 	if (atomic_read(&q->use_count) > 1) {
 		atomic_inc(&q->block_write);
-		current->state = TASK_INTERRUPTIBLE;
 		add_wait_queue(&q->flush_queue, &entry);
 		atomic_inc(&q->block_count);
 		for (;;) {
+			current->state = TASK_INTERRUPTIBLE;
 			if (!DRM_BUFCOUNT(&q->waitlist)) break;
 			schedule();
 			if (signal_pending(current)) {
diff -urN linux-2.2.18-pre23/drivers/char/drm/memory.c linux/drivers/char/drm/memory.c
--- linux-2.2.18-pre23/drivers/char/drm/memory.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/memory.c	Mon Dec  3 20:45:22 2001
@@ -32,6 +32,7 @@
 #define __NO_VERSION__
 #include <linux/config.h>
 #include "drmP.h"
+#include <linux/wrapper.h>
 
 typedef struct drm_mem_stats {
 	const char	  *name;
@@ -246,7 +247,12 @@
 	for (addr = address, sz = bytes;
 	     sz > 0;
 	     addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+#if LINUX_VERSION_CODE >= 0x020400
+				/* Argument type changed in 2.4.0-test6/pre8 */
+		mem_map_reserve(virt_to_page(addr));
+#else
 		mem_map_reserve(MAP_NR(addr));
+#endif
 	}
 	
 	return address;
@@ -267,7 +273,12 @@
 		for (addr = address, sz = bytes;
 		     sz > 0;
 		     addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+#if LINUX_VERSION_CODE >= 0x020400
+				/* Argument type changed in 2.4.0-test6/pre8 */
+			mem_map_unreserve(virt_to_page(addr));
+#else
 			mem_map_unreserve(MAP_NR(addr));
+#endif
 		}
 		free_pages(address, order);
 	}
diff -urN linux-2.2.18-pre23/drivers/char/drm/mga_context.c linux/drivers/char/drm/mga_context.c
--- linux-2.2.18-pre23/drivers/char/drm/mga_context.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/mga_context.c	Mon Dec  3 20:45:22 2001
@@ -195,6 +195,10 @@
 
 	copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
 	DRM_DEBUG("%d\n", ctx.handle);
+	if(ctx.handle == DRM_KERNEL_CONTEXT+1) {
+		priv->remove_auth_on_close = 1;
+	}
+
       	if(ctx.handle != DRM_KERNEL_CONTEXT) {
 	   	drm_ctxbitmap_free(dev, ctx.handle);
 	}
diff -urN linux-2.2.18-pre23/drivers/char/drm/mga_dma.c linux/drivers/char/drm/mga_dma.c
--- linux-2.2.18-pre23/drivers/char/drm/mga_dma.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/mga_dma.c	Mon Dec  3 20:45:22 2001
@@ -52,45 +52,28 @@
 {
 	unsigned long address;
    
-	DRM_DEBUG("%s\n", __FUNCTION__);
 	address = __get_free_page(GFP_KERNEL);
 	if(address == 0UL) {
 		return 0;
 	}
-	atomic_inc(&mem_map[MAP_NR((void *) address)].count);
-	set_bit(PG_locked, &mem_map[MAP_NR((void *) address)].flags);
+	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)
 {
-	DRM_DEBUG("%s\n", __FUNCTION__);
-
-	if(page == 0UL) {
-		return;
-	}
-	atomic_dec(&mem_map[MAP_NR((void *) page)].count);
-	clear_bit(PG_locked, &mem_map[MAP_NR((void *) page)].flags);
-	wake_up(&mem_map[MAP_NR((void *) page)].wait);
+	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;
-}
-
-void mga_flush_write_combine(void)
-{
-   	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 */ );
+	return;
 }
 
 /* These are two age tags that will never be sent to
@@ -164,7 +147,7 @@
    	unsigned long end;
 	int i;
 
-	DRM_DEBUG("%s\n", __FUNCTION__);
+	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, 
@@ -175,7 +158,9 @@
 			DRM_ERROR("irqs: %d wanted %d\n", 
 				  atomic_read(&dev->total_irq), 
 				  atomic_read(&dma->total_lost));
-			DRM_ERROR("lockup\n"); 
+			DRM_ERROR("lockup: dispatch_status = 0x%02x,"
+				  " jiffies = %lu, end = %lu\n",
+				  dev_priv->dispatch_status, jiffies, end);
 			goto out_nolock;
 		}
 		for (i = 0 ; i < 2000 ; i++) mga_delay();
@@ -225,31 +210,31 @@
 	drm_mga_freelist_t *prev;
    	drm_mga_freelist_t *next;
 	static int failed = 0;
+	int return_null = 0;
 
-	DRM_DEBUG("%s : tail->age : %d last_prim_age : %d\n", __FUNCTION__,
-	       dev_priv->tail->age, dev_priv->last_prim_age);
-   
 	if(failed >= 1000 && dev_priv->tail->age >= dev_priv->last_prim_age) {
-		DRM_DEBUG("I'm waiting on the freelist!!! %d\n", 
-		       dev_priv->last_prim_age);
-	   	set_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
-		current->state = TASK_INTERRUPTIBLE;
+		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(!test_bit(MGA_IN_GETBUF, 
-				     &dev_priv->dispatch_status)) 
+			if(dev_priv->tail->age < dev_priv->last_prim_age)
 				break;
 		   	atomic_inc(&dev->total_sleeps);
 		   	schedule();
 		   	if (signal_pending(current)) {
-				clear_bit(MGA_IN_GETBUF,
-					  &dev_priv->dispatch_status);
-			   	goto failed_getbuf;
+				++return_null;
+				break;
 			}
 		}
-	   	current->state = TASK_RUNNING;
+		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) {
@@ -263,7 +248,6 @@
 	   	return next->buf;
 	}
 
-failed_getbuf:
 	failed++;
    	return NULL;
 }
@@ -312,7 +296,6 @@
    	int i, temp, size_of_buf;
    	int offset = init->reserved_map_agpstart;
 
-	DRM_DEBUG("%s\n", __FUNCTION__);
    	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;
@@ -333,13 +316,13 @@
 	dev_priv->ioremap = drm_ioremap(dev->agp->base + offset, 
 					temp);
 	if(dev_priv->ioremap == NULL) {
-		DRM_DEBUG("Ioremap failed\n");
+		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), 
+	   	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));
@@ -474,9 +457,8 @@
    
    	if(test_and_set_bit(MGA_BUF_IN_USE, &prim_buffer->buffer_status)) {
 	   	add_wait_queue(&dev_priv->wait_queue, &entry);
-		current->state = TASK_INTERRUPTIBLE;
-
 	   	for (;;) {
+			current->state = TASK_INTERRUPTIBLE;
 		   	mga_dma_schedule(dev, 0);
 		   	if(!test_and_set_bit(MGA_BUF_IN_USE, 
 					     &prim_buffer->buffer_status)) 
@@ -521,61 +503,51 @@
 static inline int mga_decide_to_fire(drm_device_t *dev)
 {
    	drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
-      	drm_device_dma_t  *dma	    = dev->dma;
-
-   	DRM_DEBUG("%s\n", __FUNCTION__);
 
    	if(test_bit(MGA_BUF_FORCE_FIRE, &dev_priv->next_prim->buffer_status)) {
-	   	atomic_inc(&dma->total_prio);
 	   	return 1;
 	}
 
 	if (test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status) &&
 	    dev_priv->next_prim->num_dwords) {
-	   	atomic_inc(&dma->total_prio);
 	   	return 1;
 	}
 
 	if (test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) &&
 	    dev_priv->next_prim->num_dwords) {
-	   	atomic_inc(&dma->total_prio);
 	   	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)) {
-			atomic_inc(&dma->total_dmas);
 			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) {
-			atomic_inc(&dma->total_hit);
 			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) {
-			atomic_inc(&dma->total_missed_free);
 			return 1;
 		}
 	}
 
-   	atomic_inc(&dma->total_tried);
    	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;
-      	drm_device_dma_t  *dma	    = dev->dma;
-	int retval = 0;
+	int               retval    = 0;
 
-   	if (test_and_set_bit(0, &dev->dma_flag)) {
-		atomic_inc(&dma->total_missed_dma);
+   	if (!dev_priv) return -EBUSY;
+	
+	if (test_and_set_bit(0, &dev->dma_flag)) {
 		retval = -EBUSY;
 		goto sch_out_wakeup;
 	}
@@ -590,18 +562,14 @@
    
    	if (!locked && 
 	    !drm_lock_take(&dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) {
-	   	atomic_inc(&dma->total_missed_lock);
 	   	clear_bit(0, &dev->dma_flag);
-		DRM_DEBUG("Not locked\n");
 		retval = -EBUSY;
 		goto sch_out_wakeup;
 	}
-   	DRM_DEBUG("I'm locked\n");
 
    	if(!test_and_set_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status)) {
 	   	/* Fire dma buffer */
 	   	if(mga_decide_to_fire(dev)) {
-		   	DRM_DEBUG("idx :%d\n", dev_priv->next_prim->idx);
 			clear_bit(MGA_BUF_FORCE_FIRE, 
 				  &dev_priv->next_prim->buffer_status);
 		   	if(dev_priv->current_prim == dev_priv->next_prim) {
@@ -613,8 +581,6 @@
 		} else {
 			clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
 		}
-	} else {
-		DRM_DEBUG("I can't get the dispatch lock\n");
 	}
    	
 	if (!locked) {
@@ -624,6 +590,8 @@
 		}
 	}
 
+	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) {
@@ -633,17 +601,9 @@
 	}
 
 	if(test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status) &&
-	   dev_priv->tail->age < dev_priv->last_prim_age) {
-		clear_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
-		DRM_DEBUG("Waking up buf queue\n");
+	   dev_priv->tail->age < dev_priv->last_prim_age)
 		wake_up_interruptible(&dev_priv->buf_queue);
-	} else if (test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)) {
-	   	DRM_DEBUG("Not waking buf_queue on %d %d\n", 
-			  atomic_read(&dev->total_irq), 
-			  dev_priv->last_prim_age);
-	}
 
-   	clear_bit(0, &dev->dma_flag);
 	return retval;
 }
 
@@ -653,7 +613,6 @@
     	drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
     	drm_mga_prim_buf_t *last_prim_buffer;
 
-	DRM_DEBUG("%s\n", __FUNCTION__);
     	atomic_inc(&dev->total_irq);
 	if((MGA_READ(MGAREG_STATUS) & 0x00000001) != 0x00000001) return;
       	MGA_WRITE(MGAREG_ICLEAR, 0x00000001);
@@ -663,28 +622,28 @@
 	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);
-   	wake_up_interruptible(&dev_priv->wait_queue);
       	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)
 {
-	DRM_DEBUG("%s\n", __FUNCTION__);
 	mga_dma_schedule((drm_device_t *)device, 0);
 }
 
 int mga_dma_cleanup(drm_device_t *dev)
 {
-	DRM_DEBUG("%s\n", __FUNCTION__);
-
 	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 + 
@@ -727,9 +686,6 @@
 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;
-	int i;
-
-	DRM_DEBUG("%s\n", __FUNCTION__);
 
 	dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
 	if(dev_priv == NULL) return -ENOMEM;
@@ -765,24 +721,18 @@
 	dev_priv->mAccess = init->mAccess;
    	init_waitqueue_head(&dev_priv->flush_queue);
 	init_waitqueue_head(&dev_priv->buf_queue);
-	dev_priv->WarpPipe = -1;
+	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, 
+   	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);
 
-   	for (i = 0 ; i < MGA_MAX_WARP_PIPES ; i++) 
-		DRM_DEBUG("warp pipe %d: installed: %d phys: %lx size: %x\n",
-			  i, 
-			  dev_priv->WarpIndex[i].installed,
-			  dev_priv->WarpIndex[i].phys_addr,
-			  dev_priv->WarpIndex[i].size);
+	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");
@@ -952,18 +902,16 @@
   	drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
    	int ret = 0;
 
-   	DRM_DEBUG("%s\n", __FUNCTION__);
+   	if(!dev_priv) return 0;
 
-   	if(dev_priv == NULL) {
-	   	return 0;
-	}
-   
    	if(dev_priv->next_prim->num_dwords != 0) {
-   		current->state = TASK_INTERRUPTIBLE;
    		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;
@@ -992,7 +940,8 @@
       	if(dev->dev_private == NULL) return;
 	if(dma->buflist == NULL) return;
 
-	DRM_DEBUG("%s\n", __FUNCTION__);
+	DRM_DEBUG("buf_count=%d\n", dma->buf_count);
+	
         mga_flush_queue(dev);
 
 	for (i = 0; i < dma->buf_count; i++) {
@@ -1041,6 +990,7 @@
 	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;
@@ -1056,7 +1006,6 @@
 			
 				/* Contention */
 			atomic_inc(&dev->total_sleeps);
-			current->state = TASK_INTERRUPTIBLE;
 			schedule();
 			if (signal_pending(current)) {
 				ret = -ERESTARTSYS;
@@ -1075,7 +1024,8 @@
 		}
 	}
    
-	DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
+	if (ret) DRM_DEBUG("%d %s\n", lock.context,
+			   ret ? "interrupted" : "has lock");
 	return ret;
 }
 		
diff -urN linux-2.2.18-pre23/drivers/char/drm/mga_drm.h linux/drivers/char/drm/mga_drm.h
--- linux-2.2.18-pre23/drivers/char/drm/mga_drm.h	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/mga_drm.h	Mon Dec  3 20:45:22 2001
@@ -73,17 +73,19 @@
 
 /* 3d state excluding texture units:
  */
-#define MGA_CTXREG_DSTORG   0	/* validated */
-#define MGA_CTXREG_MACCESS  1	
-#define MGA_CTXREG_PLNWT    2	
-#define MGA_CTXREG_DWGCTL    3	
-#define MGA_CTXREG_ALPHACTRL 4
-#define MGA_CTXREG_FOGCOLOR  5
-#define MGA_CTXREG_WFLAG     6
-#define MGA_CTXREG_TDUAL0    7
-#define MGA_CTXREG_TDUAL1    8
-#define MGA_CTXREG_FCOL      9
-#define MGA_CTX_SETUP_SIZE   10
+#define MGA_CTXREG_DSTORG     0	/* validated */
+#define MGA_CTXREG_MACCESS    1	
+#define MGA_CTXREG_PLNWT      2 	
+#define MGA_CTXREG_DWGCTL     3	
+#define MGA_CTXREG_ALPHACTRL  4
+#define MGA_CTXREG_FOGCOLOR   5
+#define MGA_CTXREG_WFLAG      6
+#define MGA_CTXREG_TDUAL0     7
+#define MGA_CTXREG_TDUAL1     8
+#define MGA_CTXREG_FCOL       9
+#define MGA_CTXREG_STENCIL    10
+#define MGA_CTXREG_STENCILCTL 11
+#define MGA_CTX_SETUP_SIZE    12
 
 /* 2d state
  */
@@ -233,6 +235,7 @@
 	/* Mechanism to validate card state.
 	 */
    	int ctxOwner;
+   	int vertexsize;
 } drm_mga_sarea_t;	
 
 /* Device specific ioctls:
@@ -241,6 +244,8 @@
 	unsigned int clear_color;
 	unsigned int clear_depth;
 	unsigned int flags;
+	unsigned int clear_depth_mask;
+	unsigned int clear_color_mask;
 } drm_mga_clear_t;
 
 typedef struct _drm_mga_swap {
diff -urN linux-2.2.18-pre23/drivers/char/drm/mga_drv.c linux/drivers/char/drm/mga_drv.c
--- linux-2.2.18-pre23/drivers/char/drm/mga_drv.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/mga_drv.c	Mon Dec  3 20:45:22 2001
@@ -42,9 +42,9 @@
 }
 
 #define MGA_NAME	 "mga"
-#define MGA_DESC	 "Matrox g200/g400"
-#define MGA_DATE	 "20000719"
-#define MGA_MAJOR	 1
+#define MGA_DESC	 "Matrox G200/G400"
+#define MGA_DATE	 "20000910"
+#define MGA_MAJOR	 2
 #define MGA_MINOR	 0
 #define MGA_PATCHLEVEL	 0
 
@@ -52,8 +52,8 @@
 drm_ctx_t		      mga_res_ctx;
 
 static struct file_operations mga_fops = {
-#if LINUX_VERSION_CODE >= 0x020322
-				/* This started being used approx. 2.3.34 */
+#if LINUX_VERSION_CODE >= 0x020400
+				/* This started being used during 2.4.0-test */
 	owner:   THIS_MODULE,
 #endif
 	open:	 mga_open,
@@ -223,6 +223,7 @@
 
 	DRM_DEBUG("\n");
 
+	if (dev->dev_private) mga_dma_cleanup(dev);
 	if (dev->irq) mga_irq_uninstall(dev);
 	
 	down(&dev->struct_sem);
@@ -422,7 +423,6 @@
 		DRM_INFO("Module unloaded\n");
 	}
 	drm_ctxbitmap_cleanup(dev);
-	mga_dma_cleanup(dev);
 #ifdef CONFIG_MTRR
    	if(dev->agp && dev->agp->agp_mtrr) {
 	   	int retval;
@@ -514,22 +514,27 @@
 	if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)
 	    && dev->lock.pid == current->pid) {
 	      	mga_reclaim_buffers(dev, priv->pid);
-		DRM_ERROR("Process %d dead, freeing lock for context %d\n",
-			  current->pid,
-			  _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
+		DRM_INFO("Process %d dead (ctx %d, d_s = 0x%02x)\n",
+			 current->pid,
+			 _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock),
+			 dev->dev_private ?
+			 ((drm_mga_private_t *)dev->dev_private)
+			 ->dispatch_status
+			 : 0);
+
+		if (dev->dev_private)
+			((drm_mga_private_t *)dev->dev_private)
+				->dispatch_status &= MGA_IN_DISPATCH;
+		
 		drm_lock_free(dev,
 			      &dev->lock.hw_lock->lock,
 			      _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-		
-				/* FIXME: may require heavy-handed reset of
-                                   hardware at this point, possibly
-                                   processed via a callback to the X
-                                   server. */
 	} else if (dev->lock.hw_lock) {
 	   	/* The lock is required to reclaim buffers */
 	   	DECLARE_WAITQUEUE(entry, current);
 	   	add_wait_queue(&dev->lock.lock_queue, &entry);
 		for (;;) {
+			current->state = TASK_INTERRUPTIBLE;
 			if (!dev->lock.hw_lock) {
 				/* Device has been unregistered */
 				retcode = -EINTR;
@@ -544,7 +549,6 @@
 			}			
 				/* Contention */
 			atomic_inc(&dev->total_sleeps);
-			current->state = TASK_INTERRUPTIBLE;
 			schedule();
 			if (signal_pending(current)) {
 				retcode = -ERESTARTSYS;
@@ -555,6 +559,9 @@
 		remove_wait_queue(&dev->lock.lock_queue, &entry);
 	   	if(!retcode) {
 		   	mga_reclaim_buffers(dev, priv->pid);
+			if (dev->dev_private)
+				((drm_mga_private_t *)dev->dev_private)
+					->dispatch_status &= MGA_IN_DISPATCH;
 		   	drm_lock_free(dev, &dev->lock.hw_lock->lock,
 				      DRM_KERNEL_CONTEXT);
 		}
@@ -562,6 +569,13 @@
 	drm_fasync(-1, filp, 0);
 
 	down(&dev->struct_sem);
+	if (priv->remove_auth_on_close == 1) {
+		drm_file_t *temp = dev->file_first;
+		while(temp) {
+			temp->authenticated = 0;
+			temp = temp->next;
+		}
+	}
 	if (priv->prev) priv->prev->next = priv->next;
 	else		dev->file_first	 = priv->next;
 	if (priv->next) priv->next->prev = priv->prev;
@@ -619,7 +633,10 @@
 		func	  = ioctl->func;
 
 		if (!func) {
-			DRM_DEBUG("no function\n");
+			DRM_DEBUG("no function: pid = %d, cmd = 0x%02x,"
+				  " nr = 0x%02x, dev 0x%x, auth = %d\n",
+				  current->pid, cmd, nr, dev->device,
+				  priv->authenticated);
 			retcode = -EINVAL;
 		} else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN))
 			    || (ioctl->auth_needed && !priv->authenticated)) {
diff -urN linux-2.2.18-pre23/drivers/char/drm/mga_drv.h linux/drivers/char/drm/mga_drv.h
--- linux-2.2.18-pre23/drivers/char/drm/mga_drv.h	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/mga_drv.h	Mon Dec  3 20:45:22 2001
@@ -39,8 +39,8 @@
 
 typedef struct {
 	u32 buffer_status;
-   	unsigned int num_dwords;
-   	unsigned int max_dwords;
+   	int num_dwords;
+   	int max_dwords;
    	u32 *current_dma_ptr;
    	u32 *head;
    	u32 phys_head;
@@ -50,7 +50,7 @@
 } drm_mga_prim_buf_t;
 
 typedef struct _drm_mga_freelist {
-   	unsigned int age;
+   	__volatile__ unsigned int age;
    	drm_buf_t *buf;
    	struct _drm_mga_freelist *next;
    	struct _drm_mga_freelist *prev;
@@ -82,6 +82,7 @@
 	int use_agp;
    	drm_mga_warp_index_t WarpIndex[MGA_MAX_G400_PIPES];
 	unsigned int WarpPipe;
+	unsigned int vertexsize;
    	atomic_t pending_bufs;
    	void *status_page;
    	unsigned long real_status_page;
@@ -128,7 +129,6 @@
 extern int mga_dma_cleanup(drm_device_t *dev);
 extern int mga_flush_ioctl(struct inode *inode, struct file *filp,
 			   unsigned int cmd, unsigned long arg);
-extern void mga_flush_write_combine(void);
 extern unsigned int mga_create_sync_tag(drm_device_t *dev);
 extern drm_buf_t *mga_freelist_get(drm_device_t *dev);
 extern int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf);
@@ -179,6 +179,7 @@
 extern int  mga_context_switch(drm_device_t *dev, int old, int new);
 extern int  mga_context_switch_complete(drm_device_t *dev, int new);
 
+#define mga_flush_write_combine()	mb()
 
 typedef enum {
 	TT_GENERAL,
@@ -209,19 +210,26 @@
 #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);				\
- 	} 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);				\
-	}								\
+#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 {					\
@@ -287,7 +295,7 @@
 		       num_dwords + 1 + outcount, ADRINDEX(reg), val);	\
 	if( ++outcount == 4) {						\
 		outcount = 0;						\
-		dma_ptr[0] = *(u32 *)tempIndex;				\
+		dma_ptr[0] = *(unsigned long *)tempIndex;		\
 		dma_ptr+=5;						\
 		num_dwords += 5;					\
 	}								\
@@ -368,6 +376,72 @@
 #define MGAREG_YDSTORG				0x1c94
 #define MGAREG_YTOP 				0x1c98
 #define MGAREG_ZORG 				0x1c0c
+
+/* Warp registers */
+#define MGAREG_WR0                              0x2d00
+#define MGAREG_WR1                              0x2d04
+#define MGAREG_WR2                              0x2d08
+#define MGAREG_WR3                              0x2d0c
+#define MGAREG_WR4                              0x2d10
+#define MGAREG_WR5                              0x2d14
+#define MGAREG_WR6                              0x2d18
+#define MGAREG_WR7                              0x2d1c
+#define MGAREG_WR8                              0x2d20
+#define MGAREG_WR9                              0x2d24
+#define MGAREG_WR10                             0x2d28
+#define MGAREG_WR11                             0x2d2c
+#define MGAREG_WR12                             0x2d30
+#define MGAREG_WR13                             0x2d34
+#define MGAREG_WR14                             0x2d38
+#define MGAREG_WR15                             0x2d3c
+#define MGAREG_WR16                             0x2d40
+#define MGAREG_WR17                             0x2d44
+#define MGAREG_WR18                             0x2d48
+#define MGAREG_WR19                             0x2d4c
+#define MGAREG_WR20                             0x2d50
+#define MGAREG_WR21                             0x2d54
+#define MGAREG_WR22                             0x2d58
+#define MGAREG_WR23                             0x2d5c
+#define MGAREG_WR24                             0x2d60
+#define MGAREG_WR25                             0x2d64
+#define MGAREG_WR26                             0x2d68
+#define MGAREG_WR27                             0x2d6c
+#define MGAREG_WR28                             0x2d70
+#define MGAREG_WR29                             0x2d74
+#define MGAREG_WR30                             0x2d78
+#define MGAREG_WR31                             0x2d7c
+#define MGAREG_WR32                             0x2d80
+#define MGAREG_WR33                             0x2d84
+#define MGAREG_WR34                             0x2d88
+#define MGAREG_WR35                             0x2d8c
+#define MGAREG_WR36                             0x2d90
+#define MGAREG_WR37                             0x2d94
+#define MGAREG_WR38                             0x2d98
+#define MGAREG_WR39                             0x2d9c
+#define MGAREG_WR40                             0x2da0
+#define MGAREG_WR41                             0x2da4
+#define MGAREG_WR42                             0x2da8
+#define MGAREG_WR43                             0x2dac
+#define MGAREG_WR44                             0x2db0
+#define MGAREG_WR45                             0x2db4
+#define MGAREG_WR46                             0x2db8
+#define MGAREG_WR47                             0x2dbc
+#define MGAREG_WR48                             0x2dc0
+#define MGAREG_WR49                             0x2dc4
+#define MGAREG_WR50                             0x2dc8
+#define MGAREG_WR51                             0x2dcc
+#define MGAREG_WR52                             0x2dd0
+#define MGAREG_WR53                             0x2dd4
+#define MGAREG_WR54                             0x2dd8
+#define MGAREG_WR55                             0x2ddc
+#define MGAREG_WR56                             0x2de0
+#define MGAREG_WR57                             0x2de4
+#define MGAREG_WR58                             0x2de8
+#define MGAREG_WR59                             0x2dec
+#define MGAREG_WR60                             0x2df0
+#define MGAREG_WR61                             0x2df4
+#define MGAREG_WR62                             0x2df8
+#define MGAREG_WR63                             0x2dfc
 
 #define PDEA_pagpxfer_enable			0x2
 
diff -urN linux-2.2.18-pre23/drivers/char/drm/mga_state.c linux/drivers/char/drm/mga_state.c
--- linux-2.2.18-pre23/drivers/char/drm/mga_state.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/mga_state.c	Mon Dec  3 20:45:22 2001
@@ -34,34 +34,50 @@
 #include "mga_drv.h"
 #include "drm.h"
 
+/* If you change the functions to set state, PLEASE
+ * change these values
+ */
+
+#define MGAEMITCLIP_SIZE	10
+#define MGAEMITCTX_SIZE		20
+#define MGAG200EMITTEX_SIZE 	20
+#define MGAG400EMITTEX0_SIZE	30
+#define MGAG400EMITTEX1_SIZE	25
+#define MGAG400EMITPIPE_SIZE	50
+#define MGAG200EMITPIPE_SIZE	15
+
+#define MAX_STATE_SIZE ((MGAEMITCLIP_SIZE * MGA_NR_SAREA_CLIPRECTS) + \
+			MGAEMITCTX_SIZE + MGAG400EMITTEX0_SIZE + \
+			MGAG400EMITTEX1_SIZE + MGAG400EMITPIPE_SIZE)
+
 static void mgaEmitClipRect(drm_mga_private_t * dev_priv,
 			    drm_clip_rect_t * box)
 {
 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	unsigned int *regs = sarea_priv->ContextState;
 	PRIMLOCALS;
-	DRM_DEBUG("%s\n", __FUNCTION__);
 
 	/* This takes 10 dwords */
 	PRIMGETPTR(dev_priv);
 
-	/* Force reset of dwgctl (eliminates clip disable) */
+	/* Force reset of dwgctl on G400 (eliminates clip disable bit) */
+	if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
 #if 0
-	PRIMOUTREG(MGAREG_DMAPAD, 0);
-	PRIMOUTREG(MGAREG_DWGSYNC, 0);
-	PRIMOUTREG(MGAREG_DWGSYNC, 0);
-	PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
+		PRIMOUTREG(MGAREG_DMAPAD, 0);
+		PRIMOUTREG(MGAREG_DWGSYNC, 0);
+		PRIMOUTREG(MGAREG_DWGSYNC, 0);
+		PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
 #else
-	PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
-	PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0x80000000);
-	PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
-	PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0x80000000);
+		PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
+		PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0x80000000);
+		PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
+		PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0x80000000);
 #endif
-
+	}
 	PRIMOUTREG(MGAREG_DMAPAD, 0);
 	PRIMOUTREG(MGAREG_CXBNDRY, ((box->x2) << 16) | (box->x1));
-	PRIMOUTREG(MGAREG_YTOP, box->y1 * dev_priv->stride / 2);
-	PRIMOUTREG(MGAREG_YBOT, box->y2 * dev_priv->stride / 2);
+	PRIMOUTREG(MGAREG_YTOP, box->y1 * dev_priv->stride / dev_priv->cpp);
+	PRIMOUTREG(MGAREG_YBOT, box->y2 * dev_priv->stride / dev_priv->cpp);
 
 	PRIMADVANCE(dev_priv);
 }
@@ -71,9 +87,8 @@
 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	unsigned int *regs = sarea_priv->ContextState;
 	PRIMLOCALS;
-	DRM_DEBUG("%s\n", __FUNCTION__);
 
-	/* This takes a max of 15 dwords */
+	/* This takes a max of 20 dwords */
 	PRIMGETPTR(dev_priv);
 
 	PRIMOUTREG(MGAREG_DSTORG, regs[MGA_CTXREG_DSTORG]);
@@ -91,6 +106,11 @@
 		PRIMOUTREG(MGAREG_TDUALSTAGE0, regs[MGA_CTXREG_TDUAL0]);
 		PRIMOUTREG(MGAREG_TDUALSTAGE1, regs[MGA_CTXREG_TDUAL1]);
 		PRIMOUTREG(MGAREG_FCOL, regs[MGA_CTXREG_FCOL]);
+
+		PRIMOUTREG(MGAREG_STENCIL, regs[MGA_CTXREG_STENCIL]);
+		PRIMOUTREG(MGAREG_STENCILCTL, regs[MGA_CTXREG_STENCILCTL]);
+		PRIMOUTREG(MGAREG_DMAPAD, 0);
+		PRIMOUTREG(MGAREG_DMAPAD, 0);
 	} else {
 		PRIMOUTREG(MGAREG_FCOL, regs[MGA_CTXREG_FCOL]);
 		PRIMOUTREG(MGAREG_DMAPAD, 0);
@@ -125,9 +145,9 @@
 	PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4]);
 	PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH]);
 	PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT]);
-	PRIMOUTREG(0x2d00 + 24 * 4, regs[MGA_TEXREG_WIDTH]);
+	PRIMOUTREG(MGAREG_WR24, regs[MGA_TEXREG_WIDTH]);
 
-	PRIMOUTREG(0x2d00 + 34 * 4, regs[MGA_TEXREG_HEIGHT]);
+	PRIMOUTREG(MGAREG_WR34, regs[MGA_TEXREG_HEIGHT]);
 	PRIMOUTREG(MGAREG_TEXTRANS, 0xffff);
 	PRIMOUTREG(MGAREG_TEXTRANSHIGH, 0xffff);
 	PRIMOUTREG(MGAREG_DMAPAD, 0);
@@ -135,17 +155,17 @@
 	PRIMADVANCE(dev_priv);
 }
 
+#define TMC_dualtex_enable 		0x80
+
 static void mgaG400EmitTex0(drm_mga_private_t * dev_priv)
 {
 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	unsigned int *regs = sarea_priv->TexState[0];
-	int multitex = sarea_priv->WarpPipe & MGA_T2;
 	PRIMLOCALS;
-	DRM_DEBUG("%s\n", __FUNCTION__);
 
 	PRIMGETPTR(dev_priv);
 
-	/* This takes a max of 30 dwords */
+	/* This takes 30 dwords */
 
 	PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] | 0x00008000);
 	PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL]);
@@ -160,22 +180,20 @@
 	PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4]);
 	PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH]);
 	PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT]);
-	PRIMOUTREG(0x2d00 + 49 * 4, 0);
+	PRIMOUTREG(MGAREG_WR49, 0);
 
-	PRIMOUTREG(0x2d00 + 57 * 4, 0);
-	PRIMOUTREG(0x2d00 + 53 * 4, 0);
-	PRIMOUTREG(0x2d00 + 61 * 4, 0);
+	PRIMOUTREG(MGAREG_WR57, 0);
+	PRIMOUTREG(MGAREG_WR53, 0);
+	PRIMOUTREG(MGAREG_WR61, 0);
+	PRIMOUTREG(MGAREG_WR52, 0x40);
+
+	PRIMOUTREG(MGAREG_WR60, 0x40);
+	PRIMOUTREG(MGAREG_WR54, regs[MGA_TEXREG_WIDTH] | 0x40);
+	PRIMOUTREG(MGAREG_WR62, regs[MGA_TEXREG_HEIGHT] | 0x40);
 	PRIMOUTREG(MGAREG_DMAPAD, 0);
 
-	if (!multitex) {
-		PRIMOUTREG(0x2d00 + 52 * 4, 0x40);
-		PRIMOUTREG(0x2d00 + 60 * 4, 0x40);
-		PRIMOUTREG(MGAREG_DMAPAD, 0);
-		PRIMOUTREG(MGAREG_DMAPAD, 0);
-	}
-
-	PRIMOUTREG(0x2d00 + 54 * 4, regs[MGA_TEXREG_WIDTH] | 0x40);
-	PRIMOUTREG(0x2d00 + 62 * 4, regs[MGA_TEXREG_HEIGHT] | 0x40);
+	PRIMOUTREG(MGAREG_DMAPAD, 0);
+	PRIMOUTREG(MGAREG_DMAPAD, 0);
 	PRIMOUTREG(MGAREG_TEXTRANS, 0xffff);
 	PRIMOUTREG(MGAREG_TEXTRANSHIGH, 0xffff);
 
@@ -209,14 +227,14 @@
 	PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4]);
 	PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH]);
 	PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT]);
-	PRIMOUTREG(0x2d00 + 49 * 4, 0);
+	PRIMOUTREG(MGAREG_WR49, 0);
 
-	PRIMOUTREG(0x2d00 + 57 * 4, 0);
-	PRIMOUTREG(0x2d00 + 53 * 4, 0);
-	PRIMOUTREG(0x2d00 + 61 * 4, 0);
-	PRIMOUTREG(0x2d00 + 52 * 4, regs[MGA_TEXREG_WIDTH] | 0x40);
+	PRIMOUTREG(MGAREG_WR57, 0);
+	PRIMOUTREG(MGAREG_WR53, 0);
+	PRIMOUTREG(MGAREG_WR61, 0);
+	PRIMOUTREG(MGAREG_WR52, regs[MGA_TEXREG_WIDTH] | 0x40);
 
-	PRIMOUTREG(0x2d00 + 60 * 4, regs[MGA_TEXREG_HEIGHT] | 0x40);
+	PRIMOUTREG(MGAREG_WR60, regs[MGA_TEXREG_HEIGHT] | 0x40);
 	PRIMOUTREG(MGAREG_TEXTRANS, 0xffff);
 	PRIMOUTREG(MGAREG_TEXTRANSHIGH, 0xffff);
 	PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] | 0x00008000);
@@ -224,14 +242,16 @@
 	PRIMADVANCE(dev_priv);
 }
 
-#define EMIT_PIPE 50
+#define MAGIC_FPARAM_HEX_VALUE 0x46480000
+/* This is the hex value of 12800.0f which is a magic value we must
+ * set in wr56.
+ */
+
 static void mgaG400EmitPipe(drm_mga_private_t * dev_priv)
 {
 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	unsigned int pipe = sarea_priv->WarpPipe;
-	float fParam = 12800.0f;
 	PRIMLOCALS;
-	DRM_DEBUG("%s\n", __FUNCTION__);
 
 	PRIMGETPTR(dev_priv);
 
@@ -263,14 +283,14 @@
 			PRIMOUTREG(MGAREG_DWGCTL, MGA_FLUSH_CMD);
 
 			PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 1);
-			PRIMOUTREG(MGAREG_DMAPAD, 0);
 			PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);
-			PRIMOUTREG(MGAREG_DMAPAD, 0);
-
-			PRIMOUTREG(MGAREG_TEXCTL2, 0 | 0x00008000);
+			PRIMOUTREG(MGAREG_TEXCTL2, 0x00008000);
 			PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
+
 			PRIMOUTREG(MGAREG_TEXCTL2, 0x80 | 0x00008000);
 			PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
+			PRIMOUTREG(MGAREG_DMAPAD, 0);
+			PRIMOUTREG(MGAREG_DMAPAD, 0);
 		}
 
 		PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001807);
@@ -286,18 +306,18 @@
 
 	PRIMOUTREG(MGAREG_WFLAG, 0);
 	PRIMOUTREG(MGAREG_WFLAG1, 0);
-	PRIMOUTREG(0x2d00 + 56 * 4, *((u32 *) (&fParam)));
+	PRIMOUTREG(MGAREG_WR56, MAGIC_FPARAM_HEX_VALUE);
 	PRIMOUTREG(MGAREG_DMAPAD, 0);
 
-	PRIMOUTREG(0x2d00 + 49 * 4, 0);	/* Tex stage 0 */
-	PRIMOUTREG(0x2d00 + 57 * 4, 0);	/* Tex stage 0 */
-	PRIMOUTREG(0x2d00 + 53 * 4, 0);	/* Tex stage 1 */
-	PRIMOUTREG(0x2d00 + 61 * 4, 0);	/* Tex stage 1 */
-
-	PRIMOUTREG(0x2d00 + 54 * 4, 0x40);	/* Tex stage 0 : w */
-	PRIMOUTREG(0x2d00 + 62 * 4, 0x40);	/* Tex stage 0 : h */
-	PRIMOUTREG(0x2d00 + 52 * 4, 0x40);	/* Tex stage 1 : w */
-	PRIMOUTREG(0x2d00 + 60 * 4, 0x40);	/* Tex stage 1 : h */
+	PRIMOUTREG(MGAREG_WR49, 0);	/* Tex stage 0 */
+	PRIMOUTREG(MGAREG_WR57, 0);	/* Tex stage 0 */
+	PRIMOUTREG(MGAREG_WR53, 0);	/* Tex stage 1 */
+	PRIMOUTREG(MGAREG_WR61, 0);	/* Tex stage 1 */
+
+	PRIMOUTREG(MGAREG_WR54, 0x40);	/* Tex stage 0 : w */
+	PRIMOUTREG(MGAREG_WR62, 0x40);	/* Tex stage 0 : h */
+	PRIMOUTREG(MGAREG_WR52, 0x40);	/* Tex stage 1 : w */
+	PRIMOUTREG(MGAREG_WR60, 0x40);	/* Tex stage 1 : h */
 
 	/* Dma pading required due to hw bug */
 	PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
@@ -323,12 +343,12 @@
 	PRIMOUTREG(MGAREG_WIADDR, WIA_wmode_suspend);
 	PRIMOUTREG(MGAREG_WVRTXSZ, 7);
 	PRIMOUTREG(MGAREG_WFLAG, 0);
-	PRIMOUTREG(0x2d00 + 24 * 4, 0);	/* tex w/h */
+	PRIMOUTREG(MGAREG_WR24, 0);	/* tex w/h */
 
-	PRIMOUTREG(0x2d00 + 25 * 4, 0x100);
-	PRIMOUTREG(0x2d00 + 34 * 4, 0);	/* tex w/h */
-	PRIMOUTREG(0x2d00 + 42 * 4, 0xFFFF);
-	PRIMOUTREG(0x2d00 + 60 * 4, 0xFFFF);
+	PRIMOUTREG(MGAREG_WR25, 0x100);
+	PRIMOUTREG(MGAREG_WR34, 0);	/* tex w/h */
+	PRIMOUTREG(MGAREG_WR42, 0xFFFF);
+	PRIMOUTREG(MGAREG_WR60, 0xFFFF);
 
 	/* Dma pading required due to hw bug */
 	PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
@@ -487,16 +507,13 @@
 	int use_agp = PDEA_pagpxfer_enable | 0x00000001;
 	u16 y2;
 	PRIMLOCALS;
-	DRM_DEBUG("%s\n", __FUNCTION__);
 
 	y2 = length / 64;
 
 	PRIM_OVERFLOW(dev, dev_priv, 30);
-	PRIMGETPTR(dev_priv);
 
 	PRIMOUTREG(MGAREG_DSTORG, destOrg);
 	PRIMOUTREG(MGAREG_MACCESS, 0x00000000);
-	DRM_DEBUG("srcorg : %lx\n", bus_address | use_agp);
 	PRIMOUTREG(MGAREG_SRCORG, (u32) bus_address | use_agp);
 	PRIMOUTREG(MGAREG_AR5, 64);
 
@@ -510,10 +527,10 @@
 	PRIMOUTREG(MGAREG_FXBNDRY, (63 << 16));
 	PRIMOUTREG(MGAREG_YDSTLEN + MGAREG_MGA_EXEC, y2);
 
+	PRIMOUTREG(MGAREG_DMAPAD, 0);
 	PRIMOUTREG(MGAREG_SRCORG, 0);
 	PRIMOUTREG(MGAREG_PITCH, dev_priv->stride / dev_priv->cpp);
-	PRIMOUTREG(MGAREG_DMAPAD, 0);
-	PRIMOUTREG(MGAREG_DMAPAD, 0);
+	PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);
 	PRIMADVANCE(dev_priv);
 }
 
@@ -526,37 +543,23 @@
 	int length = buf->used;
 	int use_agp = PDEA_pagpxfer_enable;
 	int i = 0;
-	int primary_needed;
 	PRIMLOCALS;
-	DRM_DEBUG("%s\n", __FUNCTION__);
-
-	DRM_DEBUG("dispatch vertex %d addr 0x%lx, "
-		  "length 0x%x nbox %d dirty %x\n",
-		  buf->idx, address, length,
-		  sarea_priv->nbox, sarea_priv->dirty);
-
-	DRM_DEBUG("used : %d, total : %d\n", buf->used, buf->total);
 
 	if (buf->used) {
 		/* WARNING: if you change any of the state functions verify
 		 * these numbers (Overestimating this doesn't hurt).  
 		 */
 		buf_priv->dispatched = 1;
-		primary_needed = (50 + 15 + 15 + 30 + 25 +
-				  10 + 15 * MGA_NR_SAREA_CLIPRECTS);
-		PRIM_OVERFLOW(dev, dev_priv, primary_needed);
+		PRIM_OVERFLOW(dev, dev_priv,
+			      (MAX_STATE_SIZE + (5 * MGA_NR_SAREA_CLIPRECTS)));
 		mgaEmitState(dev_priv);
+
+#if 0
+		length = dev_priv->vertexsize * 3 * 4;
+#endif
+
 		do {
 			if (i < sarea_priv->nbox) {
-				DRM_DEBUG("idx %d Emit box %d/%d:"
-					  "%d,%d - %d,%d\n",
-					  buf->idx,
-					  i, sarea_priv->nbox,
-					  sarea_priv->boxes[i].x1,
-					  sarea_priv->boxes[i].y1,
-					  sarea_priv->boxes[i].x2,
-					  sarea_priv->boxes[i].y2);
-
 				mgaEmitClipRect(dev_priv,
 						&sarea_priv->boxes[i]);
 			}
@@ -592,36 +595,19 @@
 	unsigned int address = (unsigned int) buf->bus_address;
 	int use_agp = PDEA_pagpxfer_enable;
 	int i = 0;
-	int primary_needed;
 	PRIMLOCALS;
-	DRM_DEBUG("%s\n", __FUNCTION__);
-
-	DRM_DEBUG("dispatch indices %d addr 0x%x, "
-		  "start 0x%x end 0x%x nbox %d dirty %x\n",
-		  buf->idx, address, start, end,
-		  sarea_priv->nbox, sarea_priv->dirty);
 
 	if (start != end) {
 		/* WARNING: if you change any of the state functions verify
 		 * these numbers (Overestimating this doesn't hurt).  
 		 */
 		buf_priv->dispatched = 1;
-		primary_needed = (50 + 15 + 15 + 30 + 25 +
-				  10 + 15 * MGA_NR_SAREA_CLIPRECTS);
-		PRIM_OVERFLOW(dev, dev_priv, primary_needed);
+		PRIM_OVERFLOW(dev, dev_priv,
+			      (MAX_STATE_SIZE + (5 * MGA_NR_SAREA_CLIPRECTS)));
 		mgaEmitState(dev_priv);
 
 		do {
 			if (i < sarea_priv->nbox) {
-				DRM_DEBUG("idx %d Emit box %d/%d:"
-					  "%d,%d - %d,%d\n",
-					  buf->idx,
-					  i, sarea_priv->nbox,
-					  sarea_priv->boxes[i].x1,
-					  sarea_priv->boxes[i].y1,
-					  sarea_priv->boxes[i].x2,
-					  sarea_priv->boxes[i].y2);
-
 				mgaEmitClipRect(dev_priv,
 						&sarea_priv->boxes[i]);
 			}
@@ -648,7 +634,9 @@
 
 static void mga_dma_dispatch_clear(drm_device_t * dev, int flags,
 				   unsigned int clear_color,
-				   unsigned int clear_zval)
+				   unsigned int clear_zval,
+				   unsigned int clear_colormask,
+				   unsigned int clear_depthmask)
 {
 	drm_mga_private_t *dev_priv = dev->dev_private;
 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -657,32 +645,21 @@
 	drm_clip_rect_t *pbox = sarea_priv->boxes;
 	unsigned int cmd;
 	int i;
-	int primary_needed;
 	PRIMLOCALS;
-	DRM_DEBUG("%s\n", __FUNCTION__);
 
 	if (dev_priv->sgram)
 		cmd = MGA_CLEAR_CMD | DC_atype_blk;
 	else
 		cmd = MGA_CLEAR_CMD | DC_atype_rstr;
 
-	primary_needed = nbox * 70;
-	if (primary_needed == 0)
-		primary_needed = 70;
-	PRIM_OVERFLOW(dev, dev_priv, primary_needed);
-	PRIMGETPTR(dev_priv);
+	PRIM_OVERFLOW(dev, dev_priv, 35 * MGA_NR_SAREA_CLIPRECTS);
 
 	for (i = 0; i < nbox; i++) {
 		unsigned int height = pbox[i].y2 - pbox[i].y1;
 
-		DRM_DEBUG("dispatch clear %d,%d-%d,%d flags %x!\n",
-			  pbox[i].x1, pbox[i].y1, pbox[i].x2,
-			  pbox[i].y2, flags);
-
 		if (flags & MGA_FRONT) {
-			DRM_DEBUG("clear front\n");
-			PRIMOUTREG(MGAREG_DMAPAD, 0);
 			PRIMOUTREG(MGAREG_DMAPAD, 0);
+			PRIMOUTREG(MGAREG_PLNWT, clear_colormask);
 			PRIMOUTREG(MGAREG_YDSTLEN,
 				   (pbox[i].y1 << 16) | height);
 			PRIMOUTREG(MGAREG_FXBNDRY,
@@ -695,9 +672,8 @@
 		}
 
 		if (flags & MGA_BACK) {
-			DRM_DEBUG("clear back\n");
-			PRIMOUTREG(MGAREG_DMAPAD, 0);
 			PRIMOUTREG(MGAREG_DMAPAD, 0);
+			PRIMOUTREG(MGAREG_PLNWT, clear_colormask);
 			PRIMOUTREG(MGAREG_YDSTLEN,
 				   (pbox[i].y1 << 16) | height);
 			PRIMOUTREG(MGAREG_FXBNDRY,
@@ -710,9 +686,8 @@
 		}
 
 		if (flags & MGA_DEPTH) {
-			DRM_DEBUG("clear depth\n");
-			PRIMOUTREG(MGAREG_DMAPAD, 0);
 			PRIMOUTREG(MGAREG_DMAPAD, 0);
+			PRIMOUTREG(MGAREG_PLNWT, clear_depthmask);
 			PRIMOUTREG(MGAREG_YDSTLEN,
 				   (pbox[i].y1 << 16) | height);
 			PRIMOUTREG(MGAREG_FXBNDRY,
@@ -741,14 +716,11 @@
 	int nbox = sarea_priv->nbox;
 	drm_clip_rect_t *pbox = sarea_priv->boxes;
 	int i;
-	int primary_needed;
+	int pixel_stride = dev_priv->stride / dev_priv->cpp;
+
 	PRIMLOCALS;
-	DRM_DEBUG("%s\n", __FUNCTION__);
 
-	primary_needed = nbox * 5;
-	primary_needed += 65;
-	PRIM_OVERFLOW(dev, dev_priv, primary_needed);
-	PRIMGETPTR(dev_priv);
+	PRIM_OVERFLOW(dev, dev_priv, (MGA_NR_SAREA_CLIPRECTS * 5) + 20);
 
 	PRIMOUTREG(MGAREG_DMAPAD, 0);
 	PRIMOUTREG(MGAREG_DMAPAD, 0);
@@ -758,7 +730,7 @@
 	PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset);
 	PRIMOUTREG(MGAREG_MACCESS, dev_priv->mAccess);
 	PRIMOUTREG(MGAREG_SRCORG, dev_priv->backOffset);
-	PRIMOUTREG(MGAREG_AR5, dev_priv->stride / 2);
+	PRIMOUTREG(MGAREG_AR5, pixel_stride);
 
 	PRIMOUTREG(MGAREG_DMAPAD, 0);
 	PRIMOUTREG(MGAREG_DMAPAD, 0);
@@ -767,10 +739,7 @@
 
 	for (i = 0; i < nbox; i++) {
 		unsigned int h = pbox[i].y2 - pbox[i].y1;
-		unsigned int start = pbox[i].y1 * dev_priv->stride / 2;
-
-		DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n",
-			  pbox[i].x1, pbox[i].y1, pbox[i].x2, pbox[i].y2);
+		unsigned int start = pbox[i].y1 * pixel_stride;
 
 		PRIMOUTREG(MGAREG_AR0, start + pbox[i].x2 - 1);
 		PRIMOUTREG(MGAREG_AR3, start + pbox[i].x1);
@@ -815,7 +784,10 @@
 	 */
 	dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX;
 	mga_dma_dispatch_clear(dev, clear.flags,
-			       clear.clear_color, clear.clear_depth);
+			       clear.clear_color,
+			       clear.clear_depth,
+			       clear.clear_color_mask,
+			       clear.clear_depth_mask);
 	PRIMUPDATE(dev_priv);
 	mga_flush_write_combine();
 	mga_dma_schedule(dev, 1);
diff -urN linux-2.2.18-pre23/drivers/char/drm/r128_dma.c linux/drivers/char/drm/r128_dma.c
--- linux-2.2.18-pre23/drivers/char/drm/r128_dma.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/r128_dma.c	Mon Dec  3 20:45:22 2001
@@ -68,24 +68,8 @@
 	return R128_READ(R128_CLOCK_CNTL_DATA);
 }
 
-static void r128_flush_write_combine(void)
-{
-	int xchangeDummy;
+#define r128_flush_write_combine()	mb()
 
-	__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 */ );
-}
 
 static void r128_status(drm_device_t *dev)
 {
diff -urN linux-2.2.18-pre23/drivers/char/drm/r128_drv.c linux/drivers/char/drm/r128_drv.c
--- linux-2.2.18-pre23/drivers/char/drm/r128_drv.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/r128_drv.c	Mon Dec  3 20:45:22 2001
@@ -51,8 +51,8 @@
 drm_ctx_t	              r128_res_ctx;
 
 static struct file_operations r128_fops = {
-#if LINUX_VERSION_CODE >= 0x020322
-				/* This started being used approx. 2.3.34 */
+#if LINUX_VERSION_CODE >= 0x020400
+				/* This started being used during 2.4.0-test */
 	owner:   THIS_MODULE,
 #endif
 	open:	 r128_open,
@@ -607,6 +607,7 @@
 #endif
                 add_wait_queue(&dev->lock.lock_queue, &entry);
                 for (;;) {
+                        current->state = TASK_INTERRUPTIBLE;
                         if (!dev->lock.hw_lock) {
                                 /* Device has been unregistered */
                                 ret = -EINTR;
@@ -619,10 +620,8 @@
                                 atomic_inc(&dev->total_locks);
                                 break;  /* Got lock */
                         }
-
                                 /* Contention */
                         atomic_inc(&dev->total_sleeps);
-                        current->state = TASK_INTERRUPTIBLE;
 #if 1
 			current->policy |= SCHED_YIELD;
 #endif
diff -urN linux-2.2.18-pre23/drivers/char/drm/tdfx_drv.c linux/drivers/char/drm/tdfx_drv.c
--- linux-2.2.18-pre23/drivers/char/drm/tdfx_drv.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/tdfx_drv.c	Mon Dec  3 20:45:22 2001
@@ -34,11 +34,15 @@
 #include "drmP.h"
 #include "tdfx_drv.h"
 
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
 #include <linux/agp_backend.h>
+#endif
 
 static void __attribute__((unused)) unused(void)
 {
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
 	agp_enable(0);
+#endif
 }
 
 #define TDFX_NAME	 "tdfx"
@@ -566,6 +570,7 @@
 #endif
                 add_wait_queue(&dev->lock.lock_queue, &entry);
                 for (;;) {
+                        current->state = TASK_INTERRUPTIBLE;
                         if (!dev->lock.hw_lock) {
                                 /* Device has been unregistered */
                                 ret = -EINTR;
@@ -578,10 +583,8 @@
                                 atomic_inc(&dev->total_locks);
                                 break;  /* Got lock */
                         }
-                        
                                 /* Contention */
                         atomic_inc(&dev->total_sleeps);
-                        current->state = TASK_INTERRUPTIBLE;
 #if 1
 			current->policy |= SCHED_YIELD;
 #endif
diff -urN linux-2.2.18-pre23/drivers/char/drm/vm.c linux/drivers/char/drm/vm.c
--- linux-2.2.18-pre23/drivers/char/drm/vm.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/drm/vm.c	Mon Dec  3 20:45:22 2001
@@ -44,6 +44,12 @@
 	close:	 drm_vm_close,
 };
 
+struct vm_operations_struct   drm_vm_shm_lock_ops = {
+	nopage:	 drm_vm_shm_nopage_lock,
+	open:	 drm_vm_open,
+	close:	 drm_vm_close,
+};
+
 struct vm_operations_struct   drm_vm_dma_ops = {
 	nopage:	 drm_vm_dma_nopage,
 	open:	 drm_vm_open,
@@ -77,6 +83,40 @@
 			       int write_access)
 #endif
 {
+#if LINUX_VERSION_CODE >= 0x020300
+	drm_map_t	 *map	 = (drm_map_t *)vma->vm_private_data;
+#else
+	drm_map_t	 *map	 = (drm_map_t *)vma->vm_pte;
+#endif
+	unsigned long	 physical;
+	unsigned long	 offset;
+
+	if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
+	if (!map)    		   return NOPAGE_OOM;  /* Nothing allocated */
+
+	offset	 = address - vma->vm_start;
+	physical = (unsigned long)map->handle + offset;
+	atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */
+
+	DRM_DEBUG("0x%08lx => 0x%08lx\n", address, physical);
+#if LINUX_VERSION_CODE < 0x020317
+	return physical;
+#else
+	return virt_to_page(physical);
+#endif
+}
+
+#if LINUX_VERSION_CODE < 0x020317
+unsigned long drm_vm_shm_nopage_lock(struct vm_area_struct *vma,
+				     unsigned long address,
+				     int write_access)
+#else
+				/* Return type changed in 2.3.23 */
+struct page *drm_vm_shm_nopage_lock(struct vm_area_struct *vma,
+				    unsigned long address,
+				    int write_access)
+#endif
+{
 	drm_file_t	 *priv	 = vma->vm_file->private_data;
 	drm_device_t	 *dev	 = priv->dev;
 	unsigned long	 physical;
@@ -89,13 +129,13 @@
 	offset	 = address - vma->vm_start;
 	page	 = offset >> PAGE_SHIFT;
 	physical = (unsigned long)dev->lock.hw_lock + offset;
-	atomic_inc(&mem_map[MAP_NR(physical)].count); /* Dec. by kernel */
+	atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */
 
 	DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", address, page, physical);
 #if LINUX_VERSION_CODE < 0x020317
 	return physical;
 #else
-	return mem_map + MAP_NR(physical);
+	return virt_to_page(physical);
 #endif
 }
 
@@ -124,13 +164,13 @@
 	offset	 = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
 	page	 = offset >> PAGE_SHIFT;
 	physical = dma->pagelist[page] + (offset & (~PAGE_MASK));
-	atomic_inc(&mem_map[MAP_NR(physical)].count); /* Dec. by kernel */
+	atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */
 
 	DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", address, page, physical);
 #if LINUX_VERSION_CODE < 0x020317
 	return physical;
 #else
-	return mem_map + MAP_NR(physical);
+	return virt_to_page(physical);
 #endif
 }
 
@@ -210,7 +250,7 @@
 		  vma->vm_start, vma->vm_end, VM_OFFSET(vma));
 
 				/* Length must match exact page count */
-	if ((length >> PAGE_SHIFT) != dma->page_count) {
+	if (!dma || (length >> PAGE_SHIFT) != dma->page_count) {
 		unlock_kernel();
 		return -EINVAL;
 	}
@@ -283,6 +323,9 @@
 				pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
 				pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
 			}
+#elif defined(__ia64__)
+			if (map->type != _DRM_AGP)
+				vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
 #endif
 			vma->vm_flags |= VM_IO;	/* not in core dump */
 		}
@@ -298,7 +341,17 @@
 		vma->vm_ops = &drm_vm_ops;
 		break;
 	case _DRM_SHM:
-		vma->vm_ops = &drm_vm_shm_ops;
+		if (map->flags & _DRM_CONTAINS_LOCK)
+			vma->vm_ops = &drm_vm_shm_lock_ops;
+		else {
+			vma->vm_ops = &drm_vm_shm_ops;
+#if LINUX_VERSION_CODE >= 0x020300
+			vma->vm_private_data = (void *)map;
+#else
+			vma->vm_pte = (unsigned long)map;
+#endif
+		}
+
 				/* Don't let this area swap.  Change when
 				   DRM_KERNEL advisory is supported. */
 		vma->vm_flags |= VM_LOCKED;
diff -urN linux-2.2.18-pre23/drivers/char/i810_rng.c linux/drivers/char/i810_rng.c
--- linux-2.2.18-pre23/drivers/char/i810_rng.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/i810_rng.c	Mon Dec  3 20:45:22 2001
@@ -84,6 +84,7 @@
 #include <linux/random.h>
 #include <linux/sysctl.h>
 #include <linux/miscdevice.h>
+#include <linux/mm.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -438,6 +439,8 @@
 	pdev = pci_find_device (0x8086, 0x2418, NULL);
 	if (!pdev)
 		pdev = pci_find_device (0x8086, 0x2428, NULL);
+	if (!pdev)
+		pdev = pci_find_device (0x8086, 0x1130, NULL);
 	if (!pdev)
 		return -ENODEV;
 
diff -urN linux-2.2.18-pre23/drivers/char/pc_keyb.c linux/drivers/char/pc_keyb.c
--- linux-2.2.18-pre23/drivers/char/pc_keyb.c	Mon Dec  3 20:44:35 2001
+++ linux/drivers/char/pc_keyb.c	Mon Dec  3 20:45:22 2001
@@ -432,6 +432,7 @@
 }
 
 static unsigned char kbd_exists = 1;
+static unsigned char status_mask = 0;	/* At probe time we want all */
 
 /*
  * This reads the keyboard status port, and does the
@@ -453,7 +454,7 @@
 		/* Check for errors. Shouldnt ever happen but it does on Compaq
 		   Presario 16[89]. */
 		   
-		if(!(status&(KBD_STAT_GTO|KBD_STAT_PERR)))
+		if(!(status& status_mask))
 		{
 			if (status & KBD_STAT_MOUSE_OBF) {
 				handle_mouse_event(scancode);
@@ -748,7 +749,8 @@
 #if defined CONFIG_PSMOUSE
 	psaux_init();
 #endif
-
+	/* Switch keyboard processing to checking error bits */
+	status_mask = KBD_STAT_GTO|KBD_STAT_PERR;
 	/* Ok, finally allocate the IRQ, and off we go.. */
 	kbd_request_irq(keyboard_interrupt);
 }
diff -urN linux-2.2.18-pre23/drivers/net/cosa.c linux/drivers/net/cosa.c
--- linux-2.2.18-pre23/drivers/net/cosa.c	Mon Dec  3 20:44:36 2001
+++ linux/drivers/net/cosa.c	Mon Dec  3 20:45:22 2001
@@ -568,6 +568,7 @@
 	struct device *d;
 	chan->if_ptr = &chan->pppdev;
 	chan->pppdev.dev = kmalloc(sizeof(struct device), GFP_KERNEL);
+	memset(chan->pppdev.dev, 0, sizeof(struct device));
 	sppp_attach(&chan->pppdev);
 	d=chan->pppdev.dev;
 	d->name = chan->name;
diff -urN linux-2.2.18-pre23/drivers/sound/via82cxxx_audio.c linux/drivers/sound/via82cxxx_audio.c
--- linux-2.2.18-pre23/drivers/sound/via82cxxx_audio.c	Mon Dec  3 20:44:48 2001
+++ linux/drivers/sound/via82cxxx_audio.c	Mon Dec  3 20:45:28 2001
@@ -30,6 +30,7 @@
 #include <linux/soundcard.h>
 #include <linux/ac97_codec.h>
 #include <linux/smp_lock.h>
+#include <linux/delay.h>
 #include <asm/io.h>
 #include <asm/delay.h>
 #include <asm/uaccess.h>
diff -urN linux-2.2.18-pre23/fs/dquot.c linux/fs/dquot.c
--- linux-2.2.18-pre23/fs/dquot.c	Mon Dec  3 20:44:49 2001
+++ linux/fs/dquot.c	Mon Dec  3 20:45:28 2001
@@ -1528,7 +1528,7 @@
 	if (IS_ERR(f))
 		goto out_lock;
 	error = -EIO;
-	if (!f->f_op->read && !f->f_op->write)
+	if (!f->f_op || (!f->f_op->read && !f->f_op->write))
 		goto out_f;
 	inode = f->f_dentry->d_inode;
 	error = -EACCES;
diff -urN linux-2.2.18-pre23/fs/ext2/file.c linux/fs/ext2/file.c
--- linux-2.2.18-pre23/fs/ext2/file.c	Mon Dec  3 20:44:49 2001
+++ linux/fs/ext2/file.c	Mon Dec  3 20:45:28 2001
@@ -120,14 +120,14 @@
 		case 1:
 			offset += file->f_pos;
 	}
-	if (((unsigned long long) offset >> 32) != 0) {
 #if BITS_PER_LONG < 64
+	if (offset >> 31)
 		return -EINVAL;
 #else
-		if (offset > ext2_max_sizes[EXT2_BLOCK_SIZE_BITS(inode->i_sb)])
-			return -EINVAL;
+	if (offset < 0 ||
+	    offset > ext2_max_sizes[EXT2_BLOCK_SIZE_BITS(inode->i_sb)])
+		return -EINVAL;
 #endif
-	} 
 	if (offset != file->f_pos) {
 		file->f_pos = offset;
 		file->f_reada = 0;
diff -urN linux-2.2.18-pre23/fs/locks.c linux/fs/locks.c
--- linux-2.2.18-pre23/fs/locks.c	Mon Dec  3 20:44:49 2001
+++ linux/fs/locks.c	Mon Dec  3 20:45:28 2001
@@ -339,7 +339,7 @@
 		goto out;
 
 	error = -EINVAL;
-	if (!filp->f_dentry || !filp->f_dentry->d_inode)
+	if (!filp->f_dentry || !filp->f_dentry->d_inode || !filp->f_op)
 		goto out_putf;
 
 	if (!posix_make_lock(filp, &file_lock, &flock))
@@ -409,6 +409,8 @@
 		goto out_putf;
 	if (!(inode = dentry->d_inode))
 		goto out_putf;
+	if (!filp->f_op)
+		goto out_putf;
 
 	/* Don't allow mandatory locks on files that may be memory mapped
 	 * and shared.
@@ -489,7 +491,9 @@
 	while ((fl = *before) != NULL) {
 		if ((fl->fl_flags & FL_POSIX) && fl->fl_owner == owner) {
 			int (*lock)(struct file *, int, struct file_lock *);
-			lock = filp->f_op->lock;
+			lock = NULL;
+			if(filp->f_op)
+				lock = filp->f_op->lock;
 			if (lock) {
 				file_lock = *fl;
 				file_lock.fl_type = F_UNLCK;
diff -urN linux-2.2.18-pre23/fs/ncpfs/dir.c linux/fs/ncpfs/dir.c
--- linux-2.2.18-pre23/fs/ncpfs/dir.c	Wed Jun  7 14:26:43 2000
+++ linux/fs/ncpfs/dir.c	Mon Dec  3 20:45:28 2001
@@ -5,6 +5,8 @@
  *  Modified for big endian by J.F. Chadima and David S. Miller
  *  Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache
  *  Modified 1998 Wolfram Pienkoss for NLS
+ *  22/11/2000 - Fixed ncp_date_unix2dos for dates earlier than 01/01/1980
+ *		 by Igor Zhbanov(bsg@uniyar.ac.ru)
  *
  */
 
@@ -1158,6 +1160,8 @@
 	int day, year, nl_day, month;
 
 	unix_date = utc2local(unix_date);
+	if (unix_date < 315532800)
+		unix_date = 315532800; /* Jan 1 GMT 00:00:00 1980. But what about another time zone? */
 	*time = (unix_date % 60) / 2 + (((unix_date / 60) % 60) << 5) +
 	    (((unix_date / 3600) % 24) << 11);
 	day = unix_date / 86400 - 3652;
diff -urN linux-2.2.18-pre23/fs/open.c linux/fs/open.c
--- linux-2.2.18-pre23/fs/open.c	Tue Jan  4 10:12:23 2000
+++ linux/fs/open.c	Mon Dec  3 20:45:29 2001
@@ -748,13 +748,6 @@
 	return error;
 }
 
-inline void put_unused_fd(unsigned int fd)
-{
-	FD_CLR(fd, current->files->open_fds);
-	if (fd < current->files->next_fd)
-		current->files->next_fd = fd;
-}
-
 asmlinkage int sys_open(const char * filename, int flags, int mode)
 {
 	char * tmp;
diff -urN linux-2.2.18-pre23/fs/proc/mem.c linux/fs/proc/mem.c
--- linux-2.2.18-pre23/fs/proc/mem.c	Tue Jan  4 10:12:23 2000
+++ linux/fs/proc/mem.c	Mon Dec  3 20:45:29 2001
@@ -196,14 +196,17 @@
 {
 	switch (orig) {
 		case 0:
-			file->f_pos = offset;
-			return file->f_pos;
+			break;
 		case 1:
-			file->f_pos += offset;
-			return file->f_pos;
+			offset += file->f_pos;
+			break;
 		default:
 			return -EINVAL;
 	}
+	if (offset < 0)
+			return -EINVAL;
+	file->f_pos = offset;
+	return offset;
 }
 
 /*
diff -urN linux-2.2.18-pre23/i815.patch linux/i815.patch
--- linux-2.2.18-pre23/i815.patch	Wed Dec 31 16:00:00 1969
+++ linux/i815.patch	Mon Dec  3 20:45:29 2001
@@ -0,0 +1,11 @@
+--- i810_rng.c_orig	Sun Nov 26 18:58:26 2000
++++ i810_rng.c	Sun Nov 26 18:59:27 2000
+@@ -439,6 +439,8 @@
+ 	if (!pdev)
+ 		pdev = pci_find_device (0x8086, 0x2428, NULL);
+ 	if (!pdev)
++		pdev = pci_find_device (0x8086, 0x1130, NULL);
++	if (!pdev)
+ 		return -ENODEV;
+ 
+ 	DPRINTK ("ENTER\n");
diff -urN linux-2.2.18-pre23/include/asm-alpha/processor.h linux/include/asm-alpha/processor.h
--- linux-2.2.18-pre23/include/asm-alpha/processor.h	Mon Aug  9 12:04:57 1999
+++ linux/include/asm-alpha/processor.h	Mon Dec  3 20:45:29 2001
@@ -126,4 +126,11 @@
 #define init_task	(init_task_union.task)
 #define init_stack	(init_task_union.stack)
 
+extern long __kernel_thread(unsigned long, int (*)(void *), void *);
+
+static inline long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+	return __kernel_thread(flags | CLONE_VM, fn, arg);
+}
+
 #endif /* __ASM_ALPHA_PROCESSOR_H */
diff -urN linux-2.2.18-pre23/include/asm-alpha/system.h linux/include/asm-alpha/system.h
--- linux-2.2.18-pre23/include/asm-alpha/system.h	Wed Jun  7 14:26:44 2000
+++ linux/include/asm-alpha/system.h	Mon Dec  3 20:45:29 2001
@@ -376,6 +376,94 @@
 #define tas(ptr) (xchg((ptr),1))
 #define gethere() ({ here: && here;  })
 
+/* 
+ * Atomic compare and exchange.  Compare OLD with MEM, if identical,
+ * store NEW in MEM.  Return the initial value in MEM.  Success is
+ * indicated by comparing RETURN with OLD.
+ *
+ * The memory barrier should be placed in SMP only when we actually
+ * make the change. If we don't change anything (so if the returned
+ * prev is equal to old) then we aren't acquiring anything new and
+ * we don't need any memory barrier as far I can tell.
+ */
+
+#define __HAVE_ARCH_CMPXCHG 1
+
+extern __inline__ unsigned long
+__cmpxchg_u32(volatile int *m, int old, int new)
+{
+	unsigned long prev, cmp;
+
+	__asm__ __volatile__(
+	"1:	ldl_l %0,%5\n"
+	"	cmpeq %0,%3,%1\n"
+	"	beq %1,2f\n"
+	"	mov %4,%1\n"
+	"	stl_c %1,%2\n"
+	"	beq %1,3f\n"
+#ifdef CONFIG_SMP
+	"	mb\n"
+#endif
+	"2:\n"
+	".subsection 2\n"
+	"3:	br 1b\n"
+	".previous"
+	: "=&r"(prev), "=&r"(cmp), "=m"(*m)
+	: "r"((long) old), "r"(new), "m"(*m) : "memory");
+
+	return prev;
+}
+
+extern __inline__ unsigned long
+__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
+{
+	unsigned long prev, cmp;
+
+	__asm__ __volatile__(
+	"1:	ldq_l %0,%5\n"
+	"	cmpeq %0,%3,%1\n"
+	"	beq %1,2f\n"
+	"	mov %4,%1\n"
+	"	stq_c %1,%2\n"
+	"	beq %1,3f\n"
+#ifdef CONFIG_SMP
+	"	mb\n"
+#endif
+	"2:\n"
+	".subsection 2\n"
+	"3:	br 1b\n"
+	".previous"
+	: "=&r"(prev), "=&r"(cmp), "=m"(*m)
+	: "r"((long) old), "r"(new), "m"(*m) : "memory");
+
+	return prev;
+}
+
+/* This function doesn't exist, so you'll get a linker error
+   if something tries to do an invalid cmpxchg().  */
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+static __inline__ unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
+{
+	switch (size) {
+		case 4:
+			return __cmpxchg_u32(ptr, old, new);
+		case 8:
+			return __cmpxchg_u64(ptr, old, new);
+	}
+	__cmpxchg_called_with_bad_pointer();
+	return old;
+}
+
+#define cmpxchg(ptr,o,n)						 \
+  ({									 \
+     __typeof__(*(ptr)) _o_ = (o);					 \
+     __typeof__(*(ptr)) _n_ = (n);					 \
+     (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,		 \
+				    (unsigned long)_n_, sizeof(*(ptr))); \
+  })
+
 #endif /* __ASSEMBLY__ */
 
 #endif
diff -urN linux-2.2.18-pre23/include/asm-alpha/unistd.h linux/include/asm-alpha/unistd.h
--- linux-2.2.18-pre23/include/asm-alpha/unistd.h	Mon Sep  4 10:39:28 2000
+++ linux/include/asm-alpha/unistd.h	Mon Dec  3 20:45:29 2001
@@ -502,13 +502,6 @@
 #include <linux/string.h>
 #include <linux/signal.h>
 
-extern long __kernel_thread(unsigned long, int (*)(void *), void *);
-
-static inline long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
-	return __kernel_thread(flags | CLONE_VM, fn, arg);
-}
-
 extern void sys_idle(void);
 static inline void idle(void)
 {
diff -urN linux-2.2.18-pre23/include/linux/file.h linux/include/linux/file.h
--- linux-2.2.18-pre23/include/linux/file.h	Sat Jan  9 19:16:44 1999
+++ linux/include/linux/file.h	Mon Dec  3 20:45:29 2001
@@ -41,6 +41,15 @@
 	return file;
 }
 
+extern int get_unused_fd(void);   /* in fs/open.c */
+
+static inline void put_unused_fd(unsigned int fd)
+{
+	FD_CLR(fd, current->files->open_fds);
+	if (fd < current->files->next_fd)
+		current->files->next_fd = fd;
+}
+
 /*
  * Install a file pointer in the fd array.
  */
diff -urN linux-2.2.18-pre23/include/linux/fs.h linux/include/linux/fs.h
--- linux-2.2.18-pre23/include/linux/fs.h	Mon Dec  3 20:44:50 2001
+++ linux/include/linux/fs.h	Mon Dec  3 20:45:29 2001
@@ -726,8 +726,6 @@
 asmlinkage int sys_open(const char *, int, int);
 asmlinkage int sys_close(unsigned int);		/* yes, it's really unsigned */
 extern int do_truncate(struct dentry *, unsigned long);
-extern int get_unused_fd(void);
-extern void put_unused_fd(unsigned int);
 
 extern struct file *filp_open(const char *, int, int);
 extern int filp_close(struct file *, fl_owner_t id);
diff -urN linux-2.2.18-pre23/include/linux/kcomp.h linux/include/linux/kcomp.h
--- linux-2.2.18-pre23/include/linux/kcomp.h	Mon Dec  3 20:44:50 2001
+++ linux/include/linux/kcomp.h	Mon Dec  3 20:45:29 2001
@@ -9,16 +9,6 @@
 
 #define __exit
 
-#ifdef __alpha
-extern long __kernel_thread (unsigned long, int (*)(void *), void *);
-static inline long kernel_thread (int (*fn) (void *), void *arg, unsigned long flags)
-{
-	return __kernel_thread (flags | CLONE_VM, fn, arg);
-}
-#undef CONFIG_APM
-#endif
-
-
 #define pci_enable_device(x)			0
 
 #define page_address(x)				(x | PAGE_OFFSET)
