]> git.neil.brown.name Git - history.git/commitdiff
Linux 2.2.18pre24 2.2.18pre24
authorAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:22:53 +0000 (15:22 -0500)
committerAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:22:53 +0000 (15:22 -0500)
o Expose put_unused_fd for modules (Andi Kleen)
o Fix the ps/2 mouse probe I hope (Alan Cox)
o Fix crash in cosa driver (Jan Kasprzak)
o Fix procfs negative seek offset error reporting (HJ Lu)
o Fix ext2 file limit constraints (Andrea Arcangeli)
o Fix lockf corner cases (Andi Kleen, Alan Cox)
o Fix NCPfs date limits (Igor Zhbanov)
o Update DRM (Chip Salzenberg)
o Fix missing Alpha includes (Matt Wilson)
o Fix missing symbols on alpha (Matt Wilson)

45 files changed:
Makefile
arch/alpha/boot/Makefile
arch/alpha/kernel/alpha_ksyms.c
arch/i386/kernel/dmi_scan.c
drivers/char/Makefile
drivers/char/drm/agpsupport.c
drivers/char/drm/auth.c
drivers/char/drm/bufs.c
drivers/char/drm/dma.c
drivers/char/drm/drmP.h
drivers/char/drm/ffb_drv.c
drivers/char/drm/gamma_dma.c
drivers/char/drm/gamma_drv.c
drivers/char/drm/i810_dma.c
drivers/char/drm/i810_drv.c
drivers/char/drm/lists.c
drivers/char/drm/lock.c
drivers/char/drm/memory.c
drivers/char/drm/mga_context.c
drivers/char/drm/mga_dma.c
drivers/char/drm/mga_drm.h
drivers/char/drm/mga_drv.c
drivers/char/drm/mga_drv.h
drivers/char/drm/mga_state.c
drivers/char/drm/r128_dma.c
drivers/char/drm/r128_drv.c
drivers/char/drm/tdfx_drv.c
drivers/char/drm/vm.c
drivers/char/i810_rng.c
drivers/char/pc_keyb.c
drivers/net/cosa.c
drivers/sound/via82cxxx_audio.c
fs/dquot.c
fs/ext2/file.c
fs/locks.c
fs/ncpfs/dir.c
fs/open.c
fs/proc/mem.c
i815.patch [new file with mode: 0644]
include/asm-alpha/processor.h
include/asm-alpha/system.h
include/asm-alpha/unistd.h
include/linux/file.h
include/linux/fs.h
include/linux/kcomp.h

index 4fb7f46b9cf5628d078f987290e4dc6ec5733480..cacde83e6e79799acd4ef2de51e0356f00d174c8 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -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/)
 
index ee3460463efde8605af8ed59b14eaa17a0778c46..13990ada0c93c571c404f16a04ae4613656d01de 100644 (file)
@@ -80,7 +80,7 @@ tools/bootph: bootpheader $(OBJSTRIP)
        $(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
index 04c9256db25ca1f7c0562ae6c6735f9019b23ac6..3809345b34bc10d77e1915d151b9c1da342741c9 100644 (file)
@@ -210,5 +210,6 @@ EXPORT_SYMBOL_NOVERS(__remq);
 EXPORT_SYMBOL_NOVERS(__remqu);
 EXPORT_SYMBOL_NOVERS(memcpy);
 EXPORT_SYMBOL_NOVERS(memset);
+EXPORT_SYMBOL_NOVERS(memscan);
 
 
index 67e11abd901e20c86dfc68c2aca8d10bb5bbfdef..27b52e6215b0470f58419965dbcd1a7f50a6de56 100644 (file)
@@ -31,7 +31,7 @@ static int __init dmi_table(u32 base, int len, int num, void (*decode)(struct dm
        char *buf;
        struct dmi_header *dm;
        u8 *data;
-       int i=0;
+       int i=1;
                
                
        buf = ioremap(base, len);
@@ -124,8 +124,8 @@ static void __init dmi_decode(struct dmi_header *dm)
                         */
                         
                        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);
index 9a64a7b6fd6f0d9437f3cc498056ef1088ee69f1..79fa5398f38bceb9384cf35f3cb498c5ffa00fe4 100644 (file)
@@ -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 @@ else
   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
@@ -642,18 +654,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
 else
index 68f14a7aeb46646923d07d1c396231da9b115ecf..8ab3374c31891db4d7a0ebc63e4687f63f71984e 100644 (file)
@@ -287,6 +287,10 @@ drm_agp_head_t *drm_agp_init(void)
                        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 @@ drm_agp_head_t *drm_agp_init(void)
                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,
index 9f81c5391dde9182c66004629fe5ee7936c4b3e1..4556bd9660911926d97ef935be8d3fac0d49bba1 100644 (file)
@@ -126,12 +126,12 @@ int drm_getmagic(struct inode *inode, struct file *filp, unsigned int cmd,
        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);
        }
index c00f051a8409846bdace74bf28231b545d00d104..1f09df8edee94a7d534d929ba44cf98689c664de 100644 (file)
@@ -73,7 +73,7 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd,
        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);
index ac2d1bc5aac7325056596748a1071e4d73846c4f..0464451cd63325136544ea422e71db8ccfd3c787 100644 (file)
@@ -397,10 +397,10 @@ int drm_dma_enqueue(drm_device_t *dev, drm_dma_t *d)
 
        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)) {
index df202f08a3d3a24ee49250c03a3624e62a774264..22624e4f704ff802dc1e7f250f5f1456b886ed73 100644 (file)
 #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>
 #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
@@ -130,12 +138,27 @@ typedef struct wait_queue *wait_queue_head_t;
 #endif
 #ifndef NOPAGE_OOM
 #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 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
 #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 @@ typedef struct drm_freelist {
        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 @@ typedef struct drm_file {
        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_nopage(struct vm_area_struct *vma,
 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_nopage(struct vm_area_struct *vma,
 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 void      drm_vm_close(struct vm_area_struct *vma);
 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);
index 0aea8057e884ed7370e9533718cefa017e13de38..c610de62ebcbe7ad9b640269d46f10ba8e491617 100644 (file)
@@ -648,6 +648,7 @@ static int ffb_lock(struct inode *inode, struct file *filp, unsigned int cmd, un
 
        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 @@ static int ffb_lock(struct inode *inode, struct file *filp, unsigned int cmd, un
                         
                /* Contention */
                atomic_inc(&dev->total_sleeps);
-               current->state = TASK_INTERRUPTIBLE;
                current->policy |= SCHED_YIELD;
                schedule();
                if (signal_pending(current)) {
index a99f24caeef1c5b91802a3cb2ed948db37f0e19e..00328d56619da68684af8271f092fc9c00b1a346 100644 (file)
@@ -542,8 +542,8 @@ static int gamma_dma_send_buffers(drm_device_t *dev, drm_dma_t *d)
        
        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 @@ int gamma_lock(struct inode *inode, struct file *filp, unsigned int cmd,
                }
                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 @@ int gamma_lock(struct inode *inode, struct file *filp, unsigned int cmd,
                        
                                /* Contention */
                        atomic_inc(&dev->total_sleeps);
-                       current->state = TASK_INTERRUPTIBLE;
                        schedule();
                        if (signal_pending(current)) {
                                ret = -ERESTARTSYS;
index e078e25cd9a1e8fc0cd7198966ef550ad7aa667f..bdd77267b93dee87eefc56e7bef2cce502414996 100644 (file)
@@ -57,8 +57,8 @@ static void __attribute__((unused)) unused(void)
 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,
index f3d9db43ee0edc0be5b9cf9ae54f17bc9388578d..f5c7c9b4e42dfa9fd622ae8a7ae5649129c6ec61 100644 (file)
@@ -282,8 +282,8 @@ static unsigned long i810_alloc_page(drm_device_t *dev)
        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 @@ static void i810_free_page(drm_device_t *dev, unsigned long page)
        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 @@ static void i810_dma_quiescent(drm_device_t *dev)
                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 @@ static int i810_flush_queue(drm_device_t *dev)
                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 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd,
        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 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd,
                        
                                /* Contention */
                        atomic_inc(&dev->total_sleeps);
-                       current->state = TASK_INTERRUPTIBLE;
                        DRM_DEBUG("Calling lock schedule\n");
                        schedule();
                        if (signal_pending(current)) {
index 371c8d7bca5e2f2169b13811f40a45071e4257fe..4f1550f356e5923af287e19c3ec3816774535ec8 100644 (file)
@@ -514,6 +514,7 @@ int i810_release(struct inode *inode, struct file *filp)
                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 @@ int i810_release(struct inode *inode, struct file *filp)
                        }                       
                                /* Contention */
                        atomic_inc(&dev->total_sleeps);
-                       current->state = TASK_INTERRUPTIBLE;
                        schedule();
                        if (signal_pending(current)) {
                                retcode = -ERESTARTSYS;
index f62495aa21d2f75ec475abd7e269aa0409b70c74..cd387761fa9b1ecfd2a198490041ee670d5ce8b0 100644 (file)
@@ -116,6 +116,7 @@ int drm_freelist_create(drm_freelist_t *bl, int count)
        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_destroy(drm_freelist_t *bl)
 
 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 @@ int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
        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 @@ int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
 
 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 @@ drm_buf_t *drm_freelist_get(drm_freelist_t *bl, int block)
        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();
index 550827278084e3def16fbef9210a54c7795d5407..e0c6e0fbffb7c79edb93d828d546edada3630a7d 100644 (file)
@@ -128,10 +128,10 @@ static int drm_flush_queue(drm_device_t *dev, int context)
        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)) {
index 5023de808920eb6f72adfe56949a0b52bd10990a..34d19b203665010c2fb2404d8575cdbebaf43a69 100644 (file)
@@ -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 @@ unsigned long drm_alloc_pages(int order, int area)
        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 @@ void drm_free_pages(unsigned long address, int order, int area)
                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);
        }
index 9a73e6c14f5834c27479c35236c4137ef5c30214..ebe078bd2e747711efe3a28a6656f6c9f814ca88 100644 (file)
@@ -195,6 +195,10 @@ int mga_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
 
        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);
        }
index 28e8811c86949a3df5098e67ef2c1ed333b4a873..8d39958e54e25fd9930dfe91d81d50a3296746f3 100644 (file)
@@ -52,45 +52,28 @@ static unsigned long mga_alloc_page(drm_device_t *dev)
 {
        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 @@ static inline void mga_dma_quiescent(drm_device_t *dev)
        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 @@ static inline void mga_dma_quiescent(drm_device_t *dev)
                        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_buf_t *mga_freelist_get(drm_device_t *dev)
        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 @@ drm_buf_t *mga_freelist_get(drm_device_t *dev)
                return next->buf;
        }
 
-failed_getbuf:
        failed++;
        return NULL;
 }
@@ -312,7 +296,6 @@ static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init)
        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 @@ static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init)
        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 @@ int mga_advance_primary(drm_device_t *dev)
    
        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 @@ int mga_advance_primary(drm_device_t *dev)
 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 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
    
        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 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
                } 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 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
                }
        }
 
+       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 @@ sch_out_wakeup:
        }
 
        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 @@ static void mga_dma_service(int irq, void *device, struct pt_regs *regs)
        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 @@ static void mga_dma_service(int irq, void *device, struct pt_regs *regs)
        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 @@ int mga_dma_cleanup(drm_device_t *dev)
 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 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
        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 @@ static int mga_flush_queue(drm_device_t *dev)
        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 @@ void mga_reclaim_buffers(drm_device_t *dev, pid_t pid)
        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 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
        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 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
                        
                                /* Contention */
                        atomic_inc(&dev->total_sleeps);
-                       current->state = TASK_INTERRUPTIBLE;
                        schedule();
                        if (signal_pending(current)) {
                                ret = -ERESTARTSYS;
@@ -1075,7 +1024,8 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
                }
        }
    
-       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;
 }
                
index e75e91a4f501de8e6855b9b985f756123644156f..52cf77665aa14825c07992b7dc12067c22e8bf3e 100644 (file)
 
 /* 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 @@ typedef struct _drm_mga_sarea {
        /* Mechanism to validate card state.
         */
        int ctxOwner;
+       int vertexsize;
 } drm_mga_sarea_t;     
 
 /* Device specific ioctls:
@@ -241,6 +244,8 @@ typedef struct _drm_mga_clear {
        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 {
index 011294fcea931b2159619ba55378810b8885e271..bb5d07f4d4cffbbd9ce4a852415d4be1d94743b4 100644 (file)
@@ -42,9 +42,9 @@ static void __attribute__((unused)) unused(void)
 }
 
 #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 @@ static drm_device_t         mga_device;
 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 @@ static int mga_takedown(drm_device_t *dev)
 
        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 @@ static void mga_cleanup(void)
                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 @@ int mga_release(struct inode *inode, struct file *filp)
        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 @@ int mga_release(struct inode *inode, struct file *filp)
                        }                       
                                /* Contention */
                        atomic_inc(&dev->total_sleeps);
-                       current->state = TASK_INTERRUPTIBLE;
                        schedule();
                        if (signal_pending(current)) {
                                retcode = -ERESTARTSYS;
@@ -555,6 +559,9 @@ int mga_release(struct inode *inode, struct file *filp)
                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 @@ int mga_release(struct inode *inode, struct file *filp)
        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 @@ int mga_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
                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)) {
index fe9e3dbe9bb70061c923754bb1536464f7e2c2f0..7a9369fcc2847ad7e7c0a54b14d4f353c98b44b3 100644 (file)
@@ -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 @@ typedef struct {
 } 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 @@ typedef struct _drm_mga_private {
        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_init(struct inode *inode, struct file *filp,
 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_rmctx(struct inode *inode, struct file *filp,
 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 @@ typedef struct {
 #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 @@ drm_mga_prim_buf_t *tmp_buf =                                       \
                       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;                                        \
        }                                                               \
@@ -369,6 +377,72 @@ drm_mga_prim_buf_t *tmp_buf =                                      \
 #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
 
 #define WIA_wmode_suspend                      0x0
index 723ccc539e04e3c089f76a99aa179c282f5a9606..a56a600bc0e940cf2c5836a5d86f47d72685c051 100644 (file)
 #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 @@ static void mgaEmitContext(drm_mga_private_t * dev_priv)
        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 @@ static void mgaEmitContext(drm_mga_private_t * dev_priv)
                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 @@ static void mgaG200EmitTex(drm_mga_private_t * dev_priv)
        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 @@ static void mgaG200EmitTex(drm_mga_private_t * dev_priv)
        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 @@ static void mgaG400EmitTex0(drm_mga_private_t * dev_priv)
        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_DMAPAD, 0);
+       PRIMOUTREG(MGAREG_WR57, 0);
+       PRIMOUTREG(MGAREG_WR53, 0);
+       PRIMOUTREG(MGAREG_WR61, 0);
+       PRIMOUTREG(MGAREG_WR52, 0x40);
 
-       if (!multitex) {
-               PRIMOUTREG(0x2d00 + 52 * 4, 0x40);
-               PRIMOUTREG(0x2d00 + 60 * 4, 0x40);
-               PRIMOUTREG(MGAREG_DMAPAD, 0);
-               PRIMOUTREG(MGAREG_DMAPAD, 0);
-       }
+       PRIMOUTREG(MGAREG_WR60, 0x40);
+       PRIMOUTREG(MGAREG_WR54, regs[MGA_TEXREG_WIDTH] | 0x40);
+       PRIMOUTREG(MGAREG_WR62, regs[MGA_TEXREG_HEIGHT] | 0x40);
+       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 @@ static void mgaG400EmitTex1(drm_mga_private_t * dev_priv)
        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 @@ static void mgaG400EmitTex1(drm_mga_private_t * dev_priv)
        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 @@ static void mgaG400EmitPipe(drm_mga_private_t * dev_priv)
                        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 @@ static void mgaG400EmitPipe(drm_mga_private_t * dev_priv)
 
        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(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(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_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 @@ static void mgaG200EmitPipe(drm_mga_private_t * dev_priv)
        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 @@ static void mga_dma_dispatch_tex_blit(drm_device_t * dev,
        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 @@ static void mga_dma_dispatch_tex_blit(drm_device_t * dev,
        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 @@ static void mga_dma_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf)
        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 @@ static void mga_dma_dispatch_indices(drm_device_t * dev,
        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_indices(drm_device_t * dev,
 
 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 @@ static void mga_dma_dispatch_clear(drm_device_t * dev, int flags,
        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 @@ static void mga_dma_dispatch_clear(drm_device_t * dev, int flags,
                }
 
                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 @@ static void mga_dma_dispatch_clear(drm_device_t * dev, int flags,
                }
 
                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 @@ static void mga_dma_dispatch_swap(drm_device_t * dev)
        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 @@ static void mga_dma_dispatch_swap(drm_device_t * dev)
        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 @@ static void mga_dma_dispatch_swap(drm_device_t * dev)
 
        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 @@ int mga_clear_bufs(struct inode *inode, struct file *filp,
         */
        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);
index 16f79c1f6840e3f8ffcd63fdf091a6dbf4f2cb71..a16a4c0eba3b7f66024612130050b8468d408940 100644 (file)
@@ -68,24 +68,8 @@ int R128_READ_PLL(drm_device_t *dev, int addr)
        return R128_READ(R128_CLOCK_CNTL_DATA);
 }
 
-static void r128_flush_write_combine(void)
-{
-       int xchangeDummy;
-
-       __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 */ );
-}
+#define r128_flush_write_combine()     mb()
+
 
 static void r128_status(drm_device_t *dev)
 {
index 3180c919f41bc5c263f7eb7bb7938d8cae5ce589..ddeec7175170d2745f2db7d0d251ed925727ef03 100644 (file)
@@ -51,8 +51,8 @@ static drm_device_t         r128_device;
 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 @@ int r128_lock(struct inode *inode, struct file *filp, unsigned int cmd,
 #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 @@ int r128_lock(struct inode *inode, struct file *filp, unsigned int cmd,
                                 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
index 6782cf44094e034204a1be18261780d9bf0c4c8a..a9287ec341501dad63ad28222332083caeab9175 100644 (file)
 #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 @@ int tdfx_lock(struct inode *inode, struct file *filp, unsigned int cmd,
 #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 @@ int tdfx_lock(struct inode *inode, struct file *filp, unsigned int cmd,
                                 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
index 5ee9e3242f8e04fa8e92debaab11ccc67073d463..7c5a24bc988a59706f9bf81fe0d3e9a3239bdc58 100644 (file)
@@ -44,6 +44,12 @@ struct vm_operations_struct   drm_vm_shm_ops = {
        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,
@@ -76,6 +82,40 @@ struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
                               unsigned long address,
                               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;
@@ -89,13 +129,13 @@ struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
        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 @@ struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
        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 @@ int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
                  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 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
                                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 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
                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;
index 5116fcdde37ccdc2465a03300e2b4f2e2102bbd6..06207750eecb966cf00e3e7fad0c953f70b78e19 100644 (file)
@@ -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 @@ int __init rng_init (void)
        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;
 
index 16150dc75457032cc1b4b972877e75bc28707516..b99dcc9bbf0aefa3d32345167d4bba48b940ff88 100644 (file)
@@ -432,6 +432,7 @@ static inline void handle_mouse_event(unsigned char scancode)
 }
 
 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 @@ static unsigned char handle_kbd_event(void)
                /* 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 @@ void __init pckbd_init_hw(void)
 #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);
 }
index 5267df34ce34ad6519ac8c44cfcb9445964d7123..fa08a9907cc0c39050a36ca7cf5af0b9ee5afba7 100644 (file)
@@ -568,6 +568,7 @@ static void sppp_channel_init(struct channel_data *chan)
        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;
index dbf4bb3836d324e982bd2ecbbd488d4e86f20b44..11bb820d3a8fcea88522a0a91707dd07c87ccb0a 100644 (file)
@@ -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>
index dc1178a191ae06407e7c82d33cfa1d5ebeb9b4ac..a4a986f447d707b4f6b02e63258b2e50f3549a0b 100644 (file)
@@ -1528,7 +1528,7 @@ int quota_on(kdev_t dev, short type, char *path)
        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;
index 7c111f53d41eb32c5fe3b60fa902ee93364b58ac..a3f0df26a3c13d42753c494f2ea1622dff31b13d 100644 (file)
@@ -120,14 +120,14 @@ static long long ext2_file_lseek(
                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;
index 3d92427164f72b17cc1391fb4c3794f4d2bd1771..1444b39fb15cbca1cfb63f97bcf4b8bac5042460 100644 (file)
@@ -339,7 +339,7 @@ int fcntl_getlk(unsigned int fd, struct flock *l)
                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 @@ int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l)
                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 @@ repeat:
        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;
index 63bb0650fa59e07ea605a87cda15309f7838a36d..acc98b83f4409803343784281d094646745eaa2d 100644 (file)
@@ -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 @@ ncp_date_unix2dos(int unix_date, unsigned short *time, unsigned short *date)
        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;
index d965f1fb309c1b34651cad89493504fbd2fec7a5..7a9fa444e48f28cd9d033f3fca1326aa072f8d75 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -748,13 +748,6 @@ out:
        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;
index 3d264811579851472df51392bf32859c1ed3a135..35c55ec235b2220e7155b2b436ec313890a87b62 100644 (file)
@@ -196,14 +196,17 @@ static long long mem_lseek(struct file * file, long long offset, int orig)
 {
        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 --git a/i815.patch b/i815.patch
new file mode 100644 (file)
index 0000000..0c1c2ca
--- /dev/null
@@ -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");
index d42419196365fba40d18959be659782bd9767095..4b37452bea4c74f7baa0dc70ce528c98916db8c1 100644 (file)
@@ -126,4 +126,11 @@ extern void release_thread(struct task_struct *);
 #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 */
index d6881efc79b539e262dbef79297dc053e8108a00..c748674690120a0177e8c00678dda081159476af 100644 (file)
@@ -376,6 +376,94 @@ __xchg(unsigned long x, volatile void * ptr, int size)
 #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
index b89c68148cf1d49167ab9c7309ec09838dcc81d1..2fc3a4ecf9b87057a3c20d97c93562fca8f187d5 100644 (file)
@@ -502,13 +502,6 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6)\
 #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)
 {
index 05f388f08be79cc0a46431332d3fb1e05edec478..ecebf2d324d6fa0ffa10efd77ab6af1a4c23803f 100644 (file)
@@ -41,6 +41,15 @@ extern inline struct file * fget(unsigned int fd)
        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.
  */
index f0b427c1b50f50901d873c3f83cf8c35b4041fac..83057fe724c90186da12a7c845ed58710379f2a1 100644 (file)
@@ -726,8 +726,6 @@ extern inline int locks_verify_area(int read_write, struct inode *inode,
 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);
index 95de8e4ee75922becf6f6f9d5fac3b18d37c31e6..2718430f3a9d89edd0016b3fd2464046c4e617df 100644 (file)
@@ -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)