From 8fd1391bb14d8b90a48feaaba466b38121d89e79 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 23 Nov 2007 15:22:53 -0500 Subject: [PATCH] Linux 2.2.18pre24 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) --- Makefile | 2 +- arch/alpha/boot/Makefile | 2 +- arch/alpha/kernel/alpha_ksyms.c | 1 + arch/i386/kernel/dmi_scan.c | 6 +- drivers/char/Makefile | 26 ++-- drivers/char/drm/agpsupport.c | 19 ++- drivers/char/drm/auth.c | 4 +- drivers/char/drm/bufs.c | 2 +- drivers/char/drm/dma.c | 2 +- drivers/char/drm/drmP.h | 38 ++++- drivers/char/drm/ffb_drv.c | 2 +- drivers/char/drm/gamma_dma.c | 4 +- drivers/char/drm/gamma_drv.c | 4 +- drivers/char/drm/i810_dma.c | 16 +-- drivers/char/drm/i810_drv.c | 2 +- drivers/char/drm/lists.c | 49 +++---- drivers/char/drm/lock.c | 2 +- drivers/char/drm/memory.c | 11 ++ drivers/char/drm/mga_context.c | 4 + drivers/char/drm/mga_dma.c | 154 +++++++------------- drivers/char/drm/mga_drm.h | 27 ++-- drivers/char/drm/mga_drv.c | 49 ++++--- drivers/char/drm/mga_drv.h | 110 ++++++++++++--- drivers/char/drm/mga_state.c | 242 ++++++++++++++------------------ drivers/char/drm/r128_dma.c | 20 +-- drivers/char/drm/r128_drv.c | 7 +- drivers/char/drm/tdfx_drv.c | 7 +- drivers/char/drm/vm.c | 65 ++++++++- drivers/char/i810_rng.c | 3 + drivers/char/pc_keyb.c | 6 +- drivers/net/cosa.c | 1 + drivers/sound/via82cxxx_audio.c | 1 + fs/dquot.c | 2 +- fs/ext2/file.c | 8 +- fs/locks.c | 8 +- fs/ncpfs/dir.c | 4 + fs/open.c | 7 - fs/proc/mem.c | 11 +- i815.patch | 11 ++ include/asm-alpha/processor.h | 7 + include/asm-alpha/system.h | 88 ++++++++++++ include/asm-alpha/unistd.h | 7 - include/linux/file.h | 9 ++ include/linux/fs.h | 2 - include/linux/kcomp.h | 10 -- 45 files changed, 636 insertions(+), 426 deletions(-) create mode 100644 i815.patch diff --git a/Makefile b/Makefile index 4fb7f46b9cf5..cacde83e6e79 100644 --- 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/) diff --git a/arch/alpha/boot/Makefile b/arch/alpha/boot/Makefile index ee3460463efd..13990ada0c93 100644 --- a/arch/alpha/boot/Makefile +++ b/arch/alpha/boot/Makefile @@ -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 diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index 04c9256db25c..3809345b34bc 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c @@ -210,5 +210,6 @@ EXPORT_SYMBOL_NOVERS(__remq); EXPORT_SYMBOL_NOVERS(__remqu); EXPORT_SYMBOL_NOVERS(memcpy); EXPORT_SYMBOL_NOVERS(memset); +EXPORT_SYMBOL_NOVERS(memscan); diff --git a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c index 67e11abd901e..27b52e6215b0 100644 --- a/arch/i386/kernel/dmi_scan.c +++ b/arch/i386/kernel/dmi_scan.c @@ -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); diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 9a64a7b6fd6f..79fa5398f38b 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -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 diff --git a/drivers/char/drm/agpsupport.c b/drivers/char/drm/agpsupport.c index 68f14a7aeb46..8ab3374c3189 100644 --- a/drivers/char/drm/agpsupport.c +++ b/drivers/char/drm/agpsupport.c @@ -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, diff --git a/drivers/char/drm/auth.c b/drivers/char/drm/auth.c index 9f81c5391dde..4556bd966091 100644 --- a/drivers/char/drm/auth.c +++ b/drivers/char/drm/auth.c @@ -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); } diff --git a/drivers/char/drm/bufs.c b/drivers/char/drm/bufs.c index c00f051a8409..1f09df8edee9 100644 --- a/drivers/char/drm/bufs.c +++ b/drivers/char/drm/bufs.c @@ -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); diff --git a/drivers/char/drm/dma.c b/drivers/char/drm/dma.c index ac2d1bc5aac7..0464451cd633 100644 --- a/drivers/char/drm/dma.c +++ b/drivers/char/drm/dma.c @@ -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)) { diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index df202f08a3d3..22624e4f704f 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h @@ -33,6 +33,11 @@ #define _DRM_P_H_ #ifdef __KERNEL__ +#ifdef __alpha__ +/* add include of current.h so that "current" is defined + * before static inline funcs in wait.h. 4/21/2000 S + B */ +#include +#endif /* __alpha__ */ #include #include #include @@ -46,10 +51,13 @@ #include #include #include /* For (un)lock_kernel */ +#include +#ifdef __alpha__ +#include /* For pte_wrprotect */ +#endif #include #include #include -#include #ifdef CONFIG_MTRR #include #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); diff --git a/drivers/char/drm/ffb_drv.c b/drivers/char/drm/ffb_drv.c index 0aea8057e884..c610de62ebcb 100644 --- a/drivers/char/drm/ffb_drv.c +++ b/drivers/char/drm/ffb_drv.c @@ -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)) { diff --git a/drivers/char/drm/gamma_dma.c b/drivers/char/drm/gamma_dma.c index a99f24caeef1..00328d56619d 100644 --- a/drivers/char/drm/gamma_dma.c +++ b/drivers/char/drm/gamma_dma.c @@ -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; diff --git a/drivers/char/drm/gamma_drv.c b/drivers/char/drm/gamma_drv.c index e078e25cd9a1..bdd77267b93d 100644 --- a/drivers/char/drm/gamma_drv.c +++ b/drivers/char/drm/gamma_drv.c @@ -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, diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c index f3d9db43ee0e..f5c7c9b4e42d 100644 --- a/drivers/char/drm/i810_dma.c +++ b/drivers/char/drm/i810_dma.c @@ -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)) { diff --git a/drivers/char/drm/i810_drv.c b/drivers/char/drm/i810_drv.c index 371c8d7bca5e..4f1550f356e5 100644 --- a/drivers/char/drm/i810_drv.c +++ b/drivers/char/drm/i810_drv.c @@ -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; diff --git a/drivers/char/drm/lists.c b/drivers/char/drm/lists.c index f62495aa21d2..cd387761fa9b 100644 --- a/drivers/char/drm/lists.c +++ b/drivers/char/drm/lists.c @@ -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(); diff --git a/drivers/char/drm/lock.c b/drivers/char/drm/lock.c index 550827278084..e0c6e0fbffb7 100644 --- a/drivers/char/drm/lock.c +++ b/drivers/char/drm/lock.c @@ -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)) { diff --git a/drivers/char/drm/memory.c b/drivers/char/drm/memory.c index 5023de808920..34d19b203665 100644 --- a/drivers/char/drm/memory.c +++ b/drivers/char/drm/memory.c @@ -32,6 +32,7 @@ #define __NO_VERSION__ #include #include "drmP.h" +#include 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); } diff --git a/drivers/char/drm/mga_context.c b/drivers/char/drm/mga_context.c index 9a73e6c14f58..ebe078bd2e74 100644 --- a/drivers/char/drm/mga_context.c +++ b/drivers/char/drm/mga_context.c @@ -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); } diff --git a/drivers/char/drm/mga_dma.c b/drivers/char/drm/mga_dma.c index 28e8811c8694..8d39958e54e2 100644 --- a/drivers/char/drm/mga_dma.c +++ b/drivers/char/drm/mga_dma.c @@ -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; } diff --git a/drivers/char/drm/mga_drm.h b/drivers/char/drm/mga_drm.h index e75e91a4f501..52cf77665aa1 100644 --- a/drivers/char/drm/mga_drm.h +++ b/drivers/char/drm/mga_drm.h @@ -73,17 +73,19 @@ /* 3d state excluding texture units: */ -#define MGA_CTXREG_DSTORG 0 /* validated */ -#define MGA_CTXREG_MACCESS 1 -#define MGA_CTXREG_PLNWT 2 -#define MGA_CTXREG_DWGCTL 3 -#define MGA_CTXREG_ALPHACTRL 4 -#define MGA_CTXREG_FOGCOLOR 5 -#define MGA_CTXREG_WFLAG 6 -#define MGA_CTXREG_TDUAL0 7 -#define MGA_CTXREG_TDUAL1 8 -#define MGA_CTXREG_FCOL 9 -#define MGA_CTX_SETUP_SIZE 10 +#define MGA_CTXREG_DSTORG 0 /* validated */ +#define MGA_CTXREG_MACCESS 1 +#define MGA_CTXREG_PLNWT 2 +#define MGA_CTXREG_DWGCTL 3 +#define MGA_CTXREG_ALPHACTRL 4 +#define MGA_CTXREG_FOGCOLOR 5 +#define MGA_CTXREG_WFLAG 6 +#define MGA_CTXREG_TDUAL0 7 +#define MGA_CTXREG_TDUAL1 8 +#define MGA_CTXREG_FCOL 9 +#define MGA_CTXREG_STENCIL 10 +#define MGA_CTXREG_STENCILCTL 11 +#define MGA_CTX_SETUP_SIZE 12 /* 2d state */ @@ -233,6 +235,7 @@ 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 { diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c index 011294fcea93..bb5d07f4d4cf 100644 --- a/drivers/char/drm/mga_drv.c +++ b/drivers/char/drm/mga_drv.c @@ -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)) { diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h index fe9e3dbe9bb7..7a9369fcc284 100644 --- a/drivers/char/drm/mga_drv.h +++ b/drivers/char/drm/mga_drv.h @@ -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 diff --git a/drivers/char/drm/mga_state.c b/drivers/char/drm/mga_state.c index 723ccc539e04..a56a600bc0e9 100644 --- a/drivers/char/drm/mga_state.c +++ b/drivers/char/drm/mga_state.c @@ -34,34 +34,50 @@ #include "mga_drv.h" #include "drm.h" +/* If you change the functions to set state, PLEASE + * change these values + */ + +#define MGAEMITCLIP_SIZE 10 +#define MGAEMITCTX_SIZE 20 +#define MGAG200EMITTEX_SIZE 20 +#define MGAG400EMITTEX0_SIZE 30 +#define MGAG400EMITTEX1_SIZE 25 +#define MGAG400EMITPIPE_SIZE 50 +#define MGAG200EMITPIPE_SIZE 15 + +#define MAX_STATE_SIZE ((MGAEMITCLIP_SIZE * MGA_NR_SAREA_CLIPRECTS) + \ + MGAEMITCTX_SIZE + MGAG400EMITTEX0_SIZE + \ + MGAG400EMITTEX1_SIZE + MGAG400EMITPIPE_SIZE) + static void mgaEmitClipRect(drm_mga_private_t * dev_priv, drm_clip_rect_t * box) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int *regs = sarea_priv->ContextState; PRIMLOCALS; - DRM_DEBUG("%s\n", __FUNCTION__); /* This takes 10 dwords */ PRIMGETPTR(dev_priv); - /* Force reset of dwgctl (eliminates clip disable) */ + /* Force reset of dwgctl on G400 (eliminates clip disable bit) */ + if (dev_priv->chipset == MGA_CARD_TYPE_G400) { #if 0 - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DWGSYNC, 0); - PRIMOUTREG(MGAREG_DWGSYNC, 0); - PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]); + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DWGSYNC, 0); + PRIMOUTREG(MGAREG_DWGSYNC, 0); + PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]); #else - PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]); - PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0x80000000); - PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]); - PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0x80000000); + PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]); + PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0x80000000); + PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]); + PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0x80000000); #endif - + } PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_CXBNDRY, ((box->x2) << 16) | (box->x1)); - PRIMOUTREG(MGAREG_YTOP, box->y1 * dev_priv->stride / 2); - PRIMOUTREG(MGAREG_YBOT, box->y2 * dev_priv->stride / 2); + PRIMOUTREG(MGAREG_YTOP, box->y1 * dev_priv->stride / dev_priv->cpp); + PRIMOUTREG(MGAREG_YBOT, box->y2 * dev_priv->stride / dev_priv->cpp); PRIMADVANCE(dev_priv); } @@ -71,9 +87,8 @@ 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); diff --git a/drivers/char/drm/r128_dma.c b/drivers/char/drm/r128_dma.c index 16f79c1f6840..a16a4c0eba3b 100644 --- a/drivers/char/drm/r128_dma.c +++ b/drivers/char/drm/r128_dma.c @@ -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) { diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c index 3180c919f41b..ddeec7175170 100644 --- a/drivers/char/drm/r128_drv.c +++ b/drivers/char/drm/r128_drv.c @@ -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 diff --git a/drivers/char/drm/tdfx_drv.c b/drivers/char/drm/tdfx_drv.c index 6782cf44094e..a9287ec34150 100644 --- a/drivers/char/drm/tdfx_drv.c +++ b/drivers/char/drm/tdfx_drv.c @@ -34,11 +34,15 @@ #include "drmP.h" #include "tdfx_drv.h" +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) #include +#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 diff --git a/drivers/char/drm/vm.c b/drivers/char/drm/vm.c index 5ee9e3242f8e..7c5a24bc988a 100644 --- a/drivers/char/drm/vm.c +++ b/drivers/char/drm/vm.c @@ -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; diff --git a/drivers/char/i810_rng.c b/drivers/char/i810_rng.c index 5116fcdde37c..06207750eecb 100644 --- a/drivers/char/i810_rng.c +++ b/drivers/char/i810_rng.c @@ -84,6 +84,7 @@ #include #include #include +#include #include #include @@ -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; diff --git a/drivers/char/pc_keyb.c b/drivers/char/pc_keyb.c index 16150dc75457..b99dcc9bbf0a 100644 --- a/drivers/char/pc_keyb.c +++ b/drivers/char/pc_keyb.c @@ -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); } diff --git a/drivers/net/cosa.c b/drivers/net/cosa.c index 5267df34ce34..fa08a9907cc0 100644 --- a/drivers/net/cosa.c +++ b/drivers/net/cosa.c @@ -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; diff --git a/drivers/sound/via82cxxx_audio.c b/drivers/sound/via82cxxx_audio.c index dbf4bb3836d3..11bb820d3a8f 100644 --- a/drivers/sound/via82cxxx_audio.c +++ b/drivers/sound/via82cxxx_audio.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/fs/dquot.c b/fs/dquot.c index dc1178a191ae..a4a986f447d7 100644 --- a/fs/dquot.c +++ b/fs/dquot.c @@ -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; diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 7c111f53d41e..a3f0df26a3c1 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -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; diff --git a/fs/locks.c b/fs/locks.c index 3d92427164f7..1444b39fb15c 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -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; diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 63bb0650fa59..acc98b83f440 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c @@ -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; diff --git a/fs/open.c b/fs/open.c index d965f1fb309c..7a9fa444e48f 100644 --- 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; diff --git a/fs/proc/mem.c b/fs/proc/mem.c index 3d2648115798..35c55ec235b2 100644 --- a/fs/proc/mem.c +++ b/fs/proc/mem.c @@ -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 index 000000000000..0c1c2ca914b8 --- /dev/null +++ b/i815.patch @@ -0,0 +1,11 @@ +--- i810_rng.c_orig Sun Nov 26 18:58:26 2000 ++++ i810_rng.c Sun Nov 26 18:59:27 2000 +@@ -439,6 +439,8 @@ + if (!pdev) + pdev = pci_find_device (0x8086, 0x2428, NULL); + if (!pdev) ++ pdev = pci_find_device (0x8086, 0x1130, NULL); ++ if (!pdev) + return -ENODEV; + + DPRINTK ("ENTER\n"); diff --git a/include/asm-alpha/processor.h b/include/asm-alpha/processor.h index d42419196365..4b37452bea4c 100644 --- a/include/asm-alpha/processor.h +++ b/include/asm-alpha/processor.h @@ -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 */ diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h index d6881efc79b5..c74867469012 100644 --- a/include/asm-alpha/system.h +++ b/include/asm-alpha/system.h @@ -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 diff --git a/include/asm-alpha/unistd.h b/include/asm-alpha/unistd.h index b89c68148cf1..2fc3a4ecf9b8 100644 --- a/include/asm-alpha/unistd.h +++ b/include/asm-alpha/unistd.h @@ -502,13 +502,6 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6)\ #include #include -extern long __kernel_thread(unsigned long, int (*)(void *), void *); - -static inline long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) -{ - return __kernel_thread(flags | CLONE_VM, fn, arg); -} - extern void sys_idle(void); static inline void idle(void) { diff --git a/include/linux/file.h b/include/linux/file.h index 05f388f08be7..ecebf2d324d6 100644 --- a/include/linux/file.h +++ b/include/linux/file.h @@ -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. */ diff --git a/include/linux/fs.h b/include/linux/fs.h index f0b427c1b50f..83057fe724c9 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -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); diff --git a/include/linux/kcomp.h b/include/linux/kcomp.h index 95de8e4ee759..2718430f3a9d 100644 --- a/include/linux/kcomp.h +++ b/include/linux/kcomp.h @@ -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) -- 2.39.5